拳不离手、曲不离口 - Speak with your code, my friend, not your word.

[LFS]快速搭建一个简陋但干净的CLFS。

注:要使用支持eabi的交叉编译工具,并且所有的东西都要用eabi的方式去编译,否则会出问题!

CLFS可以做得很简单,也可以做得很复杂,我还是推崇由浅入深的道理,用最快的速度,最简单的步骤,自己搭建一个CLFS,想学CLFS的朋友,跟我来吧。

首先我们需要作一些准备工作:

一台host(PC),一台target(开发板-AT91SAM9261),U-boot源码(1.1.5+9261补丁),Linux Kernel源码(2.6.27),Busybox源码(1.14-noon),Cross-ToolChain(到网上下一个,制作过程我不太清楚),在host上开启TFTP服务,配置host的IP地址。

呵呵,就这么多,除了toolchain难搞一点,其他都很容易不是吗?U-boot对9261支持不太好,虽然1.3.4开始支持这块板子了,但是还有问题,启动后,运行saveenv命令,重启立马死机,原因我正在找,幸好 www.linux4sam.org/twiki/bin/view/Linux4SAM/U-Boot 这个网站提供了一个1.1.5版的补丁,我用的1.7版本,打上补丁之后,没什么大问题了,或许你的板子被uboot支持得比较好,不用打补丁。我这里只讲一个总的流程,尽量适用于一般情况。

好啦,准备工作做好后,开始吧,只需3步,就解决问题。

1,烧bootloader。

首先需要u-boot.bin这个文件,进入U-boot源码目录。

(1)修改源码(此步可跳过),为什么要修改呢?因为u-boot有很多环境变量,比如说传给kernel的字符串阿,ip地址阿,mac地址都是作为环境变量出现的,源码默认会有一些环境变量,你自己可以在uboot启动后修改或者添加自己的环境变量,但是我觉得这样挺麻烦的,在源码里自己也可以修改,添加,所以我选择在源码里改。打开开发板对应的头文件,我的是,./include/configs/at91sam9261ek.h,按照下面修改

 

...
#define CONFIG_BOOTCOMMAND "nand read 20008000 40000 200000;bootm 20008000"
#define CONFIG_BOOTARGS "console=ttySAC0,115200 mem=64M root=/dev/mtdblock2"
#define CONFIG_ETHADDR  08.10.24.11.05.36
#define CONFIG_IPADDR   192.168.1.6
#define CONFIG_SERVERIP 192.168.1.20

#define CONFIG_BOOTDELAY    1

#define CONFIG_EXTRA_ENV_SETTINGS  \
        "wk=nand erase 40000 200000;tftp 20008000 uImage;nand write 20008000 40000 200000""\0" \
        "wki=nand erase 40000 200000;tftp 20008000 uImage;nand write.i 20008000 40000 200000""\0" \
        "wf=setenv bootargs mem=64M console=ttySAC0,115200 initrd=0x21100000,2000000 root=/dev/ram0 rw;tftp 21100000 initrd.gz;bootm 20008000""\0" \
        "wkft=tftp 20008000 uImage;run wf""\0" \
        "wkf=run wk;run wf""\0" \
        "wm=setenv bootargs mem=64M console=ttySAC0,115200 initrd=0x21100000,2000000 root=/dev/ram0 rw;tftp 21100000 ramdisk.gz;bootm 20008000""\0" \
        "wkmt=tftp 20008000 uImage;run wm""\0" \
        "wkm=run wk;run wm"
...

 

(2)make distclean,然后make at91sam9261ek_config,然后make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnuebai- -j4

然后不出意外的话就编译好了,源码目录下就生成了u-boot.bin。

然后呢,9261这块板子还需要一个dataflashboot.bin,用来启动bootloader,不用管他,这是板子特性,dataflashboot.bin是开发板光盘里自己提供的,照说明书把两个bin烧到板子就可以了,我估计一般的开发板只需要烧一个u-boot.bin就可以了。

好了第一步完成,重启系统,看到控制台写的u-boot1.1.5就算大功告成了,如果你没有修改代码,你还需要在控制台设一些环境变量,就是上面写的那些啦,不过设的时候要用\;转义; 那些"\0"不用写,代码判断用的,\也不用写,c语言里的连行符,应该都懂得吧。

2,准备kernel

这一步最简单了,进源码目录,make mrproper;cp arch/arm/configs/at91sam9261ek_defconfig .config;make ARCH=arm menuconfig;菜单配置选项中开启eabi,把启动字符串内容清除掉,保存后退出;make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnuebai- -j4

好了,zImage就生成了,然后用u-boot.bin提供的工具mkuImage把zImage转换成u-boot能用的uImage,把uImage放到Host机的TFTP目录中。

3,准备rootfs

最后一步啦,做rootfs最简单的方法,busybox,进源码目录,make mrproper;make defconfig;make ARCH=arm menuconfig;在菜单选项里加上静态编译,这一点很重要哇,还有裁掉swapon/swapoff命令,不这么做rootfs关机后会自动调swapoff,而这个简陋的系统哪有swap分区你说是吧,所以会报警告就不干净了,保存退出;make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnuebai- -j4;make install

好了,编译顺利的话,在源码目录下会有一个_install文件夹,里面就是rootfs的雏形啦,四个文件夹/文件,其实就是一个文件外带海量的符号链接,但是这还不够哦,在这个目录下新建四个文件夹,用来放虚拟文件,呵呵,也就是那里面的文件是系统自动管理的,不用你管,简单吧。忘了说了,四个文件夹是dev,proc,sys,tmp,虽说不用你管,但其实还是要自己加点文件进去,在dev下面加几个设备节点console,null,tty2,tty3,tty4,呵呵,其实标题说了这是一个简陋且干净的CLFS,所以才加了这么多节点,其实设备节点正规的做法是用udev自动加载,但是这里不用udev,简陋嘛,上什么udev阿,这些设备节点呢,从主机上拷吧,别忘了cp后面加-a阿。好差不多了,我们还有最后一个文件夹要建,最后一个文件要建,体现你个性的etc,新建etc,在etc里面建init.d,在init.d里面建rcS,好了在rcS里写几句话,很简单的。这里我要把kernel到rootfs的过程简单的说一下:kernel启动到后面会找initrd,然后解压,然后到里面也就是我们的这个busybox里找linuxrc,然后执行它,而linuxrc呢,是busybox提供的,这里面流程呢busybox会提供一个默认的流程,默认流程的第一步就是去执行/etc/init.d/rcS脚本。懂了吧,我们想做点啥,就写到rcS里,我写了最简单的几句,谁都能看懂的。

 

#!/bin/sh

mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /tmp

echo "Hello clfs!"

/前面那个名字随便起,虚拟文件系统嘛。好了我们的rootfs建成了!最后讲一下,busybox除了执行rcS之外,还会做一些其他事,比如运行/bin/sh等,所以系统一起来我们就有shell用了。

事情还没完,目前我们只是建了文件夹而已,而kernel所认识的initrd可不是文件夹阿,我们需要把这个文件夹转换成一个image文件并打成gz包,怎么转换呢?在host的shell下输入命令。

dd if=/dev/zero of=/tmp/initrd bs=1024 count=3000
mke2fs -F -m 0 -b 1024 /tmp/initrd 3000
mount /tmp/initrd /mnt/abc -t ext2 -o loop
cp __install/* /mnt/abc -ar
umount /mnt/abc
gzip /tmp/initrd

好啦,现在/tmp目录下的那个initrd.gz就是我们需要的那个gz包啦,把它拷到TFTP的目录下,也就是和uImage放在一起。

 

终于到了检验成果的时候啦,串口线、网线连好,启动板子吧,进入到u-boot命令行下,这时候是不是看到一个crc错误的warning阿,看着不爽,教你怎么去掉它,打入命令saveenv,重启,没有了吧呵呵。输入我定义的快捷命令run wkft,启动信息刷刷刷,最后看到Hello clfs了吧,这就是我所说的简陋但干净的CLFS了,看不到烦人的警告吧呵呵。你可以玩玩busybox自带的很多命令,当然有的还不能用,比如fdisk等,这样的系统不能做什么,因为是initrd做的rootfs,放在内存里的,保存点什么东西掉电后就没有了。但是你可以用它做一个桥梁去mount真正的rootfs,比如qtopia,甚至andriod,怎么把它们和kernel联系起来呢?前面不是说了个rcS嘛,你可以在里面做很多事的阿。但是具体的肯定复杂的多,需要你不断去摸索。好了,不管怎么说,这个简陋却也干净的CLFS已经完成了,去小轻松一下吧