bootloader(代码片段)

dongry dongry     2023-03-09     405

关键词:

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,... 查看详情