mini-uboot 启动过程简单分析

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

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

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


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

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

一、Makefile

[cpp] view plaincopy
在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 plaincopy
在CODE上查看代码片派生到我的代码片
  1. #ARCH=arm  
  2. #CPU=arm920t  
  3. #VENDOR=samsung  
  4. #SOC=s3c2410  
  5. #BOARD=smdk2410  

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

[cpp] view plaincopy
在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 plaincopy
在CODE上查看代码片派生到我的代码片
  1. ifeq ($(ARCH), arm)   
  2. CROSS_COMPILE=arm-cortex_a8-linux-gnueabi-  
  3. endif  

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

[cpp] view plaincopy
在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 plaincopy
在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 plaincopy
在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 plaincopy
在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  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402063.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySql中的varchar类型

2019独角兽企业重金招聘Python工程师标准>>> MySql中的varchar类型&#xff08;转&#xff09; 今天新开始的项目在做数据库设计&#xff0c;发现自己对MySql的varchar类型还不熟悉&#xff0c;故又上网收集资料整理如下。 1.varchar类型的变化 MySQL 数据库的va…

进入保护模式(三)内存的分页

2019独角兽企业重金招聘Python工程师标准>>> 一、分页 先入为主理解的分页和系统中内存内应的分页 1.弄过数据库数据查找展示&#xff0c;有个数据分页展示的概念&#xff0c;这个的目的是为了速度、和展示效果上的提升 2.内存的分页又是怎么回事哪&#xff1f; …

C#实现简单的 Ping 的功能,用于测试网络是否已经联通

1 /// <summary>2 /// 是否能 Ping 通指定的主机3 /// </summary>4 /// <param name"ip">ip 地址或主机名或域名</param>5 /// <returns>true 通&#xff0c;false 不通</returns>6 …

Binutils工具集 解析

对于嵌入式系统开发&#xff0c;掌握相应的工具至关重要&#xff0c;它能使我们解决问题的效率大大提高。目前&#xff0c;可以说嵌入式系统的开发工具是GNU的天下&#xff0c;因为来自GNU的GCC编译器支持大量的目标处理器。除了GCC&#xff0c;还有一个非常重要的、同样来自于…

ARM 软中断指令SWI

前面我们学习ARM工作模式中&#xff0c;处理器模式切换可以通过软件控制进行切换&#xff0c;即修改CPSR模式位&#xff0c;但这是在特权模式下&#xff0c;当我们处于用户模式下&#xff0c;是没有权限实现模式转换的。若想实现模式切换&#xff0c;只能由另一种方法来实现&am…

yum install 失败

https://blog.csdn.net/weixin_45621658/article/details/110734514 原因&#xff1a;centos6的默认源在2012年-12月左右被官方搞掉了 下列是错误详情 Bash [rootc8-20 ~]# yum makecache Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile YumRepo …

sphinx

2019独角兽企业重金招聘Python工程师标准>>> ./configure --prefix/usr/local/sphinx --with-mysql/usr/local/mysql make && make install cd /usr/local/sphinx/etc cp sphinx.conf.dist sphinx.conf vim sphinx.conf mysql -u test < /usr/local/sphi…

Exynos4412裸机开发综合练习

下面是一个案例需求&#xff1a; 1、编写一段程序,该程序的主要功能是监控电路板上的电压值,若电压值超过当前的电压限制则通过蜂鸣器报警,通过按键解除报警; 2、其具体要求如下; a) 程序下载20s后,进入电压采集状态(使用RTC ALARM功能完成), 要求1s采集1次电路板电压值;(采用…

Exynos4412 裸机开发 —— IIC总线

前言&#xff1a; I2C(Inter-Integrated Circuit)总线(也称 IIC 或 I2C) 是有PHILIPS公司开发的两线式串行总线&#xff0c;用于连接微控制器及外围设备&#xff0c;是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式&#xff0c;具有接口线少、控制方式…

Exynos4412裸机开发 —— A/D转换器

一、Exynos4412 A/D转换器概述 1、简述 10位或12位CMOS再循环式模拟数字转换器&#xff0c;它具有10通道输入&#xff0c;并可将模拟量转换至10位或12位二进制数。5Mhz A/D 转换时钟时&#xff0c;最大1Msps的转换速度。A/D转换具备片上采样保持功能&#xff0c;同时也支持待机…

Exynos4412裸机开发 —— UART

一、Exynos4412 UART 的特性 Exynos4412 中UART&#xff0c;有4 个独立的通道&#xff0c;每个通道都可以工作于中断模式或DMA 模式&#xff0c;即 UART 可以发出中断或 DMA 请求以便在UART 、CPU 间传输数据。UART 由波特率发生器、发送器、接收器和控制逻辑组成。 使用系统时…

Exynos4412裸机开发 —— 看门狗定时器

一、看门狗定时器概述 看门狗&#xff08;WatchDog Timer) 定时器和PWM的定时功能目的不一样。它的特点是&#xff0c;需要不同的接收信号&#xff08;一些外置看门狗芯片&#xff09;或重新设置计数器&#xff0c;保持计数值不为0。一旦一些时间接收不到信号&#xff0c;或计数…

Exynos4412裸机开发 —— RTC 实时时钟单元

RTC(Real-Time Clock) 实时时钟。RTC是集成电路&#xff0c;通常称为时钟芯片。在一个嵌入式系统中&#xff0c;通常采用RTC来提供可靠的系统时间&#xff0c;包括时分秒和年月日等&#xff0c;而且要求在系统处于关机状态下它也能正常工作&#xff08;通常采用后备电池供电&am…

Exynos4412裸机开发——中断处理

以KEY2控制LED3亮灭为例&#xff1a; 一、轮询方式 【0】检测按键k2&#xff0c;按键k2按下一次&#xff0c;灯LED2闪一次。 【1】查看原理图&#xff0c;连接引脚和控制逻辑 &#xff08;1&#xff09;按键k2 连接在GPX1_1引脚 &#xff08;2&#xff09;控制逻辑 k2 按…

远程WEB控制MP3播放器设计(基于mini2440)

网上有很多 基于mini2440的MP3播放器设计的资料&#xff0c;多是按键控制&#xff0c;这里博主做了些轻微改动&#xff0c;利用远程WEB来控制MP3播放&#xff0c;具体怎么实现&#xff0c;下面会给出&#xff0c;大家先看看效果&#xff1a; WEB界面&#xff1a; 后台运行&…

嵌入式数据库 SQLite 浅析

SQLite是一个非常轻量级自包含(lightweight and self-contained)的DBMS&#xff0c;它可移植性好&#xff0c;很容易使用&#xff0c;很小&#xff0c;高效而且可靠。SQLite嵌入到使用它的应用程序中&#xff0c;它们共用相同的进程空间&#xff0c;而不是单独的一个进程。从外…

socket 请求Web服务器过程

HTTP协议只是一个应用层协议&#xff0c;它底层是通过TCP进行传输数据的。因此&#xff0c;浏览器访问Web服务器的过程必须先有“连接建立”的发生。 而有人或许会问&#xff1a;众所周知&#xff0c;HTTP协议有两大特性&#xff0c;一个是“无连接”性&#xff0c;一个是“无状…

有些事情现在不做一辈子就都不会做了

这句话最近一直印在我的脑海里。这句话最早是在Casperkid的百度空间里面看见的&#xff0c;那时他生日。作为师傅的刺&#xff08;道哥&#xff09;送了他自己写的一本《白帽子讲WEB安全》给他&#xff0c;并在扉页上写着这句话。那时一看到这句话&#xff0c;仿佛有种触电的感…

HTTP 数据包头解析

一、连接至Web服务器 一个客户端应用&#xff08;如Web浏览器&#xff09;打开到Web服务器的HTTP端口的一个套接字&#xff08;缺省为80&#xff09;。 例如&#xff1a;http://www.myweb.com:8080/index.html 在Java中&#xff0c;这将等同于代码&#xff1a; [java] view pla…

Shell 脚本中如何使用make命令

最近开发的项目中需要编写Shell脚本对整个工程进行自动化编译&#xff0c;即在Shell脚本中使用make命令来进行编译&#xff0c;下面回顾一下Shell脚本中如何使用make命令&#xff09; 在开发一个系统时&#xff0c;一般是将一个系统分成几个模块&#xff0c;这样做提高了系统的…