嵌入式学习笔记101-uboot_1.1.6移植(1)
来源:互联网 发布:人工智能技术推广方案 编辑:程序博客网 时间:2024/06/03 20:44
根据前篇博文(嵌入式学习笔记100-uboot1.1.6初体验)最后的结论,现在开始将其实现:
a. 修改makefile的CROSS_COMPILE指定编译器- arm-linux-gcc -v –> gcc version 3.4.5
- CROSS_COMPILE = /opt/EmbedSky/crosstools_3.4.5_softfloat/gcc-3.4.5-glibc-2.3.6/arm-linux/bin/arm-linux-
- chmod -R 777 u-boot-1.1.6/
b. 在makefile里增加类似该配置
1.tq2440_config : unconfig
@(MKCONFIG) (@:_config=) arm arm920t tq2440 NULL s3c24x0c. 在board目录下新增板子的名称为目录
- cd board/
- cp -ar smdk2410/ tq2440
- mv smdk2410.c tq2440.c
- Makefile smdk2410.o –> tq2440.o
d. 在include/configs下新增板子的头文件,文件名是配置第一个参数名
- cd include/configs/
- cp smdk2410.h tq2440.h
e. make xxx_config 配置板子
- make tq2440_config –> Configuring for tq2440 board…
f. make all 编译配置信息
- make all –> 会在跟目录生成bin等文件
启动流程分析:
a.删除不必要的文件以免干扰
根目录下lib开头的库,其中保留lib_arm lib_generic
删除board下除smdk2410 和tq2440 外所有文件
删除include下除asm-arm外的asm-xx目录 include下configs下除smdk2410.h 和tq2440.h外的所有头文件
删除cpu下除arm920t外所有的cpu
重新建立一个新的project或者在原有的project syncb.第一阶段code分析
/* * armboot - Startup Code for ARM920 CPU-core * * Copyright (c) 2001 Marius Gr鰃er <mag@sysgo.de> * Copyright (c) 2002 Alex Z黳ke <azu@sysgo.de> * Copyright (c) 2002 Gary Jennejohn <gj@denx.de> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include <config.h>#include <version.h>/*============ === 代码分析======================**还记得P28的config.h怎么来的么,前篇博文有提到*mkconfig 会在include下生成config.h,最终里面指向*#include <configs/tq2440.h>,所以接下来的很多宏定义都是*在include/configs/tq2440.h里定义的**=================================================*//* ************************************************************************* * * Jump vector table as in table 3.1 in [1] * ************************************************************************* */.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_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/*============ === 代码分析======================**P41-P57 主要设置了中断和异常的向量*对应的处理函数其实除了IRQ,FIQ其他并没有做啥**=================================================*//* ************************************************************************* * * Startup Code (reset vector) * * do important init only if we don't start from memory! * relocate armboot to ram * setup stack * jump to second stage * ************************************************************************* */_TEXT_BASE: .word TEXT_BASE.globl _armboot_start_armboot_start: .word _start/* * These are defined in the board-specific linker script. */.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/*============ === 代码分析======================**很明显想要使能IRQ/FIQ的话要在tq2440.h里*定义这个CONFIG_USE_IRQ,不过stack的值就不是*这个0x0badc0de,要更改成合适的**=================================================*//* * the actual reset code */reset: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0/* turn off the watchdog */#if defined(CONFIG_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 INTSUBMSK 0x4A00001C# define CLKDIVN 0x4C000014 /* clock divisor register */#endif#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] /* * mask all IRQs by setting all bits in the INTMR - default */ mov r1, #0xffffffff ldr r0, =INTMSK str r1, [r0]# if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str r1, [r0]# endif /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0]#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 *//*============ === 代码分析======================**P131-P174无非就是跟之前裸奔程序一样*关闭看门狗,设置时钟和中断**=================================================*/ /* * we do sys-critical inits only at reboot, * not when booting from ram! */#ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_crit#endif/*============ === 代码分析======================**P188-P190会做一次系统更基本的初始化*根据上面的注释可知如果是直接从RAM*启动的话不能调用cpu_init_crit 因为他会对RAM做*清零的动作,code download到RAM结果自己清自己*明显不行,否则程序跑到cpu_init_crit就挂了**=================================================*/#ifndef CONFIG_SKIP_RELOCATE_UBOOTrelocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */copy_loop: ldmia r0!, {r3-r10} /* copy from source address [r0] */ stmia r1!, {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop#endif /* CONFIG_SKIP_RELOCATE_UBOOT *//*============ === 代码分析======================**P202-P219会判断此时正在跑的code是否就是指定的地址*其中adr r0, _start的用法就是获得真正的运行地址*比如_start会等于board/tq2440/config.mk * TEXT_BASE = 0x33F80000*但是程序刚跑是前面的博文讲过PC是从0开始+4的,所以*地址无关的PC减去_start偏移最后_start=0,而*_TEXT_BASE = 0x33F80000,所以会执行后面的copy动作,*如果我们直接将code download到RAM的0x33F80000处,这部分的*code则相当于无效**=================================================*/ /* Set up the stack */stack_setup: 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 *//*============ === 代码分析======================**P237-P245跟之前的裸奔一样设置好栈,为第二阶段的C准备*这里需要注意的是,由于栈是对_TEXT_BASE往下偏移的,这就*要求_TEXT_BASE不能为RAM的基址,如果将_TEXT_BASE设置成*0x30000000,那再往下就不是RAM了! 这是要注意的,同时_TEXT_BASE*下还作为CFG_MALLOC_LEN的buffer,CFG_GBL_DATA_SIZE等用于*传给linux的参数**=================================================*/clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */clbss_l:str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 ble clbss_l#if 0 /* try doing this stuff after the relocation */ ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] /* * mask all IRQs by setting all bits in the INTMR - default */ mov r1, #0xffffffff ldr r0, =INTMR str r1, [r0] /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] /* END stuff after relocation */#endif ldr pc, _start_armboot_start_armboot: .word start_armboot/*============ === 代码分析======================**设置好栈后直接调用_start_armboot,由于采用的是*ldr pc, _start_armboot ldr是赋值绝对地址,最终导致*跑到运行地址处**=================================================*//* ************************************************************************* * * CPU_init_critical registers * * setup important registers * setup memory timing * ************************************************************************* */#ifndef CONFIG_SKIP_LOWLEVEL_INITcpu_init_crit: /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ /* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 /* * 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, lr bl lowlevel_init mov lr, ip mov pc, lr#endif /* CONFIG_SKIP_LOWLEVEL_INIT *//* ************************************************************************* * * Interrupt handling * ************************************************************************* */@@ IRQ stack frame.@#define S_FRAME_SIZE 72#define S_OLD_R0 68#define S_PSR 64#define S_PC 60#define S_LR 56#define S_SP 52#define S_IP 48#define S_FP 44#define S_R10 40#define S_R9 36#define S_R8 32#define S_R7 28#define S_R6 24#define S_R5 20#define S_R4 16#define S_R3 12#define S_R2 8#define S_R1 4#define S_R0 0#define MODE_SVC 0x13#define I_BIT 0x80/* * use bad_save_user_regs for abort/prefetch/undef/swi ... * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling */ .macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack ldmia r2, {r2 - r3} @ get pc, cpsr add r0, sp, #S_FRAME_SIZE @ restore sp_SVC add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr mov r0, sp .endm .macro irq_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 add r8, sp, #S_PC stmdb r8, {sp, lr}^ @ Calling SP, LR str lr, [r8, #0] @ Save calling PC mrs r6, spsr str r6, [r8, #4] @ Save CPSR str r0, [r8, #8] @ Save OLD_R0 mov r0, sp .endm .macro irq_restore_user_regs ldmia sp, {r0 - lr}^ @ Calling r0 - lr mov r0, r0 ldr lr, [sp, #S_PC] @ Get PC add sp, sp, #S_FRAME_SIZE subs pc, lr, #4 @ return & move spsr_svc into cpsr .endm .macro get_bad_stack ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack str lr, [r13] @ save caller lr / spsr mrs lr, spsr str lr, [r13, #4] mov r13, #MODE_SVC @ prepare SVC-Mode @ msr spsr_c, r13 msr spsr, r13 mov lr, pc movs pc, lr .endm .macro get_irq_stack @ setup IRQ stack ldr sp, IRQ_STACK_START .endm .macro get_fiq_stack @ setup FIQ stack ldr sp, FIQ_STACK_START .endm/* * exception handlers */ .align 5undefined_instruction: get_bad_stack bad_save_user_regs bl do_undefined_instruction .align 5software_interrupt: get_bad_stack bad_save_user_regs bl do_software_interrupt .align 5prefetch_abort: get_bad_stack bad_save_user_regs bl do_prefetch_abort .align 5data_abort: get_bad_stack bad_save_user_regs bl do_data_abort .align 5not_used: get_bad_stack bad_save_user_regs bl do_not_used#ifdef CONFIG_USE_IRQ .align 5irq: get_irq_stack irq_save_user_regs bl do_irq irq_restore_user_regs .align 5fiq: get_fiq_stack /* someone ought to write a more effiction fiq_save_user_regs */ irq_save_user_regs bl do_fiq irq_restore_user_regs#else .align 5irq: get_bad_stack bad_save_user_regs bl do_irq .align 5fiq: get_bad_stack bad_save_user_regs bl do_fiq#endif
0 0
- 嵌入式学习笔记101-uboot_1.1.6移植(1)
- 嵌入式学习笔记102-uboot_1.1.6移植(2)
- 嵌入式学习笔记103-uboot_1.1.6移植(3)
- 嵌入式学习笔记104-uboot_1.1.6移植(4)
- uboot_1.1.6学习1_undefined reference to "raise"
- 嵌入式学习笔记(3)---YAFFS文件系统的制作移植
- Uboot_1.1.6ReadMe翻译
- 【嵌入式开发学习笔记】Exynos4412 uboot移植笔记
- 嵌入式学习笔记(1)
- cortex_m3_stm32嵌入式学习笔记(十三):USMART调试组件移植(调试神器)
- 嵌入式学习笔记(19)——AVR单片机之C51向ICCAVR的移植
- 嵌入式学习笔记(C和C++嵌入式系統編程)【1】
- 嵌入式系统 体系结构 学习笔记(1)
- 嵌入式Linux学习笔记(1)
- 从零开始学习嵌入式-笔记(1)
- 嵌入式系统学习笔记(1)
- uboot_1.1.6源码分析——第一阶段
- 嵌入式学习笔记 (3)
- hdu 3790 最短路径问题(spfa)
- Navicat for Oracle 连接 Oracle 11G 操作流程
- uva 1220 ,Patty at Hali-Bula 树形dp 树上最大独立集 并判断是否唯一
- 4、javamail
- Ubunto 安装Apache2以后 httpd.conf文件找不到问题
- 嵌入式学习笔记101-uboot_1.1.6移植(1)
- 2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛——Fruit Ninja II
- 第一课:Logistics, iOS 8 Overview
- java解析xml文件
- Java GC基本算法
- TOJ Area of Circles
- C Interfaces and Implementations 关于setjmp,longjmp和volatile
- php ajax提交普通表单
- ubuntu update apt-get sourcelist