u-boot新结构浏览

213 /* Set stackpointer in internal RAM to call board_init_f */
214 call_board_init_f:
215         ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
216         bic     sp, sp, #7 /* 8-byte alignment for ABI compliance */
217         ldr     r0,=0x00000000
218         bl      board_init_f
CONFIG_SYS_INIT_SP_ADDR
在板级头文件定义
228 /* additions for new relocation code, must be added to all boards */
229 #define CONFIG_SYS_SDRAM_BASE   PHYS_SDRAM_1
230 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - \
231                                 GENERATED_GBL_DATA_SIZE)
232 
233 #define CONFIG_BOARD_EARLY_INIT_F
根据TQ2440硬件信息定义,PHY_SDRAM_1 = 0X3000 0000,那么0x3000 0000 + 4k -128B
此为堆栈地址,GENERATED_GBL_DATA_SIZE为全局数据的大小即gd_t全局指针所指向的单元大小

216行使sp指针8字节对齐以符合ABI规则,R0 = 0,作为参数传递给board_init_f().
arch/arm/lib/board.c:
CONFIG_SYS_INIT_SP_ADDR 指向栈底,也是全局数据指针的区的首地址,

265 void board_init_f(ulong bootflag)
266 {
267         bd_t *bd;
268         init_fnc_t **init_fnc_ptr;
269         gd_t *id;
270         ulong addr, addr_sp;
271 #ifdef CONFIG_PRAM
272         ulong reg;
273 #endif
274 
275         bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
276 
277         /* Pointer is writable since we allocated a register for it */
278         gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);  /*
以R8作为全局数据指针的存储器,并始终保持*/
279         /* compiler optimization barrier needed for GCC >= 3.4 */
280         __asm__ __volatile__("": : :"memory");                    
281 
282         memset((void *)gd, 0, sizeof(gd_t));             /* 清零全局数据区
*/
283 
284         gd->mon_len = _bss_end_ofs;                     /* 整个u-boot映像大小
*/
285 #ifdef CONFIG_OF_EMBED
286         /* Get a pointer to the FDT */
287         gd->fdt_blob = _binary_dt_dtb_start;
288 #elif defined CONFIG_OF_SEPARATE
289         /* FDT is at end of image */
290         gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
291 #endif
292         /* Allow the early environment to override the fdt address */
293         gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
294                                                 (uintptr_t)gd->fdt_blob);
在旧版u-boot中,init_fnc_ptr()的执行是放在启动代码第二段中,难道这里就相当与原来的stage2?

在慢慢分析
295 
296         for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
297                 if ((*init_fnc_ptr)() != 0) {
298                         hang ();
299                 }
300         }
301 
302 #ifdef CONFIG_OF_CONTROL
303         /* For now, put this check after the console is ready */
304         if (fdtdec_prepare_fdt()) {
305                 panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
306                         "doc/README.fdt-control");
307         }
308 #endif
309 
310         debug("monitor len: %08lX\n", gd->mon_len);
311         /*
312          * Ram is setup, size stored in gd !!
313          */
314         debug("ramsize: %08lX\n", gd->ram_size);

init_fnc_t *init_sequence[]这个函数指针数组变化不大,只跟踪关心的部分,
234 init_fnc_t *init_sequence[] = {
235         arch_cpu_init,          /* basic arch cpu dependent setup */
236 
237 #if defined(CONFIG_BOARD_EARLY_INIT_F)
238         board_early_init_f, /*
原来叫board_init */
239 #endif

跟踪到board/samsung/smdk2410/smdk2410.c中
board_early_init_f(),另外还有board_init(),有点小疑问,怎么由两个板级初始化,研读了代码,
发现这两个函数都执行了,在不同的阶段.贴一下代码:
70 int board_early_init_f(void)
 71 {
 72         struct s3c24x0_clock_power * const clk_power =
 73                                         s3c24x0_get_base_clock_power();
 74         struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
 75 
 76         /* to reduce PLL lock time, adjust the LOCKTIME register */
 77         writel(0xFFFFFF, &clk_power->locktime);
 78 
 79         /* configure MPLL */
 80         writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
 81                &clk_power->mpllcon);
 82 
 83         /* some delay between MPLL and UPLL */
 84         pll_delay(4000);
 85 
 86         /* configure UPLL */
 87         writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,
 88                &clk_power->upllcon);
 89 
 90         /* some delay between MPLL and UPLL */
 91         pll_delay(8000);
。。。

111 }
113 int board_init(void)
114 {
115         /* arch number of SMDK2410-Board */
116         gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
117 
118         /* adress of boot parameters */
119         gd->bd->bi_boot_params = 0x30000100;
120 
121         icache_enable();
122         dcache_enable();
123 
124         return 0;
125 }
熟悉u-boot的可以看出了,其实这两个函数的功能就是以前board_init的功能,即时钟初始和GPIO配置,和传递参数配置,
只是现在进行了拆分,这样u-boot越来越规范,硬件的初始化与上层明确划分,不得不说这是一个好的方向。由此有些问题也能解释了,
void board_init_f()
void board_init_r(); 这是板级初始化的前半部和后半部,board_init_f()进行最基本的初始化,可以说是SOC的初始化,比如内存
串口,初始化gd_t,规划内存等...
然后返回汇编部分进行代码搬运,并初始化bss等,此时又回调用void board_init_r();且看说明

453 /*
454  ************************************************************************
455  *
456  * This is the next part if the initialization sequence: we are now
457  * running from RAM and have a "normal" C environment, i. e. global
458  * data can be written, BSS has been cleared, the stack size in not
459  * that critical any more, etc.
460  *
461  ************************************************************************
462  */
代码到这里已经“正常”运行在SDRAM上了,即所需的环境在前面已经搭建好了,这里会进行更高以及的初始化:
比如nand ,net,LCD然后进入命令模式。了解了大概流程,才恍然其结构与以前u-boot大致一样,不过更加标准了。
还是返回到board_init_f();看其具体流程。
328 
329         addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; /*
整个sdram大小0x3000 0000 + 0x400 0000,
gd->ram_size在dram_init()中被初始化
*/

349 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
350         /* reserve TLB table */
351         addr -= (4096 * 4);
352 
353         /* round down to next 64 kB limit */
354         addr &= ~(0x10000 - 1);
355 
356         gd->tlb_addr = addr;
357         debug("TLB table at: %08lx\n", addr);
358 #endif

360         /* round down to next 4 kB limit */
361         addr &= ~(4096 - 1);                     /* 舍去掉不足4KB的地址空间,为什么是4KB.? */
362         debug("Top of RAM usable for U-Boot at: %08lx\n", addr);

378         addr -= gd->mon_len;    /* 减去u-boot镜像大小,镜像包括Code,Data,bss区,此时addr应该和TEXT_BASE相同*/
379         addr &= ~(4096 - 1);    /* 舍去不足4K的地址空间
*/
380 
381         debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
        /* 调试信息:u-boot加载地址且预留多少空间给
U-BOOT */
382 
383 #ifndef CONFIG_SPL_BUILD
384         /*
385          * reserve memory for malloc() arena
386          */
387         addr_sp = addr - TOTAL_MALLOC_LEN;  /* 没有特殊定义,这里heap应该为4M,因为会作为解压缓冲区,所以分配大些
*/
388         debug("Reserving %dk for malloc() at: %08lx\n",
389                         TOTAL_MALLOC_LEN >> 10, addr_sp);
390         /*
391          * (permanently) allocate a Board Info struct
392          * and a permanent copy of the "global" data
393          */
394         addr_sp -= sizeof (bd_t);          /* 分配heap以后,继续分配bd_t结构体,此时addr_sp指向该结构首地址
*/
395         bd = (bd_t *) addr_sp;
396         gd->bd = bd;                       /* 将该首地址赋值给gd_t->bd初始化
*/
397         debug("Reserving %zu Bytes for Board Info at: %08lx\n",
398                         sizeof (bd_t), addr_sp);
399 
400 #ifdef CONFIG_MACH_TYPE
401         gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
402 #endif
403 
404         addr_sp -= sizeof (gd_t);          /* 接着再次分配gd_t结构体,前面已经分配一次,是因为刚进入C代码,堆栈还具体划分,只做临时保存
*/ 
405         id = (gd_t *) addr_sp;             /* 剩下的空间,才是真正的用户栈区,S3C2440采用栈方式为FD,满栈递减向下生长
*/
406         debug("Reserving %zu Bytes for Global Data at: %08lx\n",
407                         sizeof (gd_t), addr_sp);
408 
409         /* setup stackpointer for exeptions */
410         gd->irq_sp = addr_sp;              /*  如果开启中断,比如使用USB下载功能,这里还不是真正的栈底,还要划分中断栈区
*/
411 #ifdef CONFIG_USE_IRQ
412         addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
413         debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
414                 CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
415 #endif
416         /* leave 3 words for abort-stack    */
417         addr_sp -= 12;                     /* 留3个字的指令预取中止栈
*/
418 
419         /* 8-byte alignment for ABI compliance */
420         addr_sp &= ~0x07;
421 #else
422         addr_sp += 128; /* leave 32 words for abort-stack   */
423         gd->irq_sp = addr_sp;
424 #endif
425 
426         debug("New Stack Pointer is: %08lx\n", addr_sp);
427 
428 #ifdef CONFIG_POST
429         post_bootmode_init();
430         post_run(NULL, POST_ROM | post_bootmode_get(0));
431 #endif
432 
433         gd->bd->bi_baudrate = gd->baudrate;    /* 串口波特率
*/
434         /* Ram ist board specific, so move it to board code ... */
435         dram_init_banksize();
436         display_dram_config();  /* and display it */
437 
438         gd->relocaddr = addr;                  /* 镜像重载地址,即
TEXT_BASE */
439         gd->start_addr_sp = addr_sp;           /* 栈指针
*/
440         gd->reloc_off = addr - _TEXT_BASE;     /* 重载映像相对与预先指定的地址(TEXT_BASE)的偏移地址,并且始终大于等于
0 */
441         debug("relocation Offset is: %08lx\n", gd->reloc_off);
442         memcpy(id, (void *)gd, sizeof(gd_t));  /* 将临时gd_t数据复制进全局结构体
*/
443 
444         relocate_code(addr_sp, id, addr);      /* 调用汇编代码,相当于返回start.进行代码重载,参数为R0-栈指针,

R1-全局数据指针,R2-加载地址. */
445 
446         /* NOTREACHED - relocate_code() does not return */
447 }
这里又回到了汇编部分,注意这里传回的地址并不是通过宏CONFIG_SYS_TEXT_BASE指定的地址
*/
230 relocate_code:
231         mov     r4, r0  /* save addr_sp */   
232         mov     r5, r1  /* save addr of gd */
233         mov     r6, r2  /* save addr of destination */
234 
235         /* Set up the stack 
236 stack_setup:
237         mov     sp, r4       /* 初始化栈指针
*/
238 
239         adr     r0, _start   /* 当前_start标号地址,如果没搬运代码,这里为
0x0 */
240         cmp     r0, r6       
241         beq     clear_bss               /* skip relocation */
242         mov     r1, r6                  /* r1 <- scratch for copy_loop */
243         ldr     r3, _bss_start_ofs
244         add     r2, r0, r3              /* r2 <- source end address         */
245 
246 copy_loop:                              /* NOR flash搬运到SDRAM,这里只搬运了代码区,数据域并没也编译
*/
247         ldmia   r0!, {r9-r10}           /* copy from source address [r0]    */
248         stmia   r1!, {r9-r10}           /* copy to   target address [r1]    */
249         cmp     r0, r2                  /* until source end address [r2]    */
250         blo     copy_loop
251 
252 #ifndef CONFIG_SPL_BUILD
253         /*
254          * fix .rel.dyn relocations ,在链接时指定-pie,编译生成位置无关的映像
*/
255          */
256         ldr     r0, _TEXT_BASE          /* r0 <- Text base */
257         sub     r9, r6, r0              /* r9 <- relocation offset */
258         ldr     r10, _dynsym_start_ofs  /* r10 <- sym table ofs */
259         add     r10, r10, r0            /* r10 <- sym table in FLASH */
260         ldr     r2, _rel_dyn_start_ofs  /* r2 <- rel dyn start ofs */
261         add     r2, r2, r0              /* r2 <- rel dyn start in FLASH */
262         ldr     r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */
263         add     r3, r3, r0              /* r3 <- rel dyn end in FLASH */
264 fixloop:
265         ldr     r0, [r2]                /* r0 <- location to fix up, IN FLASH! */
266         add     r0, r0, r9              /* r0 <- location to fix up in RAM */
267         ldr     r1, [r2, #4]
268         and     r7, r1, #0xff
269         cmp     r7, #23                 /* relative fixup? */
270         beq     fixrel
271         cmp     r7, #2                  /* absolute fixup? */
272         beq     fixabs
273         /* ignore unknown type of fixup */
274         b       fixnext
275 fixabs:
276         /* absolute fix: set location to (offset) symbol value */
277         mov     r1, r1, LSR #4          /* r1 <- symbol index in .dynsym */
278         add     r1, r10, r1             /* r1 <- address of symbol in table */
279         ldr     r1, [r1, #4]            /* r1 <- symbol value */
280         add     r1, r1, r9              /* r1 <- relocated sym addr */
281         b       fixnext
282 fixrel:
283         /* relative fix: increase location by offset */
284         ldr     r1, [r0]
285         add     r1, r1, r9
286 fixnext:
287         str     r1, [r0]
288         add     r2, r2, #8              /* each rel.dyn entry is 8 bytes */
289         cmp     r2, r3
290         blo     fixloop
291 #endif
292

u-boot新结构浏览相关推荐

  1. Spring Boot项目结构

    目录 Spring Boot项目结构 一.代码层结构 二.资源目录结构 三.测试测序目录结构 四.项目结构示例 Spring Boot项目结构 一.代码层结构 根目录:src/main/java 入口 ...

  2. android boot.img 结构

    android 的boot.img 包括 boot header,kernel, ramdisk 首先来看看Makefile是如何产生我们的boot.img的: boot镜像不是普通意义上的文件系统, ...

  3. 阿里云发布 Spring Boot 新脚手架,真香

    作者 | 良名 阿里巴巴技术专家 背景 相信很多人都使用过 start.spring.io 来初始化自己的 Spring Boot 工程,这个工具为开发者提供了丰富的可选组件,并且可以选择多种打包方式 ...

  4. idea springboot 发布webservice 发布服务_阿里云发布 Spring Boot 新脚手架,真香

    作者 | 良名  阿里巴巴技术专家 背景 相信很多人都使用过 start.spring.io 来初始化自己的 Spring Boot 工程,这个工具为开发者提供了丰富的可选组件,并且可以选择多种打包方 ...

  5. springboot项目层次结构_spring boot项目结构

    项目之初,一般我们会根据团队的构成和项目的需求把技术选型.框架定下来,技术选型框架确定后,在团队成员参与开发之前,项目的一些基础服务和组织架构需要资深的负责人或者团队讨论一起分工完成.这样在开始开发后 ...

  6. spring boot jar包_「Spring Boot 新特性」 jar 大小自动瘦身

    自动分析瘦身 Spring Boot 项目最终构建处理 JAR 包大小一直是个诟病,需要把所有依赖包内置最终输出可运行的 jar.当然可以使用其他的插件扩展 实现依赖 JAR 和 可运行 jar 分离 ...

  7. boot sprint 项目结构_Spring Boot 项目结构

    (1)代码层的结构 根目录:com.springboot 1.工程启动类(Application.java)置于com.springboot.build包下 2.实体类(domain)置于com.sp ...

  8. android boot.img 结构,android boot.img文件结构、拆包、打包

    boot.img is not a compressed filesystem image like system.img. It is read by the bootloader, and con ...

  9. Spring Boot 项目结构介绍

    POM文件 <!-- 父工程 --><parent><groupId>org.springframework.boot</groupId><art ...

  10. 小宇宙爆发!Spring Boot 新特性:节省95%内存占用

    作者 | 冷冷 来源 | https://mp.weixin.qq.com/s/0m6ofmMlQTDUQwC7oRRIrQ GraalVM[1] 是一种高性能的虚拟机,它可以显著的提高程序的性能和运 ...

最新文章

  1. lasTools laszip.exe 点云las/laz的无损压缩/解压缩工具
  2. mac下homebrew一些总结
  3. 20080608-昨日回顾今日计划
  4. php 保护变量,保护PHP中的“包含污染”变量
  5. 浅谈个性化推荐系统中的非采样学习
  6. 旗舰杀手!红米旗舰定名 干翻全场?
  7. CIO必看:跨国集团采购部报表系统的建设经验分享
  8. android 1024 github,1024 怎么能少了这款高颜值、敲实用的 GitHub 第三方客户端呢?...
  9. 计算机仿真实验之一 霍尔效应测磁场,2004_01大学物理实验教程_11539522.pdf
  10. Python数据分析实战(1)数据分析概述
  11. GitHub项目之12306抢票软件
  12. 可汗学院公开课——统计学学习:62-81
  13. 服务器装win7没有硬盘分区,深度win7安装没有磁盘分区怎么办?
  14. Delphi著名皮肤控件库大全
  15. 王兴:为什么中国的To B企业都活得这么惨?(演讲全文)
  16. MATLAB绘制小胖墩
  17. 云计算助推金融行业信息化发展
  18. 将Sleuth添加到项目里做链路追踪的三种方式(Greenwich.SR5版)
  19. 论文解读 | LGD:用于物体检测的标签引导自蒸馏
  20. 线索二叉树(线索链表遍历,二叉树线索化)

热门文章

  1. cpp-http 库的使用
  2. 局域网计算机如何传输文件,局域网文件传输,教您局域网如何传输文件
  3. UI设计新手怎么求职 UI面试必备攻略是什么
  4. 查询计算机的配置命令是什么,查看电脑配置指令大全
  5. “元宇宙”是什么?涂子沛:人可在数据空间“复活”
  6. K-means算法实现及分析
  7. 数据字典的作用是什么,它有哪些条目?
  8. html5控制gif速度,用gifsicle优化GIF动图
  9. QCA6174A方案PCI-E接口双频蓝牙WiFi二合一模块8274B-PR
  10. matlab中wavread函数,关于wavread函数的用法