41日目-車両オペレーティングシステム
81854 ワード
ロールデバイス
コンテキストの切り替え
CPUのRegiter値をスタックに配置し、OSのTask Control Blockメモリに格納します.
void * OSTaskStkInit(void (*task)(void *pd), void *pdata, void *ptos, INT16U opt)
{
OS_STK* stk;
stk = (OS_STK *) ptos; // Load stack pointer
*--stk = (INT32U) pdata; // Simulate a function call (to pass the parameter)
*--stk = (INT32U) TaskBucket; // Return address in case the task exits.
*--stk = 0x00000202; // Eflags (interrupt flag enabled)
*--stk = CS_SELECTOR; // CS
*--stk = (INT32U) task; // Entry point
*--stk = 0; // EAX
*--stk = 0; // ECX
*--stk = 0; // EDX
*--stk = 0; // EBX
*--stk = 0; // ESP (unused)
*--stk = 0; // EBP
*--stk = 0; // ESI
*--stk = 0; // EDI
return stk;
}
実習スケルトンの作成
/***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: module_init, module_exit
***************************************/
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static int sk_init(void)
{
printk("SK Module is up... \n");
return 0;
}
static void sk_exit(void)
{
printk("The module is down...\n");
}
module_init(sk_init);
module_exit(sk_exit);
obj-m += sk.o #startstop.o#hello-1.o hello-2.o hello-3.o hello-4.o
startstop-objs := start.o stop.o
#KDIR := /lib/modules/$(shell uname -r)/build
KDIR := /tftpboot/kernel-mds2450-3.0.22
all:
make -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
make -C $(KDIR) SUBDIRS=$(PWD) clean
ロールデバイスの登録
ポインタ配列と配列ポインタ
포인터 배열 및 배열 포인터 활용사례
1. main 함수 argv : 명령어 라인 인풋
2. 드라이버 등록 함수 -> register_chardev
3. 시그날 함수 -> signal
- 응용프로그램이 상황을 인지할 때 (OS 빼고는 알 수가 없으므로.. 북한)
4. 문자열 간접 정렬 - DataBase index 정렬..
5. 인터럽트 핸들링(벡터링) - 펌웨어 c_handler 함수
6. 동적 배열 활용 - dynamic array
7. 기타 교재내의 예제들 etc ...
API
regstister chrdev P:登録文字デバイス
unregister chrdev:文字デバイスの無効化
=========>>以前の方法
cdev_init, cdev_add... register_chrdev_region.. 等
register_chrdev_region()
alloc_chrdev_region()
Manual allcoation
Dynamic allocation
Major/Minor Number組合せ
cdev構造体
struct cdev
{
struct kobject kobj;
struct module *owner;
const struct file_operations *pos;
struct list_head list;
dev_t dev;
unsigned int count;
}
cdev init()ロールデバイスの登録
cdev add()ロールデバイスの登録
cdev del()ロールデバイスを無効にする
実習デバイス登録
/***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: register and unregister chrdev
***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h> // 파일에 읽고 써야하니까
#include <linux/cdev.h> // 캐릭터 디바이스 (저장매체들)
MODULE_LICENSE("GPL");
static int sk_major = 0, sk_minor = 0;
static int result;
static dev_t sk_dev;
/* file_operations의 레코드를 할당한다. */
static struct file_operations sk_fops;
static struct cdev sk_cdev;
static int sk_register_cdev(void);
static int sk_init(void)
{
printk("SK Module is up... \n");
/* 문자 디바이스의 등록 */
if((result = sk_register_cdev()) < 0)
{
return result;
}
return 0;
}
static void sk_exit(void)
{
printk("The module is down...\n");
cdev_del(&sk_cdev); // 장치 떼어낸다.
unregister_chrdev_region(sk_dev, 1); // 번호 해제
}
static int sk_register_cdev(void)
{
int error;
/* allocation device number */
if(sk_major)
{
sk_dev = MKDEV(sk_major, sk_minor);
error = register_chrdev_region(sk_dev, 1, "sk");
} else
{
error = alloc_chrdev_region(&sk_dev, sk_minor, 1, "sk");
sk_major = MAJOR(sk_dev);
}
if(error < 0)
{
printk(KERN_WARNING "sk: can't get major %d\n", sk_major);
return result;
}
printk("major number=%d\n", sk_major);
/* register chrdev */
cdev_init(&sk_cdev, &sk_fops);
sk_cdev.owner = THIS_MODULE;
sk_cdev.ops = &sk_fops;
error = cdev_add(&sk_cdev, sk_dev, 1);
if(error)
printk(KERN_NOTICE "sk Register Error %d\n", error);
return 0;
}
module_init(sk_init);
module_exit(sk_exit);
実習デバイスファイルの作成 lsmod sk2.ko
mknod /dev/SK c 253 0 # device name, type, major number, minor nubmber
ls /dev -al | grep SK
rm /dev/SK
rmmod sk
file_operations
lsmod sk2.ko
mknod /dev/SK c 253 0 # device name, type, major number, minor nubmber
ls /dev -al | grep SK
rm /dev/SK
rmmod sk
実習open & release
/***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: Implementation of system call
***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/cdev.h>
MODULE_LICENSE("GPL");
static int sk_major = 0, sk_minor = 0;
static int result;
static dev_t sk_dev;
static struct cdev sk_cdev;
static int sk_register_cdev(void);
/* TODO: Define Prototype of functions */
static int sk_open(struct inode *inode, struct file *filp);
static int sk_release(struct inode *inode, struct file *filp);
/* TODO: Implementation of functions */
static int sk_open(struct inode *inode, struct file *filp)
{
printk("Device has been opened...\n");
/* H/W Initalization */
//MOD_INC_USE_COUNT; /* for kernel 2.4 */
return 0;
}
static int sk_release(struct inode *inode, struct file *filp)
{
printk("Device has been closed...\n");
return 0;
}
struct file_operations sk_fops = {
.open = sk_open,
.release = sk_release,
};
static int __init sk_init(void)
{
printk("SK Module is up... \n");
if((result = sk_register_cdev()) < 0)
{
return result;
}
return 0;
}
static void __exit sk_exit(void)
{
printk("The module is down...\n");
cdev_del(&sk_cdev);
unregister_chrdev_region(sk_dev, 1);
}
static int sk_register_cdev(void)
{
int error;
/* allocation device number */
if(sk_major)
{
sk_dev = MKDEV(sk_major, sk_minor);
error = register_chrdev_region(sk_dev, 1, "sk");
}
else
{
error = alloc_chrdev_region(&sk_dev, sk_minor, 1, "sk");
sk_major = MAJOR(sk_dev);
}
if(error < 0)
{
printk(KERN_WARNING "sk: can't get major %d\n", sk_major);
return result;
}
printk("major number=%d\n", sk_major);
/* register chrdev */
cdev_init(&sk_cdev, &sk_fops);
sk_cdev.owner = THIS_MODULE;
sk_cdev.ops = &sk_fops;
error = cdev_add(&sk_cdev, sk_dev, 1);
if(error)
printk(KERN_NOTICE "sk Register Error %d\n", error);
return 0;
}
module_init(sk_init);
module_exit(sk_exit);
/***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: Implementation of system call
***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/cdev.h>
MODULE_LICENSE("GPL");
static int sk_major = 0, sk_minor = 0;
static int result;
static dev_t sk_dev;
static struct cdev sk_cdev;
static int sk_register_cdev(void);
/* TODO: Define Prototype of functions */
static int sk_open(struct inode *inode, struct file *filp);
static int sk_release(struct inode *inode, struct file *filp);
/* TODO: Implementation of functions */
static int sk_open(struct inode *inode, struct file *filp)
{
printk("Device has been opened...\n");
/* H/W Initalization */
//MOD_INC_USE_COUNT; /* for kernel 2.4 */
return 0;
}
static int sk_release(struct inode *inode, struct file *filp)
{
printk("Device has been closed...\n");
return 0;
}
struct file_operations sk_fops = {
.open = sk_open,
.release = sk_release,
};
static int __init sk_init(void)
{
printk("SK Module is up... \n");
if((result = sk_register_cdev()) < 0)
{
return result;
}
return 0;
}
static void __exit sk_exit(void)
{
printk("The module is down...\n");
cdev_del(&sk_cdev);
unregister_chrdev_region(sk_dev, 1);
}
static int sk_register_cdev(void)
{
int error;
/* allocation device number */
if(sk_major)
{
sk_dev = MKDEV(sk_major, sk_minor);
error = register_chrdev_region(sk_dev, 1, "sk");
}
else
{
error = alloc_chrdev_region(&sk_dev, sk_minor, 1, "sk");
sk_major = MAJOR(sk_dev);
}
if(error < 0)
{
printk(KERN_WARNING "sk: can't get major %d\n", sk_major);
return result;
}
printk("major number=%d\n", sk_major);
/* register chrdev */
cdev_init(&sk_cdev, &sk_fops);
sk_cdev.owner = THIS_MODULE;
sk_cdev.ops = &sk_fops;
error = cdev_add(&sk_cdev, sk_dev, 1);
if(error)
printk(KERN_NOTICE "sk Register Error %d\n", error);
return 0;
}
module_init(sk_init);
module_exit(sk_exit);
実習writeの追加 /***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: Implementation of system call
***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
static int sk_major = 0, sk_minor = 0;
static int result;
static dev_t sk_dev;
static struct cdev sk_cdev;
static int sk_register_cdev(void);
/* TODO: Define Prototype of functions */
static int sk_open(struct inode *inode, struct file *filp);
static int sk_release(struct inode *inode, struct file *filp);
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
/* TODO: Implementation of functions */
static int sk_open(struct inode *inode, struct file *filp)
{
printk("Device has been opened...\n");
/* H/W Initalization */
return 0;
}
static int sk_release(struct inode *inode, struct file *filp)
{
printk("Device has been closed...\n");
return 0;
}
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
char data[11];
copy_from_user(data, buf, count);
printk("data >>>>> = %s\n", data);
return count;
}
struct file_operations sk_fops = {
.open = sk_open,
.release = sk_release,
.write = sk_write,
};
static int __init sk_init(void)
{
printk("SK Module is up... \n");
if((result = sk_register_cdev()) < 0)
{
return result;
}
return 0;
}
static void __exit sk_exit(void)
{
printk("The module is down...\n");
cdev_del(&sk_cdev);
unregister_chrdev_region(sk_dev, 1);
}
static int sk_register_cdev(void)
{
int error;
/* allocation device number */
if(sk_major)
{
sk_dev = MKDEV(sk_major, sk_minor);
error = register_chrdev_region(sk_dev, 1, "sk");
} else {
error = alloc_chrdev_region(&sk_dev, sk_minor, 1, "sk");
sk_major = MAJOR(sk_dev);
if(error < 0)
{
printk(KERN_WARNING "sk: can't get major %d\n", sk_major);
return result;
}
printk("major number=%d\n", sk_major);
/* register chrdev */
cdev_init(&sk_cdev, &sk_fops);
sk_cdev.owner = THIS_MODULE;
sk_cdev.ops = &sk_fops;
error = cdev_add(&sk_cdev, sk_dev, 1);
if(error)
printk(KERN_NOTICE "sk Register Error %d\n", error);
return 0;
}
module_init(sk_init);
module_exit(sk_exit);
/***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: Implementation of system call
***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
static int sk_major = 0, sk_minor = 0;
static int result;
static dev_t sk_dev;
static struct cdev sk_cdev;
static int sk_register_cdev(void);
/* TODO: Define Prototype of functions */
static int sk_open(struct inode *inode, struct file *filp);
static int sk_release(struct inode *inode, struct file *filp);
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
/* TODO: Implementation of functions */
static int sk_open(struct inode *inode, struct file *filp)
{
printk("Device has been opened...\n");
/* H/W Initalization */
return 0;
}
static int sk_release(struct inode *inode, struct file *filp)
{
printk("Device has been closed...\n");
return 0;
}
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
char data[11];
copy_from_user(data, buf, count);
printk("data >>>>> = %s\n", data);
return count;
}
struct file_operations sk_fops = {
.open = sk_open,
.release = sk_release,
.write = sk_write,
};
static int __init sk_init(void)
{
printk("SK Module is up... \n");
if((result = sk_register_cdev()) < 0)
{
return result;
}
return 0;
}
static void __exit sk_exit(void)
{
printk("The module is down...\n");
cdev_del(&sk_cdev);
unregister_chrdev_region(sk_dev, 1);
}
static int sk_register_cdev(void)
{
int error;
/* allocation device number */
if(sk_major)
{
sk_dev = MKDEV(sk_major, sk_minor);
error = register_chrdev_region(sk_dev, 1, "sk");
} else {
error = alloc_chrdev_region(&sk_dev, sk_minor, 1, "sk");
sk_major = MAJOR(sk_dev);
if(error < 0)
{
printk(KERN_WARNING "sk: can't get major %d\n", sk_major);
return result;
}
printk("major number=%d\n", sk_major);
/* register chrdev */
cdev_init(&sk_cdev, &sk_fops);
sk_cdev.owner = THIS_MODULE;
sk_cdev.ops = &sk_fops;
error = cdev_add(&sk_cdev, sk_dev, 1);
if(error)
printk(KERN_NOTICE "sk Register Error %d\n", error);
return 0;
}
module_init(sk_init);
module_exit(sk_exit);
/***************************************
* Filename: sk_app.c
* Title: Skeleton Device Application
* Desc: Implementation of system call
***************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
int main(void)
{
int retn;
int fd;
/* write에서 사용할 버퍼 */
char buf[100] = "write...\n";
fd = open("/dev/SK", O_RDWR);
printf("fd = %d\n", fd);
if (fd<0)
{
perror("/dev/SK error");
exit(-1);
}
else
printf("SK has been detected...\n");
/* fd가 가르키는 파일에 buf에 있는 10바이트를 쓰라는 의미 */
retn = write(fd, buf, 10);
printf("\nSize of written data : %d\n", retn);
close(fd);
return 0;
}
./sk4
甲級Linux同期 A task -> -1 -> 1
↓
Some Register -> 1 (A의 1 저장)
↑
B task -> -1 -> 0 (B의 0 저장?)
A task -> -1 -> 1
↓
Some Register -> 1 (A의 1 저장)
↑
B task -> -1 -> 0 (B의 0 저장?)
解決策
実習readの追加 /***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: Implementation of system call
***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
static int sk_major = 0, sk_minor = 0;
static int result;
static dev_t sk_dev;
static struct cdev sk_cdev;
static int sk_register_cdev(void);
/* TODO: Define Prototype of functions */
static int sk_open(struct inode *inode, struct file *filp);
static int sk_release(struct inode *inode, struct file *filp);
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
static int sk_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
/* TODO: Implementation of functions */
static int sk_open(struct inode *inode, struct file *filp) {
printk("Device has been opened...\n");
/* H/W Initalization */
return 0;
}
static int sk_release(struct inode *inode, struct file *filp) {
printk("Device has been closed...\n");
return 0;
}
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
char data[11];
copy_from_user(data, buf, count);
printk("data >>>>> = %s\n", data);
return count;
}
static int sk_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) {
/* App. 에 전달할 문자열을 담은공간 */
char data[20] = "this is read func...";
/* App. 으로 전달 받은 주소로부터 count까지의 내용을 buf로 옮긴다 */
copy_to_user(buf, data, count);
return 0;
}
struct file_operations sk_fops = {
.open = sk_open,
.release = sk_release,
.write = sk_write,
.read = sk_read,
}
;
static int __init sk_init(void) {
printk("SK Module is up... \n");
if((result = sk_register_cdev()) < 0) {
return result;
}
return 0;
}
static void __exit sk_exit(void) {
printk("The module is down...\n");
cdev_del(&sk_cdev);
unregister_chrdev_region(sk_dev, 1);
}
static int sk_register_cdev(void) {
int error;
/* allocation device number */
if(sk_major) {
sk_dev = MKDEV(sk_major, sk_minor);
error = register_chrdev_region(sk_dev, 1, "sk");
} else {
error = alloc_chrdev_region(&sk_dev, sk_minor, 1, "sk");
sk_major = MAJOR(sk_dev);
}
if(error < 0) {
printk(KERN_WARNING "sk: can't get major %d\n", sk_major);
return result;
}
printk("major number=%d\n", sk_major);
/* register chrdev */
cdev_init(&sk_cdev, &sk_fops);
sk_cdev.owner = THIS_MODULE;
sk_cdev.ops = &sk_fops;
error = cdev_add(&sk_cdev, sk_dev, 1);
if(error)
printk(KERN_NOTICE "sk Register Error %d\n", error);
return 0;
}
module_init(sk_init);
module_exit(sk_exit);
/***************************************
* Filename: sk.c
* Title: Skeleton Device
* Desc: Implementation of system call
***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
static int sk_major = 0, sk_minor = 0;
static int result;
static dev_t sk_dev;
static struct cdev sk_cdev;
static int sk_register_cdev(void);
/* TODO: Define Prototype of functions */
static int sk_open(struct inode *inode, struct file *filp);
static int sk_release(struct inode *inode, struct file *filp);
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
static int sk_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
/* TODO: Implementation of functions */
static int sk_open(struct inode *inode, struct file *filp) {
printk("Device has been opened...\n");
/* H/W Initalization */
return 0;
}
static int sk_release(struct inode *inode, struct file *filp) {
printk("Device has been closed...\n");
return 0;
}
static int sk_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
char data[11];
copy_from_user(data, buf, count);
printk("data >>>>> = %s\n", data);
return count;
}
static int sk_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) {
/* App. 에 전달할 문자열을 담은공간 */
char data[20] = "this is read func...";
/* App. 으로 전달 받은 주소로부터 count까지의 내용을 buf로 옮긴다 */
copy_to_user(buf, data, count);
return 0;
}
struct file_operations sk_fops = {
.open = sk_open,
.release = sk_release,
.write = sk_write,
.read = sk_read,
}
;
static int __init sk_init(void) {
printk("SK Module is up... \n");
if((result = sk_register_cdev()) < 0) {
return result;
}
return 0;
}
static void __exit sk_exit(void) {
printk("The module is down...\n");
cdev_del(&sk_cdev);
unregister_chrdev_region(sk_dev, 1);
}
static int sk_register_cdev(void) {
int error;
/* allocation device number */
if(sk_major) {
sk_dev = MKDEV(sk_major, sk_minor);
error = register_chrdev_region(sk_dev, 1, "sk");
} else {
error = alloc_chrdev_region(&sk_dev, sk_minor, 1, "sk");
sk_major = MAJOR(sk_dev);
}
if(error < 0) {
printk(KERN_WARNING "sk: can't get major %d\n", sk_major);
return result;
}
printk("major number=%d\n", sk_major);
/* register chrdev */
cdev_init(&sk_cdev, &sk_fops);
sk_cdev.owner = THIS_MODULE;
sk_cdev.ops = &sk_fops;
error = cdev_add(&sk_cdev, sk_dev, 1);
if(error)
printk(KERN_NOTICE "sk Register Error %d\n", error);
return 0;
}
module_init(sk_init);
module_exit(sk_exit);
/***************************************
* Filename: sk_app.c
* Title: Skeleton Device Application
* Desc: Implementation of system call
***************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
int main(void) {
int retn;
int fd;
// char buf[100] = "write...\n";
char buf[100] = {
0
}
;
fd = open("/dev/SK", O_RDWR);
printf("fd = %d\n", fd);
if (fd<0) {
perror("/dev/SK error");
exit(-1);
} else
printf("SK has been detected...\n");
//retn = write(fd, buf, 10);
retn = read(fd, buf, 20);
// fd가 가르키는 파일에 buf에서 20byte 읽음
printf("\ndata : %s\n", buf);
close(fd);
return 0;
}
ioctl
Reference
この問題について(41日目-車両オペレーティングシステム), 我々は、より多くの情報をここで見つけました https://velog.io/@lottocomeon/41일차-차량용-OSテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol