1 / 88

Linux I/O

Linux I/O. 9762599 劉哲維 9762579 郭逸旻. OUTLINE. I/O Architecture The Device Driver Model Device Files Device Drivers Character Device Drivers. I/O Architecture. PC Architecture. I/O Architecture. I/O Bus I/O Port I/O Interface I/O Controller. I/O Ports.

olive
Télécharger la présentation

Linux I/O

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linux I/O • 9762599 劉哲維 • 9762579 郭逸旻

  2. OUTLINE • I/O Architecture • The Device Driver Model • Device Files • Device Drivers • Character Device Drivers

  3. I/O Architecture

  4. PC Architecture

  5. I/O Architecture • I/O Bus • I/O Port • I/O Interface • I/O Controller

  6. I/O Ports • Each device connected to the I/O bus has its own set of I/O addresses, which are usually called I/O ports. • Four special assembly language instructions • In() • Ins() • Out() • Outs()

  7. I/O Ports

  8. I/O Ports • Kernel treats I/O ports as "resources“ • Tree-like data structure

  9. I/O Ports • Device driver use the following functions: root (0~65535) A (0~3) B (16~19) C (20~23) New (4~7)

  10. request_resource() /* Return the conflict entry if you can't request it */ static struct resource * __request_resource(struct resource *root, struct resource *new) { unsigned long start = new->start; unsigned long end = new->end; struct resource *tmp, **p; /* conflict checking : compare start and end */ p = &root->child; for (;;) { tmp = *p; if (!tmp || tmp->start > end) { new->sibling = tmp; *p = new; new->parent = root; return NULL; // request successfully } p = &tmp->sibling; if (tmp->end < start) continue; return tmp; } }

  11. release_resource() static int __release_resource(struct resource *old) { struct resource *tmp, **p; p = &old->parent->child; for (;;) { tmp = *p; if (!tmp) break; if (tmp == old) { *p = tmp->sibling; old->parent = NULL; return 0; } p = &tmp->sibling; } return -EINVAL; }

  12. I/OInterfaces • Between I/O port and Device Controller • Acts as an interpreter that translates for the I/O ports and the device • Connect through an IRQ line to a Programmable Interrupt Controller

  13. I/OInterfaces • Custom I/O interfaces • Graphic interface • Disk interface • Network interface • General-purpose I/O interfaces • Parallel port • Serial port • USB • PCMCIA

  14. Device Controllers • Interprets the high-level commands received from the I/O interface and forces the device to execute specific actions • Interprets the electrical signals received from the device and modifies (through the I/O interface) the value of the status register • Disk Controller

  15. The Device Driver Model

  16. Sysfs File system The sysfs filesystem is a special virtual filesystem that is usually mounted on the /sys directory. It allows User Mode applications to access kernel internal data structures of device driver model.

  17. kobjects • The core data structure of the device driver model • Each kobject corresponds to a directory in sysfsfilesystem • Usually embedded inside a “Container” that describe the component of device driver model.

  18. kobjects Embedding a kobject inside a container allows the kernel to: Keep a reference counter for the container Maintain hierarchical lists or sets of containers (for instance, a sysfs directory associated with a block device includes a different subdirectory for each disk partition) Provide a User Mode view for the attributes of the container

  19. kobjects kref:Reference counter Ktype: Release method Sysfs_ops Default attribute

  20. ktype

  21. kset “kset” is a collection of kobjects of the same ktype

  22. kset An embedded kobject: Kobject_get() instead of kset_get() Kset data structure can be embedded in a container Kset data structure can be a member of another kset

  23. ksystem A collection of ksets kset An embedded kset Can also be embedded in a container Rwsem A read-write semaphore

  24. Device <include/linux/device.h>

  25. Driver <include/linux/device.h>

  26. Bus <include/linux/device.h>

  27. Registration Add into the internal kernel data structure register kobject_register( ) kset_register ( ) device_register( ) driver_register( ) unregister

  28. Example

  29. Device Files

  30. Device File • I/O devices are treated as special files • Device file in : /dev directory, like /dev/hda • Three types of device file: • Block device • Fixed transmission • Storage divice • Character device • Byte-transmission • At least 4 system call • Network interface

  31. Device File • i-node of device file: • Must include an identifier of the hardware device • Type of device file:Block or Character • Major number • Minor number • mknod() system call: • Used to create device file • It needs name, type , major and minor number • mknod /dev/usbservice b 8 0

  32. Device File

  33. Device File Handling • 8-bit major and minor number are insufficient for large-scale system • 12-bit major and 20-bit minorin 32-bit dev_t • MAJOR、MINOR、MKDEV Macro • Compatible with old device file • Dynamicallyallocate device number and create device file

  34. Dynamicallycreate device file • At the system startup the /dev directory is emptied • Device files can be created "on demand" • udev program scans the subdirectories of /sys/class looking for the dev files

  35. Device Drivers

  36. Levels of Kernel Support • No support at all • The application program interacts directly with the device's I/O ports • Minimal support • The kernel does not recognize the hardware device, but does recognize its I/O interface. • kernel takes care of the I/O interface by offering a device file • the application program handles the external hardware device by reading and writing the device file • Extended support • The kernel recognizes the hardware device and handles the I/O interface itself.

  37. Device Driver • Device Driver • A device driver is the set of kernel routines that makes a hardware device respond to the programming interface defined by the canonical set of VFS functions (open, read, lseek, ioctl, and so forth) that control a device.

  38. Device Driver Registering • Device Driver Registering • Allocating a new device_driver descriptor • Insert it in the data structures of the device driver model • Link it to the corresponding device file(s) • System call on device file • translated by the kernel into an invocation of a suitable function of a corresponding device driver

  39. Device Driver Registering • character device • register_chrdev() • ex: /drivers/char/Lp.c • block device • register_blkdev() • ex: /drivers/block/hd.c

  40. Device Driver Registering • /include/linux/fs.h externint register_chrdev(unsigned int,const char *,conststruct file_operations *); • /drivers/chr/lp.c if (register_chrdev (LP_MAJOR, "lp", &lp_fops)) { printk (KERN_ERR "lp: unable to get major %d\n", LP_MAJOR); return -EIO;//I/O發生錯誤 }

  41. Device Driver Registering • /drivers/chr/lp.c static const struct file_operations lp_fops = { .owner = THIS_MODULE, .write = lp_write, .ioctl = lp_ioctl, .open = lp_open, .release = lp_release, #ifdef CONFIG_PARPORT_1284 .read = lp_read, #endif };

  42. Device Driver Registering • struct module *owner; • 不同於file_operations結構裡的其它欄位,此欄位不是函式指標,而是一個指向結構所屬模組的指標。驅動程式本身用不到此欄位,因為他是供核心用來維護模組的用量計次(usage count)。 • ssize_t (*read) (struct file *,char *,size_t,loff_t *); • 用於擷取出裝置上的資料。若將此欄位設定為NULL,則read()系統呼叫發生-EINVAL失敗。(Invalid argument,引數值無效) ,如果成功,則傳回一個非負數值,代表成功讀取的位元數。 • ssize_t (*write) (struct file *, const char *, size_t, loff_t *); • 將資料寫入裝置。若發生錯誤,則觸發write()系統呼叫的行程會收到-EINVAL。如果成功,write將傳回一個非負值,代表成功寫出的位元數。

  43. Device Driver Registering • int (*ioctl) (struct inode *, struct file *, unsigned int,unsigned long); • 每個裝置或多或少都有其特殊功能,標準的作業方法不見得能提供應用程式所需要的一切功能(ex:格式化),對於隨裝置而定的功能,應用程式可透過ioctl()系統呼叫來執行一系列裝置特有命令,而ioctl作業發法的任務,就是實現在類特殊命令。 • int (*open) (struct inode *, struct file *); • 開啟,這必定是裝置檔操作程序的第一步,但是驅動程式並非一定要宣告一個對應方法不可。如果將此欄位指向NULL,開啟裝置的動作一定會成功,只不過驅動程式不會收到通知而已。 • int (*release) (struct inode *, struct file *); • 在file結構被釋放之前,此方法會被呼叫。(並非,每次呼叫close( )都會觸發release)

  44. Device Driver Registering • /fs/char_dev.c static struct char_device_struct { struct char_device_struct *next;//The pointer to next element in hash collision list unsigned int major; unsignedint baseminor;//minor number int minorct; //The interval size char name[64]; struct cdev *cdev;//pointer to the character device driver descriptor } *chrdevs[CHRDEV_MAJOR_HASH_SIZE];

  45. Device Driver Registering • Major number • 代表裝置所配合的驅動程式 • 當核心收到open()系統呼叫時,就是依據“major number”來選擇驅動程式 • Minor number • 驅動程式以次編號來辨認同類裝置的個體 • 核心本身用不到,只有驅動程式自己才知道次編號的意義 • 每當核心要呼叫驅動程式,都必須讓驅動程式知道,他應該作用在哪一個裝置上;驅動程式以裝置編號來變任期作用對象。(裝置編號=major number + minor number) Major (12 bits) Minor(20 bits)

  46. Device Driver Registering • /include/linux/Cdev.h struct cdev { struct kobject kobj; //Embedded kobject struct module *owner; conststruct file_operations *ops; struct list_head list;// Head of the list of inodes relative to device files for this character device dev_t dev; //major and minor number unsignedint count; //size of the range of device number };

  47. Device Driver Registering kobj file_operations

  48. Device Driver Registering • /fs/char_dev.c • Invokes the _ _register_chrdev_region( ) function to allocate the requested interval. If the function returns an error code (the interval cannot be assigned), it terminates. int register_chrdev(unsignedint major,const char*name,conststruct file_operations *fops){ struct char_device_struct *cd; struct cdev *cdev; char *s; int err = -ENOMEM; cd = __register_chrdev_region(major, 0, 256, name); if (IS_ERR(cd)) return PTR_ERR(cd);

  49. Device Driver Registering • The _ _register_chrdev_region( ) function executes the following steps: • Allocates a new char_device_struct structure, and fills it with zeros. • If the major number of the interval is zero, then the device driver has requested the dynamic allocation of the major number. • Initializes the fields of the char_device_struct structure with the initial device number of the interval, the interval size, and the name of the device driver. cd->major = major; cd->baseminor = baseminor; cd->minorct = minorct; strncpy(cd->name,name, 64);

More Related