CS 635 Advanced Systems Programming Spring 2005 Professor Allan B. Cruse University of San Francisco Instructor Contact Information • Office: Harney Science Center – 212 • Hours: Mon-Wed 6:30pm-7:15pm Tues-Thurs 2:30pm-3:15pm • Phone: (415) 422-6562 • Email: cruse@usfca.edu • Webpage: cs.usfca.edu/~cruse/ Course Textbooks Alessandro Rubini and Jonathan Corbet, Linux Device Drivers (Third Edition), O’Reilly & Associates, Inc (2005) M. Beck et al, Linux Kernel Programming (Third Edition), Addison-Wesley (2002) ‘Extensibility’ • A modern OS needs the ability to evolve – Will need to support new devices – Will need to allow ‘bugs’ to be fixed – Will need to permit performance gains • Else OS may suffer early obsolescence! Two Extensibility Mechanisms • ‘Open Source’ programming • ‘Loadable’ kernel modules Loadable Kernel Modules • • • • • A great mechanism for OS ‘extensibility’ Also allows us to study how kernel works Kernel can be modified while it’s running No need to recompile and then reboot But inherently unsafe: any ‘bug’ can cause a system malfunction or a complete crash! ‘Superuser’ privileges • Modifying a running kernel is ‘risky’ • Only authorized ‘system administrators’ are allowed to install kernel modules • Our classroom workstations will allow us some limited administrator privileges ‘insmod’ and ‘rmmod’ • We are allowed to ‘install’ kernel objects: $ /sbin/insmod myLKM.ko • We are allowed to ‘remove’ kernel objects: $ /sbin/rmmod myLKM • Anyone is allowed to ‘list’ kernel objects: $ /sbin/lsmod Creating a new LKM • You can use any text-editor (e.g., ‘vi’ or ‘emacs’) to create the source-code (in C) for a Linux kernel module (e.g., mod.c) • But a kernel module differs from a normal C application program (e.g., no ‘main()’ function) • A kernel module cannot call any of the familiar functions from the standard C runtime libraries • For any LKM, two entry-points are mandatory (i.e., ‘init_module()’ and ‘cleanup_module()’) Normal module structure • Two ‘module administration’ functions [these are required] plus • Appropriate ‘module service’ functions [these are optional] Required module functions • int init_module( void ); • // gets called during module installation • void cleanup_module( void ); • // gets called during module removal A ‘minimal’ module • We have written a ‘wizard’ application that automatically creates the C boilerplate for a new module: $ newmod <module-name> • It creates a source-file with the essential Linux header, the two required functions, and a ‘MODULE_LICENSE’ statement • It uses ‘printk()’ for logging messages How to compile an LKM • The Linux kernel has been a moving target • Each new version has introduced changes • A big change in kernel 2.6 concerns how a kernel module gets compiled • No longer independent of kernel’s options • Requires a specially created ‘Makefile’ for the specific module(s) you wish to compile • See the discussion in our LDD3 textbook Format of the ‘Makefile’ ifneq ($(KERNELRELEASE),) obj-m := mymod.o else KERNELDIR := /lib/modules/$(shell uname –r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif Inconveniences • Your ‘Makefile’ has to be edited every time you create another new module • Then, when you compile the new module, like this: $ make there are more than a half-dozen files that get created (some of them are ‘hidden’) in your current directory, but just one is the ‘.ko’ (kernel object) that you really wanted Our ‘mmake’ tool • Since we will be writing and compiling lots of modules during our course, we wrote a tool that conveniently automates the steps • You simply type: $ mmake • It creates the ‘Makefile’ you need, in your current directory, to compile all modules that reside in that directory • Afterward it erases all the unneeded files! Try it out • As an in-class programming exercise, you are asked to ‘download’ our two developer tools newmod.cpp and mmake.cpp from the CS 635 website (under ‘Handouts’) • Compile these two application-programs: $ make newmod $ make mmake • Run ‘newmod’ to create a mimimal module • Then run ‘mmake’ to compile that module Kernel 2.6 options • Numerous configuration options exist for recent versions of the Linux kernel (our workstations are using version 2.6.10) • Our System Administrator had to choose which specific features to ‘activate’ when this kernel was being compiled • Which features got ‘enabled’ will have an impact on our kernel module programs An example: TASK_SIZE • Previous Linux versions (e.g., 2.2 and 2.4) normally implemented the user-memory and kernel-memory for each task within the same 4GB virtual address-space map, and this is still possible with kernel 2.6 • But the default configuration for kernel 2.6 (in the Fedora Core 3 distribution) uses a different scheme in which user-memory and kernel-memory use separate maps Traditional Linux kernel memory (1 GB) 0xC0000000 TASK_SIZE = 0xC0000000 (Upper-limit of user-space) user memory (3 GB) PAGE_OFFSET = 0xC0000000 (Lower bound of kernel space) 0x00000000 The 4GB/4GB split TASK_SIZE = 0xFF000000 fixed maps fixed maps user-memory (~4GB) kernel-memory (~4GB) PAGE_OFFSET = 0x02000000 In-Class Exercise #2 • After you have successfully built, compiled and installed, then removed, your ‘minimal’ module, try adding some statements to its ‘init_module()’ function that will print useful information, like this: printk( “PAGE_OFFSET=%08X “, PAGE_OFFSET ); printk( “TASK_SIZE=%08X \n“, TASK_SIZE ); Summary • • • • • • • Download newmod.cpp and mmake.cpp Compile these using ‘make’ Run ‘newmod mod’ to create ‘mod.c’ Run ‘mmake’ to compile ‘mod.c’ Install ‘mod.ko’ (and see printk-message) Remove ‘mod’ and add new statements Recompile and reinstall to see new info