0
커널 프로그램을 읽기 위해 노력하고 있습니다. 먼저 사용자가 숫자를 입력해야합니다 (입력 번호 0은 입력을 중지합니다). 숫자 입력은 이미 저에게 제 일은 읽기 기능을 만드는 것이 었습니다. 읽기 기능은 입력 된 숫자의 양을 추적해야하며 모듈이 활성화 된 이후 입력 된 숫자가있는 버퍼가 있습니다. summer.c에서 읽은 버퍼 및 문자 수를 test-summer.c로 가져 와서 인쇄합니다.리눅스 커널 읽기 기능
Summer.c 코드 :
/* example of a character device using ioctl
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "summer.h"
#define BUF_LEN 80 /* Max length of the message from the device */
/* the memory of the device*/
int total;
/* Global variables declared as staic, so are global within the file.*/
static char *msg_Ptr;
static char msg[BUF_LEN];
/* called after the device is opened*/
int device_open(struct inode *inode, struct file *file)
{
printk("\nsummer device is open\n");
total = 0;
// sprintf(msg);
printk(msg);
msg_Ptr = msg;
return 0;
}
/* called after the device is closed
*/
int device_close(struct inode *inode, struct file *file)
{
printk("\nsummer device is closed\n");
return 0;
}
/* handling of ioctl events
*/
long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
int number;
switch(ioctl_num)
{
case SUMMER_SET:
__get_user(number, (int*)ioctl_param);
total += number;
break;
case SUMMER_GET:
__put_user(total, (int*)ioctl_param);
break;
}
return 0;
}
/* Read function */
static ssize_t device_read(struct file *filep, char *buffer, size_t length, loff_t *offset){
/* Number of bytes actually written to the buffer */
int bytes_read = 0;
/* If we're at the end of the message, return 0 signifying end of file */
if (*msg_Ptr == 0) return 0;
/* Actually put the data into the buffer */
while (length && *msg_Ptr) {
/* The buffer is in the user data segment, not the kernel segment;
* assignment won't work. We have to use put_use which copies data from
* the kernel data segment to the user data segment. */
put_user(*(msg_Ptr++), buffer++);
length--;
bytes_read++;
}
/* Most read functions return the number of bytes put into the buffer */
return bytes_read;
}
/* table of event handlers of the device
*/
struct file_operations fops =
{
read: device_read,
// write: device_write,
open: device_open,
release: device_close,
unlocked_ioctl: device_ioctl,
compat_ioctl: device_ioctl
};
/* called after the kernelmodule is opened
*/
int init_module(void)
{
/* register the device
** after registration the device is known to linux by its major number
** example: mknod /dev/summer0 c 240 0
** this creates the device /dev/summer0
** which is a character device (c) with major number 240 and minor number 0
*/
int retval = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
if(retval < 0)
{
printk("character device not registered\n");
return retval;
}
printk("summer kernel module loaded\n");
return 0;
}
/* called after the module is closed
*/
void cleanup_module(void)
{
/* unregister the device
*/
unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
printk("summer kernel module unloaded\n");
}
테스트 - summer.c 코드
/* example of use of a character device through ioctl
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "../summer.h"
int main(void)
{
int sum;
char* buffer;
/* open character device */
int fd = open("/dev/summer0", O_RDWR); // open device
if(fd < 0)
{
printf("no device found\n");
return;
}
/* read from device */
int nc = read(fd,buffer,4,0);
for(;;)
{
int num;
printf("Number (exit with 0) = ");
while(scanf("%d", &num) != 1)
;
printf("-- %d --\n", num);
if(num <= 0) break;
/* use ioctl to pass a value to the character device */
ioctl(fd, SUMMER_SET, &num);
}
/* use ioctl to get a value from the character device */
ioctl(fd, SUMMER_GET, &sum);
printf("Result = %d\n", sum);
/* print num of chars + the buffer as a string with the amount of numbers read since the kernel is active. */
printf("#char = %d\n", nc);
printf("Buffer: %s\n" , buffer);
close(fd); // close device
return 0;
}
simple_read()를 사용하지 않는 이유가 있습니까? –
내가 이것을 읽는 이유는 인터넷에서이 함수를 가진 예제를 발견했다는 것입니다 – Sybren