发现自己的知识体系有一段很大的空缺,就是对于 ARM 还是太缺少了解,下面是AVR系列单片机,上面是PC机、服务器,好歹都还算大概见过是怎么一回事,而对于SOC,就了解得很不够,包括对于手机、安卓或是苹果系都只是停留在应用层面,至于开发是怎么样子就没有什么感性认识,感觉一打开这扇门,就会有各种知识领域排山倒海而来。不过该来的总是要来么,连
linux 内核 kernel 都不会编译,实在是不敢自诩为Geeker。好在现在开源ARM平台中,相信树莓派(Raspberry Pi,简称“RPi”)的资料很全,社区也庞大。所以,在盲目去买 ARM 开发板之前,还是先把手边现有的 RPi 和 Mk802 先玩起来再说。
这次尝试给RPi编译 kernel,主要参考了官方教程和Peter Mount’s Blog上的这篇文章。我会结合自己操作过程中的实际情况,配合截图做个记录。
开发环境:我使用的系统是Ubuntu 12.10,因为使用的是“交叉编译”,也就说编译环境是PC,而运行环境是RPi,所使用的编译器也都是为目标系统所定制,所以相信不用纠结于PC这边的具体linux发行版。
1. 连接系统
如题图所示,PC通过USB转串口芯片连接到RPi的串口(当然还要共地),这样我在PC终端这边,可以通过minicom登录RPi并进行操作。
截图中,蓝底黄字的为minicom窗口,黑底白字为本地终端。通过minicom登录RPi以后,可以运行以下命令以查看当前Kernel的版本。
$ uname -a |
我现在使用的kenrel版本为3.2.27,生成日期为2012年9月26日。SD卡上原先烧的镜像是比较经典的“2012-08-08-wheezy-armel.zip”。
2. 下载编译工具、Kernel源文件、固件 Firmware
简单起见,我们都使用官方提供的资源。
$ mkdir rasperberrypi $ cd raspberrypi $ git clone git://github.com/raspberrypi/firmware.git PRiFirmware $ git clone git://github.com/raspberrypi/linux.git RpiLinux $ git clone git://github.com/raspberrypi/tools.git RpiTools |
在 git clone 命令的源后,可以跟上文件名,对下载文件夹名称进行指定。因为git
clone似乎不支持断点续传,而这几个项目都是上百M,如果网络不稳定的话,下载会比较郁闷。如果对更新不是很关心的话,可以直接下载github上相
应的zip压缩包。下载完成以后,应该有这样三个文件夹,分别对应固件、linux源码和编译工具。
3. 获取当前Kernel的.config文件,并进行自定义的配置
把config.gz文件拷贝到RPi的home目录之后,就可以将RPi关机,将SD卡插入PC,获取并解压该配置文件。sdc对应SD卡,其又分为两个分区sdc1、sdc2,分别对应RPi的“/boot”和“/”
$ sudo mkdir /media/agu/SD $ sudo mount /dev/sdc2 /media/agu/SD/ $ cp /media/agu/SD/home/pi/config.gz . $ zcat config.gz > .config $ ls -a . .. .config config.gz RpiFirmware RpiLinux RpiTools $ sudo umount /media/agu/SD |
当Linux目录下有了.config文件以后,就可以对其进行重新配置。
$ mv .config /RPiLinux $ cd RpiLinux/ $ make ARCH=arm CROSS_COMPILE=../RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi- oldconfig |
在官方提供的编译工具中包含三套工具链
- arm-bcm2708hardfp-linux-gnueabi
- arm-bcm2708-linux-gnueabi
- gcc-linaro-arm-linux-gnueabihf-raspbian
简单起见,我们就选用其中第一种,命令行的输入都通过tab补全来实现。make
oldconfig可以在原.config的基础上更新配置,菜单很长,大部分目前我自己也不清楚是什么意思,所以也是一路enter,选择默认值。大致
可以看出里面包含不少对加载驱动的选取。
如果还需要添加什么内容,可以运行
$ make ARCH=arm CROSS_COMPILE=../RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi- menuconfig |
就可以看到kernel的配置菜单:
这里就可以更加从容地添加模块,比方说摄像头之类。完成以后,选择exit退出。
3. 编译Kernel,modules
$ make ARCH=arm CROSS_COMPILE=../RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi- |
如果没有开启多线程编译的话,这个过程可能需要三四十分钟左右。
arch/arm/boot/zImage 就是我们所编译获得的文件。zImage 是 Compressed kernel image 文件,要转换为 kernel.img 还需要进一步处理。
$ cd ../RpiTools/mkimage/ $ ./imagetool-uncompressed.py ../../RpiLinux/arch/arm/boot/zImage |
可以看到当前目录中多了kenrel.img文件。
新的Kernel要正确运行,还需要编译所需的module,主要对应”/lib”目录下的内容。编译时,使用“INSTALL_MOD_PATH”参数指定目标路径。
$ cd ../.. $ mkdir modules $ cd RpiLinux/ $ make modules_install ARCH=arm CROSS_COMPILE=../RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi- INSTALL_MOD_PATH=../modules |
3. 备份 Firmware
$ cd .. $ mkdir backup $ sudo mount /dev/sdc1 /media/agu/SD/ $ cd /media/agu/SD/ $ mv *.elf *.bin ~/gitpool/raspberrypi/backup/ |
因为kernel可以通过在/boot/config.txt中进行设定,所以倒也不急着拷出来。
可以通过vi,可以添加“kernel=kernel_new.img”这行,如果原来有的话,就修改一下。这样系统就会引导到我们刚刚拷入的kernel_new.img
4. 升级RPi的kernel、Firmware、lib
$ sudo cp ~/gitpool/raspberrypi/RpiTools/mkimage/kernel.img kernel_new.img $ cd ~/gitpool/raspberrypi/RPiFirameware/boot $ cp bootcode.bin fixup.dat fixup_cd.dat start.elf /media/agu/SD/ $ cd ../hardfp/opt/ $ sudo umount /media/agu/SD $ sudo mount /dev/sdc2 /media/agu/SD/ |
将挂载点换成SD卡的第2分区,即”/”分区。
$ sudo cp -r vc/ /media/agu/SD/opt/ |
将新的vc库复制到SD卡,因为之前选用的工具链是hardfp(硬浮点),所以现在所选用的vc库也是硬浮点的版本(RPiFramware/hardfp/opt/vc)。
$ cd ../../.. $ sudo cp -r modules/lib /media/agu/SD/ |
复制编译的module/lib到RPi的”/”根分区内。
5. 享用新的 Kenrel 吧~
将SD插回RPi,可以看到其正常启动,同时其kernel已更新到3.6.11,系统的生成日期是2012年1月10日,也就是今天。
至此,我们就完成了RPi的Kernel更新。至于后续的安装,包括rootfs的选择和安装,还有待继续研究。希望本文对那些从未编译过
kernel的朋友一点帮助,如果仔细按照我的步骤,相信会得到和我一样的结果。RPi是很强大而且学习资料相当丰富的ARM平台,通过它来学习嵌入式
linux开发,相信是不错的选择。
参考资料:
RPi Kernel Compilation
Compiling a Kernel on the Raspberry PI
基于MK802 MiniPC的扩展开发应用-系统自制,如果希望多硬浮点软浮点多一些了解,可以仔细研究大H的文章哦~
本次操作所使用的USB转串口模块,由圣源电子提供。
这个过程,自己又经历了几次,发现上面记录的还是比较乱。步骤其实更简单一些,
- 备份:升级之前,如果需要备份的话,$ sudo dd bs=4M if=/dev/sdc of=2012-01-17.img 可以备份整张SD卡
- 升级firmware:RPiFirmware里面的boot和hardfp/opt/vc可以先全部覆盖到SD卡的相应位置。
- 编译升级Kernel:如果需要自定义kernel,再进行自定义配置和编译,再将kernel和新编译的lib同时拷入SD卡。
来自:http://aguegu.net/?p=1544