Linux 커널-간단한 문자 장치 scull
Hello 프로그램의 컴파일을 통해 모두가 내장 모듈에 대해 이미 알고 있다고 믿습니다.다음은 어떻게 간단한 문자 장치를 실현하는지 소개할 것이다.먼저 사용자 디렉터리에 폴더 scull을 만듭니다. 세 개의 파일을 포함합니다: scull.c、Makefile、build
scull.c
#include
#include
#include /* everything... */
#include
#include /* copy_*_user */
MODULE_LICENSE("GPL");
int scull_major = 0;
int scull_minor = 0;
struct cdev cdev; /* Char device structure */
#define MAX_SIZE 10
size_t size = 0;
char store[MAX_SIZE];
/*
* Open and close
*/
int scull_open(struct inode *inode , struct file *filp)
{
/* trim to 0 the length of the device if open was write -only
*/
if ( (filp ->f_flags & O_ACCMODE) == O_WRONLY) {
size = 0;
}
return 0; /* success */
}
int scull_release(struct inode *inode , struct file *filp)
{
return 0;
}
/*
* Data management: read and write
*/
ssize_t scull_read(struct file *filp , char __user *buf, size_t count, loff_t *f_pos)
{
ssize_t retval = 0;
if (*f_pos >= size)
goto out;
if (*f_pos + count > size)
count = size - *f_pos;
if (copy_to_user(buf, store + *f_pos , count)) {
retval = -EFAULT;
goto out;
}
*f_pos += count;
retval = count;
out:
return retval;
}
ssize_t scull_write(struct file *filp , const char __user *buf,size_t count ,loff_t *f_pos)
{
ssize_t retval = -ENOMEM; /* value used in "goto out"
statements */
if (*f_pos >= MAX_SIZE)
goto out;
if (*f_pos + count > MAX_SIZE)
count = MAX_SIZE - *f_pos;
if (copy_from_user(store + *f_pos , buf, count)) {
retval = -EFAULT;
goto out;
}
*f_pos += count;
retval = count;
/* update the size */
if (size < *f_pos)
size = *f_pos;
out:
return retval;
}
struct file_operations scull_fops = {
.owner = THIS_MODULE ,
.read = scull_read ,
.write = scull_write ,
.open = scull_open ,
.release = scull_release ,
};
int scull_init_module(void)
{
int result;
dev_t dev = 0;// linux unsigned int ,32 , , 12 , 20
/*
* Get a range of minor numbers to work with , asking for a
dynamic major
*/
result = alloc_chrdev_region(&dev, scull_minor , 1, "scull");// , "scull", 1, scull_minor, dev 。 0 。
scull_major = MAJOR(dev);
if (result < 0) {
printk(KERN_WARNING "scull:?can't?get?major?%d
",
scull_major);
return result;
}
/* register our device */
cdev_init(&cdev , &scull_fops);// scull_fops cdev。
cdev.owner = THIS_MODULE;
cdev.ops = &scull_fops;
result = cdev_add (&cdev , dev, 1);// 。
if (result) {
printk(KERN_WARNING "Error?%d?adding?scull", result)
;
unregister_chrdev_region(dev, 1);
return result;
}
return 0; /* succeed */
}
void scull_cleanup_module(void)
{
/* cleanup_module is never called if registering failed */
dev_t dev;
cdev_del(&cdev);
dev = MKDEV(scull_major , scull_minor);
unregister_chrdev_region(dev, 1);
}
module_init(scull_init_module);
module_exit(scull_cleanup_module);
cdev 구조의 설명
struct cdev {
struct kobject kobj;
struct module *owner;//
const struct file_operations *ops;//
struct list_head list;
dev_t dev; // ,int , 12 , 20
unsigned int count;
};
cdev_add (&cdev , dev, 1)
이것은 문자 장치에 장치를 추가하는 것입니다.구체적 실현 중인 kobjmap은 좀 복잡하고 관심 있는 건 스티브miao의 China Unix 블로그나 검색 관련 문제에 대한 깊은 연구.
read()와 write() 함수.
scull_read/scull_write(struct file *filp , char __user *buf, size_t count,loff_t *f_pos)
filp 파일 형식은 일반적으로 오픈 함수에서filp가 본 모듈의 파일 구조를 가리키지만 본고는 전역 변수를 사용하여filp를 사용하지 않습니다.buf는 읽을 곳,count는 읽을 개수, fops는 오프셋입니다.
copy_from_user 및 copyto_사용자의 함수 원형은strncpy입니다. 내부 핵과 사용자 권한 문제가 관련되어 봉인되어 있기 때문입니다.
build
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
Makefile
obj-m := scull.o
컴파일 마운트 모듈
컴파일링: 명령줄을 열고 다음 명령을 실행합니다.
cd scull
sh build
설치:
sudo insmod scull.ko // scull.ko
등록된 장치를 보려면:
cat /proc/devices | grep scull
만약 아래의 정보와 유사하다면, 모든 것이 순조롭다는 것을 설명할 수 있다.그렇지 않으면 모듈 초기화에 오류가 발생했습니다./var/log/kern.log 구체적 상황 파악.
250 scull
장치 파일 만들기
sudo mknod /dev/scull c 250 0// 250
테스트
sudo su
echo 123 > /dev/scull
cat /dev/scull
출력 123을 보면 장치가 정상적으로 작동하고 있음을 증명합니다.
장치 제거
sudo rm /dev/scull
sudo rmmod scull
이번 문자 설비에 대해 진지하게 대처하고 관련 자료를 읽으며 각 함수의 기능, 파라미터의 작용을 이해하기 바랍니다. 이것은 앞으로의 실험에서 여러 번 사용될 것입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.