mini-uboot 启动过程简单分析

单片机有最小系统,所谓最小系统,就是单片机能正常工作所需要的最少外设。对于Uboot来说,同样有个最小系统,因为Uboot最主要的功能就是引导内核。下面我们通过一个简单的Mini-Uboot来分析Uboot的启动加载过程。(只是分析过程,此Uboot具有引导内核功能)

注:这个uboot 只是具有基本的内核引导功能,只是作为前期简单的学习使用,入门而已,并不是正常的uboot 启动流程

       具体uboot (u-boot-2013.01)启动过程移步Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析

 

下面是mini-uboot 的根目录树状图:

     我们拿到一个工程,想了解它的功能,最方便的就是读它的makefile。

一、Makefile

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. sinclude include/config.mk  
  2.   
  3. #ARCH=arm  
  4. #CPU=arm920t  
  5. #VENDOR=samsung  
  6. #SOC=s3c2410  
  7. #BOARD=smdk2410  
  8.   
  9. SRC_TREE:=$(shell pwd)  
  10. MKCONFIG=$(SRC_TREE)/mkconfig    
  11.   
  12. INCLUDE_PATH=include  
  13. DRIVER_PATH=driver  
  14. LIB_DIR=lib  
  15.   
  16.   
  17. CFLAG=-mabi=apcs-gnu -fno-builtin  -fno-builtin-function -g -O0 -c  -I$(INCLUDE_PATH) -I$(DRIVER_PATH) -o   
  18. LDFLAG=-Tcpu/arm/arm_cortexa8/map.lds  -o  
  19. OBJS= cpu/$(ARCH)/$(CPU)/start.o  
  20. OBJS+=lib_arm/board.o  
  21. OBJS+=board/$(VENDOR)/$(BOARD)/lowlevel_init.o  
  22. OBJS+=board/$(VENDOR)/$(BOARD)/mem_setup.o  
  23. OBJS+=board/$(VENDOR)/$(BOARD)/nand.o  
  24. OBJS+=driver/uart.o  
  25. OBJS+=lib/string.o  
  26. OBJS+=common/do_go.o  
  27. OBJS+=common/main.o  
  28.   
  29. ifeq ($(ARCH), arm)   
  30. CROSS_COMPILE=arm-cortex_a8-linux-gnueabi-  
  31. endif  
  32.   
  33. PROJ_NAME=mini_uboot  
  34.       
  35. all: $(OBJS)   
  36.     $(CROSS_COMPILE)ld $(OBJS) $(LDFLAG) $(PROJ_NAME).elf                
  37.     $(CROSS_COMPILE)objcopy -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin   
  38.     $(CROSS_COMPILE)objdump -D $(PROJ_NAME).elf  > $(PROJ_NAME).dis  
  39.     cp *.bin /tftpboot  
  40.   
  41. %.o: %.S  
  42.     $(CROSS_COMPILE)gcc $(CFLAG) $@ $<       
  43. %.o: %.s  
  44.     $(CROSS_COMPILE)gcc $(CFLAG) $@ $<       
  45.   
  46. %.o: %.c  
  47.     $(CROSS_COMPILE)gcc $(CFLAG) $@ $<       
  48.   
  49. fsc100_config:          #    ARCH  CPU       VENDOR   BOARD  SOC  
  50.     $(MKCONFIG) $(@:_config=) arm arm_cortexa8 samsung fsc100 s5pc100  
  51.     #mkconfig  fsc100 arm arm_cortexa8 samsung fsc100 s5pc100  
  52.   
  53. smdk2410_config:            #    ARCH  CPU       VENDOR   BOARD  SOC  
  54.     $(MKCONFIG) $(@:_config=) arm arm920t samsung smdk2410 s3c2410  
  55.   
  56. clean:  
  57.     @rm -rf $(OBJS) *.bin *.elf config.mk  

这里以2440为例,咱们来分析:

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. #ARCH=arm  
  2. #CPU=arm920t  
  3. #VENDOR=samsung  
  4. #SOC=s3c2410  
  5. #BOARD=smdk2410  

架构为arm,CPU为arm920t,生产商 samsung,片上系统sc2410,板子为smdk2410。

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. OBJS= cpu/$(ARCH)/$(CPU)/start.o  
  2. OBJS+=lib_arm/board.o  
  3. OBJS+=board/$(VENDOR)/$(BOARD)/lowlevel_init.o  
  4. OBJS+=board/$(VENDOR)/$(BOARD)/mem_setup.o  
  5. OBJS+=board/$(VENDOR)/$(BOARD)/nand.o  
  6. OBJS+=driver/uart.o  
  7. OBJS+=lib/string.o  
  8. OBJS+=common/do_go.o  
  9. OBJS+=common/main.o  

OBJS为依赖文件,生成的.o文件。

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. ifeq ($(ARCH), arm)   
  2. CROSS_COMPILE=arm-cortex_a8-linux-gnueabi-  
  3. endif  

根据相应的架构,制作相应的交叉编译工具。

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. all: $(OBJS)   
  2.     $(CROSS_COMPILE)ld $(OBJS) $(LDFLAG) $(PROJ_NAME).elf                
  3.     $(CROSS_COMPILE)objcopy -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin   
  4.     $(CROSS_COMPILE)objdump -D $(PROJ_NAME).elf  > $(PROJ_NAME).dis  

第一步:连接 ;第二步:格式转换;第三步:反汇编 " >" 为重定向的意思;

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. %.o: %.S  
  2.     $(CROSS_COMPILE)gcc $(CFLAG) $@ $<       
  3. %.o: %.s  
  4.     $(CROSS_COMPILE)gcc $(CFLAG) $@ $<       
  5.   
  6. %.o: %.c  
  7.     $(CROSS_COMPILE)gcc $(CFLAG) $@ $<       

将所有的.S 文件、.s文件、.c文件编译成.o文件。

注意:.S文件可以在编译过程接受参数,.s文件不可以。

 

二、链接文件

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
  1. OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")  
  2. /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/  
  3. OUTPUT_ARCH(arm)  
  4. ENTRY(_start)  //指定入口地址  
  5. SECTIONS    //段信息  
  6. {  
  7.     /* . */   
  8.     . = 0x22000000; //elf文件的入口地址  
  9.     . = ALIGN(4);   //指定四字节对齐  
  10.     .text      :    //代码段  
  11.     {  
  12.         cpu/arm/arm_cortexa8/start.o(.text) //确保执行的第一段代码是start.o  
  13.         *(.text)        //所有代码段融合在一起  
  14.     }  
  15.     . = ALIGN(4);  
  16.     .rodata :   //只读数据段  
  17.     { *(.rodata) }  //所有数据段  
  18.     . = ALIGN(4);  
  19.     .data :     //数据段  
  20.     { *(.data) }  
  21.     . = ALIGN(4);  
  22.   
  23.     _start_bss = .; //bss段开始地址  
  24.     .bss :  
  25.      { *(.bss) }  
  26.     _end_bss = .;       //bss段结束地址,两者可确定bss段大小  
  27. }  


三、start.s文件(Uboot执行的第一个文件)

[cpp]  view plain  copy
 在CODE上查看代码片派生到我的代码片
    1. @ 汇编中的宏  
    2. .equ USER_MODE, 0x10    @define USER_MODE 0x10  
    3. .equ IRQ_MODE,  0x12  
    4. .equ SVC_MODE,  0x13  
    5. .equ MODE_MASK, 0x1f  
    6.   
    7. .section .text  
    8. .global _start  
    9.   
    10.     @ 不支持异常处理的,这里只写了复位异常处理  
    11. _start:  
    12. vector:  
    13.     b  reset_handler  
    14.     nop     @undef ......  
    15.     nop  
    16.     nop  
    17.     nop  
    18.     nop  
    19.     nop  
    20.     nop  
    21.   
    22. reset_handler:  
    23.     @step 1: svc close irq fiq      //第一步:将运行模式改成SVC模式    
    24.     mrs r0, cpsr            //修改cpsr模式位  
    25.     bic r0, r0, #0x1f  
    26.     orr r0, r0, #0xc0  @IRQ FIQ     //关闭IRQ FIQ  
    27.     msr cpsr_c, r0  
    28.   
    29.     @step 2: cache 关闭I CACHE D CACHE    //第二步:关闭cache,直接运行,不需缓存  
    30.     mrc p15, 0, r0, c12, c0, 0  
    31.     bic r0, #0x1000  
    32.     bic r0, #0x2  
    33.     mcr p15, 0, r0, c12, c0, 0  
    34.       
    35.     @step 3:                //第三步:调用电路板级初始化程序, system clock , dram, watchdog  
    36.     @bl low_level_init      //初始化时钟、dram、关闭看门狗  
    37.   
    38.     @step 4: sp-> 0x30000000     //第四步:设置栈指针,使其指向一个地址即可  
    39.     ldr sp, =0x2e000000  
    40.   
    41.     @step 5: mini_uboot.bin  > 16KB   bin < 16KB   
    42.     @step 5 代码自搬移  
    43.     @copy_miniuboot_rto_sdram 如果你的代码大于了16KB代码需要实现自我搬移  
    44.   
    45.     @step 6:                //第六步:清除BSS段,BSS段大小由链接文件里确定   
    46.     @STEP 6.1 , 清除 BSS段  
    47.     @  
    48. clear_bss:  
    49.     ldr r0, =_start_bss   @| BSS 起始地址  
    50.     ldr r1, =_end_bss     @| BSS 终止地址  
    51.     mov r2, #0  
    52. bss_loop:  
    53.     cmp r0, r1  
    54.     strne r2, [r0], #4  
    55.     bne bss_loop  
    56.   
    57.     @step  7, 进入C           //跳转到C程序入口  
    58.     b start_armboot  
    59. stop:  
    60.     b stop  
    61.   
    62.     .end  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值