210 likes | 394 Views
Computer System Laboratory. Lab12-Driver. Experimental Goal. Understand the architecture of Linux device drivers and learn how to control the LCD of PXA270. LCD. Environment. Host System Windows XP Build System VirtualBox + Ubuntu 8.04 Target System Creator XScale PXA270 Software
E N D
Computer System Laboratory Lab12-Driver
Experimental Goal • Understand the architecture of Linux device drivers and learn how to control the LCD of PXA270. LCD / 21
Environment • Host System • Windows XP • Build System • VirtualBox + Ubuntu 8.04 • Target System • Creator XScale PXA270 • Software • Linux kernel, please refer to Lab5 • BusyBox, please refer to Lab6 • Creator PXA270 LCD driver • You can download all software from RSWiki CSL Course Software / 21
Introduction to Device Drivers • What are device drivers? • Make a particular piece of hardware respond to a well-defined internal programming interface. • Hide completely the details of how the device works. • User activities are performed by means of a set of standardized calls that are independent of the specific driver. • Mapping those calls to device-specific operations that act on real hardware is then the role of a device driver. / 21
Linux Device Drivers (1/2) • There are three fundamental types of Linux device drivers. • Character device driver • Block device driver • Network device driver • We will only learn how to write character device drivers in this Lab. / 21
Linux Device Drivers (2/2) • A Linux device driver can be divided into two parts. • Virtual device driver • Physical device driver define file_operations register driver (VFS) Virtual Device Driver User implement system calls Device File Kernel define chipset header Device Driver define I/O wrapper functions Physical Device Driver Hardware implement chipset control functions / 21
Writing A Virtual Device Driver (1/2) • Define file_operations and implement system calls. #include <linux/fs.h> structfile_operationsdev_fops = { open: dev_open, read: dev_read, write: dev_write, release: dev_release, ioctl: dev_ioctl, }; Implement these functions / 21
Writing A Virtual Device Driver (2/2) • Register a character device driver in the initial function. intregister_chrdev(unsigned int major, const char *name, structfile_operations *fops); • Unregister a character device driver in the exit function. intunregister_chrdev(unsigned int major, const char *name); / 21
Writing A Physical Device Driver (1/2) • Two common approaches to access hardware. • Memory mapped I/O • Port I/O • Memory mapped I/O: • Access I/O (port) in the same way as that memory is accessed. • For example, there is a device that has a 8 bit I/O port connected to the system, and its address is mapped at 0x10000. We can read and write the I/O port like this: #define DATA_PORT (*(volatile char*)(0x10000)) char read_b() {return DATA_PORT;} void write_b(char data) {DATA_PORT = data;} / 21
Writing A Physical Device Driver (2/2) • Port I/O: • If the I/O system has its own address independent of memory, then it is port I/O. • Register the I/O port. E.g., 0x378. if (check_region(0x378, 1)) { printk("<1>parallelport: cannot reserve 0x378\n"); } else { request_region(0x378, 1, "demo"); } • Use the I/O commands. char data = inb(0x378);//Read data form the port 0x378 outb(data, 0x378); //Write data to the port 0x378 • Release I/O port. release_region(0x378, 1); / 21
Creating A Device File • In Linux, devices are accessed in the same way as that files are accessed. • These device files are normally in the /dev directory. • We can create a device file by the following command. • % mknod /dev/demo c <MAJOR_NUM><MINOR_NUM> • More details about mknod can be found at • 鳥哥的 Linux 私房菜. • So, we can manipulate the device via reading/writing its device file. • Most Linux drivers are implemented as kernel modules. / 21
Introduction to Kernel Module • A kernel module is an object file that contains code to extend the running kernel of an operating system. • Typically used to add support for new hardware and/or filesystems, or for adding system calls. • When the functionality provided by an kernel module is no longer required, it can be unloaded in order to free memory and other resources. / 21
Related Commands in Linux • % insmodmodule.ko • This command is used to insert a module into the kernel. • It doesn’t modify the module’s disk file, but rather than in-memory copy. • % rmmodmodule.ko • This command is used to remove a module from the kernel. • This command invokes the delete_module() system call, which calls cleanup_module() in the module itself if the usage count is zero or returns an error otherwise. • % lsmod • List the module currently linked to Linux. / 21
How to Write a Module? (1/2) #include <linux/init.h>#include <linux/kernel.h>#include <linux/module.h> static intinit_demo(void) {printk("Hello World!\n");return 0;} static void cleanup_demo(void) {printk("Goodbye World!\n");} module_init(init_demo); module_exit(cleanup_demo); MODULE_LICENSE("Dual BSD/GPL"); initial function cleanup function declaration of initial/cleanup functions / 21
How to Write a Module? (2/2) • Note that the messages in printk will be showed in the kernel, you can use dmesg command to check the messages. • We need to compile this module with kernel, and the result will be demo.ko. Here is the example of Makefile. CC = arm-unknown-linux-gnu-gcc obj-m := demo.o all: make -C <kernel path> M=$(PWD) modules clean: make -C <kernel path> M=$(PWD) clean / 21
Using Drivers In User Space • Open the file /dev/demo and test its read and write functions just like a normal file. #include <stdio.h>#include <unistd.h>#include <fcntl.h> int main() { intfd, data; if((fd = open("/dev/demo", O_RDWR)) < 0) {printf("couldn't open /dev/demo\n");return 1;} write(fd, "Hello World!", 13); read(fd, &data, 4); close(fd); return 0; } / 21
The PXA270 LCD Driver (1/2) • Now we add the PXA270 LCD driver to Linux kernel as a kernel module. • Step 1: extract the driver, and copy to your Linux kernel source in Lab5. • Step 2: compile modules. • We build the driver as a module. • % make menuconfig • “Device Drivers” “Character devices” “Creator-pxa270 LCD” • % make modules • The result creator-pxa270-lcd.ko is in drivers/char/. • Step 3: add lsmod, insmod, rmmod commands in BusyBox. (refer to Lab6) • Please check the size of root filesystemwhich is defined by Linux kernel. • These commands are under “Linux Module Utilities”. • You need to check the support of 2.6.x Linux Kernels. / 21
The PXA270 LCD Driver (2/2) • Step 4: copy the new root filesystemto PXA270. • Step 5: transfer creator-pxa270-lcd.ko to PXA270. • Step 6: insert the module to Linux. • % insmod creator-pxa270-lcd.ko • You will see “good” on the 4-Digit 7 segment LED. • Tip • If you want to reload the module, do not forget to remove the running module first. • % rmmodcreator-pxa270-lcd.ko / 21
Lab Step • Please refer to previous slides to implement a simple driver for a virtual device demo. • Create the device with major number 60 and minor number 0. • When you initialize module, delete module, open device, close device, read device and write device, please print messages. • E.g., printk(“Open command is issued.”); • You don’t need to implement the “real work” of functions. • Write an application to control the LCD. • Trace the driver code and know how it works. • Do not forget to create the LCD device file. • % mknod /dev/lcd c 120 0 / 21
Hint • You can refer to the PXA270 LCD driver to implement your demo driver. • See the structfile_operations and know how to implement these system calls. • Also see how to control LCD by ioctl commands. • You may want to define some ioctlcommands in your application. • You can refer to Writing device drivers in Linux: A brief tutorial for more information. / 21
Lab Requirement • Show the messages of accessing the demo device. • Including open, close, read, write, initial, remove. • Show more than one messages on LCD from applications. • Show your group number, and your student IDs. / 21