在网上找到http://blog.csdn.net/armeasy/article/details/7023555这篇文章,才知道原来之前烧的BL1是u-boot的前8k制作而成的。
在s5pv210_irom_applicationnote_preliminary_20091126.pdf手册的:2.9 Header information data for Boot Code description,有介绍BL1的组成介绍。
u-boot-samsung-dev/sd_fusing目录下就有制作BL1的工具,和源代码。
看了源代码之后,有一点不明白的地方就是,一以前我们看u-boot的源码,可以说是从u-boot.bin文件的0x00000000位置开始执行,但是从sd_fdisk.c源码看,前面16个字节被程序修改了,因此,u-boot.bin应该是从0x00000010开始执行的。但在看了u-boot-samsung-dev/cpu/s5pc11x/start.S文件后,这个问题就解决了。start.S文件和官方u-boot源码比较,前面多出了:
#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED) .word 0x2000 .word 0x0 .word 0x0 .word 0x0 #endif
刚好16个字节,第一个字,表示8192字节,指的BL1大小是8K。
那么也就解开了上篇中为什么u-boot.bin要烧写到seek=49处了:三星修改过的u-boot的前8k代码里面,会从seek=49处载入BL2,也就是u-boot了。
结合start.S文件,u-boot.bin文件,u-boot.map文件,u-boot.dis文件来理解一下start.S文件。u-boot.dis文件是u-boot.bin对应的汇编。
先来看懂三星提供的u-boot源码,才好移植官方的u-boot。
使用开发版提供的SD-bl1-8k.bin,然后自己编译u-boot-samsung-dev源码,烧写到seek=49处,就是没有一点反应,几种smdkv210XXXXX_config都编译过,都不能用,而且在一开始的start.S里面刚启动的时候,尝试点灯都不行。就这什么现象都没有,困扰了我好长时间,真痛苦,卡在这里没有一点进展。
后来想到,SD-bl1-8k.bin是从u-boot.bin前面分离出来的前8K,那么SD-bl1-8k.bin应该就是从u-boot.nand_restore.sdboot分离出来的前8K了,所以可能就和我编译出来的u-boot.bin不兼容,而且我也有对比u-boot.nand_restore.sdboot和我编译出来的u-boot.bin,前面512字节里面有几个地方的不一样,特别是_bss_start变量的只不同。
如是想到,更本搞不清楚SD-bl1-8k.bin是跳转到u-boot的哪里开始执行,如是想到直接编译bl1,从bl1开始入手。如是再次编译u-boot-samsung-dev,因为是加启动的最前面,所以编译smdkv210XXX_config哪种都行,我加到的位置是start.S的:
reset: /* * set the cpu to SVC32 mode and IRQ & FIQ disable */ @;mrs r0,cpsr @;bic r0,r0,#0x1f @;orr r0,r0,#0xd3 @;msr cpsr,r0 msr cpsr_c, #0xd3 @ I & F disable, Mode: 0x13 - SVC ldr r0, =0xE0200C00 ldr r1, =0x1111 str r1, [r0] ldr r1, =0x0F str r1, [r0, #4]
到但是在start.S里面加入了点灯的汇编,编译完成后,使用:
./sd_fusing/mkbl1 u-boot.bin bl1.bin 8192生成bl1.bin,然后
dd seek=1 if=bl1.bin of=/dev/sdc烧到sd卡中,结果qt210的四个灯都亮了,说明点灯成功,看来真的得从bl1入手了,慢慢熟悉u-boot源码吧……
qt210上面有四个led灯,分别对应GPH0_0、GPH0_1、GPH0_2、GPH0_3。点灯的方法是,先将对应的GPH0CON配置为Output,再配置GPH0DAT对应的位,输出电平。
GPH0CON, R/W, Address = 0xE020_0C00 GPH0DAT, R/W, Address = 0xE020_0C04对这两个寄存器的详细介绍在手册的2.2.56.1 Port Group GPH0 Control Register (GPH0CON, R/W, Address = 0xE020_0C00)和2.2.56.2 Port Group GPH0 Control Register (GPH0DAT, R/W, Address = 0xE020_0C04),这里就不截图了。
汇编点灯代码:
ldr r0, =0xE0200C00 ldr r1, =0x1111 str r1, [r0] ldr r1, =0x0F str r1, [r0, #4]
ldr r1, =0x1111的意思是配置GPH0_0、GPH0_1、GPH0_2、GPH0_3都为Output。
ldr r1, =0x0F的意思是配置GPH0_0、GPH0_1、GPH0_2、GPH0_3都输出1。
C语言点灯:
*(volatile unsignet int *)0xE0200C00 = 0x00001111; *(volatile unsignet int *)0xE0200C04 = 0x0000000F;
终于有点进展了!