分类: LINUX
2011-09-08 16:15:14
作者: dangbinghoo <>
日期: 2011-08-09
修订:
版权: dangbinghoo@gmail.com
...
一般来说 ARM Soc 系统的硬件结构都是具有内部sram,外部dram控制器,flash控制器, nand控制器等. 而且对于现代的处理器,都会支持nand启动系统,而flash则是传统的方式.
flash启动系统相对简单,因为flash与sram具有相似的硬件访问方式,所以程序直接可以在flash上运行,那么系统往往都是从flash上启动之后再relocate代码到dram中,然后跳转到ram运行.
对于nand启动,就会稍微复杂一些, 由于nand 是一种串行访问的存储器,并不能直接运行代码,所以需要将程序完全搬到ram中之后再运行,尽管很多厂家对于从nand启动所启用的名称都不同,但是几乎都是处理器会自动拷贝前4K的nand内容到内部的4Kram中运行,然后系统启动代码就需要在这部分作工作,初始化dram控制器使dram可用,然后拷贝后续需要运行的代码到dram中,然后再作跳转.
对于nand启动, Uboot本身是有支持的,在早期的代码中,各架构处理器会自行在start.S中作支持, 较新的uboot 引入了nand spl机制, uboot代码被分割为两部分,nand spl和 uboot, nand spl使用C语言调用nand驱动部分的部分函数简单拷贝后续的uboot到ram中然后再跳转启动.
ATmel的ARM处理器常常都是将nand启动的部分作为一个单独的程序来设计的,这就是BootStrap,就是从nand拷贝代码到指定ram的地址处,然后作简单判断后跳转.
传统的Bootstrap的nand 加载地址就是uboot的 0x23f00000, 拷贝的size为0x40000,这对于老的uboot工作会很好,但是新的uboot的atmel底层代码作了变动,代码会当是flash启动,需要relocate,而且也不支持skip relocate, 所以我们就需要修改bootstrap的启动加载地址,将ram的加载地址改为跟最终的relocate地址不同,uboot里面的config文件暗示应该改为21f00000, 这样ralocet的代码即便不skip也不会让uboot死掉. 另外如果你的uboot启用了较多功能,编译出来的体积大于0x40000的话,也需要修改Bootstrap拷贝代码的大小.
0.1 Uboot的编译Uboot的编译相对简单,如果代码没有问题,配置正确,那么编译肯定会一路顺风的.
先做at91sam9260ek的board配置,然后make即可, 交叉工具链跟内核一样可以使用CROSS_COMPILE变量来指定.
<注意>
这个版本不同于较早的 1.3.4 这样的版本, 对于 ubifs已经很完善的支持了. 而且底层代码重新编写,层次清晰.对于mac设置传递给内核,这些都是默认就工作正常的. 所以选用新的uboot,我们就不需要作很多"hack"就可以工作了.
1.2 SAM-ba烧写UbootSAM-ba是atmel的 串口isp程序, 将开发板启动到RomBoot> 模式(短接nand数据线),然后启动sam_ba,先enable sdram, 然后 enable nand flash,然后erase all,接着 send bootfile,也就是Bootstrap,然后再下载uboot到0x20000.
注意: 如果使用新的uboot,请使用修改过加载地址的bootstrap 1.3 使用支持nand烧写的Uboot直接更新烧写工作无非就是把程序写入nand 或者flash, 对于nand启动,我们只需要将支持nand启动的代码写入第一个block,然后将uboot写入bootstrap之后就可以了,如果开发板上有nand读写支持,那么就不需要使用sam-ba了,个人认为,sam-ba是一个很低效的烧写工具.如果你的uboot支持网络,那么烧写速率是很可观的.使用如下的命令即可:
烧写新的uboot之后,就支持mtd分区设置了, 启动到uboot,然后设置环境变量mtdparts=atmel_nand:128K(BootAgent)ro,896K(Uboot)ro,4M(Kernel),100M(Root),-(data)
> set mtdparts 'mtdparts=atmel_nand:128K(BootAgent)ro,896K(Uboot)ro,4M(Kernel),100M(Root),-(data)'这样你将得到这样的分区结果:
这样, 以后我们就可以把 20000, 这样的nand 起始地址使用 Uboot代替了, 也就是分区的概念.
1.5 使用tftp或者loady下载img到ram > tftp U-boot.bin > loady 22000000 1.6 烧写内核 > tftp Uimage.2.6.38.2 > nand erase Kernel 400000 > nand write 22000000 Kernel [size] 1.7 烧写系统 > tftp root-ubifs.img > nand erase Root 400000 > ubi part Root > ubi createvol Root > ubi writevol 22000000 Root [size] 2. 启动系统与设置设置启动内核的命令
> set bootcmd 'nand read 0x20008000 Kernel 0x300000;bootm 0x20008000' 2.1 Uboot内核启动参数使用ubi分区及文件系统,我们需要给内核传递正确的mtd分区设置,以及哪个分区是root,以及文件系统的类型.
> set bootargs 'console=ttySAC0,115200 mem=64M mtdparts=atmel_nand:128K(BootAgent)ro,896K(Uboot)ro,4M(Kernel),100M(Root),-(data) ubi.mtd=3 root=ubi0:Root rootfstype=ubifs rw' 2.2 启动到系统设置好了启动命令及内核参数之后就使用boot命令或者重启开发板启动系统.
2.3 系统启动简析与nanoRC设置好uboot之后,就可以启动到内核了,内核启动之后,会根据内核的参数来判定根分区,然后挂载根文件系统, 挂载成功之后就会尝试在根分区找init程序并启动,init是系统启动之后的第一个程序, 往往可以是系统的启动脚本, 如 /etc/init.d/rcS,实际上是shell脚本. 或者可以象标准linux一样,使用init系统,init程序会根据/etc/inittab来决定系统的启动运行级别,以及运行那些脚本. nanoRC是笔者现开发的一个简单rc系统,具有跟gentoo openRC类似的运行级别方式,但是相对是很简单和高效的. 目前nonoRC支持固定的优先级安排启动方式. 支持reboot和shutdown 系统脚本.RC脚本支持标准的start|stop|restart 命令.
其中网络,主机名等脚本视为默认系统脚本,支持在/etc/conf.d/net对网络进行配置.可以使用/etc/init.d/network.eth0启动eth0的网络配置.
2.4 使用nanoRC RC系统的配置nanoRC里面的系统重要参数主要在/etc/conf.d下面配置,对于常规服务的标准配置文件,往往按照默认位置放置到/etc,但是对于用户需要设置的参数,则会在/etc/conf.d下面安排一个配置文件.
2.5 nanoRC 运行级别与系统服务脚本nanoRC有4各运行级别:
start | 运行级别是系统很底层的启动脚本,一般不需要作修改. |
default | 默认级别, 系统需要启动的服务脚本都放到这里 |
reboot | 系统重启时候执行的脚本 |
shutdown | 系统关闭时候执行的脚本 |
附: nanoRC启动信息