好久没有编译过内核了,最近要弄驱动,查看了一下在/usr/src下面有两个文件夹,里面都是空的,没有任何内核源代码。
我用的是CentOS 5.1,其实红帽系列在redora出现之后就一直没有附带linux内核源代码了,所以这些个头文件什么的在你安装好系统那刻起是都不会有的了。
当然了,不管是什么发行版本的linux系统,下面方法都应该适用。
自己从新安装一个就是,现下载:
www.kernel.org下载,如图:
下载后解压到/usr/src下:
bzip2 -dc linux-2.6.24.4.tar.bz2 | tar xvf -
把文件夹linux-2.6.24.4改名字为:linux-kernel
随便在哪个文件夹下面,编写一个shell文件名叫a.sh,内容如下:
#! /bin/bash
mkdir -p /home/name/build/kernel
cd /usr/src/linux-kernel
make mrproper
make O=/home/name/build/kernel menuconfig
make O=/home/name/build/kernel
sudo make O=/home/name/build/kernel modules_install install
然后打开一个终端执行
bash a.sh
shell文件里面O=/home/name/build/kernel表示编译配置在=号后面的文件夹里面进行,中间可以自己查看一下。
后面的过程除了在配置内核的时候,都可以不管了。
这个过程会自动生成新的的内核启动映象,并且自动复制到/boot目录下面去,不用手动复制了。
之后修改grub.conf文件,让以后的系统用新的的内核启动:
vim /etc/grub.conf
内容如下:
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,6)
# kernel /boot/vmlinuz-version ro root=/dev/sda7
# initrd /boot/initrd-version.img
#boot=/dev/sda
default=2
timeout=5
splashimage=(hd0,6)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.24.4)
root (hd0,6)
kernel /boot/vmlinuz-2.6.24.4 ro root=LABEL=/ rhgb quiet
initrd /boot/initrd-2.6.24.4.img
title CentOS (2.6.18-53.el5)
root (hd0,6)
kernel /boot/vmlinuz-2.6.18-53.el5 ro root=LABEL=/ rhgb quiet
initrd /boot/initrd-2.6.18-53.el5.img
title Windows XP
rootnoverify (hd0,0)
chainloader +1
把这一部分注释掉:
title CentOS (2.6.18-53.el5)
root (hd0,6)
kernel /boot/vmlinuz-2.6.18-53.el5 ro root=LABEL=/ rhgb quiet
initrd /boot/initrd-2.6.18-53.el5.img
修改为
#title CentOS (2.6.18-53.el5)
# root (hd0,6)
# kernel /boot/vmlinuz-2.6.18-53.el5 ro root=LABEL=/ rhgb quiet
# initrd /boot/initrd-2.6.18-53.el5.img
再修改default = 0,这里0对应第一个title,下面一次类推
重启就可以了。
编译内核的输出文件太大了,就是开始的/home/name/build/kernel,把这个文件夹可以删除了最后。要写驱动的话,不要删除。
写一个最简单的驱动程序:hello.c
A simple kernel module : " hello world "
======================================================================*/
# include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE( " Dual BSD/GPL " );
static int hello_init(void)
{
printk(KERN_ALERT " Hello World enter " );
return 0 ;
}
static void hello_exit(void)
{
printk(KERN_ALERT " Hello World exit " );
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR( " ztz0223 " );
MODULE_DESCRIPTION( " A simple Hello World Module " );
MODULE_ALIAS( " a simplest module " );
然后写一个Makefile
如下:
KERNEL_SRC = /usr/src/linux-2.6.24.4/
obj-m := hello.o
module-objs := hello.o
all:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules
clean:
rm *.ko
rm *.o
打开终端进入到hello.c路径下make,2.6的内核好像不支持用gcc直接编译了,要用make,如下:
[root @BTazuo hello] # dir
hello . c Makefile
[root @BTazuo hello] # make //编译
make - C / lib / modules / 2.6 . 24.4 / build M =/ azuo / hello modules
make[ 1 ] : Entering directory ` / usr / src / linux - 2.6 . 24.4 '
CC [M] /azuo/hello/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /azuo/hello/hello.mod.o
LD [M] /azuo/hello/hello.ko
make[1]: Leaving directory `/usr/src/linux-2.6.24.4 '
[root @BTazuo hello] # dir //编译成功
hello . c hello . ko hello . mod . c hello . mod . o hello . o Makefile Module . symvers
[root @BTazuo hello] #
加载和卸载驱动:
[root @BTazuo hello] # rmmod ./hello.ko
打开/var/log/messages文件可以看到,最后有内核加载和卸载的信息:
Hello World enterHello World exit
表示内核加载和卸载成功!