欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOC文档下载
    分享到微信 分享到微博 分享到QQ空间

    Uboot启动流程分析(基于u-boot1.1.4).doc

    • 资源ID:610129       资源大小:142KB        全文页数:15页
    • 资源格式: DOC        下载积分:15金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Uboot启动流程分析(基于u-boot1.1.4).doc

    1、Uboot启动流程分析(基于u-boot1.1.4) 先分析一下u-boot启动的两个阶段,分别对应start.S和board.c这两个文件。 先看board/smsk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序。OUTPUT_FORMAT(elf32-littlearm, elf32-littlearm, elf32-littlearm)/*OUTPUT_FORMAT(elf32-arm, elf32-arm, elf32-arm)*/OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS. = 0x00000000; /*指定可执行ima

    2、ge文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。必须使编译器知道这个地址,通常都是修改此处来完成*/. = ALIGN(4);.text :cpu/arm920t/start.o (.text)*(.text). = ALIGN(4);.rodata : *(.rodata) . = ALIGN(4);.data : *(.data) . = ALIGN(4);.got : *(.got) . = .;_u_boot_cmd_start = .;.u_boot_cmd : *(.u_boot_cmd) _u_boot_cmd_end = .;. = ALIGN(4);_

    3、bss_start = .;.bss : *(.bss) _end = .; 第一个要链接的是cpu/arm920t/start.o,那么U-Boot的入口指令一定位于这个程序中。下面详细分析一下程序跳转和函数的调用关系以及函数实现。1Stage1:cpu/arm920t/start.S 这个汇编程序是U-Boot的入口程序,开头就是复位向量的代码。U-Boot启动代码流程图_start: b reset /复位向量 ;设置异常向量表ldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortl

    4、dr pc, _data_abortldr pc, _not_usedldr pc, _irq /中断向量ldr pc, _fiq /中断向量/* the actual reset code */reset: /复位启动子程序/* 设置CPU为SVC32模式 */mrs r0,cpsrbic r0,r0,#0x1f ;位清除,将某些位的值置0:r0 = r0 AND ( !0x1f)orr r0,r0,#0xd3 ;逻辑或,将r0与立即数进行逻辑或,放在r0中(第一个)msr cpsr,r0/* 关闭看门狗 */* turn off the watchdog */#if defined(CON

    5、FIG_S3C2400)# define pWTCON 0x15300000# define INTMSK 0x14400008 /* Interupt-Controller base addresses */# define CLKDIVN 0x14800014 /* clock divisor register */#elif defined(CONFIG_S3C2410)# define pWTCON 0x53000000# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */# define INTSUBMS

    6、K 0x4A00001C# define CLKDIVN 0x4C000014 /* clock divisor register */#endif#if defined(CONFIG_S3C2400) | defined(CONFIG_S3C2410)ldr r0, =pWTCONmov r1, #0x0str r1, r0/* 禁止所有中断和设置CPU频率 */* mask all IRQs by setting all bits in the INTMR - default*/mov r1, #0xffffffffldr r0, =INTMSKstr r1, r0# if defined

    7、(CONFIG_S3C2410)ldr r1, =0x3ffldr r0, =INTSUBMSKstr r1, r0# endif/* FCLK:HCLK:PCLK = 1:2:4 */ ;FCLK用于CPU,HCLK用于AHB,PCLK用于APB/* default FCLK is 120 MHz ! */ldr r0, =CLKDIVN ;根据硬件手册来设置CLKDIVN寄存器mov r1, #3 ;用户手册的推荐值str r1, r0#endif /* CONFIG_S3C2400 | CONFIG_S3C2410 */* 这些初始化代码在系统重起的时候执行,运行时热复位从RAM中启动不

    8、执行 */* we do sys-critical inits only at reboot,* not when booting from */#ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_crit ;跳转去初始化CPU#endif;#ifdef CONFIG_INIT_CRITICAL 原文中的,估计是1.1.16版本的; bl cpu_init_crit;#endif/* CPU和RAM两个关键的初始化子程序 */* 初始化CPU */cpu_init_crit:/* flush v4 I/D caches 设置CP15*/mov r0, #0

    9、mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ ;使I/D cache失效:将寄存器r0的数据传送到协处理器p15的c7中。C7寄存器位对应cp15中的cache控制寄存器mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ ;使TLB操作寄存器失效:将r0数据送到cp15的c8、c7中。C8对应TLB操作寄存器/* disable MMU stuff and caches 禁止MMU和caches*/mrc p15, 0, r0, c1, c0, 0 ;先把c1和c0寄存器的各位置0(r0 = 0)bic

    10、 r0, r0, #0x00002300 clear bits 13, 9:8 (-V- -RS)bic r0, r0, #0x00000087 clear bits 7, 2:0 (B- -CAM) ;这里我本来有个疑问:为什么要分开设置。因为arm汇编要求的立即数格式所决定的orr r0, r0, #0x00000002 set bit 2(?) (A) Align ;上一条已经设置bit1为0,这一条又设置为1?orr r0, r0, #0x00001000 set bit 12 (I) I-Cachemcr p15, 0, r0, c1, c0, 0 ;用上面(见下面)设定的r0的值设

    11、置c1?(cache类型寄存器)和c0(control字寄存器),以下为c0的位定义;bit8: 0 = Disable System protection;bit9: 0 = Disable ROM protection;bit0: 0 = MMU disabled;bit1: 0 = Fault checking disabled 禁止纠错;bit2: 0 = Data cache disabled;bit7: 0 = Little-endian operation;bit12: 1 = Instruction cache enabled/* 配置内存区控制寄存器 ?有待分析,是1.1.4

    12、版本的* before relocating, we have to setup RAM timing* because memory timing is board-dependend, you will* find a lowlevel_init.S in your board directory.*/mov ip, lrbl lowlevel_init ;位于board/smdk2410/lowlevel_init.S:用于完成芯片存储器的初始化,执行完成后返回mov lr, ipmov pc, lrrelocate: /* 把U-Boot重新定位到RAM */adr r0, _star

    13、t /* r0是代码的当前位置 */ ;adr伪指令,汇编器自动通过当前PC的值算出 如果执行到_start时PC的值,放到r0中:当此段在flash中执行时r0 = _start = 0;当此段在RAM中执行时_start = _TEXT_BASE(在board/smdk2410/config.mk中指定的值为0x33F80000,即u-boot在把代码拷贝到RAM中去执行的代码段的开始)ldr r1, _TEXT_BASE /* 测试判断是从Flash启动,还是RAM */ ;此句执行的结果r1始终是0x33FF80000,因为此值是又编译器指定的(ads中设置,或-D设置编译器参数)cm

    14、p r0, r1 /* 比较r0和r1,调试的时候不要执行重定位 */beq stack_setup /* 如果r0等于r1,跳过重定位代码 */* 准备重新定位代码 */ ;以上确定了复位启动代码是在flash中执行的(是系统重启,而不是软复位),就需要把代码拷贝到RAM中去执行,以下为计算即将拷贝的代码的长度ldr r2, _armboot_start ;前面定义了,就是_startldr r3, _bss_start ;所谓bss段,就是未被初始化的静态变量存放的地方,这个地址是如何的出来的?根据board/smsk2410/u-boot.lds内容?sub r2, r3, r2 /*

    15、r2 得到armboot的大小 */add r2, r0, r2 /* r2 得到要复制代码的末尾地址 */copy_loop: /* 重新定位代码 */ ;开始循环拷贝启动的代码到RAM中ldmia r3-r10 /*从源地址r0复制 */ ;r0指向_start(=0)stmia r3-r10 /* 复制到目的地址r1 */ ;r1指向_TEXT_BASE(=0x33F80000)cmp r0, r2 /* 复制数据块直到源数据末尾地址r2 */ble copy_loop;这里附上u-boot各存储区域的映射图,从网上找的,这下对于这几个地址的位置就一目了然了,对于我这种菜鸟真的是好图啊!

    16、/* 初始化堆栈等 */stack_setup:ldr r0, _TEXT_BASE /* 上面是128 KiB重定位的u-boot */sub r0, r0, #CFG_MALLOC_LEN /* 向下是内存分配空间 */sub r0, r0, #CFG_GBL_DATA_SIZE /* 然后是bdinfo结构体地址空间 */#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endif;这些宏定义在/include/configs/smdk2410.h中:#define CFG_MALL

    17、OC_LEN(CFG_ENV_SIZE + 128*1024);64K+128K=0xC0#define CFG_ENV_SIZE0x10000/* Total Size of Environment Sector 64k*/#define CONFIG_STACKSIZE(128*1024)/* regular stack 128k */#define CFG_GBL_DATA_SIZE 128/* size in bytes reserved for initial data */用0x33F8000 0xC0 0x80得到_TEXT_BASE向下(低地址)的堆栈指针sp的起点地址sub

    18、sp, r0, #12 /* 为abort-stack预留3个字 */;得到最终sp指针初始值clear_bss:ldr r0, _bss_start /* 找到bss段起始地址 */ldr r1, _bss_end /* bss段末尾地址 */mov r2, #0x00000000 /* 清零 */clbss_l:str r2, r0 /* bss段地址空间清零循环. */add r0, r0, #4cmp r0, r1bne clbss_l/* 跳转到start_armboot函数入口,_start_armboot字保存函数入口指针 */ldr pc, _start_armboot_sta

    19、rt_armboot: .word start_armboot ;start_armboot函数在lib_arm/board.c中实现2Stage2:lib_arm/board.c 此文件是u-boot Stage2部分,入口为Stage1最后调用的start_armboot函数。注意上面最后ldr到pc的是_start_armboot这个地址,而非start_armboot变量。 start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。void start_armboot (void)DECLARE_GLOBAL_DATA_PTR;

    20、/此宏定义了一个gd_t类型的指针 *gd,并指名用r8寄存器来存储:#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm (r8)ulong size;init_fnc_t *init_fnc_ptr;char *s;/* Pointer is writable since we allocated a register for it 上面那个宏的作用*/gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t);/此C语句引用的是start.S中的地址标号_a

    21、rmboot_start,但是得到的却是其中所指的变量_start的值(在RAM中,_start = 0x33F80000)。Ps:_armboot_start:.word _start/gd是全局变量,位置在堆栈区以下(低地址):typedef struct global_data bd_t *bd;unsigned long flags;unsigned long baudrate;unsigned long have_console; /* serial_init() was called */unsigned long reloc_off; /* Relocation Offset *

    22、/此变量有什么用?unsigned long env_addr; /* Address of Environment struct */unsigned long env_valid; /* Checksum of Environment valid? */unsigned long fb_base; /* base address of frame buffer */#ifdef CONFIG_VFDunsigned char vfd_type; /* display type */#endif#if 0unsigned long cpu_clk; /* CPU clock in Hz! *

    23、/unsigned long bus_clk;unsigned long ram_size; /* RAM size */unsigned long reset_status; /* reset status register at boot */#endifvoid *jt; /* jump table */ gd_t;/* compiler optimization barrier needed for GCC = 3.4 */_asm_ _volatile_(: : :memory);memset (void*)gd, 0, sizeof (gd_t);gd-bd = (bd_t*)(c

    24、har*)gd - sizeof(bd_t);/得到bd的起点memset (gd-bd, 0, sizeof (bd_t);monitor_flash_len = _bss_start - _armboot_start;/* 顺序执行init_sequence数组中的初始化函数 */for (init_fnc_ptr = init_sequence; *init_fnc_ptr; +init_fnc_ptr) if (*init_fnc_ptr)() != 0) hang ();/*配置可用的Flash */size = flash_init ();/初始化Nor flash的函数,函数实现

    25、在下面display_flash_config (size);/打印到控制台:Flash: 512 kB/* _armboot_start 在u-boot.lds链接脚本中定义 */mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);/将CFG_MALLOC_LEN区域用memset函数清零(直接往目的地址写0)/* 配置环境变量,重新定位 */env_relocate ();/刚才的初始化函数中有一个是env_init(),根据CRC校验来初始化gd-env_addr变量(自己设定的还是初始值),此函数是作用是将环境变量值从某个flash和RA

    26、M之间的拷贝。下图描述了ENV的初始化过程:/* 从环境变量中获取IP地址,放到全局变量gd中 */gd-bd-bi_ip_addr = getenv_IPaddr (ipaddr);/* 以太网接口MAC 地址,放到全局变量gd中,实现过程有待研究*/int i;ulong reg;char *s, *e;uchar tmp64;i = getenv_r (ethaddr, tmp, sizeof (tmp);s = (i 0) ? tmp : NULL;for (reg = 0; reg bd-bi_enetaddrreg = s ? simple_strtoul (s, &e, 16) : 0;if (s)s = (*e) ? e + 1 : e;devices_init (); /* 获取列表中的设备 */jumptable_init ();console_init_r (); /* 完整地初始化控制台设备 */enable_interrupts (); /* 使能例外处理 */* 通过环境变量初始化 */if (s = getenv (loadaddr) != NULL) load_addr = simple_strtoul (s, NULL, 16);/以上几个初始化函数有待研究/* main_loop()总是试图自动


    注意事项

    本文(Uboot启动流程分析(基于u-boot1.1.4).doc)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开