0. 准备工作
1. 编译uboot
2. 将uboot写入SD卡
3. 编译kernel,设置其可以通过NFS挂载根文件系统
4. 开发环境安装TFTP服务器
5. 开发环境安装NFS服务器
6. 目标环境设置uboot参数
7. 制作根文件系统(optional)。
8. 完整的启动LOG。
有几位网友发信问我uboot挂载文件系统的方法,其实这个部分也不是我原创的,大部分都是参考其他网友的方法,现在将我的手顺记录下来,希望对大家有所帮助。
整体思路大概是这样:
* 将uboot烧写到SD卡。
* 从SD卡启动系统,SD卡中的uboot通过TFTP协议将远程的的Kernel下载到内存中。
* uboot将内核参数设定为ROOT分区为远程的NFS-SERVER共享的一个目录,并JUMP到内核的START ADDRESS。
* kernel自解压,并JUMP 到解压后的新的内核START ADDRESS,内核正常启动。
* 最后通过内核通过uboot设置的ROOTFS参数得知根文件系统在远程,并通过NFS挂载ROOTFS。
* 根文件系统挂载完了以后,就会去执行init程序, init程序被uboot指定为 /linuxrc。
我的开发环境是 ubunto 12.04LTS。
目标系统的内核是 3.0.8 ,源代码位于 /opt/S5PV210/rootfs/usr/src/linux-3.0.8。
uboot的源代码位于 /opt/S5PV210/rootfs/usr/src/opencsbc-u-boot。
目标环境的根文件系统位于/opt/S5PV210/rootfs。
交叉编译器位于/opt/linaro-gcc473-eglibc216-armv7a-neon。
0. 准备工作
编译uboot和linux内核都需要使用到交叉编译器,所以需要确保shell 的PATH 环境中包含了你的交叉编译器的路径。
比如我的PATH为:(通过export查看)
declare -xPATH="/usr/lib/lightdm/lightdm:/opt/linaro-gcc473-eglibc216-armv7a-neon/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
这样,就可以直接查找到 arm-linux-gcc 这条命令了,不许要输入 arm-linux-gcc 的绝对路径。
1. 编译uboot
uboot来自于kasim修改的uboot,原帖在http://www.arm9home.net/read.php?tid-16001.html。
可以通过https://gitorious.org/opencsbc/u-boot/trees/mini210_linaro-2012.11- stable 右边的 download mini210_linaro-2012.11-stable astar.gz 这个按钮获取到打包的源代码。
将源代码下载下来以后,解压到某一个目录,我机器上是位于/opt/S5PV210/rootfs/usr/src/opencsbc-u-boot 这个目录。进入到这个目录。
首先配置uboot是针对 tiny210 环境的。 tiny210v2 也是使用的这个配置项:
复制代码
|
然后才是真正的编译uboot:
复制代码
|
编译完成以后,就可以看到uboot的二进制文件 spl/tiny210-spl.bin 和 uboot.bin。
另外还有一个用于制作 uImage 的工具 tool/mkimage。为了方便,把这个文件拷贝到 /usr/bin:
复制代码
|
2. 将uboot写入SD卡
注意,这部需要特别留心,别因为误写入,把你的硬盘给弄坏了。
注意,SD卡的内容最好备份好。
将SD卡放到读卡器里面,并将SD卡读卡器接入开发环境,在我的环境中, SD卡会被识别为 /dev/sdc。
通过下面的命令将uboot写入SD卡,保证这个SD卡可以启动。
复制代码
|
如果怕写入不同步,可以再执行一下 sync 这个命令,保证cache都写入到磁盘中。
到此为止,就可以通过SD卡启动uboot了。
3. 编译kernel,设置其可以通过NFS挂载根文件系统
光盘中带的内核,默认不支持从NFS挂载ROOTFS。需要重新配置并编译内核。
在/opt/S5PV210/rootfs/usr/src/linux-3.0.8目录下,通过 make menuconfig 启动ncurses图形配置界面。
下面几个个内核配置项,必须选中。
复制代码
|
注意,这个选项下面的 IP:DHCP support / IP:BOOTP support /IP:RARP aupport 不能选。
因为我的开发环境中没有安装 DHCP server。开发板的 IP 是在内核启动参数中指定的。
复制代码
|
将退出配置,并保存。
执行下面的命令生成 uImage 内核镜像文件,这个过程其实是先生成了 zImage ,然后调用了刚才uboot的那个 mkimage 生成 uImage。
复制代码
|
下面的LOG表明 uImage 生成了,位于 arch/arm/boot/uImage。
复制代码
|
编译内核的时候,如果你使用的是 4.6以后的 gcc,需要在Makefile中添加 -mno-unaligned-access 给 KBUILD_CFLAGS 防止内核解压完以后启动不了。
复制代码
|
如果你生成的内核有问题,可以试一试我的内核配置文件 my_config。
4. 开发环境安装TFTP服务器
接下来,就是要在开发环境上安装 TFTP 服务器,使开发板可以通过TFTP协议下载 uImage 这个文件。
在 ubuntu 下,可以通过下面的命令安装 TFTP 服务器,这个服务是通过 inet 监听的。
复制代码
|
安装完以后,需要配置一下 TFTP 的默认查找目录,我将其设定为 /srv/tftp:
确认 /etc/inetd.conf 文件中有如下一行:
复制代码
|
因为 TFTP 服务主要是给 uboot提供内核镜像文件,为了避免每次内核编译完以后都拷贝到 /srv/tftp 目录中,
我在 /srv/tftp 目录中,建立了一个符号文件,指向 /opt/S5PV210/rootfs/usr/src/linux-3.0.8/arch/arm/boot/uImage。
复制代码
|
可以通过下面的命令重启 inetd ,保证这个 supper服务器能够监听 TFTP 端口:
复制代码
|
可以通过查看端口确认 inetd 是否真的在监听 TFTP 端口:
复制代码
|
可以通过下面的命令测试一下 TFTP 服务是否正常工作:
复制代码
|
5. 开发环境安装NFS服务器
接下来是配置 NFS 服务器,用于开发板上内核启动以后挂载开发环境的ROOTFS。
通过下面的命令安装 nfs 服务器:
复制代码
|
安装完成以后,还需要修改 /etc/exports 文件,设置 NFS 共享的文件目录。我们需要将 /opt/S5PV210/rootfs 设置为NFS共享目录。
复制代码
|
每一次修改 /etc/exports 这个文件,都需要重新启动 NFS 服务器:
复制代码
|
可以通过下面的命令测试 NFS 服务器是否设置正确:
复制代码
|
也可以通过 df 命令查看挂载情况:
复制代码
|
6. 目标环境设置uboot参数
注意: ubuntu 的 network manager,如果开发板和开发环境的PC直连的话,每次开发板哪掉电,开发环境PC会检测为网络未链接,
nm 就会将已经设置好的网卡 down 掉。这在开发板reset的时候特别讨厌,你得每次都重新去设置PC的IP地址。
因此我将桌面右上角的network manager的 Enable Networking 设置为不选中,禁止 network manager 去管理网络。
然后在终端里通过下面的命令,将网卡设置为 192.168.1.5,这样每次开发板reset就不用再设置开发环境PC的IP了。
复制代码
|
当然,如果你的开发板和开发环境PC都是链接到路由器或者HUB,就没有这个烦恼。
现在所有的东西都准备好了。将SD卡插入开发板,并调整switch,设置从SD卡启动系统。
正常情况下,就应该能够看到 uboot 的界面了( FriendlyLEG-TINY210 )了:
在 uboot 的shell中,通过 setenv 命令设置相关参数。
复制代码
|
bootcmd参数中的 tftp 21000000 用于:通过 TFTP 命令,将 192.168.1.5 的 /srv/tftp/uImage 下载到 0x21000000 这个位置。
bootcmd参数中的 bootm 21000000 用于: uboot将CPU执行权地交给 0x21000000 这个位置的内核镜像,也就是启动内核。
bootargs参数用于设置内核的启动参数,其中 root=/dev/fs rwnfsroot=$serverip:/opt/S5PV210/rootfs,nolock,tcp 告诉内核通过NFS启动,
根文件系统位于192.168.1.5:/opt/S5PV210/rootfs
NFS 的参数为 nolock,tcp ,用于防止 udp 不稳定导致 NFS 读取NG 的情况。
ip=$ipaddr 设置开发板自身的ip地址为 192.168.1.80 。
通过 saveenv 将上面的参数写入到 SD卡中,这样就不用每次reset都输入一遍uboot的参数了。
通过 boot 命令,将CPU 执行权专递给 Kernel。
7. 制作根文件系统(optional)。
待续,busybox + toolchain。