U-BOOT启动流程之一
来源:互联网 发布:excel查找重复数据 编辑:程序博客网 时间:2024/05/22 03:12
U-boot的启动流程
u-boot的作用主要是初始化一部分硬件,设置堆栈,然后把U-boot自身代码搬运到sdram当中运行.
U-BOOT的启动分为两个部分.
第一部分
(1) 初始化一部分硬件,比如关闭watch dog,中断等
(2) 搬运u-boot自身代码到sdram中
(3) 设置堆栈sp
(4) 跳到启动代码的第二部分开始执行(C语言部分)
第二部分
(1) 初始化需要用到的硬件,比如tty,flash,i2c总线等。
(2) 加载kernel到sdram中。
(3) 设置内核启动的参数。
(4) 调用内核。
总的来说,分为这几个步骤,调用内核后,就会开始执行内核部分代码。
系统上电后会从0x00000000地址处执行代码
在cpu的目录下,有几种类型的的CPU,比如arm920T,arm720T等,我使用的开发板为s3c2440,为CPU为arm920T,在arm920T目录下有个uboot的链接文件u-boot.lds.其代码如下
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{ . = 0x00000000; . = ALIGN(4); .text : { cpu/arm920t/start.o (.text) board/samsung/Ethan2440/lowlevel_init.o (.text) board/samsung/Ethan2440/nand_read.o (.text) *(.text) } ...............}
这里面的地址有两个,一个是链接文件(u-boot.lds)中的开始地址是0x0,代码段应该是从0地址开始运行,另一个\board\samsung\Ethan2440\config.mk中的代码段的链接地址。查看system.map可以看出代码段是0x33f80000开始链接的,那么代码怎么会在0x0中运行?查了一些资料,个人理解如下:如果理解透彻的可以讨论一下,这里面的使用的跳转指令ldr,bl,adr应该和地址是无关的,是基于PC指针偏移的,start.s,lowlevel_init.s,nand_read.s才参在系统刚启动的时候代码段得以运行,从而实现把"自身"搬运到0x33f80000的地址处。
globl _start/*跳到start_code处开始执行代码.使用b跳转后,是不会再跳回来了*/start: b start_code/*把标号放到pc寄存器中执行*/ 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, _fiqundefined_instruction: .word undefined_instructionsoftware_interrupt: .word software_interruptprefetch_abort:.word prefetch_abortdata_abort: .word data_abortnot_used: .word not_usedirq: .word irqfiq: .word fiq/* 定义一个4字节的函数名来初始,比如undefined_instuction,下面是个函数名,同理其它的也是一样. */.balignl 16,0xdeadbeef
这里面的汇编使用采用AT&T语法,globl是linux下汇编的关键字, .global关键字用来让一个符号对链接器可见,可以供其他链接对象模块使用._start就是一个标号,也可以说是一个地址.
/**_TEXT_BASE用TEXT_BASE来初始化, TEXT_BASE的值是多少呢,经过自己查找,在board/Samsung/smdk2410下的config.mk, TEXT_BASE = 0x33F80000。*/_TEXT_BASE: .word TEXT_BASE.globl _armboot_start_armboot_start: .word _start/* * These are defined in the board-specific linker script. *//**_bss_start,_bss_end初始化,它们在哪儿定义,它们的值是多少呢,可以在cpu/arm920t/u-boot.lds中查到.它的值是多少呢,自己计算吧.*/.globl _bss_start_bss_start: .word __bss_start.globl _bss_end_bss_end: .word _end#ifdef CONFIG_USE_IRQ/* IRQ stack memory (calculated at run-time) */.globl IRQ_STACK_STARTIRQ_STACK_START: .word 0x0badc0de/* IRQ stack memory (calculated at run-time) */.globl FIQ_STACK_STARTFIQ_STACK_START: .word 0x0badc0de#endif
(1)下面是代码真正开始执行的部分,上面是一些变量的定义及初始化
start_code: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0
第1行mrs,cpsr是什么,查一下汇编指令, MSR指令用于将操作数的内容传送到程序状态寄存器的特定域中,这里面的程序状态寄存器可以是cpsr,spsr.所以这里面,是把cpsr的值放到了r0中.
第2行bic指令是把r0与#0x1f取反后相与,也就是把后5位清零.可以查一下bic指令的用法.
第3行orr指令是把r0与#0xd3相或,前面已经把后5位清0,这里面后5位就是0xd3了.
第4行msr和mrs相对应的,把r0的值传送到cpsr中,这四句代码到底是做什么的,看上面的注释就知道是把cpu设置成管理模式的,哪怎么设置的呢,自己查的,你也可以查
CPSR格式如下所示。SPSR和CPSR格式相同。
31 30 29 28 27 26 7 6 5 4 3 2 1 0
N Z C V Q DNM(RAZ) I F T M4 M3 M2 M1 M0
这里面我们重点关注后面8位,因为我们的是0xd3,也就11010011,对应上面的,第I位和F位置1,也就禁止IRQ和FIQ中断,哪后的10011,就是管理模式了.
(2)watch dog中断及分频的设置
058 # if defined(CONFIG_S3C2400)059 # define pWTCON 0x15300000060 # define INTMSK 0x14400008 /* Interupt-Controller base addresses */061 # define CLKDIVN 0x14800014 /* clock divisor register */062 #else063 # define pWTCON 0x53000000064 # define INTMSK 0x4A000008 /* Interupt-Controller base addresses */065 # define INTSUBMSK 0x4A00001C066 # define CLKDIVN 0x4C000014 /* clock divisor register */067 # endif069 ldr r0, =pWTCON070 mov r1, #0x0071 str r1, [r0]072 /*073 * mask all IRQs by setting all bits in the INTMR - default074 */075 movr1, #0xffffffff076 ldr r0, =INTMSK077 str r1, [r0]084 #if defined(CONFIG_S3C2440)085 ldr r1, =0x7fff086 ldr r0, =INTSUBMSK087 str r1, [r0]088 #endif089 #if defined(CONFIG_S3C2440)090 #define MPLLCON 0x4C000004091 #define UPLLCON 0x4C000008092 ldr r0, =CLKDIVN093 movr1, #5094 str r1,[r0]095 096 mrc p15,0,r1,c1,c0,0097 orr r1,r1,#0xc0000000098 mcrp15,0,r1,c1,c0,0100 ldr r0, =MPLLCON101 ldr r1, =0x7F021102 str r1,[r0]104 ldr r0,=UPLLCON105 ldr r1,=0x38022106 str r1,[r0]107 #endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
第63-67行分别用宏定义了watchdog intmask等寄存器的地址,查datasheet看寄存器的地址.
第69-71行把watchdog的寄存器设为0,关闭watchdog。
第75-77行是设置INTMSK寄存器,屏蔽掉所有中断,设为0xffffffff。
第85-87行也是屏蔽中断。
第90-91行分别对MPLL和UPLL的宏定义,MPLL用于定义FCLK,HCLK,PCLK,FCLK用于CPU核,HCLK用于AHB总线上的设备.比如,中断控制器,LCD控制器,DMA等.PCLK用于APB总线上的设备,如WATCHDOG,,IIS,I2C,PWM定时器等.UPLL主要USB设备
第92-94行设置CLKDIVN寄存器,这个寄存器用于设置FCLK HCLK PCLK三者的比例,这里CLKDIVN的值为5,根据samsung手册,5为101,10时HCLK=FCLK/4,最后一位的1,PCLK=HCLK/2,所以FCLK:HCLK:PCLK=1:4:8了.
第96-98行这段代码没有研究,参考了别人的,对s3c2440,如果HDIVN非0,则由fast bus mode变为asynchronous bus mode.
第100-102行是对MPLL寄存器的设置,这里面设置0x7F021。
第104-106行对UPLL寄存器设置
- U-BOOT启动流程之一
- u-boot启动流程
- u-boot启动流程
- u-boot启动流程
- u-boot启动流程
- u-boot启动流程
- u-boot总的启动流程
- u-boot启动流程一
- U-BOOT的启动流程
- u-boot启动流程分析
- U-Boot启动内核流程
- u-boot启动流程分析
- u-boot-2012.10启动流程
- u-boot启动流程-第一阶段
- u-boot关于启动流程
- u-boot启动流程分析
- u-boot-2016.5启动流程
- U-Boot的启动流程
- CIDR(Classless Inter-Domain Routing,无类域间路由)
- delphi中package的使用心得
- Openfire插件开发人员指南
- 第九周任务五之 设计一元一次方程类,求形如ax+b=0的方程的解
- C++标准库类型
- U-BOOT启动流程之一
- 第九周上机任务1
- ubuntu11.10下为android模拟器编译内核到为android开发内核模块(.ko文件)全过程纪实
- MSSQL 触发器常用操作
- 数据结构之后缀数组
- 快排和堆排序对比
- 亲,您的时间需要时间管理?
- 第九周上机任务2
- USB学习总结1—s3c6410的USB驱动修改