문자 버퍼를 읽고 쓰는 장치 드라이버를 설계하고 있습니다. 그러나 내 질문은 file_operations
구조의 두 함수에 관한 것입니다. read
및 write
입니다. 나는 진정으로 loff_t *offp
이 무엇인지 이해하지 못합니다. 읽기 및 쓰기 작업 모두에 대해 *offp
은 파일의 현재 읽기/쓰기 위치를 의미하는 파일 오프셋이지만, 장치 파일에 쓰거나 읽는 것이 무엇을 의미하는지조차 확실하지 않습니다.file_operations에 대한 loff_t * offp에 대한 이해
내가 수집 한 것에서 이것은 내 장치에서 쓰고 읽는 방법입니다. 나는 my_char_struct
이라고 부르는 내 장치를 나타내는 구조를 만듭니다. 아래 그림을 참조하십시오.
struct my_char_structure{
struct cdev my_cdev;
struct semaphore sem;
char *data;
ssize_t data_size;
unsigned int access_key;
unsigned long size;
};
이 초기화 내 드라이버가 같은 insmod
때 가리키는 정적 구조입니다.
static dev_t dev_num;
static struct my_char_structure Dev;
int start_mod(void){
//Because we are dealing with a fictitious device, I want
//the driver to create my two devices with arbitrarily
//assigned major numbers.
struct my_char_structure *my_dev = &Dev;
int err;
alloc_chrdev_region(&dev_num, FIRST_MINOR, COUNT, DEVICE_NAME);
sema_init(&(my_dev->sem),1);
cdev_init(&(my_dev->my_cdev), &fops);
my_dev->my_cdev.owner = THIS_MODULE;
my_dev->my_cdev.ops = &fops;// fops is my file operations struct
err = cdev_add(&my_dev->my_cdev, dev_num, COUNT);
if(err<0)
printk(KERN_ALERT "There was an error %d.",err);
printk(KERN_ALERT " insmod to major number %d",MAJOR(dev_num));
return 0;
}
module_init(start_mod);
내 장치가 열려있을 때, 난 그냥 같은
module_init(start_mod)
동안 설정 한 정적 구조를 가리 키도록 열려있는 파일에 대한 포인터를 만들
...
int dev_open(struct inode *in_node, struct file *filp){
static struct my_char_structure *my_dev;
my_dev = container_of(in_node->i_cdev, struct my_char_structure, my_cdev);
printk(KERN_ALERT "The device number is %d",iminor(in_node));
if(!my_dev)
printk(KERN_ALERT "something didn't work. my_dev not initialized.");
filp->private_data = my_dev;
return 0;
}
어떤 내 읽기 및 쓰기 메소드는 열린 파일을 가리키며 초기 구조 Dev를 수정합니다. 무엇이든지간에 내 구조의 copy_to_user
은 사용자가 장치에 기록한 것으로 간주하고 무엇이든지간에 나는 사용자가 자신이 쓰고 있다고 생각하는 것이 무엇이든간에 copy_from_user
이라고 생각합니다. 그러나 초기 구조 Dev를 변경하는 것보다 파일 위치 또는 오프셋에 대한 아이디어는 임의의 구조 또는 유형에 대해 커널 내에서 버퍼링 된 메모리에 대한 포인터를 언급하지 않는 한 의미가 없습니다. 그게 내가 파일 오프셋에 대한 유일한 해석이 맞습니까? 여기에 loff_t *offp
은 무엇입니까?
write(struct file *filp, const char __user *buff, size_t count, loff_t *offp)
read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
* offp을 처음으로 설정 loff_t 있는지, 어떤 file_operation 등이 읽기/쓰기로라고 나는 개인적으로 *offp
을 설정하지 않은 경우 (주어진 나의 이해는 올바른)?
마지막 file_operation에서 offp = some_arbitrary_address (내가 그렇게 말했기 때문에)라면이 작업을 다시 호출 할 때 offp가 설정되는 것입니까?
다른 file_opens 작업을 실행하면 어떻게됩니까? 마지막 file_operation이 남긴 작업으로 설정되거나 사용 된 file_open 작업의 탭을 유지하고 * offp를 file_open의 작업 탭으로 대체합니까?
문자 장치의 개념은 장치 자체가 파일처럼 정보를 저장하지 않는 것처럼 보이지만 정보를 저장하는 드라이버라고 생각하면 너무 추상적입니다. 나는 나의 fogginess를 설명했기를 바란다. 그리고 나는 내가 모호하게 보인 무엇이라도 깨끗하게 할 것이다.
오프셋을 + bytes_read/write로 변경하면 사용자 포인터가 변경되지만 자동으로 수행하지 않습니까? 나는 이것이 나를 위해 몇 가지를 정리한다고 생각한다. 나는 리눅스 디바이스 드라이버 세번째 버전의 책을 읽고 있었고, 다른 사람들은 소개로 읽었으며 오프셋 포인터가 파일 위치라고 불리는 이상한 커널 추상화 (더 나은 단어가 없음)를 참조하는 다이어그램을 가지고 있었다. 도움을 주셔서 감사합니다, 이런 종류의 물건을 지워 요. –
예. (아마도'* offp + = nbytes'를 의미합니다.) 변경하려는 변수는 실제로 커널 공간 일 뿐이지 만 * 사용자의 탐색 오프셋을 나타냅니다. (또는 어떤 경우에는'pread' 또는'pwrite' 호출에 제공되는 오프셋이나, 다른 무엇보다 사용자의'lseek' 오프셋이 가장 많습니다.) "이상한 커널 추상화"라고 부르면, '(prog1; prog2)> output'을 만드는 것입니다. 덧붙여 말하자면 * BSD 커널에는'user I/O offset '을 자동으로 업데이트하는'uiomove'라는 함수가 있습니다; 리눅스는 다른 방향으로 나아갔습니다. – torek