Энциклопедия разработчика модулей ядра Linux - [11]
> while (length && *Message_Ptr) {
> /* Because the buffer is in the user data segment,
> * not the kernel data segment, assignment wouldn't
> * work. Instead, we have to use put_user which
> * copies data from the kernel data segment to the
> * user data segment. */
> put_user(*(Message_Ptr++), buffer++);
> length--;
> bytes_read++;
> }
>#ifdef DEBUG
> printk("Read %d bytes, %d left\n", bytes_read, length);
>#endif
> /* Read functions are supposed to return the number
> * of bytes actually inserted into the buffer */
> return bytes_read;
>}
>/* This function is called when somebody tries to write into our device file. */
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
>static ssize_t device_write(struct file *file, const char *buffer, size_t length, loff_t *offset)
>#else
>static int device_write(struct inode *inode, struct file *file, const char *buffer, int length)
>#endif
>{
> int i;
>#ifdef DEBUG
> printk("device_write(%p,%s,%d)", file, buffer, length);
>#endif
> for(i=0; i
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
> get_user(Message[i], buffer+i);
>#else
> Message[i] = get_user(buffer+i);
>#endif
> Message_Ptr = Message;
> /* Again, return the number of input characters used */
> return i;
>}
>/* This function is called whenever a process tries to
>* do an ioctl on our device file. We get two extra
>* parameters (additional to the inode and file
>* structures, which all device functions get): the number
>* of the ioctl called and the parameter given to the ioctl function.
>*
>* If the ioctl is write or read/write (meaning output
>* is returned to the calling process), the ioctl call
>* returns the output of this function. */
>int device_ioctl(struct inode *inode, struct file *file,
> unsigned int ioctl_num, /* The number of the ioctl */
> unsigned long ioctl_param) /* The parameter to it */
>{
> int i;
> char *temp;
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
> char ch;
>#endif
> /* Switch according to the ioctl called */
> switch (ioctl_num) {
> case IOCTL_SET_MSG:
> /* Receive a pointer to a message (in user space)
> * and set that to be the device's message. */
> /* Get the parameter given to ioctl by the process */
> temp = (char*)ioctl_param;
> /* Find the length of the message */
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
> get_user(ch, temp);
> for (i=0; ch && i
>#else
> for (i=0; get_user(temp) && i
>#endif
> /* Don't reinvent the wheel - call device_write */
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
> device_write(file, (char*)ioctl_param, i, 0);
>#else
> device_write(inode, file, (char*)ioctl_param, i);
>#endif
> break;
> case IOCTL_GET_MSG:
> /* Give the current message to the calling
> * process - the parameter we got is a pointer, fill it. */
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
> i = device_read(file, (char*)ioctl_param, 99, 0);
>#else
> i = device_read(inode, file, (char*)ioctl_param, 99);
>#endif
> /* Warning - we assume here the buffer length is
> * 100. If it's less than that we might overflow
> * the buffer, causing the process to core dump.
> *
> * The reason we only allow up to 99 characters is
> * that the NULL which terminates the string also needs room. */
> /* Put a zero at the end of the buffer, so it will be properly terminated */
> put_user('\0', (char*)ioctl_param+i);
> break;
> case IOCTL_GET_NTH_BYTE:
> /* This ioctl is both input (ioctl_param) and
> * output (the return value of this function) */
> return Message[ioctl_param];
> break;
> }
> return SUCCESS;
>}
>/* Module Declarations *************************** */
>/* This structure will hold the functions to be called
>* when a process does something to the device we
>* created. Since a pointer to this structure is kept in
>* the devices table, it can't be local to
>* init_module. NULL is for unimplemented functions. */
>struct file_operations Fops = {
> NULL, /* seek */
> device_read,
> device_write,
> NULL, /* readdir */
> NULL, /* select */
> device_ioctl, /* ioctl */
> NULL, /* mmap */
> device_open,
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
> NULL, /* flush */
>#endif
> device_release /* a.k.a. close */
>};
>/* Initialize the module - Register the character device */
>int init_module() {
> int ret_val;
> /* Register the character device (atleast try) */
> ret_val = module_register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
> /* Negative values signify an error */
> if (ret_val < 0) {
> printk("%s failed with %d\n", "Sorry, registering the character device ", ret_val);
> return ret_val;
> }
> printk("%s The major device number is %d.\n", "Registeration is a success", MAJOR_NUM);
> printk("If you want to talk to the device driver,\n");
> printk ("you'll have to create a device file. \n");
> printk ("We suggest you use:\n");
> printk ("mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
> printk ("The device file name is important, because\n");
> printk ("the ioctl program assumes that's the\n");
> printk ("file you'll use.\n");
> return 0;
>}
>/* Cleanup - unregister the appropriate file from /proc */
>void cleanup_module() {
> int ret;
> /* Unregister the device */
> ret = module_unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.