Rapid prototyping of LKMs Configuring our Linux systems for the quick creation and use of loadable kernel modules Fewer keystrokes? • If you want to run a program you wrote that resides in your current directory, you normally have to type the full pathname: $ ./myprog • But you can adjust your logon-settings so you won’t have to specify the directory: $ myprog • You just need to edit your ‘.bash_profile’ Environment variables • You can view your present ‘environment’ using the ‘set’ command, like this: $ set | more • Look for the line that begins with ‘PATH=‘ • This line tells your command-shell (‘bash’) which directories it should search to find a program whose name you entered, so you can add ‘.’ (the current directory) to PATH The ‘PATH=‘ variable • Your ‘PATH’ environment-variable gets initialized each time you login • Its value is setup by your ‘.bash_profile’ • This hidden file is your ‘home’ directrory • You can view it using the ‘cat’ command: • You can also edit it (e.g., with ‘vi’) – but be very careful if you do so! Including ‘.’ in your PATH • If you want your command-shell to search for programs in your current directory, you can edit the ‘PATH=‘ line in .bash_profile • Example: change the line that says PATH=$PATH:$HOME/bin so that it looks like this: PATH=$PATH:.:$HOME/bin Notice: ‘$HOME/bin’ • You can create a new subdirectoy (named ‘bin’) in your home directory, and use it as a place to put your often-used programs (such as tools like ‘newmod’ and ‘mmake’) • Then, after you execute the ‘.bash_profile’ script, you can run those programs from any directory, without having to type a full pathname -- ‘bash’ will now find them! A word about ‘wizards’ • • • • We will be writing lots of modules We can ‘automate’ the boilerplate We should write a ‘wizard’ program It will save us LOTS of time! Our ‘newmod’ example • The ‘newmod.cpp’ application creates the bare minimum of module source-code • It’s an example of a ‘wizard’ tool – but it’s not as useful as it could be, since the code it creates doesn’t really DO anything • Tonight we learn to use a better ‘wizard’, one that will prove very useful in studying the way the new Linux kernel 2.6 works Types of files • UNIX systems implement ordinary files for semi-permanent storage of programs/data • But UNIX systems also implement several kinds of ‘special’ files (such as device-files and symbolic links) which enable users to employ familiar commands and functions (e.g., open(), read(), write(), and close()) when working with other kinds of objects Pseudo-files • Among the various types of ‘special’ files are the so-called ‘pseudo’ files • Unlike ordinary files which hold information that is ‘static’, the pseudo-files don’t ‘store’ any information at all – but they ‘produce’ information that is created dynamically at the moment when they are being read • Traditionally they’re known as ‘/proc’ files Text in ‘/proc’ files • Usually the data produced by reading from a ‘/proc’ file consists of pure ASCII text (a few exceptions exist, however) • This means you can view the contents of a ‘/proc’ file without having to write a special application program – just use ‘cat’! • For example: $ cat /proc/version More ‘/proc’ examples • • • • • • $ cat /proc/cpuinfo $ cat /proc/modules $ cat /proc/meminfo $ cat /proc/iomem $ cat /proc/devices $ cat /proc/self/maps [Read the ‘man-page’ for details: $ man proc ] Create your own pseudo-files • You can use our ‘newinfo.cpp’ wizard to create ‘boilerplate’ code for a module that will create a new pseudo-file when you ‘install’ the module into a running kernel • The module’s ‘payload’ is a function that will get called by the operating system if an application tries to ‘read’ from that file • The ‘get_info()’ function has full privileges! An example: ‘jiffies.c’ • There is a volatile kernel variable (named ‘jiffies’) that keeps track of elapsed time • It is used by the task-scheduler to decide when to perform a task-switch • It increments 100 times/sec (kernel 2.4) • It’s normally inaccessible to user programs • But we can create a ‘/proc’ file that will let us view the ‘jiffies’ value at any moment Edit the ‘get_info()’ function Just replace the statement: len += sprintf( buf+len, “%s\n”, modname ); with this statement: len += sprintf( buf+len, “ jiffies = %d \n”, jiffies ); Compile and install the module, then type: $ cat /proc/jiffies In-class exercise #1 • • • • • • Try creating your own ‘jiffies’ pseudo-file 1) use ‘newinfo’ to build your ‘boilerplate’ 2) edit one line in your module’s ‘get_info’ 3) compile your module (using ‘mmake’) 4) install your ‘jiffies.ko’ kernel-object 5) use the ‘cat’ command to see jiffies A more important example Control Register Cr4 This Pentium register contains a collection of flag-bits which enable or disable special architectural extensions to the CPU (as documented in Intel’s Software Developer Manual, vol3) movl %cr4, %ebx # privileged instruction Among the flag-bits in this register are two which affect how the Pentium translatres virtual memory-address into physical memory-addresses. We’ll need to know how these are set! Our ‘cr4.c’ module • We’ve written a module that will create a pseudo-file (named ‘/proc/cr4’) that can let us view the contents of Control Register 4 $ cat /proc/cr4 • You can download our module’s code from the class website and try it out • You can learn what all the flag-bits mean by reading Intel’s Developer Manual online In-class exercise #2 • Revise the source-code in the ‘cr4.c’ file so that it will display the meanings of each flag-bit in register CR4 • For example, your ‘/proc/cr4’ file should print output that looks like this: cr4 = 000006D0 PSE=1 PAE=0 VME=0 (but show ALL of the implemented bits)