最近在s5pv210平台上,尝试uboot去引导eboot,然后由eboot加载内核镜像NK(xip.bin)。
储备知识: samsung 平台上电启动到执行uboot的流程;uboot的流程;
关于s5pv210 CPU上电启动,《S5PV210_iROM_ApplicationNote_Preliminary_20091126》讲了IROM如何引导bootloader的过程。
按照三星《S5PV210_UM_REV1.1》手册上说明的启动流程,S5PV210上电将从IROM处执行固化的启动代码,对时钟等初始化、对启动设备进行判断,并从启动设备中复制BL1(最大16KB)到IRAM(0xd002_0000处,其中0xd002_0010之前的16个字节储存的BL1的校验信息和BL1尺寸)中,并对BL1进行校验,校验OK转入BL1进行执行;BL1继续初始化,并将BL2复制到IRAM中并对其校验,OK后转入BL2;BL2则要进行比较复杂的初始化,包括DRAM的初始化,完成后将OS代码复制到DRAM中,并转入到OS中执行并完成启动引导。
但是,上述的IRAM只有96K大小,对于日益复杂的uboot来说,肯定是不够的,所以使用UBOOT启动引导的时候,也没全按三星手册上说的执行,具体如下:
首先解释一下我认为的BL0、BL1、BL2:
BL0:是指S5PV210的IROM中固化的启动代码;
BL1:是指在IRAM中执行的UBOOT的部分代码;
BL2:是指在内存中执行的的UBOOT的完整代码;
参考http://blog.csdn.net/s5pv210_devboard/article/details/7936405; 这是tiny210的。 s5pv210平台的详细过程参考uboot源码,
第一阶段的代码看下/board/samsung/***/u-boot.lds的文本段就可以知道拉。
uboot启动流程,网上资料一大堆。这里不在赘述。
====== wince6.0启动
wince开发经验为零。wince启动流程大概只知道其大概,主要参考《SMDKV210_WinCE60_BSP_InstallationGuide》
stepldr.nb0:由IROM加载到SRAM中,主要初始化硬件,加载eboot。 类似uboot的BL1.
eboot.nb0: 也会初始化些;加载OS镜像,boot image...
bootimage.nb0: stepldr + eboot
OS iamge: single-XIP multiple-XIP 这个其实不用我们知道啦。我的工作只负责引导eboot,让eboot正常工作就ok。
调试过程:
1,wince文件:boot.nb0 logo.bmp xip.bin
boot.nb0就是上述的bootimage.nb0, 我引导的是eboot,所以要知道boot.nb0的分布: 0x32 sector stepldr + 0x400 sector eboot.
.nb0文件是data文件,可直接在内存中运行。
2, 确定uboot,eboot在各自的系统环境下能够单独的正常工作。
3,确定eboot加载的内存地址:0x47700000, 大小0x8000(0x400 * 512); 物理地址。
uboot下载模式下,可以通过movi read eboot 47700000 8000从sd/mmc设备中读取 到内存;也可fatload mmc 0:1 47700000 eboot来实现,从sd卡vfat分区中将eboot文件搬到内存。
头疼的开始啦。 思路很清晰,也很简单。 当信誓旦旦go 47700000时,发现啥log都没有。
悲剧了... 期间各种不懂,各种调试,各种失望阿... 现总结下:
1)要花时间了解uboot的第一阶段,特别汇编部分代码。 u-boot.lds 发起, cpu/s5pc11x/start.S ->
./lib_arm/board.c:start_armboot() 的详细过程。 硬件初始化:I/D cache、MMU、DDR、PLL...
2)学会调试手段。虽然条件有限,但是要学会创造条件...
首先,确保PC指针指向了0x47700000处,搬移到该处的内容是不是正确的。
run_command搬移指令流程中,最基本的打印出搬移后0x47700000出的内容;和eboot源数据比较。 由于没有硬件仿真器,跟踪不了PC指针,CPSR等ARM寄存器的值;用了点灯法,跳转eboot后,控制GPIO口输出跟踪代码执行。 <uboot中能有啥方法打印trace,跟踪PC呢?>
发现,点灯法没效果;串口仍然没有打印(anroid,wince的uart debuger相同,也初始化了串口)。那原因估计是uboot和eboot的环境配置不同。 查吧 ... 这个首先要做好1)部分 工作。做此工作时参考链接的一些思路和方向 http://social.msdn.microsoft.com/Forums/en-US/winembplatdev/thread/4810a3c0-4362-46a8-b57b-80e12ca8ba9d
值得一提的是,期间怀疑的地方很多(DDR,mmu,PLL,power...)在修改时,组合的可能性太多了。这种“愚蠢”的不停尝试行为,为无经验和技术不扎实买了单了。 这看似体力劳动的行为成了最好的办法;每次看到没有log,失望;但总感觉离成功不远。
就这样,一直比较wince bootloader中 stepldr和uboot的环境配置有何区别。后来... 剩下的也只有成功引导eboot了。
原因:
uboot中必须要关闭MMU; 虽然之前搬移的0x47700000是物理地址。 eboot中,重新开启MMU,它的内存映射不同uboot了。
为什么?http://blog.csdn.net/xxblinux/article/details/6281295 看了这个能懂些。MMU即使打开,但要确保虚拟地址映射的物理地址和0x47700000内存的物理地址一致!
屏蔽include/configs/smdkv210single_wincalcd_android.h //#define CONFIG_ENABLE_MMU
还要注意 board/samsung/wicalcd/config.mk 文件里 TEXT_BASE = 0xC3e00000
0xC开始表示是虚地址,如果关掉了MMU要改成 0x2 开始,在顶层目录Makefile中将c3e00000改成23e00000即可。
因为uboot会用这个地址和pc寄存器比较,如果不匹配,就拷贝程序到SDRAM,如果匹配就跑程序。
既然是双系统,关闭MMU的uboot又要能够引导android的kernel。笔者认为在uboot开启MMU没啥作用,在以后内核中会重新初始化MMU的 http://celinux.wikidot.com/linuxboot 在uboot代码中将虚拟地址对应改成物理地址。
#define CONFIG_BOOTCOMMAND"movi read kernel C0008000; movi read rootfs 20A00000 180000; bootm C0008000 20A00000"
中的C0008000改成20008000; 同样,对于recovery模式,改成“fatload mmc 2:1 20008000 zImage ” "bootm 20008000"
eboot引导xip.bin:
需求:
1,wince kernel会把其image之后的inand空间当作用户空间,重新格式化成FAT32,这样下次启动后android系统启动不了了。
2,要实现android,wince共享inand的hard-disk分区。
android: vfat; wince: fat32 (fat32兼容vfat文件系统)
双系统镜像在iNand中的分布:
init_raw_area_table: 1block = 512Byte
开始(块为单位) 大小(块) 名称
image[0]: - - eFuse
image[1]: 1 8KB(16) BL1
image[2]: 17 16KB(32) ENV
image[3]: 49 512KB(1024) BL2
image[4]: 1073 4MB(8192) Kernel
image[5]: 9265 26MB(53248) RFS
image[6]: 62513 xMB() Eboot(wince)
剩下的空间是android的系统分区。