单片机有最小系统,Uboot同样也有, mini-uboot 启动过程简单分析

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


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



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





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


一、Makefile


[cpp] view plain copy

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

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

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

1. ifeq ($(ARCH), arm)

2. CROSS_COMPILE=arm-cortex_a8-linux-gnueabi-

3. endif



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

[cpp] view plain copy

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

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

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

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

...全文
156 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

27,370

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧