uboot 代码运行流程
- 格式:docx
- 大小:11.49 KB
- 文档页数:2
U-boot 启动流程(Linux 内核)的分析(三)U-boot 属于两阶段的Bootloader ,第一阶段的文件为cpu/arm920t/start.S 和board\samsung\smdk2410/lowlevel_init.S,前者是平台相关的,后者是开发板相关的。
1.U-Boot 第一阶段代码分析(1)硬件设备初始化依次完成如下设置:将CPU 的工作模式设为管理模式(SVC ),关闭WATCHDOG ,设置FCLK ,HCLK ,PCLK 的比例,关闭MMU ,CACHE 。
代码在cpu/arm920t/start.S 中,(2)为加载Bootloader 的第二阶段代码准备RAM 空间。
所谓准备RAM 空间,就是初始化内存芯片,使它可用,对于S3C24x0,通过在Start.S 中调用lowlevel_init 函数来设置存储控制器,使得外接 SDRAM 可用,lowlevel_init.S,文件是与开发板相关的,这表示如果外接的设备不一样,可以修改lowlevel_init.S 文件中的相关的宏。
(3)复制Bootloader 的第二阶段代码到RAM 空间中 这里将整个U-Boot 代码都复制到SDRAM 中,这在cpu/arm920t/start.s 中实现上面这段程序,在使用NANDFlash 启动时,需要修改。
(4)设置好栈 /*栈的设置灵活性很大,只要让sp 寄存器指向一段没有使用的内存即可*/.word TEXT_BASE //这里是获得代码段的起始地址,我的是0x33F80000(在board/xxx/config.mk中//可到找到“TEXT_BASE=0x33F80000”.globl lowlevel_init //这里相当于定义一个全局的lowlevel_init以方便调用lowlevel_init :/* memory control configuration *//* make r0 relative the current location so that it *//* reads SMRDATA out of FLASH rather than memory ! */ldr r0, =SMRDATA //SMDATA表示这 13个寄存器的值存放的开始地址,值为0x33F8xxxx,处于内//存中,这一句的作用是把其值加载到r0中ldr r1, _TEXT_BASE // 把代码的起始地址(0x33F80000)加载到r1中sub r0, r0, r1 //r0减去r1其结果存入r0,也即SMDATA中的起始地址0x33F8xxxx减去//0x33F80000,其结果就是13个寄存器的值在NOR Flash存放的开始地址ldr r1, =BWSCON /* Bus Width Status Controller */ //存储控制器的基地址add r2, r0, #13*4 //在计算出来的存放地址加上#13*4,然后其结果保存在r2中//13 个寄存器,每个寄存器占4个字节0:ldr r3, [r0], #4 //内存中r0的值加载到r3中,然后r0加4,即下一个寄存器的str r3, [r1], #4 //读出寄存器的值保存到r1中,然后r1也偏移4cmp r2, r0 //比较r0与r2的值,如果不等继续返回0:执行,也即13个寄存器的值// 是否读完bne 0b/* everything is fine now */mov pc , lr //程序跳转,返回到cpu_init_crit中.ltorg/* the literal pools origin */SMRDATA :...................relocate : /* 将U-Boot复制到RAM中 */adr r0, _start /* r0:当前代码的开始地址 */ldr r1, _TEXT_BASE /* r1:代码段的连接地址*/cmp r0, r1 /* 测试现在是在FLash中,还在是RAM中,如果要从NandFlash启动的话,这里要根据需要修改 */beq stack_setup /*如果已经在RAM中,则不需要复制*/ldr r2, _armboot_start /*_armboot_start在前面定义,是第一条指令的运行地址*/ldr r3, _bss_start /*在连接脚本U-Boot.lds中定义,是代码段的结束地址*/sub r2, r3, r2 /* r2 <- 代码段长度 */add r2, r0, r2 /* r2 <-代码段的结束地址 */copy_loop :ldmia {r3-r10} /* 从地址[r0]处获得数据 */stmia {r3-r10} /* 复制到地址[r1]处 */cmp r0, r2 /* 判断是否复制完毕 */ble copy_loop /*没有复制完,则继续*/#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ldr r0, _TEXT_BASE /* _TEXT_BASE 为代码段的开始地址,值为0x33F80000 */sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* 代码段下面,留出一段内存以实现malloc */sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* 再留出一段内存,存一些全局参数 */#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ +CONFIG_STACKSIZE_FIQ )#endifsub sp , r0, #12 /* 最后,留出12字节的内存给abort异常 */clear_bss :(5)跳转到第二阶段代码的C 入口点 在跳转之前,还要清除BSS 段(初始值0,无初始值的全局变量,静态变量放在BSS 段。
uboot启动流程分析Uboot启动流程分析。
Uboot是一种常用的嵌入式系统启动加载程序,它的启动流程对于嵌入式系统的正常运行至关重要。
本文将对Uboot启动流程进行分析,以便更好地理解其工作原理。
首先,Uboot的启动流程可以分为以下几个步骤,Reset、初始化、设备初始化、加载内核。
接下来我们将逐一进行详细的分析。
Reset阶段是整个启动流程的起点,当系统上电或者复位时,CPU会跳转到Uboot的入口地址开始执行。
在这个阶段,Uboot会进行一些基本的硬件初始化工作,包括设置栈指针、初始化CPU寄存器等。
接着是初始化阶段,Uboot会进行一系列的初始化工作,包括初始化串口、初始化内存控制器、初始化时钟等。
这些初始化工作是为了确保系统能够正常地运行,并为后续的工作做好准备。
设备初始化阶段是Uboot启动流程中的一个重要环节,它包括对外设的初始化和检测。
在这个阶段,Uboot会初始化各种外设,如网卡、存储设备等,并对其进行检测,以确保它们能够正常工作。
最后一个阶段是加载内核,Uboot会从存储设备中加载操作系统的内核镜像到内存中,并跳转到内核的入口地址开始执行。
在这个过程中,Uboot会进行一些必要的设置,如传递启动参数给内核,并最终将控制权交给内核。
总的来说,Uboot的启动流程是一个非常重要的过程,它涉及到系统的硬件初始化、外设的初始化和内核的加载等工作。
只有当这些工作都顺利完成时,系统才能够正常地启动运行。
因此,对Uboot启动流程的深入理解对于嵌入式系统的开发和调试具有重要意义。
通过本文对Uboot启动流程的分析,相信读者对Uboot的工作原理有了更清晰的认识。
希望本文能够对大家有所帮助,谢谢阅读!。
关于imx51的uboot代码的启动流程分析2012.11.19baodingsheng1.首先bootrom代码会拷贝uboot的前2KB/4KB到IRAM中去,紧接着就会处理DDR2的配置数据表(即flash_header.S中的DCD段)。
2.执行完后进行CSF check,如果passed,则跳转到app_code_jump_v:.word_start接下来要开始执行的地方就是uboot中的start入口3.接下来在start.S中做的工作是:设置cpu为SVC模式、关闭中断IRQ和FIQ、MMU和L1cache的初始化、GPIO口的初始化、enable L1NEON bit、L2cache的初始化、AIPS的初始化、M4IF的初始化、clock的初始化、relocate U-Boot to RAM、设置堆栈、清除bss段、board_mmu_inint、这里使能了MMU、而后进入C代码段:dr pc,_start_armboot@jump to C codetart_armboot:.word start_armboot4.接下在void start_armboot(void)中做的工作是:a.全局变量gdgd->bd指针指向数据类型为bd_t的结构体,bd_t结构体记录开发板的参数,例如串口波特率、ip地址、机器类型、启动参数、环境变量位置等。
b.定义二级指针init_fnc_ptr指向一个存放函数指针的数组,接下来在for循环中执行的这些函数:init_fnc_t*init_sequence[]={#if defined(CONFIG_ARCH_CPU_INIT)arch_cpu_init,/*basic arch cpu dependent setup*/#endifboard_init,*basic board dependent setup*/#if defined(CONFIG_USE_IRQ)interrupt_init,/*set up exceptions*/#endiftimer_init,/*initialize timer*/env_init,/*initialize environment*/init_baudrate,/*initialze baudrate settings*/serial_init,*serial communications setup*/console_init_f,/*stage1init of console*/display_banner,/*say that we are here*/#if defined(CONFIG_DISPLAY_CPUINFO)print_cpuinfo,/*display cpu info(and speed)*/#endif#if defined(CONFIG_DISPLAY_BOARDINFO)checkboard,/*display board info*/#endif#if defined(CONFIG_HARD_I2C)||defined(CONFIG_SOFT_I2C)init_func_i2c,#endifdram_init,/*configure available RAM banks*/#if defined(CONFIG_CMD_PCI)||defined(CONFIG_PCI)arm_pci_init,#endifdisplay_dram_config,NULL,};c.arch_cpu_init函数的工作是:enable L1icache和dcache、enable L2cached.board_init函数的工作是:选择启动设备、SOC的版本、board的版本、板子的id号(bi_arch_number)、启动参数的地址(bi_boot_params),设置串口、设置nandflash控制器、设置expio、设置FEC(快速以太网控制器)、设置I2Ce.timer_init,设置GPT。
联咏方案uboot1. 联咏方案概述联咏方案(LinkIt)是联发科(MediaTek)推出的一套物联网(IoT)解决方案,包括硬件和软件。
其中,uboot(universal bootloader)是一款开源的引导加载程序,用于启动嵌入式系统。
uboot作为硬件平台和操作系统之间的桥梁,具备了丰富的功能,包括启动系统、烧录固件、设置环境变量等。
联咏方案的uboot是经过定制和优化的,以适应联咏方案的特点和需求。
本文档将介绍联咏方案的uboot的基本使用方法和常见功能,帮助开发者更好地利用uboot来开发和调试联咏方案的嵌入式系统。
2. uboot的基本使用方法2.1 编译uboot在开始使用uboot之前,需要先编译uboot源代码。
联咏方案提供了uboot的源代码和编译工具链。
以下是编译uboot的基本步骤:1.下载uboot源代码,并解压到本地目录。
2.进入uboot源代码目录,执行以下命令配置编译选项:make menuconfig3.在配置界面中,根据目标设备的特点进行配置,如处理器架构、存储设备等。
4.保存配置并退出配置界面。
5.执行以下命令编译uboot:make6.编译成功后,生成可执行文件u-boot.bin。
2.2 烧录uboot烧录uboot到目标设备的闪存中,可以使用烧录工具,如OpenOCD、J-Link等。
以下是烧录uboot的基本步骤:1.将目标设备与烧录工具连接,确保连接正常。
2.执行以下命令烧录uboot:make flash3.等待烧录完成。
2.3 uboot交互界面在uboot启动后,会进入uboot的交互界面。
通过该界面,可以执行各种uboot命令。
以下是uboot交互界面的基本命令:•help:显示所有可用的uboot命令及其说明。
•printenv:显示当前uboot的环境变量。
•setenv:设置uboot的环境变量。
•saveenv:保存uboot的环境变量。
U-Boot工作过程U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:(1)第一阶段的功能硬件设备初始化加载U-Boot第二阶段代码到RAM空间设置好栈跳转到第二阶段代码入口(2)第二阶段的功能初始化本阶段使用的硬件设备检测系统内存映射将内核从Flash读取到RAM中为内核设置启动参数调用内核1.1.1 U-Boot启动第一阶段代码分析第一阶段对应的文件是cpu/arm920t/和board/samsung/mini2440/。
U-Boot启动第一阶段流程如下:图 U-Boot启动第一阶段流程根据cpu/arm920t/中指定的连接方式:ENTRY(_start)SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{cpu/arm920t/ (.text)board/samsung/mini2440/ (.text)board/samsung/mini2440/ (.text)*(.text)}… …}第一个链接的是cpu/arm920t/,因此的入口代码在cpu/arm920t/中,其源代码在cpu/arm920t/中。
下面我们来分析cpu/arm920t/的执行。
1. 硬件设备初始化(1)设置异常向量cpu/arm920t/开头有如下的代码:.globl _start_start: b start_code /* 复位*/ldr pc, _undefined_instruction /*未定义指令向量 */ldr pc, _software_interrupt /* 软件中断向量 */ldr pc, _prefetch_abort /* 预取指令异常向量 */ldr pc, _data_abort /* 数据操作异常向量 */ldr pc, _not_used /* 未使用 */ldr pc, _irq /* irq中断向量 */ldr pc, _fiq /* fiq中断向量 */ /* 中断向量表入口地址 */_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abort: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiq.balignl 16,0xdeadbeef以上代码设置了ARM异常向量表,各个异常向量介绍如下:表 ARM异常向量表在cpu/arm920t/中还有这些异常对应的异常处理程序。
·1 引言在专用的嵌入式板子运行 GNU/Linux 系统已经变得越来越流行。
一个嵌入式 Linux 系统从软件的角度看通常可以分为四个层次:1. 引导加载程序。
固化在固件(firmware)中的 boot 代码,也就是 Boot Loader,它的启动通常分为两个阶段。
2. Linux 核。
特定于嵌入式板子的定制核以及核的启动参数。
3. 文件系统。
包括根文件系统和建立于 Flash 存设备之上文件系统,root fs。
4. 用户应用程序。
特定于用户的应用程序。
有时在用户应用程序和核层之间可能还会包括一个嵌入式图形用户界面。
常用的嵌入式 GUI 有:MicroWindows 和 MiniGUI 等。
引导加载程序是系统加电后运行的第一段软件代码。
回忆一下 PC 的体系结构我们可以知道,PC 机中的引导加载程序由 BIOS(其本质就是一段固件程序)和位于硬盘 MBR 中的 OS Boot Loader(比如,LILO 和 GRUB 等)一起组成。
BIOS 在完成硬件检测和资源分配后,将硬盘 MBR 中的 Boot Loader 读到系统的 RAM 中,然后将控制权交给 OS Boot Loader。
Boot Loader 的主要运行任务就是将核映象从硬盘上读到 RAM 中,然后跳转到核的入口点去运行,也即开始启动操作系统。
而在嵌入式系统中,通常并没有像 BIOS 那样的固件程序(注,有的嵌入式 CPU 也会嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由 Boot Loader 来完成。
比如在一个基于 ARM7TDMI core 的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000 处开始执行,而在这个地址处安排的通常就是系统的 Boot Loader 程序。
·2 bootloader简介简单地说,Boot Loader (引导加载程序)就是在操作系统核运行之前运行的一段小程序,它的作用就是加载操作系统,它是系统加电后运行的第一段软件代码。
uboot 2013 07 运行流程board:board/friendlyarm/mini2440目前只支持nor启动1、由编译链接文件u-boot.lds// arch/arm/cpu/u-boot.lds可知,第一个运行的文件为:CPUDIR/start.o//arch/arm/cpu/arm920t/start.S1)设置异常向量2)设置CPU的工作模式3)关中断4)关看门狗5)设置CPU时钟6)配置caches7)禁mmu8)bl lowlevel_init],跳到lowlevel_init.S2、lowlevel_init.S//在samsung/smdk2410/lowlevel_init.S,自己添加进来1)存储控制器初始化:位数,时序等2)返回到start.S,然后bl _main,跳到crt0.S3、crt0.S// arch/arm/lib(此文件官方说明:2013/1/ 8arm: move C runtime setup code in crt0.SMove all the C runtime setup code from every start.Sin arch/arm into arch/arm/lib/crt0.S. This coversthe code sequence from setting up the initial stackto calling into board_init_r().从2013/1/ 8起,把C语言运行环境的设置,放到crt0.S文件)1)堆栈设置2)blboard_init_f4、board_init_f()// arch/arm/lib/board.c1)第一阶段平台的初始化工作timer_init,env_init, ram_init... 计算堆栈addr_sp,设置gd、bd结构体空间,异常中断堆空间,计算出重定向u-boot的位置addr,控制台初始化,打印一些消息2)回到crt0.S设置新的sp and gd3)brelocate_code,跳到relocate.S5、relocate.S//arch/arm/lib1)把U-Boot复制到SDRAM中指定的位置处。
海思uboot启动流程详细分析(⼀)第⼀阶段 start.S⾸先我们可以在u-boot.lds中看到ENTRY(_start),即指定了⼊⼝_start,_start也就是整个start.S的最开始;1. reset在arch\arm\cpu\armv8\hi3559av100中的start.S注意x30在ARMV8中代表lr寄存器reset:/** Could be EL3/EL2/EL1, Initial State:* Little Endian, MMU Disabled, i/dCache Disabled*/adr x0, vectorsswitch_el x1, 3f, 2f, 1f3: msr vbar_el3, x0mrs x0, scr_el3orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */msr scr_el3, x0msr cptr_el3, xzr /* Enable FP/SIMD */#ifdef COUNTER_FREQUENCYldr x0, =COUNTER_FREQUENCYmsr cntfrq_el0, x0 /* Initialize CNTFRQ */#endifb 0f2: msr vbar_el2, x0mov x0, #0x33ffmsr cptr_el2, x0 /* Enable FP/SIMD */b 0f1: msr vbar_el1, x0mov x0, #3 << 20msr cpacr_el1, x0 /* Enable FP/SIMD */0:/** Cache/BPB/TLB Invalidate* i-cache is invalidated before enabled in icache_enable()* tlb is invalidated before mmu is enabled in dcache_enable()* d-cache is invalidated before enabled in dcache_enable()*//** read system register REG_SC_GEN2* check if ziju flag*/ldr x0, =SYS_CTRL_REG_BASEldr w1, [x0, #REG_SC_GEN2]ldr w2, =0x7a696a75 /* magic for "ziju" */cmp w1, w2bne normal_start_flowmov x1, sp /* save sp */str w1, [x0, #REG_SC_GEN2] /* clear ziju flag */adr x0, vectors,其中的vectors代表了异常向量表主要做了如下事情:1)reset SCTRL寄存器具体可参考reset_sctrl函数,由CONFIG_SYS_RESET_SCTRL控制,⼀般不需要打开。
uboot 代码运行流程U-Boot代码运行流程U-Boot(Universal Bootloader)是一个开源的引导加载程序,广泛应用于嵌入式系统中。
它负责在系统上电后初始化硬件并加载操作系统内核,是系统启动的重要一环。
下面将从U-Boot代码的运行流程方面进行介绍。
1. 启动阶段当系统上电后,处理器会从预定义的存储器地址开始运行代码。
U-Boot的启动代码通常存放在ROM中,处理器会从ROM的起始地址开始执行。
启动代码负责初始化处理器和一些外设,然后跳转到U-Boot的入口点。
2. 入口点U-Boot的入口点是指U-Boot的main()函数。
在启动代码的最后,会调用main()函数,从而进入U-Boot的主循环。
U-Boot的主循环负责处理用户输入的命令,并根据命令执行相应的操作。
3. 硬件初始化在main()函数中,首先会进行硬件的初始化工作。
这包括初始化串口、初始化存储器控制器、初始化网络接口等。
硬件初始化的目的是为了确保系统能够正常运行,并为后续的操作做好准备。
4. 系统启动硬件初始化完成后,U-Boot会尝试从存储设备(如闪存、SD卡)中加载操作系统内核镜像。
U-Boot会根据预定义的启动命令(例如bootcmd)来确定从哪个设备加载内核镜像,并执行相应的加载操作。
加载完成后,U-Boot会将控制权交给操作系统内核,进入操作系统的启动阶段。
5. 用户交互一般情况下,U-Boot会在系统启动后进入命令行界面,等待用户输入命令。
用户可以通过串口、网络等方式与U-Boot进行交互,执行各种操作,例如烧写固件、修改配置等。
U-Boot提供了丰富的命令集,可以满足不同的需求。
6. 系统重启当用户输入重启命令或系统发生异常时,U-Boot会执行系统重启操作。
重启操作包括重新初始化硬件、重新加载内核镜像等步骤,以重新启动系统。
U-Boot会将控制权交给重新加载的内核,然后进入内核的启动流程。
总结:U-Boot代码的运行流程包括启动阶段、入口点、硬件初始化、系统启动、用户交互和系统重启等几个关键步骤。
uboot 代码运行流程
U-boot是一款ARM处理器启动管理程序,在ARM开发板研发中具有非常广泛的应用,它可以在开发板上提供各种服务和支持,使得用户能够轻松地启动系统和进行应用开发。
本文将从U-boot代码运行流程方面来介绍U-boot的一般执行过程。
U-boot代码运行流程主要可以分为两个方面,即bootloader代码执行流程和内核启动代码执行流程。
1. Bootloader代码执行流程
Bootloader是指从CPU开始运行到操作系统启动、执行前的代码。
它的主要功能是加载操作系统内核、初始化硬件环境以及对操作系统进行配置等。
U-boot在启动过程中需要经历以下几个步骤:
1)CPU复位
在系统上电或者发生复位时,CPU内部控制块将根据复位信号重新启动,并从指定地址处读取第一条指令。
2)初始化硬件
U-boot对内存、Flash、串口等硬件进行初始化,然后启动U-boot的“彩屏”启动画面。
3)读取启动设备
U-boot通过Boot Device Driver从存储设备(SD卡、NAND Flash等)中读取启动文件,然后执行它。
默认情况下,U-boot会从SD卡中读取启动文件。
4)解析启动文件
U-boot解析启动文件,提取内核映像、设备树和命令行参数等关键信息。
然后执行其它操作,如设备树重定位、加入命令行参数等。
5)启动内核
U-boot将内核映像从Flash中加载到内存中,并将控制权转交给内核。
此时内核开始执行,U-boot自己退出。
2. 内核启动代码执行流程
内核启动代码主要是内核启动过程中的初始化工作。
启动过程中,操作系统需要对内存进行初始化、加载一些关键模块、初始化驱动程序等工作,以实现操作系统本身的功能。
1)内核初始化
内核初始化包括内存管理、进程管理、文件系统、驱动程序初始化等。
此时内核会创建init进程和kthreadd进程。
2)加载模块
内核启动后加载模块,模块提供了丰富的功能,如网络支持、图形界面等。
3)挂载文件系统
内核通过调用文件系统相关接口,将硬盘、光盘或其他存储设备的文件系统挂载到目录位置上。
4)启动运行级别
内核启动后,需要加载不同的运行级别(Runlevel)以支持不同类别的用户进程。
二、总结
以上就是U-boot代码运行流程的简要介绍。
U-boot可以为ARM处理器提供可靠的启动管理和支持服务,可以通过Bootloader代码和内核启动代码执行流程,了解系统软件启动的一般流程。
同时,U-boot支持代码定制、移植和扩展等功能,用户可以依据自己的需求进行灵活配置。