关键词:
1 Uboot启动流程
2 程序入口的查看
(1)首先在uboot文件夹中找到Makefile文件,搜索smdk2440查看配置情况;
(2)在uboot文件夹中->board文件夹->samsung文件夹->smdk2440文件夹->u-boot.lds;
在u-boot.lds中找到start文件的位置:
(3)uboot文件夹->cpu文件夹->s3c24xx文件夹->start.S
3 第一阶段程序分析
.globl _start _start: b reset /*以下语句都是用来设置中断向量表的*/ ldr pc,_undefined_instruction ldr pc,_software_interrupt ldr pc,_prefetch_abort ldr pc,_data_abort ldr pc,_not_used ldr pc,_irq ldr pc,_fiq
/*程序从b reset跳过来*/ reset: /*set the cpu to svc32 mode 设置处理器为svc32模式*/ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0
/*顺序执行下去到达*/ cpu_init_crit: /*flush v4 I/D caches 刷新I/D caches*/ mov r0,#0 mcr p15,0,r0,c7,c7,0 mcr p15,0,r0,c8,c7,0 /*disable MMU stuff and caches 关闭MMU和caches*/ mrc p15,0,r0,c1,c0,0 bic r0,r0,#0x00002300 bic r0,r0,#0x00000087 orr r0,r0,#0x00000002 orr r0,r0,#0x00001000 mcr p15,0,r0,c1,c0,0
接着到达函数“bl lowlevel_init” lowlevel_init: mov r12,lr /*init system clock 初始化系统时钟*/ bl system_clock_init /*for UART 初始化串口*/ bl uart_asm_init /*simple init for NAND 简单初始化NAND flash*/ bl nand_asm_init
/*when we already run in ram,we don‘t need to relocate U-Boot. and actually,memory controller must be configured before U-boot is running in ram 判断U-boot是否允许在内存当中*/ ldr r0,=0xf0000fff bic r1,pc,r0 /*r0<-current base addr of code*/ ldr r2,_TEXT_BASE /*r1<-original base addr in ram*/ bic r2,r2,r0 /*r0<-current base addr of code*/ cmp r1,r2 /*compare r0,r1*/ beq 1f /*r0==r1 then skip sdram init*/ adr1 r0,mem_cfg_val bl mem_con_init ldr r0,=ELFIN_UART_BASE ldr r1,=0x4b4b4b4b str r1,[r0,#0x20] 1: mov lr,r12 mov pc,lr /*如果没有运行在内存当中,说明在NAND flash中启动,就要对内存进行初始化,即(bl mem_con_init)
/*返回到start.S文件*/ /*判断是nor flash还是nand flash*/ check boot deviec: ldr r0,=0xff000fff bic r1,pc,r0 /*r0<-current base addr of code*/ ldr r2,_TEXT_BASE /*r1<-original base addr in ram*/ bic r2,r2,r0 /*r0<-current base addr of code*/ cmp r1,r2 /*compare r0,r1*/ beq after_copy /*r0==r1 then skip flash copy*/
/*set up the stack 设置堆栈*/ stack_setup: #ifdef CONFIG_MEMORY_UPPER_CODE ldr sp,=(CFG_UBOOT_BASE+CFG_UBOOT_SIZE-0xc) #else ldr r0,_TEXT_BASE /*upper 128 kib:relocated uboot*/ sub r0,r0,#CFG_MALLOC_LEN /*malloc area*/ sub r0,r0,#CFG_GBL_DATA_SIZE /*bdinfo*/ #ifdef CONFIG_USE_IRQ sub r0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp,r0,#12 /*leave 3 words for abort-stack*/
/*清除bss段*/ clear_bss: ldr r0,_bss_start /*find start of bss segment*/ ldr r1,_bss_end /*stop here*/ mov r2,#0x000000000 /*clear*/
3.1 第一阶段分析
1.上电后CPU会将NAND flash中的前4K拷贝到steppingstone中,最前面的就是start.S,然后CPU就从start.S的_start处开始运行。
2.start.S有一个环节是将NAND flash剩余的内存复制到内存(SDRAM)中去
3.从steppingstone中跳转到内存中去。
ldr pc,_start_armboot /*PC指针跳转到内存中去*/
3.2 基础配置
[email protected]:~/Uboot/uboot$ make smdk2440_config //配置 [email protected]:~/Uboot/uboot$ make //再配置 [email protected]-linux:~/Uboot/uboot$ arm-linux-objdump -D -S u-boot > dump /*生成一个dump文件*/ [email protected]-linux:~/Uboot/uboot$vim dump //打开dump文件
3.3 相关命令
“/”+要搜索的文字 //eg: /start_armboot “/”+“要搜索的文字”+“n” //同一文档连续搜寻下一个
3.4 相对跳转B
假设stepping stone的地址从零开始,内存地址从0x30008000开始,程序运行一段时间后,假设PC指针到了100,将要运行程序lowleave_init函数,假设此函数的入口地址为0x30008010,假如用bl lowleave_init PC指针指向的值为100+(0x30008010-0x30008000)=116,所以PC指针不会进入内存中去(这就是相对跳转相对的意思);
而使用 ldr pc,=0x30008010(绝对跳转)会使PC直接等于30008010跳到了内存中去。
4 第二阶段程序分析
/*第二阶段程序入口*/ ...... ldr pc,_start_armboot start_armboot: .word start_armboot
/*start_armboot在uboot/uboot2440/lib_arm的board.c中*/
第二阶段会进行两方面的初始化,一部分硬件方面的(主讲),一部分软件方面的
for(init_fnc_ptr=init_sequence;*init_fnc_ptr;++init_fnc_ptr) //init_fnc_ptr指针数组,可查 if((*init_fnc_ptr)()!=0) hang();
init_fnc_t *init_sequence[]= ... serial_init, /*serial communications setup 初始化串口*/ ...
/*LCD初始化*/ #ifdef LCD_FRAMBUFFER_ADDR addr=(void *)LCD_FRAMBUFFER_ADDR; #else addr=(_bss_end+(PAGE_SIZE-1))&~(PAGE_SIZE-1); #endif size=lcd_setmem(addr); gd->fb_base=addr; #endif
/*网卡初始化*/ eth_initialize(gd->bd)
/*led初始化*/ led_init();
/*main_loop() can return to retry autoboot,if so just run it again 用户在控制台上输入的命令去进行解析,然后执行相应的用户输入的命令*/ for(;;) main_loop();
5 uboot架构流程
bootloader介绍(代码片段)
一.BootLoader的引入首先我们知道对于pc机,他的启动过程是:BIOS(启动)—>Windows内核(挂在C/D盘)—>系统盘/应用盘(启动)—>应用程序而对于嵌入式系统(比如Android手机,工控设备等)他的启动过程是:B... 查看详情
单片机通用bootloader框架-优化(代码片段)
单片机通用Bootloader框架-优化单片机通用Bootloader框架-优化定义一个标志位变量存储在不初始化的段在IAR中定义在MDK中定义修改跳转接口这篇文章是对之前写的Bootloader的一次优化,之前博文单片机通用Bootloader框架-优化此次优... 查看详情
stm32单片机bootloader扫盲(代码片段)
STM32单片机BootLoader扫盲BootLoader和APP之间的关系APP就是平时写的单片机上的应用程序,而BootLoader本质上和APP一样,也是平时写的应用程序。BootLoader只不过是拥有从外部接收数据,更新Flash(也就是APP),跳... 查看详情
bootloader介绍(代码片段)
文章目录一.BootLoader的引入二.BootLoader的启动方式三.BootLoader的结构和启动过程四.自己写一个BootLoader1.BootLoader第一阶段2.BootLoader第二阶段一.BootLoader的引入首先我们知道对于pc机,他的启动过程是:BIOS(启动)—>Windows内核... 查看详情
bootloader介绍(代码片段)
文章目录一.BootLoader的引入二.BootLoader的启动方式三.BootLoader的结构和启动过程四.自己写一个BootLoader1.BootLoader第一阶段2.BootLoader第二阶段一.BootLoader的引入首先我们知道对于pc机,他的启动过程是:BIOS(启动)—>Windows内核... 查看详情
简易bootloader重定位问题(代码片段)
...即4KSRAM中。然后从SRAM中的0X0地址启动。基于mini2440的简易bootloader制作方法在上一篇文章中有提到。它编译出的boot.bin仅仅有1.96KB,小于STEPSTONE的4KB。 查看详情
freescale飞思卡尔hcs12系列单片机bootloader详解(代码片段)
...sp;在完成内存映射的内容后,接下来我们将进入一个简单Bootloader的实际设计中来。在第一节内容中,我们已经简单介绍了bootlaoder的作用,它实际上就是在单片机重启过程中的一个步骤:如果有bootloader的启动信号,则进入bootloade... 查看详情
实验1-----bootloader运行(代码片段)
1.bootloader启动代码分析1.1寄存器初始化为0(实模式) 其中“-estart”指出了bootblock的入口地址为start,而“-Ttext0x7C00”指出了代码段的起始地址为0x7c00。也就导致start位置的虚拟地址为0x7c00 bootloader程序被bios从引导扇... 查看详情
cc3200模块的内存地址划分和bootloader,启动流程(代码片段)
...二级BOOT,主要用途是OTA升级。二级BOOT有2个工程application_bootloader,relocator(在application_bootloader工程的里面),首先启动relocator工程,然 查看详情
stm32开发——bootloader跳转app执行的实现(代码片段)
bootloader部分要点跳转前需要关闭无关中断,防止APP中未使用该中断,却因为中断而跳转到中断向量表时找不到对应函数入口bootloader最终生成的固件大小不要超过划定的区域App部分要点在Keil设置中要设置对应的flash起始地址与大小,... 查看详情
bootloader介绍(代码片段)
一.BootLoader的引入首先我们知道对于pc机,他的启动过程是:BIOS(启动)—>Windows内核(挂在C/D盘)—>系统盘/应用盘(启动)—>应用程序而对于嵌入式系统(比如Android手机,工控设备等)他的启动过程是:B... 查看详情
自己写bootloader——mini2440(初始化nandflash)(代码片段)
参考资料:https://blog.csdn.net/qqliyunpeng/article/details/51180276程序框架 /*定义寄存器*/#defineNFCONF(*((volatileunsignedlong*)0x4E000000))#defineNFCONT(*((volatileunsignedlong*)0x4E000004))#defineNFCMMD(*( 查看详情
ucorelab1实验笔记(代码片段)
...并运行它。在这里我们将通过另外一个更加简单的软件-bootloader来完成这些工作。为此,我们需要完成一个能够切换到x86的保护模式并显示字符的bootloader,为启动操作系统ucore做准备。lab1提供了一个非常小的bootloader和ucoreOS,整... 查看详情
最简单的bootloader的编写(代码片段)
目标:写出bootloader的第一阶段代码和第二阶段代码,并测试。最简单的bootloader的编写步骤:1.初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NANDFLASH2.如果bootloader比较大,要把它重定位到SDRAM3.把内核从NANDFLASH读到SDRAM4.设... 查看详情
bootloader与内核的交互(代码片段)
...自于:韦东山老师的《嵌入式Linux应用开发》目的:了解Bootloader与内核交互的原理 由于Bootloader和内核交互是单向的,只能是B将参数传给内核,且不能同时运行,那传递参数方法就只有:Bootloader将参数放在某个约定的地方,... 查看详情
lab1系统启动bios加载bootloader加载(代码片段)
前置知识启动地址:CS和EIP结合决定启动地址(一开点,cs和eip就设置的值,值决定在哪个地址取指令地址)cs隐含一个base的内容,base为基址,base+eip就是地址,而加电后访问地址的内存是bios,会看到... 查看详情
apache_conf[xml|verycrypt:individuellebootloader-datei]#veracrypt#xml#boot#bootloader#efi#(代码片段)
[firefly-rk3399]bootloader各个引导阶段直至加载kernel的过程(代码片段)
1、BOOTROM阶段BOOTROM的代码是Rockchip原厂芯片出厂时已烧录的代码,目的是从各个存储媒介中加载miniloader(tpl+spl),以下摘自RK3399芯片手册:从图中可以看出BOOTROM会依次从NorFlash、NandFlash、eMMC、SD/MMC中校验IDBLOCK,... 查看详情