编译Linux内核(上)--编译基于x86平台的Linux内核的过程

编译Linux内核。

 

 

 

第一步:下载源码并存入Linux目录,我是放到了/usr/src目录下,别的目录也可以。一般下载下来的源码都是文件名为"linux-$版本号.tar.bz2"的数据包格式,比如"linux-2.6.15.5.tar.bz2”。

 

 

 

第二步:将数据包解压。这里一定要注意,解压这个过程必须在linux内完成,不要在windows下解压,如果在windows下解压,编译内核的时候会出现error,提示缺少某些文件,这是因为在windows下,文件名是不区分大小写的,比如direct.c和Direct.c,而在Linux下却区分大小写。在解压过程中windows会把这两个文件解压成一个文件从而导致文件丢失。linux内核源码里同目录下有很多这样的"同名"文件。

对于 .tar.bz2   后缀的文件,用tar -jxvf来解压。如"tar -jxvf linux-2.6.15.5.tar.bz2",解压后会在当前目录中生成名为 "linux-2.6.15.5"的文件夹。

附:(关于tar命令的用法详解,参考http://www.cnblogs.com/eoiioe/archive/2008/09/20/1294681.html

 

 

 

第三步:进入上一步生成的内核源码目录      cd linux-2.6.15.5

 

 

第四步:清除内核源码目录中可能存在的以前编译过程中留下的中间文件。

一般用make clean命令即可,也可用make distclean。

二者的区别:

make clean 只清除中间文件不清除配置文件。

make distclean 全部清除。

 

 

 

第五步:配置内核

此处有多个命令可用:

make config:这个命令最不好用,必须在命令行里根据提示一项一项的配置,而很多项我们可能根本不了解是什么意思。所以如果不是对内核特别了解别用这个命令。咱们这种菜鸟级的可以直接无视它。

make menuconfig:这个命令不错,推荐。跟make config相比用这个命令会有菜单项辅助我们配置,结构清晰。而且有默认设置供我们参考。

make oldconfig:比第一个好点,也是命令行输出提示信息,不过只提示新项的配置。也不好用

make Xconfig:适用于桌面系统,最直观。不过还是推荐用make menuconfig。

配置时,对于每一项,一般都有Y,M,N三种选择。选择Y表示Yes,就是将这一项编译到内核中;选择N表示不编译此项;选择M表示编译此项,但是不是直接编译到内核中,而是编译成内核模块。

配置完相应项后,保存设置。这时候内核源码目录项就多了个   .config  文件,该文件是隐藏的,要用  ls -a 才可以看到。.config文件保存了我们刚才的配置信息。

 

 

 

第六步:

一切就绪。开始编译内核,用到的命令:make zImage和make bzImage。在x86平台下,使用make zImage只能编译512K以内的内核,如果编译出的内核大于512K就会报错,而使用make bzImage则可以编译任意大小的内核(bzImage=big zImage)。在其他平台上,这两个命令没有区别。

进入内核源码目录,直接: make bzImage。这时系统开始编译我们再上一步配置过程中选择Y的项。

然后就是漫长的等待,红帽子开始刷屏:

 

 

这个时间段我们最好先玩点别的,因为这个编译过程的确很漫长。

 

二十分钟后,终于刷屏结束,内核编译完成:

 

 这时源码目录下的 arch/<cpu>/boot 目录下会出现一个名为bzImage或zImage的文件(取决于我们编译内核时用的命令是make zImage还是make bzImage),这个就是编译好的内核。

 

 

 

第七步:编译内核模块。用到的命令:make modules。同样是在源码目录下使用这个命令。这时系统开始编译我们在配置过程中选择M的项。

木有截图。

 

 

 

第八步:安装内核模块。用到的命令:make modules_install。这一步执行后系统会将内核模块从内核源码目录拷贝到  /lib/modules  下(该目录下会出现一个以内核版本号命名的文件夹,如"2.6.15.5")。

木有截图。

 

 

第九步:制作init ramdisk。用到的命令 mkinitrd

"mkinitrd initrd-2.6.15.5 2.6.15.5"

中间的initrd-2.6.15.5可任意命名,但最好命名成这样子,清晰易懂。而后面的2.6.15.5不能随便写,是那个版本就是那个版本,它对应的是上一步在/lib/modules目录中生成的文件夹。这一步执行后会在源码目录下生成initrd-2.6.15.5文件。

 

 

 

第十步:安装内核。

这一步需要先将第六步中编译生成的内核bzImage zImage文件拷贝到  /boot目录下(拷贝后的文件名任意,但最好命名成"vmlinuz-2.6.15.6"这种形式,习惯)。再将第九步生成

的源码目录下的initrd-2.6.15.5文件拷贝到/boot中。

然后修该启动文件grub.conf,此文件位于/etc下。

grub .conf文件中添加如下内容(加入我要安装的是上面举例用的2.6.15.5版本,而且各文件名也如前所说)

 

--------------------------------------------------------------------------------

title MyOwnLinux                       #(此处名称任意)

        root (hd0,0)

        kernel /boot/vmlinuz-2.6.15.5 ro root=LABEL=/ rhgb quietselinux=0

                 #上面的就是拷贝到/boot文件夹中的内核  

      initrd /boot/initrd-2.6.15.5       #拷贝到/boot目录下的的init ramdisk

---------------------------------------------------------------------------------

 

grub.conf文件的配置说明参见http://blog.csdn.net/zhuliting/article/details/5502636

弄好这一切后,重启  reboot 

然后就会看到这样的开机界面:

 

 

 

 

最后一张插图是我编译2.6.34.13时的插图。前面的几张是2.6.15.5的。由于2.6.15.5我用的源码不是官网下载的所以出现了很多问题没有成功,最后发现它的源码都有问题。所以大家一定要下载官网上的源码,稳定。

 这里说一下,编译内核的过程到第七步就算完成了,第八步往后用到的"make modules_install"、"mkinitrd"等命令不属于“编译”内核的过程,而属于内核的安装。上面我编译完后的内核之所以可以直接安装在我的PC上,是因为我编译的是基于x86平台的Linux内核,而如果编译过程选择的是其他的平台比如arm,编译出来的内核就不能直接往PC上安装了。编译内核时默认的是基于x86平台。编译基于其他平台的Linux内核的方法在  “【学习笔记】编译Linux内核(下)”中会提到。

转载:

编译过程: 1). 解压后默认的文件夹位置是在D:\Linux-0.11,如果你不是将文件解压到该目录下, 你要修改MinGW32目录下的MinGW32.bat文件,将里面的PATH指向MinGW32的bin目录. 2). 打开Linux-0.11目录,双击MinGW32.bat快捷方式,打开控制台. 3). make 一下,生成1.44M的Boot.img软盘镜像,要清除编译结果请"make clean" 4). 如果安装了bochs,直接双击bochsrc.bxrc即可运行Linux-0.11了. 5). 也可用其它虚拟机加载Boot.img后运行,如果出现Kernel panic,请把虚拟机里的硬盘删了 6). 在出现Insert root floppy and press ENTER以后,将rootimage-0.11.img载入虚拟软驱,回车 这就是能在windows环境下编译Linux 0.11了,不是在Cygwin,也不是在虚拟机里,而是使用MinGW. 下面是在Windows下编译Linux 0.11会遇到的问题和对原文件作的修改: 1.赵炯博士已经将汇编程序中引用的C变量(包括嵌入汇编的C变量)的下划线去掉了,但MinGW的gcc可能是为了与其它Windows下的编译器保持兼容,并不能识别这些不带下划线的C变量,因而还得把原先已经在汇编程序中去掉下划线的C变量加上下划线,同时也要把被C程序引用的汇编程序中的变量加上下划线. 2.MinGW中不带as86编译器,因而把boot目录下原先用as86编译的bootsect.s和setup.s两个程序修改成能用nasm编译的程序.并且更名为bootsect.asm和setup.asm. 3.在Makefile作的主要修改: 在LDFLAGS中加了--image-base 0x0000 将elf_i386改成i386pe 将cd 与 make 之间的;改成&,如cd kernel ; make 改成cd kernel & make MinGW中没有sync这个程序,可以把它注释掉,更简单的办法是写一个sync.c,这个sync.c只包含一个空的main函数,编译成sync.exe 因为类似的原因,make dep会出错 4.生成的system文件是PE格式的(PE是Portable Executable的简称),这是windows下的可执行文件的格式,显然是不能直接执行的,必须加以转化.我实现了通过两种方式加以转化. 1)写一个程序Trans.cpp将system.exe里的代码和数据从PE文件里解析出来,生成一个system.bin文件,这个文件是能被setup模块直接加载的.我已经将这个程序放在了Linux-0.11的tools目录下,要微软的编译编译. 2)自己写一个PE Loader,这种方式比较麻烦,但是想想自己也能做一个PE Loader,还是满有成就感的,尽管这是一个最简单的Loader.代码是加在Linux-0.11-With-PE-Loader\boot目录下的setup.asm文件里,里面有详细的注释. 5.对tools下的build.c作了修改,使其能生成可引导的1.44M的软盘镜像文件Boot.img 6.在Link的过程中,init目录下的main.c会出现以下错误: boot/head.o(.text+0x540c):fake: undefined reference to `_main' init/main.o(.text+0x16f):main.c: undefined reference to `_alloca' init/main.o(.text+0x174):main.c: undefined reference to `__main' make: *** [tools/system.exe] Error 1 第一个和最后一个错误还好理解,但中间那个错误那就莫明其妙了,因为Linux 0.11根本没有这个函数,在gcc的编译选项里也有-nostdinc .有一个解释是main函数不是一个普通的函数,MinGW gcc会对它作特殊的处理.解决的办法其实也很简单,把main.c下面的main函数改名为_main,或者是干脆把它改成另外一个函数,就改成start吧.记得把head.s里的_main也改了. 在最后,要感谢《自己动手写操作系统》的作者于渊,其实我也是先将原先只能在Linux编译的书里源代码用MinGW移植到Windows下编译过程中才试着在Windows下编译Linux 0.11源代码的,有了在Windows下编译Linux 0.11源代码的经验,移植高版本的源代码,像0.12,0.95,0.96等等版本应该不会有太大的麻烦了。 也要感谢Linux内核完全注释的作者赵炯博士,是他拉接了操作系统与操作系统爱好者的距离. 最后,我也非常想和操作系统爱好者们共同交流心得体会,也希望能多认识一些朋友. 我的网名:flyfish 我的QQ:785606288 E-mail:I2CBus@126.com 另外,要转载请保持本文件的完整性,请尊重别人的劳动果实. 修改日志: 08/3/29 修改了一下Makefile,旧的Makefile在某些文件更新后还会重新编译。 修改了Trans.cpp中的一个dug,该dug在translate MinGW gcc编译的程序时可能会出错。用MinGW gcc 编译的程序的VirtualAddress的形式可能是0xFFC1000这样的形式,其实0x1000才是它的VirtualAddress 08/4/2 修改了下MinGW32.bat,现在已经不用重设路径了。 08/4/4 Trans.cpp还是有错,如果VirtualAddress>0xffff,那么生成的system.bin就错了,bochs调试时会一直重启。 权宜之计,把0xffff再改成0x3ffff,这样VirtualAddress就不能大于0x3ffff,不知谁有更好的解决方法,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值