edit · history · print

Labs.HW1 History

Hide minor edits - Show changes to markup

September 15, 2006, at 05:33 PM EST by 128.119.245.81 -
Changed lines 79-80 from:
  • Use seq_printf or a similar function to output the information.
to:
  • Use seq_printfto output the information - from seq_file.h:
        int seq_printf(struct seq_file *, const char *, ...)
September 15, 2006, at 05:32 PM EST by 128.119.245.81 -
Changed lines 74-78 from:
  • As mentioned in class, since we are only only outputting a single line, the only function that needs to do anything other than return NULL or non-NULL is show(). The prototypes for these functions are in include/linux/seq_file.h
to:
  • As mentioned in class, since we are only only outputting a single line, the only function that needs to do anything other than return NULL or non-NULL is show(). The prototypes for these functions are in include/linux/seq_file.h:
        void * (*start) (struct seq_file *m, loff_t *pos);
        void (*stop) (struct seq_file *m, void *v);
        void * (*next) (struct seq_file *m, void *v, loff_t *pos);
        int (*show) (struct seq_file *m, void *v);
September 15, 2006, at 05:31 PM EST by 128.119.245.81 -
Changed line 69 from:

to:

September 15, 2006, at 05:31 PM EST by 128.119.245.81 -
Changed line 77 from:
  • the struct file_operations needs open, read, and release methods, and open and read can be no-ops. The prototypes from these functions (from include/linux/fs.h) are:\\
to:
  • the struct file_operations needs open, read, and release methods, and open and read can be no-ops. The prototypes from these functions (from include/linux/fs.h) are:
September 15, 2006, at 05:30 PM EST by 128.119.245.81 -
Added lines 3-4:

Due: Friday 9/22/06

Changed lines 24-27 from:

current timestring when opened. (note - use a miscellaneous device here, as the misc interface will do all the nonsense required to get /dev/sxtime to show up properly with udev)

  • Add a read() method; for any read call the current time string\
to:

current timestring when opened.

  • Add a read() method; for any read call the current time string \
Changed lines 27-28 from:

pointer passed to read() is invalid, then make sure you return -EFAULT. Note about errors.

to:

pointer passed to read() is invalid, then return -EFAULT.

Added lines 33-34:
Changed lines 69-82 from:
to:

Details - part 1

  1. start with the basic module skeleton from here.
  2. to create a /proc file you should use the seq_file interface, as described in class. You will need to create a struct seq_operations and initialize it with start, show, next, and stop methods.
    • As mentioned in class, since we are only only outputting a single line, the only function that needs to do anything other than return NULL or non-NULL is show(). The prototypes for these functions are in include/linux/seq_file.h
    • Use seq_printf or a similar function to output the information.
  3. to register a miscellaneous character device you need to create a struct file_operations and a struct miscdevice
    • the struct file_operations needs open, read, and release methods, and open and read can be no-ops. The prototypes from these functions (from include/linux/fs.h) are:
      int (*open) (struct inode *, struct file *);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        int (*release) (struct inode *, struct file *);
  • in the struct miscdevice you need to set .minor = MISC_DYNAMIC_MINOR, .fops to the address of your file_operations structure, and .name = "sxtime".

September 14, 2006, at 10:41 PM EST by pjd -
Changed lines 150-152 from:

note - if you follow the proceeding instructions exactly, you'll have to find out the device major number and create /dev/sxtime manually, or else do a lot of nonsense with class_device_create(). Use misc_register(), instead, as shown in rather dated article, and everything will be done for you.

to:

note - if you follow the proceeding instructions exactly, you'll have to find out the device major number and create /dev/sxtime manually, or else do a lot of nonsense with class_device_create(). Use misc_register(), instead, as shown in this rather dated article, and everything will be done for you.

September 14, 2006, at 10:41 PM EST by pjd -
Changed lines 150-152 from:

note - if you follow the proceeding instructions exactly, you'll have to find out the device major number and create /dev/sxtime manually, or else do a lot of nonsense with class_device_create(). Use misc_register()], instead, as shown in [[href="http://www.linuxjournal.com/node/2920/print|this rather dated article, and everything will be done for you.

to:

note - if you follow the proceeding instructions exactly, you'll have to find out the device major number and create /dev/sxtime manually, or else do a lot of nonsense with class_device_create(). Use misc_register(), instead, as shown in rather dated article, and everything will be done for you.

September 14, 2006, at 10:39 PM EST by pjd -
Changed lines 22-24 from:

current timestring when opened.

to:

current timestring when opened. (note - use a miscellaneous device here, as the misc interface will do all the nonsense required to get /dev/sxtime to show up properly with udev)

Deleted line 146:
Added lines 149-152:

note - if you follow the proceeding instructions exactly, you'll have to find out the device major number and create /dev/sxtime manually, or else do a lot of nonsense with class_device_create(). Use misc_register()], instead, as shown in [[href="http://www.linuxjournal.com/node/2920/print|this rather dated article, and everything will be done for you.

September 14, 2006, at 11:33 AM EST by 128.119.40.196 -
Changed lines 37-38 from:

Assignment: Add a system call, 'sxtime', which takes 3 arguments - flag, buf, and size.

to:

Assignment: Add a system call, 'sxtime', which takes 3 arguments - flag, buf, and len.

September 14, 2006, at 11:18 AM EST by pjd -
Added lines 162-168:

notes - Part 3

Send me a note if you try this section and are having trouble.

September 14, 2006, at 11:13 AM EST by pjd -
Changed lines 106-107 from:

The sxtime() function. This is a hack which will only work for September 2006.

to:

The sxtime() function. This is a hack which will only work for September 2006.

September 14, 2006, at 11:13 AM EST by pjd -
Changed line 155 from:

Note that this describes "hooking" an existing call. We are going to\

to:

Note that this describes "hooking" an existing call. We are going to \

September 14, 2006, at 11:12 AM EST by pjd -
Changed line 120 from:
	return snprintf(buf, size, "d 2006 %02d:%02d:%02d",
to:
	return snprintf(buf, size, "d %02d:%02d:%02d 2006",
September 14, 2006, at 11:10 AM EST by pjd -
Changed line 113 from:
	static char *days = {"Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"};
to:
	static char *days[] = {"Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"};
September 14, 2006, at 11:02 AM EST by pjd -
Changed line 66 from:

Notes:

to:

Notes:

September 14, 2006, at 11:01 AM EST by pjd -
Added line 101:

Changed line 126 from:

Part 1

to:

notes - Part 1

Changed lines 128-129 from:

There is a very simple module skeleton on this site, here.

to:

There is a very simple module skeleton elsewhere on this site, here.

Changed lines 150-151 from:

Part 2

to:

notes - Part 2

September 14, 2006, at 11:00 AM EST by pjd -
Added lines 64-65:

September 14, 2006, at 11:00 AM EST by pjd -
Added line 70:
Added line 78:
Added line 80:
Added line 86:
Added line 89:
Added line 95:
Added line 104:
Added line 121:
September 14, 2006, at 10:59 AM EST by pjd -
Changed lines 25-30 from:

pointer passed to read() is invalid, then make sure you return -EFAULT. Note (optional)

  • Add an ioctl() method; ioctl 1 will cause the timestring to be printk'ed, and any other ioctl code will result in an error.

Hand in: Makefile and sxtime.c

to:

pointer passed to read() is invalid, then make sure you return -EFAULT. Note about errors.

  • (optional) Add an ioctl() method; ioctl 1 will cause the timestring to be printk'ed, and any other ioctl code will result in an error.

Hand in: Makefile and sxtime.c

Changed lines 47-49 from:

Hand in: a patch to the 2.6.15 kernel source (as distributed on the course CD) which adds this system call. Note patch instructions below. (optional) - add a configuration option which enables or disables whether the system call is compiled into the kernel.

to:

Hand in: a patch to the 2.6.15 kernel source (as distributed on the course CD) which adds this system call. Note patch instructions below. (optional) - add a configuration option which enables or disables whether the system call is compiled into the kernel.

September 14, 2006, at 10:56 AM EST by pjd -
Changed lines 57-61 from:
  • ftrap.S - Assembly code for the trap handler itself, _fast_trap, which calls the C function fast_trap.
  • ktrap.c - the actual module which installs the trap.
  • modgate.h - macros and assembly code to install and remove trap handlers.
  • fast_trap.h - user-space macro for invoking the fast trap.
to:
  • ftrap.S - Assembly code for the trap handler itself, _fast_trap, which calls the C function fast_trap.
  • ktrap.c - the actual module which installs the trap.
  • modgate.h - macros and assembly code to install and remove trap handlers.
  • fast_trap.h - user-space macro for invoking the fast trap.
September 14, 2006, at 10:55 AM EST by pjd -
Changed lines 52-53 from:

Until Linux 2.6, system calls were implemented with the int 0x80 instruction, which is still used for some x86 processors. (on newer CPUs the SYSENTER instruction is used - see here for details)

to:

Until Linux 2.6, system calls were implemented on x86 processors with the int 0x80 instruction. (In 2.6, on newer CPUs the sysenter instruction is used - see here for details.)

int 0x80 jumps to a particular exception address - entry 0x80 - of 256, and the other entries available for software interrupts are unused. In the following exercise we implement a new "fast trap" into the kernel using int 0x81.

Start with the following files:

  • ftrap.S - Assembly code for the trap handler itself, _fast_trap, which calls the C function fast_trap.
  • ktrap.c - the actual module which installs the trap.
  • modgate.h - macros and assembly code to install and remove trap handlers.
  • fast_trap.h - user-space macro for invoking the fast trap.

You will need to get ftrap.S to compile, which should be an exercise in adding include files and #defines; arch/i386/kernel/entry.S should provide a good example. Then you need a fast_trap function - if it just does a printk indicating it ran, that should be enough - and a user-space program to invoke the trap.

September 14, 2006, at 09:07 AM EST by pjd -
Added lines 50-53:

Part 3 (very optional)

Until Linux 2.6, system calls were implemented with the int 0x80 instruction, which is still used for some x86 processors. (on newer CPUs the SYSENTER instruction is used - see here for details)

September 14, 2006, at 08:55 AM EST by pjd -
Changed line 127 from:

There is a description of how to modify system calls in the LMPG here:

to:

There is a description of how to modify system calls in the KMPG here:

Changed line 131 from:

add a syscall - most of the explanation from the LMPG is still applicable, but the steps are:

to:

add a syscall - most of the explanation from the KMPG is still applicable, but the steps are:

September 14, 2006, at 08:52 AM EST by pjd -
Changed lines 101-103 from:

question 1:

You may want to start with the Kernel Module Programming Guide:

to:

Part 1

There is a very simple module skeleton on this site, here.

After looking at that, you may want to refer to the Kernel Module Programming Guide:

Changed lines 125-126 from:

Question 2: A description of system call modification:

to:

Part 2

There is a description of how to modify system calls in the LMPG here:

Added line 129:
Changed line 131 from:

add a syscall, which involves:

to:

add a syscall - most of the explanation from the LMPG is still applicable, but the steps are:

September 14, 2006, at 08:48 AM EST by pjd -
Changed lines 35-36 from:

Since the system call list is kept in a fixed table in the kernel, this cannot be done in a module and must instead be done by modifying and recompiling the kernel itself. To hand in the assignment you will use a common method for packaging and exchanging kernel modifications, the patch.

to:

Since the system call list is kept in a fixed table in the kernel, this cannot be done in a module and must instead be done by modifying and recompiling the kernel itself. (see ) To hand in the assignment you will use a common method for packaging and exchanging kernel modifications, the patch.

Changed lines 88-89 from:
	/* 1/1/70 was a Thursday. 
	 */
to:
	/* 1/1/70 was a Thursday. */
Deleted line 89:
Added lines 120-132:

Question 2: A description of system call modification:

  • http://www.tldp.org/LDP/lkmpg/2.6/html/x978.html

Note that this describes "hooking" an existing call. We are going toadd a syscall, which involves:

  1. adding sys_xtime to arch/i386/kernel/syscall_table.S
  2. adding __NR_xtime to include/asm-i386/unistd.h and updating NR_syscalls.
  3. put the system call into a new file, kernel/sxtime.c
  4. adding sxtime.o in kernel/Makefile.
September 14, 2006, at 08:44 AM EST by pjd -
Changed lines 10-11 from:

At the end of this assignment, here, is a list of resources, one of which is a simple function to return the date and time as a formatted string. We will use this function as a data source in our code below.

to:

At the end of this assignment, here, is a list of resources, one of which is a simple function (sxtime) to return the date and time as a formatted string. We will use this function as a data source in our code below.

Changed lines 45-46 from:

If flag has any other value, return an error. (-EINVAL)

to:

If flag has any other value, return an error. (-EINVAL) As for the read() call, generate -EFAULT if necessary.

Added lines 81-121:

The sxtime() function. This is a hack which will only work for September 2006.

    #include <linux/time.h>
    int sxtime(char *buf, size_t size)
    {
	/* 1/1/70 was a Thursday. 
	 */
	static char *days = {"Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"};

	int n = xtime.tv_sec - 4*3600; /* adjust for GMT->EDT */
	int s = n % 60;    n = n / 60;
	int m = n % 60;    n = n / 60;              
	int h = n % 24;    n = n / 24;
	int dow = n % 7;
	int date = n - 13391;	/* crude hack - works for 9/2006 */
	return snprintf(buf, size, "%s Sep %d 2006 %02d:%02d:%02d",
                        days[dow], date, h, m, s);
    }

question 1:

You may want to start with the Kernel Module Programming Guide:

  • http://www.tldp.org/guides.html#lkmpg

In particular:

  • module skeleton: http://www.tldp.org/LDP/lkmpg/2.6/html/x121.html
  • makefile: http://www.tldp.org/LDP/lkmpg/2.6/html/x181.html
  • how to get rid of that annoying "taint" message: http://www.tldp.org/LDP/lkmpg/2.6/html/x279.html (at bottom of source listing)

For the /proc file interface, look at this first (esp. the last para.)

  • http://www.kernelnewbies.org/Documents/SeqFileHowTo

then you can check the LMPG at:

  • http://www.tldp.org/LDP/lkmpg/2.6/html/x861.html

To create and register a character device:

  • http://www.tldp.org/LDP/lkmpg/2.6/html/x569.html

Note in particular any information on copying back and forth between kernel and user space.

September 14, 2006, at 08:40 AM EST by pjd -
Changed lines 14-18 from:

The simplest way to get information out of the kernel to a user is via printk; however, to get information

Create a module named sxtime which does the following:

to:

Here we investigate methods of moving information out of and into the kernel. Printk allows us to output information directly to the user; however, to get information to a program we use a file. The /proc filesystem has a set of kernel hooks to allow us to easily output information, and for more control we can create our own character device and implement its read and write methods.

Assignment: Create a module named sxtime which does the following:

Changed lines 24-25 from:

should be returned, truncated to the read length if necessary.

to:

should be returned, truncated to the read length if necessary. If the buffer pointer passed to read() is invalid, then make sure you return -EFAULT. Note (optional)

  • Add an ioctl() method; ioctl 1 will cause the timestring to be printk'ed, and any other ioctl code will result in an error.

Hand in: Makefile and sxtime.c

Part 2

The basic method for entering the kernel from user space is the kernel call - e.g. in the section above, the open() and read() system calls were used. Here we implement a custom kernel call.

Since the system call list is kept in a fixed table in the kernel, this cannot be done in a module and must instead be done by modifying and recompiling the kernel itself. To hand in the assignment you will use a common method for packaging and exchanging kernel modifications, the patch.

Assignment: Add a system call, 'sxtime', which takes 3 arguments - flag, buf, and size.

  • If flag is 0, then buf points to a null-terminated string, and lenis ignored. Copy and save that string, and return the number of bytes saved.
  • If flag is 1, then buf,len specifies a user buffer. Copy the saved string followed by the current timestring into this buffer, and return the length written.

If flag has any other value, return an error. (-EINVAL)

Hand in: a patch to the 2.6.15 kernel source (as distributed on the course CD) which adds this system call. Note patch instructions below. (optional) - add a configuration option which enables or disables whether the system call is compiled into the kernel.

Notes:

Error codes - in (almost?) all cases, system calls return positive or zero values for success, and negative values for errors. For a full list of error codes, look at include/asm/errno.h.

Patches - the simplest way to generate a patch is to keep two copies of the kernel source tree - a pristine one and the one you are working on. To generate the patch we then run a recursive diff:

    # ls
    linux-2.6.15.pristine
    linux-2.6.15
    # diff -Naur linux-2.6.15.pristine linux-2.6.15 > changes.patch
    #

You may want to investigate the use of the following diff option:

       --exclude=pattern
              When comparing  directories,  ignore  files  and  subdirectories
              whose basenames match pattern.

The file changes.patch - the patch file - will now show the changes in any files between the two versions; in addition (the -N flag) it will contain any new files in the modified version. To apply this patch file we use the patch command, along with the '-p' option to tell it to use the path names in the diff file:

     # cp -r linux-2.6.15.pristine linux-2.6.15.new-copy
     # cd linux-2.6.15.new-copy
     # patch -p1 < ../changes.patch

(since the new directory wasn't named 'linux-2.6.15', we couldn't use -p0. Instead we use -p1, which trims off the first directory in every path, and we change directories so the modified paths will work.) Note also that you can reverse a patch by applying the -R flag; thus applying the patch in reverse to your working tree should cause it to match the pristine tree.

September 14, 2006, at 08:01 AM EST by pjd -
Added lines 9-28:

At the end of this assignment, here, is a list of resources, one of which is a simple function to return the date and time as a formatted string. We will use this function as a data source in our code below.

Part 1

The simplest way to get information out of the kernel to a user is via printk; however, to get information

Create a module named sxtime which does the following:

  • outputs the current timestring (via printk) when it is loaded.
  • registers a /proc file (/proc/sxtime) which when read outputs the current timestring as a single line.
  • registers a character device /dev/sxtime, which printks the current timestring when opened.
  • Add a read() method; for any read call the current time stringshould be returned, truncated to the read length if necessary.

Resources

September 14, 2006, at 07:54 AM EST by pjd -
Added lines 1-8:

(:title Homework 1 :)

This assignment has two goals:

  • to familiarize you with the basic ways of modifying the kernel, building kernel modules, and getting information in and out of the kernel.
  • to investigate some of the mechanisms for accessing kernel functionality from user space - system calls, the /proc filesystem, and devices.
edit · history · print
Page last modified on September 15, 2006, at 05:33 PM EST