韦东山_My_Uboot全解
来源:互联网 发布:剑三魏无羡捏脸数据 编辑:程序博客网 时间:2024/04/29 13:00
1、链接文件
在链接脚本里指定了起始地址->代码段->只读数据段->数据段
. = ALIIGN(4) //向4取整
SECTIONS {. = 0x33f80000;.text : { *(.text) }. = ALIGN(4);.rodata : {*(.rodata*)} . = ALIGN(4);.data : { *(.data) }. = ALIGN(4);__bss_start = .;.bss : { *(.bss) *(COMMON) }__bss_end = .;}
2、Makefile
CC = arm-linux-gccLD = arm-linux-ldAR = arm-linux-arOBJCOPY = arm-linux-objcopyOBJDUMP = arm-linux-objdumpCFLAGS := -Wall -O2CPPFLAGS := -nostdinc -nostdlib -fno-builtinobjs := start.o init.o boot.oboot.bin: $(objs) ${LD} -Tboot.lds -o boot.elf $^ ${OBJCOPY} -O binary -S boot.elf $@ ${OBJDUMP} -D -m arm boot.elf > boot.dis%.o:%.c ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<%.o:%.S ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<clean: rm -f *.o *.bin *.elf *.dis
这里说一下:
但当工程里面有自己定义的函数:例如strcpy,但是编译器里已经有了这个函数那么我们想不用编译器里的 ,在编译链里 加上
-fno-buiiltin
这里生成的反汇编:
arm-linux-objdump -D -m arm boot.elf>boot.dis
生成的反汇编文件特别有用:
我们一起来分析下重定位代码时,反汇编对我们的帮助:
重定位代码:
/* 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */ ldr sp, =0x34000000 bl nand_init mov r0, #0 ldr r1, =_start ldr r2, =__bss_start sub r2, r2, r1 bl copy_code_to_sdram bl clear_bss
这里很难看出到底拷贝了多少到SDRAM中。
那么我们通过反汇编来分析吧。
33f80050: eb000032 bl 33f80120 <nand_init>33f80054: e3a00000 mov r0, #0 ; 0x033f80058: e59f1058 ldr r1, [pc, #88] ; 33f800b8 <sdram_config+0x40>33f8005c: e59f2058 ldr r2, [pc, #88] ; 33f800bc <sdram_config+0x44>33f80060: e0422001 sub r2, r2, r133f80064: eb0000c8 bl 33f8038c <copy_code_to_sdram>33f80068: eb000021 bl 33f800f4 <clear_bss>33f8006c: e59fe04c ldr lr, [pc, #76] ; 33f800c0 <sdram_config+0x48>33f80070: e59ff04c ldr pc, [pc, #76] ; 33f800c4 <sdram_config+0x4c>
ldr r1,=_start== ldr r1,[pc,#88] ;33f800b8 sdram_config+0x40
跳到
33f800b8: 33f80000 mvnccs r0, #0 ; 0x0
33f800bc: 33f806b0 mvnccs r0, #184549376 ; 0xb000000
sub r2, r2, r133f800b8 - 33f800006b0 就是我们要拷贝的文件大小 1712四字节对齐 因为.=ALIGN(4);
看一下 清BSS段
跳到C函数中:
Void clear_bss(void){Extern int __bss_start,__bss_end;Int *p = &__bss_start;For(;p<&__bss_end;p++)*p = 0;}
看看一下反汇编:
33f80068: eb000021 bl 33f800f4 <clear_bss>33f8006c: e59fe04c ldr lr, [pc, #76] ; 33f800c0 <sdram_config+0x48>33f80070: e59ff04c ldr pc, [pc, #76] ; 33f800c4 <sdram_config+0x4c>
33f800f4 <clear_bss>:33f800f4: e59f301c ldr r3, [pc, #28] ; 33f80118 <.text+0x118>33f800f8: e59f101c ldr r1, [pc, #28] ; 33f8011c <.text+0x11c>33f800fc: e1530001 cmp r3, r133f80100: 21a0f00e movcs pc, lr33f80104: e3a02000 mov r2, #0 ; 0x033f80108: e4832004 str r2, [r3], #433f8010c: e1530001 cmp r3, r133f80110: 3afffffc bcc 33f80108 <clear_bss+0x14>33f80114: e1a0f00e mov pc, lr33f80118: 33f806b0 mvnccs r0, #184549376 ; 0xb00000033f8011c: 33f806b4 mvnccs r0, #188743680 ; 0xb400000
Disassembly of section .bss:33f806b0 <params>:33f806b0: 00000000 andeq r0, r0, r0Disassembly of section .comment:
3、START.S
.text.global _start_start:/* 1. 关看门狗 */ ldr r0, =0x53000000 mov r1, #0 str r1, [r0]
/* 2. 设置时钟 */ ldr r0, =0x4c000014 // mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1 mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8 str r1, [r0] /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */ mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */ orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */ mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */ /* MPLLCON = S3C2440_MPLL_200MHZ */ ldr r0, =0x4c000004 ldr r1, =S3C2440_MPLL_400MHZ str r1, [r0] /* 启动ICACHE */ mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #(1<<12) mcr p15, 0, r0, c1, c0, 0 @ write it back
/* 3. 初始化SDRAM */ ldr r0, =MEM_CTL_BASE adr r1, sdram_config /* sdram_config的当前地址 */ add r3, r0, #(13*4)1: ldr r2, [r1], #4 str r2, [r0], #4 cmp r0, r3 bne 1b
/* 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */ ldr sp, =0x34000000 bl nand_init mov r0, #0 ldr r1, =_start ldr r2, =__bss_start sub r2, r2, r1 bl copy_code_to_sdram bl clear_bss
/* 5. 执行main */ ldr lr, =halt ldr pc, =mainhalt: b haltsdram_config: .long 0x22011110 //BWSCON .long 0x00000700 //BANKCON0 .long 0x00000700 //BANKCON1 .long 0x00000700 //BANKCON2 .long 0x00000700 //BANKCON3 .long 0x00000700 //BANKCON4 .long 0x00000700 //BANKCON5 .long 0x00018005 //BANKCON6 .long 0x00018005 //BANKCON7 .long 0x008C04F4 // REFRESH .long 0x000000B1 //BANKSIZE .long 0x00000030 //MRSRB6 .long 0x00000030 //MRSRB7
设置栈 sp->内存 调用C函数
4、配置过程:
make 100ask23x0_config时候:
在u-boot源码中:
atstk1002_config : unconfig @./mkconfig $(@:_config=) avr32 at32ap atstk1000 atmel at32ap7000
就相当于 :
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL S3C24X0
分析: Mkconfig 脚本文件:
$0 $1 $2 $3 $4$#代表参数的个数。[$# -lt 4] $$ exit 1 小于4个[$# -gt 6] $$ exit1 大于6个OBJTREE := $(if$(BULLD_DIR),$(BUILD_DIR),$(CURDIR))是否定义:BULLD_DIRCd ./include rm -f asmLn -s asm-$2 asm #创建链接文件ln -s asm-arm asm因为源码include中有好多单板这里指定 arm架构Rm -f asm-$2/arch #rm -f asm-arm/archLn -s ${LNPRERIX}proc-armvasm-$2/proc #ln -s proc-armv asm-arm/procEcho “ARCH = $2”> config.mkEcho”CPU = $3”>>config.mkEcho”BOARD = $4”>>config.mk内容:ARCH = armCPU = arm920tBOARD = 100ask24x0SOC = s3c24x0
最后生成了 config.mk
5、UBOOT给内核传参数:
1、 帮内核设置串口: 内核启动的开始部分会从串口打印一些信息,但是内核一开始没有初始化串口
uart0_init();
2、从NAND FLASH里把内核读入内存
3、设置参数 tag
setup_start_tag();setup_memory_tags();setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");setup_end_tag();
分析下tag这个参数:
struct tag {struct tag_header hdr;union { struct tag_core core; struct tag_mem32 mem; struct tag_videotext videotext; struct tag_ramdisk ramdisk; struct tag_initrd initrd; struct tag_serialnr serialnr; struct tag_revision revision; struct tag_videolfb videolfb; struct tag_cmdline cmdline; /* * Acorn specific */ struct tag_acorn acorn; /* * DC21285 specific */ struct tag_memclk memclk;} u;};
struct tag_header { u32 size; u32 tag;};
这个结构体怎么用:
有一个关键函数:
#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
参数存放地址: 0x30000100
实现地址一直往后偏移0x30000100 + sizeof() +sizeof() +sizeof()
void setup_start_tag(void){ params = (struct tag *)0x30000100; params->hdr.tag = ATAG_CORE; params->hdr.size = tag_size (tag_core); params->u.core.flags = 0; params->u.core.pagesize = 0; params->u.core.rootdev = 0; params = tag_next (params);}
void setup_memory_tags(void){ params->hdr.tag = ATAG_MEM; params->hdr.size = tag_size (tag_mem32); params->u.mem.start = 0x30000000; params->u.mem.size = 64*1024*1024; params = tag_next (params);}
void setup_commandline_tag(char *cmdline){ int len = strlen(cmdline) + 1; params->hdr.tag = ATAG_CMDLINE; params->hdr.size = (sizeof (struct tag_header) + len + 3) >> 2; strcpy (params->u.cmdline.cmdline, cmdline); params = tag_next (params);}
void setup_end_tag(void){ params->hdr.tag = ATAG_NONE; params->hdr.size = 0;}
4、跳转执行
void (*theKernel)(int zero, int arch, unsigned int params);volatile unsigned int *p = (volatile unsigned int *)0x30008000;theKernel = (void (*)(int, int, unsigned int))0x30008000;theKernel(0, 362, 0x30000100);
这样 内核就启动了 uboot就一去不复返了。
- 韦东山_My_Uboot全解
- 韦东山视频 笔记
- 韦东山视频观后感
- 韦东山视频
- 韦东山嵌入式Linux
- 韦东山学习笔记
- 韦东山-wifi驱动
- 关于韦东山MMU实验
- 关于韦东山MMU实验
- 韦东山USB驱动笔记
- 韦东山百度云主页
- 韦东山第12.5课
- 韦东山--关于嵌入式学习
- 徐东山:腾讯云安全的使命和技术实现
- Poll机制分析(转韦东山)
- poll机制分析(韦东山)
- 缺少libc.a文件 韦东山
- poll机制分析(韦东山)
- Lightmap Directional Modes
- 对于内存监视器中每个参数含义解释
- C++ BFS求最短步数
- OpenSNS+内容付费,搭建社交型知识付费平台
- PHP本地运行环境搭建——phpStudy(Mysql和Apache本地已有)
- 韦东山_My_Uboot全解
- Android Studio:服务与多线程--简单音乐播放器
- Monster类
- CentOS6和CentOS7挂载本地misc实现yum源配置
- SpringMVC执行原理
- memcache集群方案
- 【JZOJ5489】海明距离
- MATLAB中批量从txt文件中读取指定行的数据保存为txt文件
- 进程编程控制