26
Writing device drivers in Linux Magnus Abrahamsson Table of Contents 2010-02-18 Mid Sweden University The Department of Information Technology and Media (ITM) Author: Magnus Abrahamsson E-mail address: [email protected] Scope: 6630 words inclusive of appendices Date: 2010-02-18

Writing Devive drivers in Linux

Embed Size (px)

DESCRIPTION

Device Drivers

Citation preview

Page 1: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

Table of Contents

2010-02-18

Mid Sweden University The Department of Information Technology and Media (ITM) Author: Magnus Abrahamsson E-mail address: [email protected] Scope: 6630 words inclusive of appendices Date: 2010-02-18

Page 2: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

Table of Contents

2010-02-18

Report Computer A, Unix Applikationsprogrammering, 7.5

points

Writing device drivers in Linux LED Parallel port

Magnus Abrahamsson

Page 3: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

Table of Contents

2010-02-18

Abstract The report will describe and give examples how to write a device driver

to the Linux operation system.

Keywords: Device driver, Linux, Ubuntu, Modules, Kernel, C.

Page 4: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

Table of Contents

2010-02-18

Foreword This report is written as an “exam” work to complete my Unix Applika-

tionsutveckling course, that I begun in another millennium. So instead of

taking a new cause exam my teacher Mikael Hasselman suggested that I

write a report on how to create a device driver for Linux. Even if it’s a long

time since I took the course I’m pretty sure we didn’t spend that much

time in kernel space back then… So this has been quit a challenge for

me, but a good one. I hope you enjoy reading it as much as I liked

writing and working with it.

Kind regards

Magnus Abrahamsson

Page 5: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

Table of Contents

2010-02-18

Table of Contents

Abstract ............................................................................................................ iii

Foreword.......................................................................................................... iv

Terminology...................................................................................................vii

1 Introduction............................................................................................1

1.1 Scope .............................................................................................1

1.2 Outline ..........................................................................................1

1.3 Contributions ...............................................................................1

2 Introduction to Kernel and User space..............................................2

2.1 Kernel space .................................................................................2

2.2 User space.....................................................................................2

2.3 Interfacing functions between user space and kernel space .3

2.4 Interfacing functions between kernel space and the

hardware device. .........................................................................3

2.5 Linux System Calls......................................................................4

3 Devices in Linux ....................................................................................5

3.1 Devices Nodes – Special files.....................................................5

3.1.1 Character and block devices ...........................................5

3.2 Device Driver ...............................................................................6

3.3 Loadable Modules.......................................................................7

4 How to write a device driver ...............................................................9

4.1 Connection of the device with its files......................................9

4.2 Load and removing driver.........................................................9

4.2.1 Load and remove modules in user space......................9

4.2.2 Initializing modules in kernel space ............................10

4.2.3 Removing modules in kernel space .............................11

4.3 Read and write to the device ...................................................12

4.3.1 Reading the device in kernel space..............................12

4.3.2 Reading the device from user space ............................12

4.3.3 Writing to the device in kernel space ..........................12

4.3.4 Writing to the device from user space.........................12

5 LED parallel port device driver - example code. ...........................13

6 Conclusions / Discussion...................................................................16

Page 6: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

Table of Contents

2010-02-18

References........................................................................................................17

Appendix A: The LED Matrix......................................................................18

Appendix B: Compile the kernel on Ubuntu system..............................19

Page 7: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

Terminology

2010-02-18

Terminology

Acronyms / Abbreviations

GUI Graphical User Interface.

LED Light Emitting Diode

I/O Input / Output

PCMCIA Personal Computer Memory Card Interna-

tional Association, also called PC-Card

Code notation

Symbol Description

Function() Functions

Page 8: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

1 Introduction

2010-02-18

1 Introduction I will in this report briefly describe how to write a device driver for Linux

and give one example how to create a parallel port LED driver.

1.1 Scope

There are several different devices for the Linux operation system. This

study has its focus on type char devices loaded as modules on an i386.

I have also chosen not to use the platform_driver driver model, introduced in

kernel 2.6.15, because I wanted to get “direct” connection with the kernel.

So in that why I’m not following the standard driver model convention,

where discovery/enumeration is handled outside the drivers, and drivers

provide probe() and remove() methods.

How to access hardware memory has also been outlined.

1.2 Outline

Chapter 2 describes brief the user space and kernel space.

Chapter 3 gives you more information regarding devices

Chapter 4 gives you more hands-on how to write a how to write a device

driver.

Chapter 5 gives you an example of a device driver written in C.

Chapter 6 gives you conclusions and more comments on the subject.

1.3 Contributions

Special big thanks to my colleague Stellan Blanc which have been very

supportive during the whole process.

Page 9: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

2 Introduction to Kernel and User space.

When you write a device driver for Linux it’s impotent to make the distinc-

tion between “user space” and kernel space”

2.1 Kernel space

The kernel manages the machine’s hardware in a simple and efficient man-

ner, offering user a simple and uniform programming interface. In that

way, the kernel, and in particular its device driver, form a bridge or inter-

face between and end-user/programmer and the hardware. Any subrou-

tines or functions forming part of the kernel (modules and device drivers, for

example) are considered to be part of the kernel space.

2.2 User space

This is where the end-user programs reside. UNIX shell or other GUI based

applications (gnome-system-monitor) are a part of the user space, for example.

When these applications need to interact with the system’s hardware they

don’t do so directly. They go through the kernel supported functions,

shown in figure 1

User processes

User service

Kernel

Hardware

Figure 1 : Linux architecture

Page 10: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

2.3 Interfacing functions between user space and kernel space

The kernel offers several subroutines or functions in user space. The end-

user application programmer is allowed through these functions to interact

with the hardware from user space. In a UNIX or Linux system, this dia-

logue is preformed via the system call interface. Usually, these operations

are read and write file functions. The reason for this is that in UNIX devices

are seen, from the user’s point of view, as files.

Usually, for each function in the user space (allowing the use of devices or

files), there exists an equivalent in kernel space (allowing the transfer of

information from kernel to the user and vice-versa). See Table 1.

Event User function Kernel function

Load module insmod module_init()

Open device fopen file_operations:open

Read device fread file_operations:read

Write device fwrite file_operations:write

Close device fclose file_operations:release

Remove device rmmod module_exit()

Table 1: Device driver events and their associated functions between kernel space and

user space.

2.4 Interfacing functions between kernel space and the hardware device.

As we mentioned in the earlier there are also functions in kernel space

which control the device or exchange information between the kernel and

the hardware (kernel functions). See Table 2.

Events Kernel function

Read data inb()

Write data outb()

Table 2: Device driver events and their associated functions between kernel space and

hardware device.

Page 11: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

Linux Platform

User Applications

Libraries

System call interface

File Subsystem

User

Space

Kernel

Space

Hardware

Process Control Subsystem

SchedulerMemory

Managment

Inter-process

Communication

Buffer Cache

Character Block

Device Driver

Hardware Control

Figure 2: Shows that user space programs communicate with the kernel using system

calls.

2.5 Linux System Calls

A system call is an interface between a user-space application and a service

that the kernel provides. Because the service is provided in the kernel, a

direct call cannot be performed; instead, you must use a process of crossing

the user-space/kernel boundary. The way you do this differs based on the

particular architecture. In this document we will stick to the most common

architecture, i386.

Page 12: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

3 Devices in Linux We will in this chapter look deeper into the different definitions as device

nodes, device drivers and loadable modules in a Linux system.

3.1 Devices Nodes – Special files

All devices look like files on a Linux system. In fact, the user-level interface

to a device is called special file. These special files or device nodes reside in

the /dev directory. Special files, like other files, have read and write

permissions.

To link the special files with the kernel module two numbers are used:

major number and minor number. Major device numbers are used by the

Linux system to map I/O requests to the driver code, thereby deciding

which device driver to execute, when a user reads from or writes to the

special file. The minor numbers are entirely under the control of the driver

writer, and usually refer to sub-devices of the device. These sub-devices

may be separate units attached to a controller. Thus, a disk device driver

may, for example, communicate with a hardware controller (the device)

which has several disk drives (sub-devices) attached. [4]

In the /usr/src/linux/Documentation/devices.txt file you can find the official

registry of allocated device numbers for the Linux operating system.

3.1.1 Character and block devices

There are two kinds of devices: character devices and block devices. They differ

in how they transfer data between the device and the computer memory.

Character device: transfers data character by character. A character device

usually produces a stream of characters (like a keyboard), consumes a

stream of characters (like a printer), or does both (like a terminal or

modem).

Block device: transfer data in batches of characters called blocks. A disk

drive is an example of a block device, whereas, terminals and line printers

are examples of character devices. This report will only handle character

device from now on. [3]

Page 13: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

The following command can be used to yield the status information of an

existing device node:

# ls -l /dev/lp* crw-rw-rw 1 root root 6, 0 April 23 1994 /dev/lp0

This example indicates that: lp0 is a character type device (the first letter of

the file mode field is c), the major number is 6, and minor device number 0

is assigned to the device.

How to create a character device file and connect it with the device driver

will be handle later in chapter 4.

3.2 Device Driver

The device driver is sometimes called an interface to its device. It is a

collection of subroutines and data within the kernel that constitutes the

software interface to an I/O device. When the kernel recognizes that a

particular action is required from the device, it calls the appropriate driver

routine, which passes control from the user process to the driver routine.

Control is returned to the user process when the driver routine has

completed. (fig 3.) [5]

Figure 3: Shows the relationship between device driver and the Linux system

Page 14: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

A device driver provides the following features:

• A set of routines that communicate with a hardware device and

provide a uniform interface to the operating system kernel.

• A self-contained component that can be added to, or removed from,

the operating system dynamically (modules).

• Management of data flow and control between user programs and a

peripheral device.

• A user-defined section of the kernel that allows a program or a

peripheral device to appear as a ”/dev“ device to the rest of the

system's software.

3.3 Loadable Modules

When you install Linux, the kernel is automatically configured to run. Many

assumptions are building into this kernel, including the type of driver need

to run the hardware and services that the kernel provides. There are times

when you have to change these assumptions. That could be done by recon-

figure the kernel. But not all changes to the features in the kernel require a

rebuild. Many drivers are available to an installed Linux system in the form

of loadable modules. Loadable modules can be used to add features to the

running kernel from user space. For example the PCMCIA feature uses

loadable modules. [2]

List modules

To see which modules are currently loaded into the running kernel space

from user space the lsmod command can be used. Here is an example:

# lsmod

Module Size Used by

parportleds 10372 0

i915 65668 2

binfmt_misc 16776 1

drm 96424 3 i915

bridge 56212 0

stp 10500 1 bridge

bnep 20224 2

Page 15: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

Information about a module

To get more information about the loaded modules, you can use the modinfo

command. For example:

# modinfo psmouse

description: PS/2 mouse driver

..

Not all modules have descriptions available.

A module can’t accomplish its task without using system resources such as

memory, I/O ports, I/O memory, and interrupt lines. We will look at the I/O

port registration, because that’s what our parallel port example will use

later on.

Page 16: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

4 How to write a device driver In this chapter you have a brief tutorial how to write a device driver for

Linux.

4.1 Connection of the device with its files

If a device file doesn’t exist you have to create it. A new device file could be

created by typing the following command as root:

# mknod /dev/parportleds c 61 0

In the example above, c means that a char device is to be created, 61 is the

major number and 0 is the minor number.

Remember also to set the right read/write user permissions on the file, for

example:

# chmod 666 /dev/parportleds

4.2 Load and removing driver

Since the release of kernel version 2.6.x compiling modules has become

slightly more complicated. First, you need to have a complete, compiled

kernel source-code-tree. It’s now also necessary to compile the module

using the same kernel that you’re going to load and use the module with.

[Appendix B]

The modules are compiled with the following command:

# make –C /usr/src/linux-headers-2.6.28-14-generic/

M={your modules dir path} modules

4.2.1 Load and remove modules in user space

Load modules

To load a module into the kernel use the following command as root:

# insmod parportleds.ko

Page 17: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

You could also use the more sophisticated modprobe command to load

modules. The .ko file then has to be moved to /lib/modules to be loaded. The

big options with modprobe are that it adds modules, remove modules, and

find module dependencies.

Remove modules

To remove a module from the kernel use following command as root:

# rmmod parportleds

4.2.2 Initializing modules in kernel space

In order to load and remove a driver in kernel space, parameters are passed

to the module_init() and module_exit() function.

To initialize the module to the right I/O system resource module_init()

function needs modification.

We star with link the char driver with the corresponding /dev file in kernel

space by using the register_chardev() function. It is called with the argument:

major number, a string of characters showing the module name, and a

file_operations structure which links the call with the file function it

defines.

int result

/* Registering device */

result = register_chrdev(61,"parportleds",

&parportleds_fops);

When this is done you need to know what memory address the system

resource are using. In our case, for the parallel port it’s 0x0378. So when

you know the address you should check if the memory region is available

(check_region), and then reserve it with request_region().

Both functions have as argument the base address of the memory region

and its length. The request region function also has third argument, device

name, which connection the memory address with the device name. [4]

/* Registering port */

port = check_region(0x378, 1);

Page 18: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

if (port) {

printk("<1>parportleds: cannot reserve 0x378\n");

result = port;

goto fail;

}

request_region(0x378, 1, "parportleds");

When you have loaded a module into kernel space you should see this in

ioports by typing:

# cat /proc/ioports

..

0378-0378 : parportleds

..

Each entry in the file specifies (in hexadecimal) a range of ports locked by a

driver or owned by a hardware device.

You can also se the printk() function above, it’s very similar to the well

known printf(), but it only works inside the kernel. The printk() writes to

the kernel system log file (/var/log/syslog), and you should also receive this

message in the system console. The <1> symbol shows the priority of the

message. The lower number the high prio.

4.2.3 Removing modules in kernel space

To remove a module from the kernel space the module_exit() function needs

some modification.

The major number is released from the module by using the

unregister_chrdev() function.

/* Make major number free! */

unregister_chrdev(parportleds_major, DRVNAME);

To free the reserved memory for the module release_region() is used, which

takes the same arguments as check_region().

/* Make port free! */

release_region(BASEPORT,1);

Page 19: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

4.3 Read and write to the device

4.3.1 Reading the device in kernel space

The read from the device function is called inb(). It returns the information

to the user space by taking the base port address (0x378) as in argument and

returns the content of the port.

/* Reading port */

parportleds_buffer = inb(BASEPORT);

4.3.2 Reading the device from user space

To read the stat of the parallel port from user space you could use the

following command:

# cat /dev/parportleds

4.3.3 Writing to the device in kernel space

The write to device function is called outb(). It makes it possible to transfer

data from user space to a device by taking the content to write in the port

and its address.

/* Writing to the port */

outb(parportleds_buffer,BASEPORT);

4.3.4 Writing to the device from user space

To write to the parallel port from user space and in that way turn on the

LEDs, execute the command:

# echo –n W > /dev/parportleds

This should turn on LED 1 to 3, 5 and 7. Leaving all of the others turned off.

Page 20: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

5 LED parallel port device driver - example code.

/********************************************************/ /* C header */ /* Filname: parportleds.c */ /* Created: 2009-08-05 */ /* Author: Magnus Abrahamsson */ /* Email: [email protected] */ /* */ /* -----------CHANGE HISTOR------------------ */ /* Date Done by Descriptipon */ /* ------------------------------------------ */ /* 05-AUG-2009 Magnus A Created */ /* 15-SEP-2009 Magnus A Module info added */ /* ------------------------------------------ */ /* */ /* Description: LED Parallel port device driver */ /* */ /* */ /********************************************************/ #include <linux/init.h> #include <linux/autoconf.h> #include <linux/module.h> #include <linux/kernel.h> /* printk() */ #include <linux/slab.h> /* kmalloc() */ #include <linux/fs.h> /* everything... */ #include <linux/errno.h> /* error codes */ #include <linux/types.h> /* size_t */ #include <linux/proc_fs.h> #include <linux/fcntl.h> /* O_ACCMODE */ #include <linux/ioport.h> #include <asm/system.h> /* cli(), *_flags */ #include <asm/uaccess.h> /* copy_from/to_user */ #include <asm/io.h> /* inb, outb */ #define DRVNAME "parportleds" #define BASEPORT 0x378 MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Magnus Abrahamsson<[email protected]>"); MODULE_DESCRIPTION("Parallel port LED driver."); /* Function declaration of parportleds.c */ int parportleds_open(struct inode *inode, struct file *filp); int parportleds_release(struct inode *inode, struct file *filp); ssize_t parportleds_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t parportleds_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos); void parportleds_exit(void); int parportleds_init(void); /* Structure that declares the common */ /* file access fcuntions */ struct file_operations parportleds_fops = { read: parportleds_read, write: parportleds_write, open: parportleds_open, release: parportleds_release }; /* Driver global variables */

Page 21: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

/* Major number */ int parportleds_major = 61; /* Control variable for memory */ /* reservation of the parallel port*/ int port; module_init(parportleds_init); module_exit(parportleds_exit); int parportleds_init(void) { int result; /* Registering device */ result = register_chrdev(parportleds_major, DRVNAME, &parportleds_fops); if (result < 0) { printk( "<1>parport: cannot obtain major number %d\n", parportleds_major); return result; } /* Registering port */ port = check_region(BASEPORT, 1); if (port) { printk("<1>parportleds: cannot reserve 0x378 \n"); result = port; goto fail; } request_region(BASEPORT, 1, DRVNAME); printk("<1>Inserting parportled module\n"); return 0; fail: parportleds_exit(); return result; } void parportleds_exit(void) { /* Make major number free! */ unregister_chrdev(parportleds_major, DRVNAME); /* Make port free! */ if (!port) { release_region(BASEPORT,1); } printk("<1>Removing module parportleds\n"); } int parportleds_open(struct inode *inode, struct file *filp) { /* Success */ return 0; } int parportleds_release(struct inode *inode, struct file *filp) { /* Success */ return 0; } ssize_t parportleds_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { /* Buffer to read the device */ char parportleds_buffer; /* Reading port */ parportleds_buffer = inb(BASEPORT); /* We transfer data to user space */ copy_to_user(buf,&parportleds_buffer,1);

Page 22: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

2 Introduction to Kernel and User

space.

2010-02-18

/* We change the reading position as best suits */ if (*f_pos == 0) { *f_pos+=1; return 1; } else { return 0; } } ssize_t parportleds_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) { char *tmp; /* Buffer writing to the device */ char parportleds_buffer; tmp=(char *)buf+count-1; copy_from_user(&parportleds_buffer,tmp,1); /* Writing to the port */ outb(parportleds_buffer,BASEPORT); printk( "<1>parport write: %d\n", parportleds_buffer); return 1; }

Page 23: Writing Devive drivers in Linux

Writing device drivers in Linux

Magnus Abrahamsson

6 Conclusions / Discussion

2010-02-18

6 Conclusions / Discussion Before you load the parportleds device driver you have to remove the exist-

ing parallel loadable modules (for example, lp, parport, parport_cp, ppdev)

from the kernel, to be get hold of the parallel port memory area.

In my case rmmod wasn’t enough, so I had to remove/move parport from

/lib/modules and reboot the system with out it.

Page 24: Writing Devive drivers in Linux

Writing device drivers in - Error!

Reference source not found.

Magnus Abrahamsson

References

2010-02-18

References

[1] Michael K. Johnson; LINUX Kernel Hackers' Guide ; 201 Howell

Street, Apt. 1C, Chapel Hill, North Carolina 27514-4818, 1993.

[2] Christopher Negus; Red Hat Linux Bible 7.2. ISBN 0-7645-3630-3,

2002, s 66

[3] Paul W. Abrahams, Bruce R. Larson; UNIX for the impatient, 2nd

edition. ISBN 0-201-41979-3, s86-91

[4] Alessandro Rubini & Jonathan Corbet; Linux Device Drivers, 2nd

Edition. ISBN 0-59600-008-1, 586 pages, June 2001

[5] By Tom Coffey and Andrew O’Shaughnessy; Networkcomput-

ing.com,”Write a Linux Hardware device driver”,

http://www.networkcomputing.com/unixworld/tutorial/010/010.t

xt.html

[6] IBM, ”Technical library”,

http://www.ibm.com/developerworks/views/linux/library.jsp

Published 07 Nov 2006. Retreived 2009-09-10.

Front page Illustration: Linux Kernel, By James M. Kenefick Jr. based on work by Rusty Russell and Christian Reinger

Page 25: Writing Devive drivers in Linux

Writing device drivers in - Error!

Reference source not found.

Magnus Abrahamsson

Appendix A: The LED Matrix

2010-02-18

Appendix A: The LED Matrix

The electronic diagram below shows how to create the LED matrix that

you can use to monitor the parallel port with.

9 258 7 6 5 4 3

~500 Ohm

LEDs

2Pin #:

25 pin D-SUB male connector

7 6 5 4 3 2 1 0Bit #:

Figure 3: The electronic diagram for the LED matix and how it’s connected to the

D-25 male.

Figure 4: The 25-pin D-SUB male and the LED matrix showing a “W” (ASCII-87,

B:11101010).

WARNING! Connecting devices to the parallel port can harm your

computer. Make sure that you are properly earthed and you computer

is turned of when connecting the device. Any problems that arise due

to undertaking these experiments are your sole responsibility.

Page 26: Writing Devive drivers in Linux

Writing device drivers in - Error!

Reference source not found.

Magnus Abrahamsson

Appendix B: Compile the kernel

on Ubuntu system

2010-02-18

Appendix B: Compile the kernel on Ubuntu system 1. Install the kernel-image-2.6.x package:

# apt-get install linux-image

2. Install the kernel-source-2.6.x package

# apt-get install linux-source

3. Change to source code directory:

# cd /usr/src

4. Unzip and untar the source code:

# bunzip2 linux-source-2.6.x.tar.bz2

# tar xvf linux-source-2.6.x.tar.

5. Change to kernel source directory:

# cd /usr/src/linux-source-2.6.x

6. Copy the default Linux kernel configuration file to your local kernel

source directory

# cp /boot/config-2.6.x .config.

7. Make the kernel and the modules with

#make

#make modules

(take a break..)

8. Fix grub.

# vi /etc/grub.conf

title Ubuntu Core (2.6.x-generic)

root (hd0,0)

kernei /boot/vmlinuz-2.6.x-generic ro root=/dev/sda3

initrd /boot/initrd.img-2.6.x-generic