Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scrivere device driver su Linux - Andrea Righi

Scrivere device driver su Linux - Andrea Righi

Avatar for Better Embedded

Better Embedded

September 25, 2012
Tweet

More Decks by Better Embedded

Other Decks in Technology

Transcript

  1. Better Embedded 2012 – Andrea Righi [email protected] Agenda • Overview

    • Kernel-space vs user-space programming • Hello, world! kernel module • Writing a character device driver • Example(s) • Q/A
  2. Better Embedded 2012 – Andrea Righi [email protected] What's a kernel?

    • The kernel provides an abstraction layer for the applications to use the physical hardware resources • Kernel basic facilities • Process management • Memory management • Device management • System call interface
  3. Better Embedded 2012 – Andrea Righi [email protected] Linux kernel key

    features • Portability • Compatible with the POSIX standard • Reliability (hard and detailed code review process) • Modularity (drivers and features can be loaded/unloaded at runtime) • Source code availability (GPLv2)
  4. Better Embedded 2012 – Andrea Righi [email protected] User space •

    Good for debugging (gdb) • Lots of user-space libraries available • Unpredictable latency (context switch, scheduler, syscall, ...) • Overhead • Impossibility to fully interact with interrupt routines • Impossibility to access certain memory address • More difficult to share certain features with other drivers • Reliability: user processes can be terminated upon critical system events (OOM, filesystem errors, etc.)
  5. Better Embedded 2012 – Andrea Righi [email protected] Kernel space •

    Written in C and assembly • No debugging tool (kgdb, UML, ...) • Bugs can hang the entire system • User memory is swappable, kernel memory can't be swapped out • Kernel stack size is small (8K / 4K - THREAD_SIZE_ORDER) • Floating point is forbidden • Userspace libraries are not available • Linux kernel must be portable (this is important if you consider to contribute mainstream) • Closed source kernel modules taint the kernel
  6. Better Embedded 2012 – Andrea Righi [email protected] Makefile NAME=hello ifndef

    KERNELRELEASE PWD := $(shell pwd) all: $(MAKE) -C /lib/modules/`uname -r`/build SUBDIRS=$(PWD) modules clean: rm -f *.o *.ko *.mod.* .*.cmd Module.symvers modules.order rm -rf .tmp_versions else obj-m := $(NAME).o endif
  7. Better Embedded 2012 – Andrea Righi [email protected] hello.c #include <linux/init.h>

    #include <linux/module.h> static int __init hello_init(void) { printk(KERN_INFO "Hello, world!\n"); return 0; } static void __exit hello_exit(void) { printk(KERN_INFO "Goodbye\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Andrea Righi <[email protected]>"); MODULE_DESCRIPTION("BetterEmbedded hello world example");
  8. Better Embedded 2012 – Andrea Righi [email protected] Kernel interfaces •

    virtual filesystem: procfs/sysfs/cgroupfs/configfs • character devices • block devices • network devices • syscall • socket: netlink (AF_NETLINK)
  9. Better Embedded 2012 – Andrea Righi [email protected] Character vs block

    devices • Character devices: • Access the resource as a stream of bytes – serial port, framebuffer, input devices, video capture devices, sound devices, I2C, SPI gateways, etc. • Block devices: • Access the resource as an array of fixed-size blocks – hard disks, DVD drives, USB storage devices, SD/MMC cards, etc.
  10. Better Embedded 2012 – Andrea Righi [email protected] Major/minor numbers •

    Used to map a device driver to a device file (/dev/) • Major: identifies the particular device driver • Minor: identifies a particular device • Example: • /dev/sda = block (8,0) – major: 8 (SCSI driver) – minor: 0 (first disk detected) • /dev/zero = character (1,5) • /dev/null = character (1,3)
  11. Better Embedded 2012 – Andrea Righi [email protected] Virtual memory •

    Each process can “see” more memory than the physical memory actually available in the system
  12. Better Embedded 2012 – Andrea Righi [email protected] Virtual memory x86_64:

    overview User space (128TB) 0x00007fffffffffff 0xffff800000000000 0xffffc7ffffffffff Physical RAM (64TB) Kernel space (2GB) 0x0000000000000000 0xffffffff80000000 0xfffffffffff00000 0 64TB Kernel space User space Virtual memory (64-bit) Physical memory
  13. Better Embedded 2012 – Andrea Righi [email protected] rawmem: requirements •

    Implement a character device that allows to map a virtual address in user-space to a generic physical memory address • The mapped pages can be in kernel space, I/O mapped memory, or even a memory areas that belong to different user-space process
  14. Better Embedded 2012 – Andrea Righi [email protected] File operations /*

    File operations implemented for our rawmem device */ static const struct file_operations rawmem_fops = { .open = rawmem_open, .release = rawmem_release, .mmap = rawmem_mmap, .owner = THIS_MODULE, };
  15. Better Embedded 2012 – Andrea Righi [email protected] rawmem: core implementation

    static int rawmem_mmap(struct file *file, struct vm_area_struct *vma) { return remap_pfn_range(vma, /* virtual address */ vma->vm_start, /* page frame number: physical address */ vma->vm_pgoff, /* size of the area being mapped */ vma->vm_end - vma->vm_start, /* requested protection */ vma->vm_page_prot); } static struct file_operations rawmem_fops = { .mmap = rawmem_mmap, };
  16. Better Embedded 2012 – Andrea Righi [email protected] References • J.

    Corbet, A. Rubini, G. Kroah-Hartman: Linux Device Drivers 3rd Edition • Linux cross reference: http://lxr.linux.no • http://wiki.kernelnewbies.org/LinuxChanges • Linux weekly news: http://lwn.net • http://lxr.linux.no/linux+v3.5.4/Documentation/ • rawmem source code example https://github.com/arighi/rawmem • Kernel source code...
  17. Better Embedded 2012 – Andrea Righi [email protected] Q/A • You're

    very welcome! • Twitter • @arighi • #bem2012