Chinaunix首页 | 论坛 | 博客
  • 博客访问: 243070
  • 博文数量: 33
  • 博客积分: 246
  • 博客等级: 二等列兵
  • 技术积分: 918
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-31 16:37
文章分类

全部博文(33)

文章存档

2014年(4)

2013年(7)

2012年(22)

分类: LINUX

2012-09-13 21:28:17

最近尝试着给自己的Virtualbox中的 Ubuntu 11.04 升级下内核.这样做的目的有两个,
第一,编译内核,学习下Linux内核的编译过程;
第二,方便学习Linux内核和驱动,因为学习Linux内核和驱动难免和内核打交道,如果可以直接修改内核,并且编译,运行的话,对内核的过程将会更好的把握和理解.
 
之前都是在公司编译开发板的内核.终于可以摆脱这个了.^_^.之前想升级到3.4.10失败.失败的原因有几个,在这里总结下:
1. 当初安装Ubuntu 11.04 的时候给的磁盘太小了.10G.导致给vdi增加了磁盘空间.但是,已经不能修改sda1磁盘分区的大小,导致磁盘一直报警. 以至于后面制作 initrd 文件都没空间.
2. 编译安装内核后, 不细心. 生成的 initrd 镜像不能使用,但是没有进一步追踪问题.虽然尝试了很多次拯救系统的方法.但是, 没有找对方向.
3. 第一次编译内核, 不熟悉. 而且,资料查阅的也不够.
 
不过,好在失败是成功之母, 并且失败也尚未结扎, 所以, 庆幸的我, 第二次就成功的将内核从2.6.38-8升级到3.0.42.
 
 
 
平台: Windows XP + VirtualBox + Ubuntu 11.04.
 
Linux内核版本升级方向: 2.6.38-8 -> 3.0.42.
 
编译升级内核步骤:<这次步骤都在VirtualBox中的Ubuntu下以root用户操作的.>
1. 下载源代码.可以通过git, 也可以通过ftp网站. 我这里是在  网站上下载的Linux 3.0.42 的内核源代码 linux-3.0.42.tar.bz2.
 
2. 安装几个工具.
(1). kenrel-package. 它是Debian系统里生成kernel-image的一些配置文件和工具.
命令: apt-get install kernel-package
(2). libncurses5-dev. 这个是make menuconfig命令需要用到.
命令: apt-get install libncurses5-dev.
 
3. 解压源代码.
大家习惯将源代码解压到 /usr/src/ 目录下, 我这里也照旧.
cp linux-3.0.42 /usr/src/;
cd /usr/src/;
tar -jxvf linux-3.0.42.tar.bz2;
 
4. 直接使用当前系统 Ubuntu 11.04 的配置文件.
由于不同的发行版Linux, 不同的平台上的Linux的内核配置是不一样的. 对于我, 只求能够成功编译, 所以, 直接使用当前系统的 Ubuntu 11.04 的配置文件. 不标新立异. 如果后续想要重新编译内核学习, 打开某些开关, 那是后话.
命令(当前在/usr/src/目录下): cp /usr/src/linux-headers-2.6.38-8-generic/.config .
 
5. 配置.
命令: make menuconfig
注: 其实我个人感觉没有必要执行这一步, 因为 .config 文件是直接从当前系统的配置拷贝过来的.我在公司编译开发板的配置文件都是拷贝,然后直接编译.所以这一步我是直接跳过的.
 
6. 编译内核.
(1). 清理源代码.
命令: make clean. (make mrproper也可以,但是这条命令会将.config文件也删掉).
(2). 编译内核.
命令: make -j2.(使用j2是两个线程同时进行.我使用的是 make -j2. 如果可以, 某天可以尝试 -j4, j8, j16等等.^_^.)
 
7. 安装内核.
命令: make install
这条命令会将编译生成的内核镜像文件, 配置文件, System.map内核导出符号文件拷贝到 /boot/ 下.
 
8. 编译安装模块
(1). make modules
此命令编译和生成 .config 中配置成 m 的那些模块, 也就是驱动. 生成的都是 ko 文件.
(2). make modules_install
 
9. 生成 init ram disk 文件.
命令: mkinitramfs -o /boot/initrd.img-3.0.42
initrd 的英文含义是 boot loader initialized RAM disk,就是由 boot loader 初始化的内存盘.initrd的最初的目的是为了把kernel的启动分成两个阶段:在kernel中保留最少最基本的启动代码,然后把对各种各样硬件设备的支持以模块的方式放在initrd中,这样就在启动过程中可以从initrd所mount的根文件系统中装载需要的模块。这样的一个好处就是在保持kernel不变的情况下,通过修改initrd中的内容就可以灵活的支持不同的硬件。在启动完成的最后阶段,根文件系统可以重新mount到其他设备上。
initrd会在内存虚拟一个文件系统,然后可以根据不同的硬件加载不同的驱动,而不需要重新编译整个核心。所以,大部分的发行版都会通过这种方式对驱动进行加载
 
10. 更新 grub.cfg.
grub.cfg 位于 /boot/grub/ 目录下.由于 grub.cfg 默认是只读权限的. 所以在修改前, 要将 grub.cfg 权限改为可读, 改完后, 要恢复只读.所以修改 grub.cfg 分为 3 步.
(1). chmod 744 /boot/grub/grub.cfg
(2). 修改 grub.cfg. 命令: vim /boot/grub/grub.cfg
找到 menuentry 选项. 增加对 initrd 的执行.修改后如下图所示(用红色框框起来的部分):
 
 
11. 升级内核完毕. 你可以重启系统了, 如果系统能够成功启动.那恭喜你. 通过命令 uname -r 查看下当前系统的内核版本.会是(3.0.42).
 但是,很不幸, 我执行到这一步后, 好几次都没有成功. 之前想升级到 3.4.10 也是卡到这里了.
 
12. 成功难产,当一回医生吧.^_^.
启动的时候,提示
warning:can't open directory /lib/modules/3.0.42/modules.dep,no such files or directory
纠结了, 忙活了好几个晚上, 总是卡在这里. 揪心着. 下面的步骤可以搞定这个.(root用户权限)
(1). depmod -a (检查所有模块的依赖性, 并且建立文件 version. 解释如下.)
man手册如此介绍 depmod.
Linux内核模块可以为其它模块提供提供服务(在代码中使用EXPORT_SYMBOL),这种服务被称作"symbols"。若第二个模块使用了这个symbol,则该模块很明显依赖于第一个模块。这些依赖关系是非常繁杂的。
depmod读取在/lib/modules/version 目录下的所有模块,并检查每个模块导出的symbol和需要的symbol,然后创建一个依赖关系列表。默认地,该列表写入到/lib/moudules /version目录下的modules.dep文件中。若命令中的filename有指定的话,则仅检查这些指定的模块(不是很有用)。
-a 检查所有模块
 
(下面步骤可以参考initrd的介绍. http://www.cnblogs.com/wwang/archive/2010/10/27/1862222.html )
(2).update-initramfs -k 3.0.42 -c
(3).cd ~
(4).gzip -dc /boot/initrd.img-3.0.42| cpio -id
(5).touch lib/modules/3.0.42/modules.dep
(6).find ./ | cpio -H newc -o > /boot/initrd.img-3.0.42.new
(7).gzip /boot/initrd.img-3.0.42.new
(8).mv /boot/initrd.img-3.0.42.new /boot/initrd.img-3.0.42
 
阅读(3412) | 评论(0) | 转发(0) |
0

上一篇:Linux小知识杂记

下一篇:Linux/Unix基本命令

给主人留下些什么吧!~~