http://leslie-chu.blog.163.com/blog/static/19986324320121411230520/
linux社区有一个项目叫LFS,帮助linux爱好者自己一步步制作一个linux系统,设置可以加入一些特性做成一个和Ubuntu、SUSE不同的发行版。
不过,在这之前我先试试编译内核源码,制作一个可启动的内核镜像。
第一步,下载linux内核源码,网址:http://www.kernel.org/
$wget -r http://www.kernel.org/pub/linux/kernel/v3.0/testing/linux-3.2-rc5.tar.bz2
第二步,解压linux-3.2.0-rc5.tar.gz
$cd ~;
$tar -xzvf linux-3.2.0-rc5.tar.gz
$cp -r linux-3.2.0-rc5 /usr/src/kernels/
$cd /usr/src/kernels/linux-3.2.0-rc5
第三步,配置.config并编译
$make menuconfig
$make
$make modules_install
第四步,设置boot
$cp ./boot/arch/i386/bzImage /boot/vmlinuz-3.2.0
$cp System.map /boot/System.map-3.2.0
$cd /boot
$mkinitrd initramfs-3.2.0-rc5.img 3.2.0
第五步,设置menu.lst(注意备份)
(添加内容):
title Leslie (3.2.0-rc5)
root(hd0,6)
kernel /vmlinuz-3.2.0 ro root=UUID=9da94500-35bc-430c-8502-12913da21a52 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=zh_CN.UTF-8 KEYTABLE=us nomodeset rhgb quiet
initrd /initramfs-3.2.0-rc5.img
第六步,重启并选择Leslie启动
$reboot
.......
$uname -r
===> 3.2.0 (说明是以最新内核启动的)
第七步,查看/lib/modules/3.2.0-rc5
$ls -l /lib/modules/3.2.0-rc5
===>
lrwxrwxrwx 1 root root 31 2月 3 16:34 build -> /usr/src/linux-3.2-rc5
drwxr-xr-x 13 root root 4096 2月 3 18:06 kernel
-rw-r--r-- 1 root root 616700 2月 3 18:07 modules.alias
-rw-r--r-- 1 root root 605455 2月 3 18:07 modules.alias.bin
-rw-r--r-- 1 root root 6635 2月 3 18:04 modules.builtin
-rw-r--r-- 1 root root 8480 2月 3 18:07 modules.builtin.bin
-rw-r--r-- 1 root root 69 2月 3 18:07 modules.ccwmap
-rw-r--r-- 1 root root 248478 2月 3 18:07 modules.dep
-rw-r--r-- 1 root root 358144 2月 3 18:07 modules.dep.bin
-rw-r--r-- 1 root root 246 2月 3 18:07 modules.devname
-rw-r--r-- 1 root root 889 2月 3 18:07 modules.ieee1394map
-rw-r--r-- 1 root root 218 2月 3 18:07 modules.inputmap
-rw-r--r-- 1 root root 15833 2月 3 18:07 modules.isapnpmap
-rw-r--r-- 1 root root 307 2月 3 18:07 modules.ofmap
-rw-r--r-- 1 root root 93563 2月 3 18:04 modules.order
-rw-r--r-- 1 root root 382117 2月 3 18:07 modules.pcimap
-rw-r--r-- 1 root root 1261 2月 3 18:07 modules.seriomap
-rw-r--r-- 1 root root 131 2月 3 18:07 modules.softdep
-rw-r--r-- 1 root root 231589 2月 3 18:07 modules.symbols
-rw-r--r-- 1 root root 293542 2月 3 18:07 modules.symbols.bin
-rw-r--r-- 1 root root 977951 2月 3 18:07 modules.usbmap
lrwxrwxrwx 1 root root 31 2月 3 18:04 source -> /usr/src/linux-3.2-rc5
第八步,修改代码,重新编译,查看特性。。。。。
$wget -r http://www.kernel.org/pub/linux/kernel/v3.0/testing/linux-3.2-rc5.tar.bz2
第二步,解压linux-3.2.0-rc5.tar.gz
$cd ~;
$tar -xzvf linux-3.2.0-rc5.tar.gz
$cp -r linux-3.2.0-rc5 /usr/src/kernels/
$cd /usr/src/kernels/linux-3.2.0-rc5
第三步,配置.config并编译
$make menuconfig
$make
$make modules_install
第四步,设置boot
$cp ./boot/arch/i386/bzImage /boot/vmlinuz-3.2.0
$cp System.map /boot/System.map-3.2.0
$cd /boot
$mkinitrd initramfs-3.2.0-rc5.img 3.2.0
第五步,设置menu.lst(注意备份)
(添加内容):
title Leslie (3.2.0-rc5)
root(hd0,6)
kernel /vmlinuz-3.2.0 ro root=UUID=9da94500-35bc-430c-8502-12913da21a52 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=zh_CN.UTF-8 KEYTABLE=us nomodeset rhgb quiet
initrd /initramfs-3.2.0-rc5.img
第六步,重启并选择Leslie启动
$reboot
.......
$uname -r
===> 3.2.0 (说明是以最新内核启动的)
第七步,查看/lib/modules/3.2.0-rc5
$ls -l /lib/modules/3.2.0-rc5
===>
lrwxrwxrwx 1 root root 31 2月 3 16:34 build -> /usr/src/linux-3.2-rc5
drwxr-xr-x 13 root root 4096 2月 3 18:06 kernel
-rw-r--r-- 1 root root 616700 2月 3 18:07 modules.alias
-rw-r--r-- 1 root root 605455 2月 3 18:07 modules.alias.bin
-rw-r--r-- 1 root root 6635 2月 3 18:04 modules.builtin
-rw-r--r-- 1 root root 8480 2月 3 18:07 modules.builtin.bin
-rw-r--r-- 1 root root 69 2月 3 18:07 modules.ccwmap
-rw-r--r-- 1 root root 248478 2月 3 18:07 modules.dep
-rw-r--r-- 1 root root 358144 2月 3 18:07 modules.dep.bin
-rw-r--r-- 1 root root 246 2月 3 18:07 modules.devname
-rw-r--r-- 1 root root 889 2月 3 18:07 modules.ieee1394map
-rw-r--r-- 1 root root 218 2月 3 18:07 modules.inputmap
-rw-r--r-- 1 root root 15833 2月 3 18:07 modules.isapnpmap
-rw-r--r-- 1 root root 307 2月 3 18:07 modules.ofmap
-rw-r--r-- 1 root root 93563 2月 3 18:04 modules.order
-rw-r--r-- 1 root root 382117 2月 3 18:07 modules.pcimap
-rw-r--r-- 1 root root 1261 2月 3 18:07 modules.seriomap
-rw-r--r-- 1 root root 131 2月 3 18:07 modules.softdep
-rw-r--r-- 1 root root 231589 2月 3 18:07 modules.symbols
-rw-r--r-- 1 root root 293542 2月 3 18:07 modules.symbols.bin
-rw-r--r-- 1 root root 977951 2月 3 18:07 modules.usbmap
lrwxrwxrwx 1 root root 31 2月 3 18:04 source -> /usr/src/linux-3.2-rc5
第八步,修改代码,重新编译,查看特性。。。。。
前面这张照片是我编译内核后用dmesg命令查看的信息,因为我在init/main.c文件的start_kernel函数入口加入了一些打印信息。因此,在CPU从自我模式进入保护模式时就需要调用此函数,从而打印我所设定的信息。这是很普通的操作,却是我学习内核的第一步。
http://leslie-chu.blog.163.com/blog/static/199863243201241225615710/?suggestedreading&wumii
以前编译过linux内核,但编译自定义模块一直失败,后来不了了之。这几天又拿起内核方面的资料看,查了点资料,竟然编译过去了,回头总结下,发现压根就是我自己不上心。
周末有时间了,顺便做点笔记,吃了点兴国鱼丝,肚里有食要好好渡过漫漫长夜,明天醒来的早还可以看场电影吧。编译内核:
编译内核,第一步肯定是下载内核源码树(www.kernel.org),然后解压到/usr/src目录(习惯)。
配置内核编译,是执行命令make menuconfig,如果想用默认配置的话,就直接退出保存即可。
编译内核执行命令make bzImage,生成的bzImage文件在arch/x86/boot/目录中。将此文件拷贝到/boot目录下并以vmlinuz开头命名。另外,把System.map拷贝到/boot目录重命名。
编译、安装模块是执行命令make modules && make modules_install,执行后会在目录/lib/modules/下建立一个以内核版本号为目录名的目录,内核模块就在此目录下。
在/boot目录下执行mkinitrd initramfs-3.2.0-rc5.img 3.2.0-rc5这里的3.2.0-rc5是我编译的内核版本号,也是/lib/modules/3.2.0-rc5目录名。
总结:
1. 下载内核文件,加压到/usr/src/;
2. make menuconfig
3. make bzImage
4. make modules && make modules_install
5. cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.0-rc5
6. cp System.map /boot/System-3.2.0-rc5.map
7. cd /boot && mkinitrd initramfs-3.2.0-rc5.img 3.2.0-rc5 (以3.2.0-rc5例)
8. vim /boot/grub/grub.conf(可选)
9. reboot
编辑grub.conf(可选):
default=1 (第一个启动title是0,这里默认以第二个title启动)
timeout=5 (停留5秒)
splashimage=(hd0,6)/grub/splash.xpm.gz (grub的背景)
hiddenmenu
title Fedora (2.6.43.2-6.fc15.i686) (系统本身内核)
root (hd0,6) (/boot所在分区)
kernel /vmlinuz-2.6.43.2-6.fc15.i686 ro root=UUID=9da94500-35bc-430c-8502-12913da21a52 (如果/etc/fstab定义了LABEL,这里是root=LABEL=/,也可以是root=/dev/sda9)
initrd /initramfs-2.6.43.2-6.fc15.i686.img (系统内核镜像)
title LeslieChu (3.2.0-rc5)
root(hd0,6)
kernel /vmlinuz-3.2.0-rc5 ro root=UUID=9da94500-35bc-430c-8502-12913da21a52
initrd /initramfs-3.2.0-rc5.img
title Windows 7(Simple Life,Freely World!)
rootnoverify (hd0,0) (win7安装在第一块磁盘的第一个分区)
chainloader +1
GRUB命令(若没有配置/boot/grub/grub.conf):
启动时,按Enter进入grub引导界面,按c进入grub命令行环境。
分两种情况,一种是/和/boot在一个分区,一种是/和/boot不在一个分区,同一个分区则路径以/boot开头。
1.确定/boot所在分区
grub>find /boot/grub/stage1 或find /grub/stage1 (这里按TAB会自动提示)
输出:(hd0,6)
grub>root (hd0,6) (设置/boot所在分区)
2.确定/所在分区或设备符或标签
grub>cat /boot/grub/grub.conf 或cat /grub/grub.conf
3.确定内核文件和内核选项
grub>kernel /boot/vmliuz-3.2.0-rc5 ro root=UUID=asdfwa-s...
或
grub>kernel /vmlinuz-3.2.0-rc5 ro root=UUID=asdfasdfs....
(这里表示/所在分区的方法很多,可以是标签root=LABEL=/,也可以是root=/dev/sda9)
4.确定引导系统内核镜像
grub> initrd /boot/initramfs-3.2.0-rc5.img
或
grub>initrd /initramfs-3.2.0-rc5.img
5.引导
grub>boot
编译自定义模块:
用新内核启动系统后,可以用uname -r来查看内核,系统只是更换了内核,其它部分是发行版本的事情,并没有其它区别。但是,如果新内核不支持某些特性,比如kvm,则kvm方面的功能无法使用。
假设有自定义模块firstmod.ko,源码文件是firstmod.c:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#define DRIVER_AUTHOR "LeslieChu"
#define DRIVER_DESC "test hello module"
#define VERSION "1.0.0"
#define ALIAS "HeiMod"
#define LICENSE "GPL"
/*导出模块变量*/
int abc = 3;
int i = 0;
module_param(abc,int,S_IRUGO);
/*定义模块信息,通过modinfo查看*/
MODULE_LICENSE(LICENSE);
MODULE_AUTHOR(DRIVER_AUTHOR );
MODULE_DESCRIPTION(DRIVER_DESC );
MODULE_VERSION(VERSION);
MODULE_ALIAS(ALIAS);
/*加载模块*/
static int __init first_init (void)
{
printk("the first mode insmod\n");
for(i=0;i<abc;i++)
printk("the i is : %d\n",i);
return 0;
}
/*导出模块函数符号*/
static void haha(void)
{
for(i=0;i<abc;i++)
printk("+++++i=%d\n",i);
}
/*卸载模块*/
static void __exit first_exit (void)
{
printk("the first mode rmmod\n");
}
/*注册模块*/
module_init(first_init);
module_exit(first_exit);
EXPORT_SYMBOL(haha);
最简单的Makefile:
obj-m:=firstmod.o
最简单的编译方法:
make -C /usr/src/linux-3.2.0-rc5/ M=`pwd` modules (在源码所在目录执行)
稍复杂的Makefile:
obj-m:=firstmod.o
KDIR:=/lib/modules/3.2.0-rc5/build
PWD:=$(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o .cmd *.ko *.mod.c .tmp_versions *.order *.sym*
稍复杂的编译方法:make
查看模块firstmod.ko:
$modinfo firstmod.ko
filename: firstmod.ko
alias: HeiMod
version: 1.0.0
description: test hello module
author: LeslieChu
license: GPL
srcversion: FE2406F74135246FCAA271C
depends:
vermagic: 3.2.0-rc5 SMP mod_unload 686
parm: abc:int
加载模块firstmod.ko:
$insmod firstmod.ko
$lsmod | grep firstmod
firstmod 12574 0
$dmesg | tail -10
.....
[11525.493829] the first mode insmod
[11525.493832] the i is : 0
[11525.493833] the i is : 1
[11525.493835] the i is : 2
.....
卸载模块firstmod.ko:
$rmmod firstmod
$dmesg
[14436.331425] the first mode rmmod
后续如果更改了内核代码,则重新编译、安装内核一次即可;如果自己写模块,则按照上面方法编译即可。模块的功能很强大,但我知道的就这么多,如果一个32位系统的模块,到了64位系统上能编译过吗?
这将是下周我要面临的难题。