u-boot是boot loader的一种,boot loader 是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。通常,boot loader 是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的 boot loader 几乎是不可能的。
官方u-boot介绍
官方提供的u-boot的可以完美的引导内核,但是如果用来学习嵌入式linux开发就不合适了,原因是官方提供的u-boot的没有网络配置信息。具体的查看方法是当系统启动的时候用串口连接调试,当有3秒停留的时候迅速按电脑上任何一个按键。然后执行
ping 局域网网关
它会提示没有ping这个命令,也没有tftp,nfs相关命令。然而这些命令在学习嵌入式开发过程中是相当有必要的。怎么办?这里给大家提供修改方法,后面把修改的源代码上传到git,你可以直接下载使用。
具体的修改过程如下:
宿主机:ubuntu-12.04(64位)
目标机:pcDuino
交叉编译器:arm-linux-gnueabihf-gcc (安装sudo apt-get install g++-arm-linux-gnueabihf)
下载u-boot源码:
git clone https://github.com/linux-sunxi/u-boot-sunxi.git
下载之后执行,查看分支
pillar@monster :~/study/kernel/u-boot-sunxi/u-boot-sunxi$ git branch -a
* sunxi
remotes/origin/HEAD -> origin/sunxi
remotes/origin/lichee-dev
remotes/origin/lichee-dev-a20
remotes/origin/lichee/lichee-dev
remotes/origin/lichee/lichee-dev-ICS
remotes/origin/lichee/lichee-dev-mmc
remotes/origin/old/sunxi-current
remotes/origin/sunxi
remotes/origin/wip/a20
可以看到官网下载的u-boot有很多分支,这里要对几个看不明白的分支说明一下:
lichee-dev:支持nand和TF卡启动,但是不支持网络,现pcDuino官方发布的版本;
sunxi和sunxi-current:支持TF卡启动,也支持网络,但是不支持nand启动;
这里只能在官方的版本上改了,将git切换到官方版本。
git checkout lichee-dev
关于git的使用,有空我会单独发布一个帖子来指导使用。
在修改这个源码之前,先给大家讲讲启动顺序。
NAND启动是ROM->Boot0->boot1->uboot->linux kernel
SD启动是ROM->spl->uboot->linux kernel
如果用livesuite的image做的SD也有boot0和boot1的。ROM的启动我的理解是这样子的,当系统上电的时候,cpu会自动将nand中前几k的代码拷贝到RAM中运行,这几k的代码即Boot0,Boot1,但是全志的Boot0,Boot1是不开源的,所以我们无法知晓,另外关于u-boot的nand启动部分也是不开源的,你就不要纠结去彻底的分析这个u-boot。
另外除了tftp和nfs这种开发方法,全志也提供了其他的方法,这里跟跟你介绍一下。
首先硬件按照一下方式连接:
pcDuino <-> 串口调试 <-> PC USB
pcDuino <-> OTG <-> PC USB
打开串口调试助手,例如putty 或者xshell之内的工具。系统上电,然后按住电脑上的”1”键,第一次的时候系统会自动安装驱动,最后弹出nanda分区。
如下图所示:
可以看到这个里面有uImage, u-boot在linux文件夹里面,只需要将你开发的uImage和u-boot拷贝到相应的位置就可以。
这种方式对于学习比较麻烦了,例如你开发调试一个uImage,你要先从虚拟机里面拷贝出来,然后按照刚才哪种方式把nanda给显示出来,整个调试过程效率相当低。
下面介绍怎么修改u-boot,然后介绍一个高效的方法。
编译配置u-boot
官网上下载的支持pcDuino的u-boot,名字并不叫pcDuino,它叫a10-evb,这里看不惯可以做相应的修改。
vim boards.cfg
189 sun4i arm armv7 pcDuino allwinner sunxi sun4i:SUNXI_EMAC
190 sun4i_sd arm armv7 a10-evb allwinner sunxi sun4i:SD_UART
191 sun5i_a12 arm armv7 a12-evb allwinner sunxi
192 sun5i_a13 arm armv7 a13-evb allwinner sunxi
193 sun5i_a13_sd arm armv7 a13-evb allwinner sunxi
在189行位置修改,然后在加上配置网络sun4i:SUNXI_EMAC,在源码里面加上pcDuino板级支持包。
pillar@monster :~/study/kernel/u-boot-sunxi$ cd board/allwinner/
a10-evb/ a13-evb/ pcDuino/
就是将a10-evb拷贝成pcDuino,进入pcDuino,修改里面的文件名为pcDuino.c,然后修改Makefile。
29 COBJS := pcDuino.o
修改pcDuino
160 #ifdef CONFIG_DISPLAY_BOARDINFO
161 int checkboard(void)
162 {
163 puts(“Board: pcDuino\n”);
164 return 0;
165 }
166 #endif
下面开始编译u-boot
cd u-boot-sunxi
mkdir build
make distclean CROSS_COMPILE=arm-linux-gnueabihf-
make sun4i_config CROSS_COMPILE=arm-linux-gnueabihf- O=build
make CROSS_COMPILE=arm-linux-gnueabihf- O=build
编译完了之后放到pcDuino上运行,怎么放呢?
scp u-boot.bin Ubuntu@pcDuino的IP:/home/ubuntu/
sudo mount /dev/nanda /mnt
sudo chmod u+w linux
sudo cd linux
sudo rm u-boot.bin
sudo cp /home/Ubuntu/u-boot.bin .
sudo cd ..
sudo chmod u-w linux
sudo reboot
重启之后在3秒停留位置停下来
这是的u-boo依然是不支持网络功能的,这一节仅仅只是修改了一下板子名
修改支持网络功能先看sunxi-current里面的源码,发现他在boards里面就已经初始化了网络,我们就从这里开始。
vim ./arch/arm/cpu/armv7/sunxi/board.c #添加
157 #if defined(CONFIG_SUNXI_EMAC)
158 /*
159 * Initializes on-chip ethernet controllers.
160 * to override, implement board_eth_init()
161 */
162 int cpu_eth_init(bd_t *bis)
163 {
164 sunxi_emac_initialize(bis);
165
166 return 0;
167 }
168 #endif
然后将sunxi-current里面的网卡驱动拷贝到lichee-dev里面
cp ~/u-boot/drivers/net/sunxi_emac.c drivers/net/
修改Makefile
vim drivers/net/Makefile #添加
29 COBJS-$(CONFIG_SUNXI_EMAC) += sunxi_emac.o
保存之后编译,这里肯定有错误的,现在你只需要解决这些错误,就可以完成u-boot的修改。下面是我的所有修改:
https://github.com/Pillar1989/sunxi-u-boot/blob/lichee-dev/diff.log
这里跟你解释里面++和—是什么意思。++表示添加,–表示删除。如果你觉得麻烦,请看我的git仓库:https://github.com/Pillar1989/sunxi-u-boot
下载测试:
sun4i# tftp 0×46000000 uImage
Using emac device
TFTP from server 192.168.2.3; our IP address is 192.168.2.22
Filename ‘uImage’.
Load address: 0×46000000
Loading: #################################################################
#############################################
done
Bytes transferred = 1611552 (189720 hex)
sun4i#tftp 0×49000000 dts/sun4i-a10-cubieboard.dtb
Using emac device
TFTP from server 192.168.2.3; our IP address is 192.168.2.22
Filename ‘dts/sun4i-a10-cubieboard.dtb’.
Load address: 0×49000000
Loading: #
done
Bytes transferred = 7940 (1f04 hex)
sun4i#bootm 0×46000000 – 0×49000000
## Booting kernel from Legacy Image at 46000000 …
Image Name: Linux-3.12.0-10089-gf16892f-dirt
Created: 2013-11-19 12:28:56 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1611488 Bytes = 1.5 MiB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum … OK
Loading Kernel Image … OK
OK
Starting kernel …
看到已经完美支持tftp下载,后面讲解怎么大家tftp服务器,nfs服务器等内容。
linksprite学习中心