mini-uboot 启动过程简单分析
单片机有最小系统,所谓最小系统,就是单片机能正常工作所需要的最少外设。对于Uboot来说,同样有个最小系统,因为Uboot最主要的功能就是引导内核。下面我们通过一个简单的Mini-Uboot来分析Uboot的启动加载过程。(只是分析过程,此Uboot具有引导内核功能)
注:这个uboot 只是具有基本的内核引导功能,只是作为前期简单的学习使用,入门而已,并不是正常的uboot 启动流程
具体uboot (u-boot-2013.01)启动过程移步Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析
下面是mini-uboot 的根目录树状图:
我们拿到一个工程,想了解它的功能,最方便的就是读它的makefile。
一、Makefile
- sinclude include/config.mk
- #ARCH=arm
- #CPU=arm920t
- #VENDOR=samsung
- #SOC=s3c2410
- #BOARD=smdk2410
- SRC_TREE:=$(shell pwd)
- MKCONFIG=$(SRC_TREE)/mkconfig
- INCLUDE_PATH=include
- DRIVER_PATH=driver
- LIB_DIR=lib
- CFLAG=-mabi=apcs-gnu -fno-builtin -fno-builtin-function -g -O0 -c -I$(INCLUDE_PATH) -I$(DRIVER_PATH) -o
- LDFLAG=-Tcpu/arm/arm_cortexa8/map.lds -o
- OBJS= cpu/$(ARCH)/$(CPU)/start.o
- OBJS+=lib_arm/board.o
- OBJS+=board/$(VENDOR)/$(BOARD)/lowlevel_init.o
- OBJS+=board/$(VENDOR)/$(BOARD)/mem_setup.o
- OBJS+=board/$(VENDOR)/$(BOARD)/nand.o
- OBJS+=driver/uart.o
- OBJS+=lib/string.o
- OBJS+=common/do_go.o
- OBJS+=common/main.o
- ifeq ($(ARCH), arm)
- CROSS_COMPILE=arm-cortex_a8-linux-gnueabi-
- endif
- PROJ_NAME=mini_uboot
- all: $(OBJS)
- $(CROSS_COMPILE)ld $(OBJS) $(LDFLAG) $(PROJ_NAME).elf
- $(CROSS_COMPILE)objcopy -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin
- $(CROSS_COMPILE)objdump -D $(PROJ_NAME).elf > $(PROJ_NAME).dis
- cp *.bin /tftpboot
- %.o: %.S
- $(CROSS_COMPILE)gcc $(CFLAG) $@ $<
- %.o: %.s
- $(CROSS_COMPILE)gcc $(CFLAG) $@ $<
- %.o: %.c
- $(CROSS_COMPILE)gcc $(CFLAG) $@ $<
- fsc100_config: # ARCH CPU VENDOR BOARD SOC
- $(MKCONFIG) $(@:_config=) arm arm_cortexa8 samsung fsc100 s5pc100
- #mkconfig fsc100 arm arm_cortexa8 samsung fsc100 s5pc100
- smdk2410_config: # ARCH CPU VENDOR BOARD SOC
- $(MKCONFIG) $(@:_config=) arm arm920t samsung smdk2410 s3c2410
- clean:
- @rm -rf $(OBJS) *.bin *.elf config.mk
这里以2440为例,咱们来分析:
- #ARCH=arm
- #CPU=arm920t
- #VENDOR=samsung
- #SOC=s3c2410
- #BOARD=smdk2410
架构为arm,CPU为arm920t,生产商 samsung,片上系统sc2410,板子为smdk2410。
- OBJS= cpu/$(ARCH)/$(CPU)/start.o
- OBJS+=lib_arm/board.o
- OBJS+=board/$(VENDOR)/$(BOARD)/lowlevel_init.o
- OBJS+=board/$(VENDOR)/$(BOARD)/mem_setup.o
- OBJS+=board/$(VENDOR)/$(BOARD)/nand.o
- OBJS+=driver/uart.o
- OBJS+=lib/string.o
- OBJS+=common/do_go.o
- OBJS+=common/main.o
OBJS为依赖文件,生成的.o文件。
- ifeq ($(ARCH), arm)
- CROSS_COMPILE=arm-cortex_a8-linux-gnueabi-
- endif
根据相应的架构,制作相应的交叉编译工具。
- all: $(OBJS)
- $(CROSS_COMPILE)ld $(OBJS) $(LDFLAG) $(PROJ_NAME).elf
- $(CROSS_COMPILE)objcopy -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin
- $(CROSS_COMPILE)objdump -D $(PROJ_NAME).elf > $(PROJ_NAME).dis
第一步:连接 ;第二步:格式转换;第三步:反汇编 " >" 为重定向的意思;
- %.o: %.S
- $(CROSS_COMPILE)gcc $(CFLAG) $@ $<
- %.o: %.s
- $(CROSS_COMPILE)gcc $(CFLAG) $@ $<
- %.o: %.c
- $(CROSS_COMPILE)gcc $(CFLAG) $@ $<
将所有的.S 文件、.s文件、.c文件编译成.o文件。
注意:.S文件可以在编译过程接受参数,.s文件不可以。
二、链接文件
- OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
- /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
- OUTPUT_ARCH(arm)
- ENTRY(_start) //指定入口地址
- SECTIONS //段信息
- {
- /* . */
- . = 0x22000000; //elf文件的入口地址
- . = ALIGN(4); //指定四字节对齐
- .text : //代码段
- {
- cpu/arm/arm_cortexa8/start.o(.text) //确保执行的第一段代码是start.o
- *(.text) //所有代码段融合在一起
- }
- . = ALIGN(4);
- .rodata : //只读数据段
- { *(.rodata) } //所有数据段
- . = ALIGN(4);
- .data : //数据段
- { *(.data) }
- . = ALIGN(4);
- _start_bss = .; //bss段开始地址
- .bss :
- { *(.bss) }
- _end_bss = .; //bss段结束地址,两者可确定bss段大小
- }
三、start.s文件(Uboot执行的第一个文件)
- @ 汇编中的宏
- .equ USER_MODE, 0x10 @define USER_MODE 0x10
- .equ IRQ_MODE, 0x12
- .equ SVC_MODE, 0x13
- .equ MODE_MASK, 0x1f
- .section .text
- .global _start
- @ 不支持异常处理的,这里只写了复位异常处理
- _start:
- vector:
- b reset_handler
- nop @undef ......
- nop
- nop
- nop
- nop
- nop
- nop
- reset_handler:
- @step 1: svc close irq fiq //第一步:将运行模式改成SVC模式
- mrs r0, cpsr //修改cpsr模式位
- bic r0, r0, #0x1f
- orr r0, r0, #0xc0 @IRQ FIQ //关闭IRQ FIQ
- msr cpsr_c, r0
- @step 2: cache 关闭I CACHE D CACHE //第二步:关闭cache,直接运行,不需缓存
- mrc p15, 0, r0, c12, c0, 0
- bic r0, #0x1000
- bic r0, #0x2
- mcr p15, 0, r0, c12, c0, 0
- @step 3: //第三步:调用电路板级初始化程序, system clock , dram, watchdog
- @bl low_level_init //初始化时钟、dram、关闭看门狗
- @step 4: sp-> 0x30000000 //第四步:设置栈指针,使其指向一个地址即可
- ldr sp, =0x2e000000
- @step 5: mini_uboot.bin > 16KB bin < 16KB
- @step 5 代码自搬移
- @copy_miniuboot_rto_sdram 如果你的代码大于了16KB代码需要实现自我搬移
- @step 6: //第六步:清除BSS段,BSS段大小由链接文件里确定
- @STEP 6.1 , 清除 BSS段
- @
- clear_bss:
- ldr r0, =_start_bss @| BSS 起始地址
- ldr r1, =_end_bss @| BSS 终止地址
- mov r2, #0
- bss_loop:
- cmp r0, r1
- strne r2, [r0], #4
- bne bss_loop
- @step 7, 进入C //跳转到C程序入口
- b start_armboot
- stop:
- b stop
- .end
mini-uboot 启动过程简单分析的更多相关文章
- U-Boot启动过程完全分析
U-Boot启动过程完全分析 1.1 U-Boot工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 硬件设备初始化 加载U-Boot第二阶段 ...
- U-Boot启动过程完全分析<转>
转载自:http://www.cnblogs.com/heaad/archive/2010/07/17/1779829.html 1.1 U-Boot工作过程 U-Boot启动内核的过程可 ...
- 【ARM-Linux开发】U-Boot启动过程--详细版的完全分析
---------------------------------------------------------------------------------------------------- ...
- Android应用程序组件Content Provider的启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6963418 通过前面的学习,我们知道在Andr ...
- uboot启动过程理解
对于2440而言,启动的方式不多.一般就是外界一个NAND FLASH ,2440内部有个NAND FLASH Controller,会自动把NAND FLASH的前4K拷贝到2440的片内SRAM. ...
- (四)SpringBoot启动过程的分析-预处理ApplicationContext
-- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(三)SpringBoot启动过程的分析-创建应用程序上下文,本文将分析上下文创建完毕之后的下一步操作:预处理上下文容器. 预处理上下文 ...
- (五)SpringBoot启动过程的分析-刷新ApplicationContext
-- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇[(四)SpringBoot启动过程的分析-预处理ApplicationContext] (https://www.cnblogs.co ...
- Android系统默认Home应用程序(Launcher)的启动过程源代码分析
在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个 Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home ...
- 海思uboot启动流程详细分析(转)
海思uboot启动流程详细分析(一) 海思uboot启动流程详细分析(二) 海思uboot启动流程详细分析(三)
随机推荐
- Vue 2.0 项目在IE下显示空白
新写的项目在 IE浏览器显示空白 解释一: Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator.Generator.Set.Maps.Proxy ...
- web前端常用的封装方法
1.放大镜 //页面加载完毕后执行 window.onload = function () { var oDemo = document.getElementById('demo'); var oMa ...
- Verilog学习笔记基本语法篇(六)········ 循环语句
在Verilog中存在着4种类型的循环语句,用来控制执行语句的执行次数. 1)forever语句: 连续执行的语句. 2)repeat语句: 连续执行n次的语句. 3)while语句: 执行语 ...
- PHP “引号兄弟”
PHP的string最大可以达到2GB,不过很少会用到这么大的字符串. 单引号: 定义一个字符串最简单的方式是使用单引号,而在单引号字符串中要想表达一个单引号,需要在她的前面加个反斜线(\)来进行转义 ...
- HDU1007 TLE代码和AC代码对比
这题卡了一天,上午开始看算法导论,然后实现了,一开始是wa,后来TLE,由于我开始的实现方式比较笨,而且在递归调用的时候很是混乱,用了好多数组.导致我的代码不断的出问题.具体是算法导论33-4. 后来 ...
- 使用Unity做2.5D游戏教程(二)
最近在研究Unity 3D,看了老外Marin Todorov写的教程很详细,就翻译过来以便自己参考,翻译不好的地方请多包涵. 这是使用Unity 游戏开发工具制作一个简单的2.5D 游戏系列教程的第 ...
- BZOJ 3143 [Hnoi2013]游走 ——概率DP
概率DP+高斯消元 与博物馆一题不同的是,最终的状态是有一定的概率到达的,但是由于不能从最终状态中出来,所以最后要把最终状态的概率置为0. 一条边$(x,y)$经过的概率是x点的概率$*x$到$y$的 ...
- Snmp的学习总结——Snmp的基本概念
摘自:http://www.cnblogs.com/xdp-gacl/p/3978825.html 一.SNMP简单概述 1.1.什么是Snmp SNMP是英文"Simple Network ...
- bzoj 4401 块的计数 思想+模拟+贪心
块的计数 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 455 Solved: 261[Submit][Status][Discuss] Descr ...
- N皇后-位运算优化
N皇后问题 时间限制: 5 Sec 内存限制: 128 MB 题目描述 魔法世界历史上曾经出现过一个伟大的罗马共和时期,出于权力平衡的目的,当时的政治理论家波利比奥斯指出:“事涉每个人的权利,绝不应 ...