Download - Computer System Laboratory
COMPUTER SYSTEM
LABORATORYLab12-Driver
/ 212Lab 12
Experimental Goal•Understand the architecture of Linux device drivers and learn how to control the LCD of PXA270.
2013/12/10
LCD
/ 213Lab 12
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 Software2013/12/10
/ 214Lab 12
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.
2013/12/10
/ 215Lab 12
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.
2013/12/10
/ 216Lab 12
Linux Device Drivers (2/2)•A Linux device driver can be divided into two parts.
• Virtual device driver• Physical device driver
2013/12/10
filename description type
major numb
er
minor numb
er
/dev/ttyS0 First UART serial port
char 4 64
User
KernelDevice Driver
Hardware
Device File
implement chipset control functions
define I/O wrapper functions
define chipset header
implement system calls
register driver (VFS)
define file_operations
Virtual Device Driver
Physical Device Driver
/ 217Lab 12
Writing A Virtual Device Driver (1/2)•Define file_operations and implement system calls.#include <linux/fs.h>
struct file_operations dev_fops =
{
open: dev_open,
read: dev_read,
write: dev_write,
release: dev_release,
ioctl: dev_ioctl,
};
2013/12/10
Implement these functions
/ 218Lab 12
Writing A Virtual Device Driver (2/2)•Register a character device driver in the initial function.
int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);
•Unregister a character device driver in the exit function.
int unregister_chrdev(unsigned int major, const char *name);
2013/12/10
/ 219Lab 12
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;}
2013/12/10
/ 2110Lab 12
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);
2013/12/10
/ 2111Lab 12
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.2013/12/10
/ 2112Lab 12
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.
2013/12/10
/ 2113Lab 12
Related Commands in Linux• % insmod module.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.• % rmmod module.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.
2013/12/10
/ 2114Lab 12
How to Write a Module? (1/2)#include <linux/init.h>#include <linux/kernel.h>#include <linux/module.h>
static int init_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");
2013/12/10
initial function
cleanup function
declaration of initial/cleanup functions
/ 2115Lab 12
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
2013/12/10
/ 2116Lab 12
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() {
int fd, 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;
}
2013/12/10
/ 2117Lab 12
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 filesystem which is defined by Linux kernel.• These commands are under “Linux Module Utilities”.• You need to check the support of 2.6.x Linux Kernels.
2013/12/10
/ 2118Lab 12
The PXA270 LCD Driver (2/2)•Step 4: copy the new root filesystem to 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.• % rmmod creator-pxa270-lcd.ko
2013/12/10
/ 2119Lab 12
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
2013/12/10
/ 2120Lab 12
Hint•You can refer to the PXA270 LCD driver to implement your demo driver.• See the struct file_operations and know how to implement these
system calls.
•Also see how to control LCD by ioctl commands.• You may want to define some ioctl commands in your application.
•You can refer to Writing device drivers in Linux: A brief tutorial for more information.
2013/12/10
/ 2121Lab 12
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.
2013/12/10