基于iTop-4412的U-Boot 2017移植[0]:Exynos4412基礎(chǔ)
參考資料:
Exynos4412 SoC基礎(chǔ)
- Exynos4412的地址空間
iROM:這段地址空間對應(yīng)Exynos4412內(nèi)部固化的一段程序拗引,Exynos4412啟動(dòng)的第一條指令就存放在這里。
iRAM:這段地址空間對應(yīng)的是Exynos4412內(nèi)部的一個(gè)存儲(chǔ)器电禀,這段存儲(chǔ)器的特點(diǎn)是上電就可以用,不用初始化该肴。
DMC0:這段地址空間就是核心板上的DDR3對應(yīng)的存儲(chǔ)空間搭幻,上電后需要初始化DRAM控制器才能使用。
- Exynos4412的啟動(dòng)過程
由圖中數(shù)字順序得知:
- iROM
- BL1
- OS
首先從iROM運(yùn)行宫患,然后根據(jù)OM的值判斷從哪個(gè)存儲(chǔ)設(shè)備(Nand\SD/MMC\eMMC\USB OTG)加載BL1到iRAM序苏;
其次手幢,BL1再根據(jù)OM的值判斷從哪個(gè)存儲(chǔ)設(shè)備加載OS到DRAM中;
最后忱详,運(yùn)行OS代碼围来。
注意: iROM固化在SoC內(nèi)部,BL1是Samsung提供的鏡像文件E4412_N.bl1.bin,OS在這里可以認(rèn)為是BL2监透,這部分是u-boot代碼中編譯生成的SPL桶错,BL2是由BL1加載到iRAM中運(yùn)行的。最后胀蛮,BL2再根據(jù)OM值院刁,從sdcard中將u-boot代碼拷貝到DRAM中。
我們接下來要進(jìn)行移植的U-Boot啟動(dòng)過程為iROM->BL1(E4412_N.bl1.bin)->BL2(U-Boot SPL)->U-Boot粪狼。
- Exynos4412的運(yùn)行空間
如圖退腥,標(biāo)出了iROM、BL1和BL2的運(yùn)行地址空間再榄。
iRAM的地址空間是0x02020000 - 0x02060000
iROM: iRAM的0x02020000 - 0x02021400的5KB地址空間分配給iROM用狡刘,用于存放iROM的全局變量(ZI/RW,分別存放全局未初始化變量不跟、全局已初始化變量)颓帝、局部變量(stack)等等米碰。
BL1: 從0x02021400 - 0x02023400的8KB地址空間屬于BL1窝革,可以認(rèn)為BL1的第一條指令就存放在0x02021400地址單元。
BL2: 緊接著的0x02023400 - 0x02027400的16KB地址空間屬于BL2吕座,即:BL2的第一條指令存放的地址就是0x02023400虐译,這個(gè)值很重要,如果我們的SPL中有非“位置無關(guān)碼”吴趴,那么就必須將SPL加載到其運(yùn)行地址處漆诽,否則在執(zhí)行那些非位置無關(guān)碼的時(shí)候會(huì)出錯(cuò)。后續(xù)編寫U-Boot的時(shí)候需要設(shè)置宏定義:
#define CONFIG_SPL_TEXT_BASE 0x02023400
锣枝。
- 用于Exynos4412啟動(dòng)的SD卡布局
其中sdcard的扇區(qū)大小是1Block = 512B厢拭。
第0個(gè)扇區(qū)是保留扇區(qū)(Reserved),第1到第16扇區(qū)共8KB的空間存放BL1(E4412_N.bl1.bin)撇叁,從第17到第48扇區(qū)的16KB空間用于存放BL2(u-boot-spl.bin)供鸠,之后的扇區(qū)可以根據(jù)實(shí)際需求自己安排。
- 制作用于Exynos4412啟動(dòng)的BL2
BL1可以自己寫也可以使用官方提供的E4412_N.bl1.bin陨闹,本次移植我們采用官方的楞捂。
Q: BL1有了,怎么制作BL2呢趋厉?
A: 使用mkbl2工具寨闹。
mkbl2.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
FILE *fp;
unsigned char src;
char *buf, *a;
int buf_len;
int nbytes, file_len;
unsigned int checksum = 0;
int i;
if (argc != 4) {
printf("Usage: mkbl2 <source file> <destination file> <size> \n");
return -1;
}
buf_len = atoi(argv[3]);
buf = (char *)malloc(buf_len);
memset(buf, 0x00, buf_len);
fp = fopen(argv[1], "rb");
if( fp == NULL) {
printf("source file open error\n");
free(buf);
return -1;
}
fseek(fp, 0L, SEEK_END);
file_len = ftell(fp);
fseek(fp, 0L, SEEK_SET);
nbytes = fread(buf, 1, file_len, fp);
if (nbytes != file_len) {
printf("source file read error\n");
free(buf);
fclose(fp);
return -1;
}
fclose(fp);
for(i = 0; i < (14 * 1024) - 4; i++)
checksum += (unsigned char)(buf[i]);
*(unsigned int*)(buf + i) = checksum;
fp = fopen(argv[2], "wb");
if (fp == NULL) {
printf("destination file open error\n");
free(buf);
return -1;
}
a = buf;
nbytes = fwrite(a, 1, buf_len, fp);
if (nbytes != buf_len) {
printf("destination file write error\n");
free(buf);
fclose(fp);
return -1;
}
free(buf);
fclose(fp);
return 0;
}
該程序的功能就是為BL2添加校驗(yàn)碼【耍【BL2 不能大于(14K – 4B) 字節(jié)繁堡,最后 4B用于存放較驗(yàn)碼】
編譯:
$ gcc mkbl2.c -o mkbl2
使用:
$ ./mkbl2 u-boot-spl.bin bl2.bin 14336
有了上面的基礎(chǔ)知識,下面開始移植。
- 我的個(gè)人主頁:http://www.techping.cn/
- 我的個(gè)人站點(diǎn)博客:http://www.techping.cn/blog/wordpress/
- 我的CSDN博客:http://blog.csdn.net/techping
- 我的簡書:http://www.reibang.com/users/b2a36e431d5e/timeline
- 我的GitHub:https://github.com/techping
歡迎相互follow~