Uboot代码结构详细分析

1. Bootloader功能分析

  • Bootloader(如Uboot、Redboot、Blob、vivi等)直接和CPU、外围硬件设备(存储器、网卡、LCD等)打交道,负责初始化硬件设备,以及负责拉起内核:建立内存空间映射图,为内核的启动运行做好一切准备,最后将Linux内核代码加载到RAM中运行。

  • 一般来说,bootload都会提供两种操作模式:

    • 正常启动模式:无需开发者和用户干涉,上电后自动开始运行,完成启动内核的任务;
    • 下载模式(开发者模式):需要用户干预,进入下载模式,使用uboot命令进行操作;
  • BootLoader程序是分级载入机制,通常分为 stage1 和 stage2 两大部分。

    • Stage1:
      BootLoader 的 stage1 依赖于CPU体系结构的代码,例如CPU相关初始化代码等, 通常都用汇编语言来实现,达到高效操作的目的。 包括以下步骤:

      • ①硬件设备初始化
        • 屏蔽所有的中断
        • 设置CPU的速度和时钟频率
        • 设置内存控制器
        • 关闭 CPU 内部指令/数据 cache
      • ②为加载 stage2 准备 RAM 空间
      • ③拷贝 stage2 到 RAM 空间中
      • ④设置好堆栈指针sp,为执行 C 语言代码作好准备;
      • ⑤跳转到 stage2 阶段的C程序入口处。
    • Stage2:

      BootLoader 的 stage2 通常用C语言来实现,可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。 包括以下步骤:

      • ①初始化本阶段要使用到的硬件设备;
        • 串口设备:以便输出信息
          ……
        • ②检测系统内存映射(memory map):准备识别在整个 4GB 物理地址空间中有哪些地址范围被分配用来寻址系统的 RAM单元;
        • ③将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中;
        • ④为内核设置启动参数;
        • ⑤调用内核:跳至内核代码入口开始执行。

2. Uboot代码结构分析

开发环境:我使用的是JZ2440开发板,处理器是三星的S3C2440,CPU是ARM920T。

开发目标:修改Uboot源代码,使之适配我的S3C2440处理器。

开发方法:1、因为Uboot默认不支持S3C2440处理器,所以先研究Uboot支持的且与S3C2440相近的S3C2410的启动过程源代码,了解自己需要修改哪些文件。

image-20210608205901907

首先,请看smdk2410的启动过程思维导图:

image-20210610214239064

2.1 一看配置文件smdk2410.h

在查看uboot源码的时候,很多配置项都取决于单板配置文件中的宏定义,比如smdk2410这个单板的配置文件是include\configs\smdk2410.h文件,在查看源码时,可以在此文件中查看宏定义是否存在。

2.2 二看链接文件u-boot.ds

可以看到,0地址处存放的是arch/arm/cpu/arm920t/start.S文件编译产生的obj文件。

image-20210608221938498

2.3 三看启动文件start.S

打开arch/arm/cpu/arm920t/start.S

.globl _start                      // .globl定义一个全局符号"_start",表明_start这个符号要被链接器用到 
_start:                            //_start:系统复位设置,以下共8种不同的异常处理
b	   start_code                  //系统启动即跳转到start_code处执行
ldr    pc, _undefined_instruction                 //未定义的指令异常 0x4
ldr    pc, _software_interrupt                 // 软件中断异常 0x8 
ldr    pc, _prefetch_abort                 //内存操作异常 0xc
ldr    pc, _data_abort                 //数据异常 0x10
ldr    pc, _not_used                 //未使用 0x14
ldr    pc, _irq                   //中断IRQ异常 0x18
ldr    pc, _fiq                 //快速中断FIQ异常 0x1c

_undefined_instruction:    .word undefined_instruction                 //0x20
_software_interrupt:    .word software_interrupt                       //0x24
_prefetch_abort:    .word prefetch_abort             // 0x28
_data_abort:    .word data_abort                     //0x2c
_not_used:    .word not_used                        //0x30
_irq:    .word irq                                  //0x34
_fiq:    .word fiq                                  //0x38

.balignl 16,0xdeadbeef                              //0x3c

在第1行中".globl _start":使用.globol声明全局符号_start,在 board/100ask24x0/u-boot.lds中ENTRY(_start)这里用到。其中符号保存的地址都在顶层目录/system.map中列出来了

system.map文件开头部分如下:

33f80000 t $a 
33f80000 T _start                   //_start符号被链接在33f80000,其中33f80000是生成bin文件的运行启始地址.
33f80020 t $d 
33f80020 t _undefined_instruction   //_undefined_instruction符号被链接在33f80020
...
33f80160 t undefined_instruction //_undefined_instruction指向的undefined_instruction符号被链接在33f80160
33f801c0 t software_interrupt
33f80220 t prefetch_abort
33f80280 t data_abort
33f802e0 t not_used
33f80340 T Launch
33f803b0 t On_Steppingstone
33f80400 t irq
...

在第2行中_start之所以有8种不同的异常处理,是在2440芯片手册已经规定好了的,如下图1:

img

从上图可以看出复位异常处理需要进入管理模式(0X00000000),所以start.S 中b start_code也可以写作b reset,都是跳转到start_code处执行,即设置CPU进入管理模式后进行核级初始化。

在linux中的异常向量地址是经过MMU(虚拟内存管理)产生的虚拟地址,比如中断地址:0x18映射到物理地址是0xc000 0018(映射地址由自己设定),所以linux把中断向量放在0xc000 0018就行了。

CPU一上电设置了入口地址"ENTRY(_start)“后,就会进入”_start"全局符号中执行上面第3行跳转到复位异常字段: b reseb start_code

1. 后面的异常处理为什么用ldr不用b指令?

之所以第一句使用b reset,是因为ldr指令属于绝对跳转,而b属于相对跳转,它的地址与代码位置无关。因为复位异常在CPU运行前是没有初始化SDRAM的(不能使用0X30000000以上地址)。

在正常工作后也可能触发复位,这时由于CPU已经对SDRAM、MMU(虚拟内存管理)等初始化了,此时的虚拟地址和物理地址完全不同,所以reset使用b指令相对跳转。

2. 后面的异常处理是怎么执行的?执行后异常处理又怎么退出?

(1)在2440芯片手册上给出,例如当处理一个中断IRQ异常时:

  • a. 保存当前PC现场(返回地址)到寄存器R14;
  • b. 把当前程序状态寄存器(CPSR)保存到备份程序状态寄存器(SPSR)中,从异常退出的时候,就可以由SPSR来恢复CPSR;
  • c. 根据中断IRQ异常处理,强制将 CPSR 模式位设为中断模式,如下图:img
  • d. 强制 PC 执行相关异常向量处的语句(跳转到中断异常处理函数处)。

(2)当退出中断IRQ异常时:**

  • a. 将中断IRQ所对应的R14_irq寄存器中的返回地址减4(PC总指向当前执行语句的下两条语句地址)得到被中断语句的下条地址放入到 PC 中。

img

  • b. 复制 SPSR 的内容给 CPSR 中。
  • c. 如果在异常进入时置位了中断禁止标志位异常,则清除中断禁止标志位。

3. 第12行中的.word类似于(unsigend long)

以第12行中 _undefined_instruction: .word undefined_instruction为例讲解:
_undefined_instructionundefined_instruction都是一个标号
,表示_undefined_instruction指向一个32位(4字节)地址,该地址用undefined_instruction符号变量代替。

用C语言表示就是: _undefined_instruction = &undefined_instruction

相当于PC从_undefined_instruction取值时将符号变量undefined_instruction的地址存到了PC中。

4. 第20行中 .balignl 16,0xdeadbeef:

它的意思就是在以当前地址开始,在地址为16的倍数的指令位置的上一个指令填入0xdeadbeef的内容。
此时当前地址刚好0x3c=60,由于ARM每个指令间隔4个字节,且64%16=0,所以在0x3c中填入0xdeadbeef。
它们的作用就是为内存做标记插在那里,表示以此为界,往前有特殊作用的内存,禁止用户访问。

接下来继续往下看start.s

/*
*实际启动代码
*/

start_code: 
/* 1、设置CPU为管理模式(SVC32 mode)*/                           
  mrs    r0,cpsr                   //MRS读出CPSR寄存器值到R0
  bic    r0,r0,#0x1f               //将R0低5位清空
  orr    r0,r0,#0xd3               //R0与b'110 10011按位或,禁止IRQ和FIQ中断,10011:复位需要设为管理模式
  msr    cpsr,r0                   //MSR写入CPSR寄存器

	/* S3C2410的内核是ARM920T,这段代码用不到 */
#if	defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
	/*
	 * relocate exception table
	 */
	ldr	r0, =_start
	ldr	r1, =0x0
	mov	r2, #16
copyex:
	subs	r2, r2, #1
	ldr	r3, [r0], #4
	str	r3, [r1], #4
	bne	copyex
#endif

#ifdef CONFIG_S3C24X0
	/* turn off the watchdog */
	/* 2、关看门狗 */
	//经过查看S3C2410/S3C2440数据手册,寄存器地址一致,不用修改

# if defined(CONFIG_S3C2400)
	#define pWTCON	0x15300000
	#define INTMSK	0x14400008	/* Interrupt-Controller base addresses */
	#define CLKDIVN	0x14800014	/* clock divisor register */
#else
	#define pWTCON     0x53000000  //看门狗定时器寄存器(0表示关闭看门狗)
	#define INTMOD     0X4A000004  //(中断模式寄存器(0:IRQ模式,1:FRQ模式)
	#define INTMSK		0x4A000008	//中断屏蔽寄存器(0:开启中断服务,1:关闭中断服务)
	#define INTSUBMSK	0x4A00001C  //中断次级屏蔽寄存器(0:开启中断服务,1:关闭中断服务)
	#define CLKDIVN    0x4C000014  //时钟分频寄存器
#endif
      
/* 关看门狗 */
ldr     r0, =pWTCON                        //R0等于WTCON地址
mov     r1, #0x0                           //R1=0x0
str     r1, [r0]                           //关闭WTCON寄存器,pWTCON=0;

/* 3、关掉所有中断   */  
    mov    r1, #0xffffffff                     //R1=0XFFFFFFFF
    ldr    r0, =INTMSK                         //R0等于INTMSK地址
    str    r1, [r0]                            //*0x4A000008=0XFFFF FFFF(关闭所有中断)

# if defined(CONFIG_S3C2410)
    ldr    r1, =0x3ff                            //R1=0x3FF
    ldr    r0, =INTSUBMSK                        //R0等于INTSUBMSK地址
    str    r1, [r0]                              //*0x4A00001C=0x3FF(关闭次级所有中断)
# endif

	/* 4. 设置系统时钟分频系数 */
	/* FCLK:HCLK:PCLK = 1:2:4 */
	/* default FCLK is 120 MHz ! */
	ldr	r0, =CLKDIVN
	mov	r1, #3
	str	r1, [r0]


	/*
	 * we do sys-critical inits only at reboot,
	 * not when booting from ram!
	 * 5. CPU内部初始化
	 *判断系统是从nand启动还是直接将程序下载到SDRAM中运行,若系统从nand启动,这里得到r0和r1值
	 *是不一样的,r1=0x33f80000,而r0=0x00000000。说明没初始化SDRAM,ne(no equal)标识符为
	 *真,所以bl cpu_init_crit执行跳转.
	 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
  adr    r0, _start     
  ldr    r1, _TEXT_BASE     
  cmp     r0, r1               
  blne    cpu_init_crit
#endif

/* Set stackpointer in internal RAM to call board_init_f */
/* 6. 设置好栈顶指针sp = 0x30000f80,然后调用C程序中的board_init_f 函数 */
call_board_init_f:
	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
	bic	sp, sp, #7 /* 8-byte alignment for ABI compliance */
	ldr	r0,=0x00000000
	bl	board_init_f


  • CPU复位后从这里开始执行bootloader的 stage1 阶段,这里初始化了:
    • 1.设置CPU为管理模式:SVC32
    • 2.关看门狗
    • 3.屏蔽所有中断
    • 4.设置系统时钟分频系数
    • 5.CPU内部(核级)初始化(进入cpu_init_crit函数关闭MMU,进入lowlevel_init初始化13个BANK寄存器来初始化SDRAM)
    • 6.设置好栈顶指针sp,调用C程序中的board_init_f 函数。

2.4 四看CPU核级初始化文件cpu_init_crit函数

  • cpu_init_crit函数的主要功能是:
    • 设置CPU中重要的寄存器
    • 设置内存控制器时序

2.4.1 设置CPU中的寄存器

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    cpu_init_crit:
	/*
	 *flush v4 I/D caches
	 */
    mov    r0, #0
    //关闭ICaches(指令缓存,关闭是为了降低MMU查表带来的开销)和DCaches(数据缓存,DCaches使用的是虚拟地址,开启MMU之前必须关闭)
    mcr    p15, 0, r0, c7, c7, 0
    //使无效整个数据和指令TLB(TLB就是负责将虚拟内存地址翻译成实际的物理内存地址)
    mcr    p15, 0, r0, c8, c7, 0
	
    /*
	 * disable MMU stuff and caches
	 */
    mrc    p15, 0, r0, c1, c0, 0
        
    //bit8:系统不保护,bit9:ROM不保护,bit13:设置正常异常模式0x0~0x1c,即异常模式基地址为0X0
    bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
        
    //bit0~2:禁止MMU,禁止地址对齐检查,禁止数据Cache.bit7:设为小端模式
    bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM) 
    orr    r0, r0, #0x00000002    @ bit2:开启地址对齐
    orr    r0, r0, #0x00001000    @ bit12:开启ICache
    mcr    p15, 0, r0, c1, c0, 0
    /*
    *Caches:是一种高速缓存存储器,用于保存CPU频繁使用的数据。在使用Cache技术的处理器上,当一条
    *指令要访问内存的数据时,首先查询cache缓存中是否有数据以及数据是否过期,如果数未过期则从
    *cache读出数据。处理器会定期回写cache中的数据到内存。根据程序的局部性原理,使用cache后可以
    *大大加快处理器访问内存数据的速度。其中DCaches和ICaches分别用来存放数据和执行这些数据的指令。
    *TLB:就是负责将虚拟内存地址翻译成实际的物理内存地址,TLB中存放了一些页表文件,文件中记录了虚
    *拟地址和物理地址的映射关系。当应用程序访问一个虚拟地址的时候,会从TLB中查询出对应的物理地址,
    *然后访问物理地址。TLB通常是一个分层结构,使用与Cache类似的原理。处理器使用一定的算法把最常用
    *的转换表放在最先访问的层次。这里禁用MMU,是方便后面直接使用物理地址来设置控制寄存。
    */
        
    /*
	 * before relocating, we have to setup RAM timing
	 * because memory timing is board-dependend, you will
	 * find a lowlevel_init.S in your board directory.
	 */
    mov    ip, lr 		//临时保存当前子程序返回地址,因为接下来执行bl会覆盖当前返回地址.
    bl    lowlevel_init //跳转到lowlevel_init(/board/samsung/smdk2410/lowlevel_init.S)
    mov    lr, ip 		//恢复当前返回地址
    mov    pc, lr 		//退出
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

2.4.2 调用lowlevel_init函数 设置内存控制器

每个单板的内存控制器设置代码都是不一样的,所以 lowlevel_init 函数放在了单板目录中的lowlevel_init.S文件中,即 board\samsung\smdk2410\lowlevel_init.S

_TEXT_BASE:
	.word	CONFIG_SYS_TEXT_BASE

.globl lowlevel_init
lowlevel_init:
	/* memory control configuration */
	/* make r0 relative the current location so that it */
	/* reads SMRDATA out of FLASH rather than memory ! */

    ldr r0, =SMRDATA 	//将SMRDATA的首地址(0x33F806C8)存到r0中 
    ldr r1, _TEXT_BASE 	//r1等于_TEXT_BASE内容,也就是TEXT_BASE(0x33F80000)
    sub    r0, r0, r1 	//将0x33F806C8与0x33F80000相减,得到现在13个寄存器值在NOR Flash上存放的开始地址
    ldr    r1, =BWSCON 	//将BWSCON寄存器地址值存到r1中 (第一个存储器寄存器首地址)
    add r2, r0, #13*4 	//每个寄存器4字节,r2=r0+13*4=NOR Flash上13个寄存器值最后一个地址
0: 
    ldr r3, [r0], #4 	//将r0的内容存到r3的内容中(r3等于SMRDATA里面值), 同时r0地址+=4;
    str r3, [r1], #4 	//将r3的内容存到r1所指的地址中(向寄存器地址里写入r3值),同时r1地址+=4;
    cmp r2, r0 			// 判断r2和r0
    bne 0b 				//不等则跳转到第6行继续执行

    mov pc, lr 			//跳回到返回地址中继续执行

SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(
B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) //设置每个BWSCON,注意BANK0由硬件连线决定了
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
//设置BANKCON0~BANKCON5 
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    
//设置BANKCON6~BANKCON7
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    
//设置REFRESH,在S3C2440中11~17位是保留的,也即(Tchr<<16)无意义
.word 0xb1 //设置BANKSIZE,对于容量可以设置大些,多出来的空内存会被自动检测出来
.word 0x30 //设置MRSRB6
.word 0x30 //设置MRSRB7

2.5 五看CPU板级初始化文件board_init_f函数

该函数在arch/arm/lib/board.c中定义:

2.5.1 gd指针

/* Pointer is writable since we allocated a register for it */
	gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);

gd指针变量是一个寄存器变量,在arch/arm/include/asm/global_data.h文件中定义:#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")。这个宏定义将gd定义为一个指向gd_t类型的寄存器变量(优势:读写效率高),并将这个寄存器指定为CPU寄存器组中的r8寄存器。

那么,gd变量指向内存中的哪个地址呢?

在stage1阶段跳转到 board_init_f 函数之前,使用汇编指令将 sp 设置为CONFIG_SYS_INIT_SP_ADDR,通过直接查看反汇编代码,得到该值为0x30000f80。

接下来具体研究一下CONFIG_SYS_INIT_SP_ADDR是如何计算出来的,在include/configs/smdk2410.h文件中可以看到计算公式:

/* additions for new relocation code, must be added to all boards */
//为了新的重定位代码添加
#define CONFIG_SYS_SDRAM_BASE	PHYS_SDRAM_1
#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)

同样在该配置文件中,定义了 PHYS_SDRAM_1 的大小:

 * Physical Memory Map
   */
   #define CONFIG_NR_DRAM_BANKS	1          /* we have 1 bank of DRAM */
   #define PHYS_SDRAM_1		0x30000000 /* SDRAM Bank #1 */
   #define PHYS_SDRAM_1_SIZE	0x04000000 /* 64 MB */

#define PHYS_FLASH_1		0x00000000 /* Flash Bank #0 */

#define CONFIG_SYS_FLASH_BASE	PHYS_FLASH_1

2.5.2 执行init_sequence(初始化序列)中的所有函数

接下来继续研读uboot源代码,在设置完gd指针之后,uboot调用执行了 init_sequence中的所有函数:

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
   
	if ((*init_fnc_ptr)() != 0) {
   
		hang ();
	}
}

这个函数指针数组init_sequence具体的定义如下(方便起见,我将其中没有用到的代码标示了“未用到”):

init_fnc_t *init_sequence[] = {
   

/*未用到*/
#if defined(CONFIG_ARCH_CPU_INIT)
	arch_cpu_init,		/* basic arch cpu dependent setup */
#endif


#if defined(CONFIG_BOARD_EARLY_INIT_F)
	board_early_init_f,
#endif

/*未用到*/
#ifdef CONFIG_OF_CONTROL
	fdtdec_check_fdt,
#endif


	timer_init,		/* initialize timer */

/*未用到*/
#ifdef CONFIG_FSL_ESDHC
	get_clocks,
#endif


	env_init,		/* initialize environment */
	init_baudrate,		/* initialze baudrate settings */
	serial_init,		/* serial communications setup */
	console_init_f,		/* stage 1 init of console */
	display_banner,		/* say that we are here */

#if defined(CONFIG_DISPLAY_CPUINFO)
	print_cpuinfo,		/* display cpu info (and speed) */
#endif

/*未用到*/
#if defined(CONFIG_DISPLAY_BOARDINFO)
	checkboard,		/* display board info */
#endif

/*未用到*/
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
	init_func_i2c,
#endif

	dram_init,		/* configure available RAM banks */
	NULL,
};

总结一下,初始化序列 init_sequence 主要是设备初始化工作

  • ① 硬件平台初始化:时钟系统初始化,GPIO初始化;
  • ② 定时器初始化;
  • ③ 外围设备初始化:串口、Flash等;
  • ④ 打印CPU信息;
  • ⑤ 初始化DRAM(SDRAM);

接下来挨个查看这些函数的源码:

  • board_early_init_f

这个函数在board/samsung/smdk2410/smdk2410.c文件中定义,是一些与硬件平台相关的初始化,包括时钟初始化、GPIO初始化

/*
 * Miscellaneous platform dependent initialisations
 * 各种各样的硬件平台相关初始化
 */

int board_early_init_f(void)
{
   
	struct s3c24x0_clock_power * const clk_power =
					s3c24x0_get_base_clock_power();
	struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();

	/* to reduce PLL lock time, adjust the LOCKTIME register */
	writel(0xFFFFFF, &clk_power->locktime);

	/* configure MPLL */
	writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
	       &clk_power->mpllcon);

	/* some delay between MPLL and UPLL */
	pll_delay(4000);

	/* configure UPLL */
	writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,
	       &clk_power->upllcon);

	/* some delay between MPLL and UPLL */
	pll_delay(8000);

	/* set up the I/O ports */
	writel(
  • 14
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
目录 u-boot-1.1.6 之 cpu/arm920t/start.s分析 ........................................................................................... 2 u-boot 中.lds连接脚本文件的分析 ...................................................................................................12 分享一篇我总结的 uboot 学习笔记(转) .....................................................................................15 U-BOOT内存布局及启动过程浅析 ...................................................................................................22 u-boot 中的命令实现 .......................................................................................................................... 25 U-BOOT环境变量实现 ........................................................................................................................28 1.相关文件 ....................................................................................................................................28 2.数据结构 ....................................................................................................................................28 3.ENV 的初始化...........................................................................................................................30 3.1env_init ............................................................................................................................30 3.2 env_relocate ...................................................................................................................30 3.3*env_relocate_spec ........................................................................................................31 4. ENV 的保存 ..............................................................................................................................31 U-Boot 环境变量 ..........................................................................................................................32 u-boot 代码链接的问题 ......................................................................................................................35 ldr 和 adr 在使用标号表达式作为操作数的区别 ............................................................................40 start_armboot 浅析 ..............................................................................................................................42 1.全局数据结构的初始化 ..........................................................................................................42 2.调用通用初始化函数...............................................................................................................43 3.初始化具体设备 .......................................................................................................................44 4.初始化环境变量 .......................................................................................................................44 5.进入主循环 ...............................................................................................................................44 u-boot 编译过程 ...................................................................................................................................44 mkconfig文件的分析 .......................................................................................................................... 47 从 NAND闪存中启动 U-BOOT的设计 ..............................................................................................50 引言 ...............................................................................................................................................50 NAND闪存工作原理 ................................................................................................................... 51 从 NAND闪存启动 U-BOOT的设计思路.................................................................................. 51 具体设计 ....................................................................................................................................... 51 支持 NAND闪存的启动程序设计 ..................................................................................... 51 支持 U-BOOT命令设计 ...................................................................................................... 52 结语 ............................................................................................................................................... 53 参考文献 ....................................................................................................................................... 53 U-boot 给 kernel 传参数和 kernel 读取参数—struct tag (以及补充) ............................................ 53 1 、u-boot 给 kernel 传 RAM 参数 ........................................................................................54 2 、Kernel 读取 U-boot 传递的相关参数 .............................................................................56 3 、关于 U-boot 中的 bd 和 gd...............................................................................................59 U-BOOT源码分析及移植 ....................................................................................................................60 一、 u-boot 工程的总体结构: ..................................................................................................61 1、源代码组织 ....................................................................................................................61 2.makefile简要分析 ............................................................................................................61 3、u-boot 的通用目录是怎么做到与平台无关的?......................................................63 4、smkd2410 其余重要的文件 : ...................................................................................63 二、u-boot 的流程、主要的数据结构、内存分配 ................................................................64 1、u-boot 的启动流程: ...................................................................................................64 2、u-boot 主要的数据结构 ...............................................................................................66 3、u-boot 重定位后的内存分布: ...................................................................................68 三、u-boot 的重要细节 。 ........................................................................................................68 关于 U-boot 中命令相关的编程 : ................................................................................. 73 四、U-boot 在 ST2410 的移植,基于 NOR FLASH和 NAND FLASH启动。......................... 76 1、从 smdk2410 到 ST2410: .............................................................................................. 76 2、移植过程: .................................................................................................................... 76 3、移植要考虑的问题: ...................................................................................................77 4、SST39VF1601: .................................................................................................................77 5、我实现的 flash.c主要部分: ...................................................................................... 78 6、增加从 Nand 启动的代码 : ..................................................................................... 82 7、添加网络命令。 ............................................................................................................ 87
Linux系统移植 目 录 第一部分 前言....................................................................................................................................8 1 硬件环境......................................................................................................................................8 1.1 主机硬件环境.......................................................................................................................8 1.2 目标板硬件环境...................................................................................................................8 1.3 工具介绍...............................................................................................................................8 2 软件环境.......................................................................................................................................8 2.1 主机软件环境.......................................................................................................................8 2.1.1 Windows 操作系统.......................................................................................................8 2.1.2 Linux 操作系统 .......................................................................................................8 2.1.3 目标板最后运行的环境...............................................................................................9 2.2 Linux 下工作用户及环境....................................................................................................9 2.2.1 交叉工具的安装...........................................................................................................9 2.2.2 u­boot移植工作目录....................................................................................................9 2.2.3 内核及应用程序移植工作...........................................................................................9 2.3 配置系统服务.....................................................................................................................10 2.3.1 tftp 服务器的配置.......................................................................................................10 2.4 工具使用.............................................................................................................................12 2.4.1 minicom的使用..........................................................................................................12 3 作者介绍....................................................................................................................................13 3.1 策划, 组织, 指导, 发布者...................................................................................................13 3.2 ADS bootloader部分..........................................................................................................13 3.3 交叉工具部分.....................................................................................................................13 3.4 uboot 部分...........................................................................................................................13 3.5 内核部分.............................................................................................................................13 3.6 应用程序部分.....................................................................................................................13 3.7 网卡驱动部分.....................................................................................................................13 3.8 Nand Flash 驱动部分.........................................................................................................13 第二部分 系统启动bootloader 的编写(ADS).................................................................................14 1 工具介绍....................................................................................................................................14 1.1 ADS 命令行命令介绍........................................................................................................14 1.1.1 armasm........................................................................................................................14 1.1.2 armcc, armcpp.............................................................................................................14 1.1.3 armlink.........................................................................................................................14 2 基本原理....................................................................................................................................15 2.1 可执行文件组成及内存映射.............................................................................................15 2.1.1 可执行文件的组成.....................................................................................................15 2.1.2 装载过程.....................................................................................................................16 2.1.3 启动过程的汇编部分.................................................................................................17 2.1.4 启动过程的 C部分.....................................................................................................17 3 AXD的使用以及源代码说明...................................................................................................18 3.1 源代码说明.........................................................................................................................18 3.1.1 汇编源代码说明.........................................................................................................18 3.1.2 C语言源代码说明......................................................................................................23 3.1.3 源代码下载.................................................................................................................23 3.2 AXD的使用.......................................................................................................................23 3.2.1 配置仿真器.................................................................................................................23 3.2.2 启动 AXD 配置开发板...............................................................................................23 第三部分 GNU交叉工具链.............................................................................................................25 1  设置环境变量,准备源码及相关补丁...................................................................................25 1.1 设置环境变量.....................................................................................................................25 1. 2 准备源码包............................................................................................................................25 1.2.1 binuils..........................................................................................................................25 1.2.2 gcc...............................................................................................................................25 1.2.3 glibc.............................................................................................................................25 1.2.4 linux kernel..................................................................................................................26 1.3 准备补丁.............................................................................................................................26 1.3.1 ioperm.c.diff................................................................................................................26 1.3.2 flow.c.diff....................................................................................................................26 1.3.3 t­linux.diff....................................................................................................................26 1.4   编译 GNU binutils...........................................................................................................26 1.5 准备内核头文件.................................................................................................................26 1.5.1 使用当前平台的 gcc编译内核头文件......................................................................26 1.5.2 复制内核头文件.........................................................................................................27 1.6   译编glibc头文件.............................................................................................................27 1.7   编译gcc第一阶段............................................................................................................27 1.8   编译完整的glibc..............................................................................................................27 1.9  编译完整的gcc.................................................................................................................28 2 GNU 交叉工具链的下载...........................................................................................................28 2.1 ARM 官方网站...................................................................................................................28 2.2 本文档提供的下载.............................................................................................................28 3 GNU 交叉工具链的介绍与使用...............................................................................................29 3.1 常用工具介绍.....................................................................................................................29 3.2.1 arm­linux­gcc的使用.................................................................................................29 3.2.2 arm­linux­ar 和 arm­linux­ranlib 的使用..................................................................30 3.2.3 arm­linux­objdump 的使用.........................................................................................30 3.2.4 arm­linux­readelf 的使用............................................................................................31 3.2.6 arm­linux­copydump 的使用......................................................................................32 4 ARM GNU 常用汇编语言介绍.................................................................................................32 4.1 ARM GNU常用汇编伪指令介绍.....................................................................................32 4.2 ARM GNU专有符号.........................................................................................................33 4.3 操作码.................................................................................................................................33 5 可执行生成说明........................................................................................................................33 5.1 lds文件说明.......................................................................................................................33 5.1.1 主要符号说明.............................................................................................................33 5.1.2 段定义说明.................................................................................................................34 第四部分 u­boot 的移植...................................................................................................................35 1 u­boot的介绍及系统结构.........................................................................................................35 1.1 u­boot 介绍.........................................................................................................................35 1.2 获取u­boot.........................................................................................................................35 1.3 u­boot 体系结构.................................................................................................................35 1.3.1 u­boot目录结构..........................................................................................................35 2 uboot的启动过程及工作原理...................................................................................................36 2.1 启动模式介绍.....................................................................................................................36 2.2 阶段1 介绍.........................................................................................................................36 2.2.1 定义入口.....................................................................................................................36 2.2.2 设置异常向量.............................................................................................................37 2.2.3 设置 CPU的模式为SVC模式..................................................................................37 2.2.4 关闭看门狗.................................................................................................................37 2.2.5 禁掉所有中断.............................................................................................................37 2.2.6 设置以 CPU的频率....................................................................................................37 2.2.7 设置 CP15...................................................................................................................37 2.2.8 配置内存区控制寄存器.............................................................................................38 2.2.9 安装 U­BOOT 使的栈空间........................................................................................38 2.2.10 BSS 段清 0................................................................................................................38 2.2.11 搬移 Nand Flash 代码...............................................................................................39 2.2.12 进入 C代码部分.......................................................................................................39 2.3 阶段2 的C语言代码部分 .............................................................................................39 2.3.1 调用一系列的初始化函数.........................................................................................39 2.3.2 初始化网络设备.........................................................................................................41 2.3.3 进入主 UBOOT 命令行..............................................................................................41 2.4 代码搬运.............................................................................................................................41 3 uboot的移植过程.......................................................................................................................42 3.1 环境.....................................................................................................................................42 3.2 步骤.....................................................................................................................................42 3.2.1 修改 Makefile..............................................................................................................42 3.2.2 在 board 子目录中建立 crane2410.............................................................................42 3.2.3 在 include/configs/中建立配置头文件......................................................................42 3.2.4 指定交叉编译工具的路径.........................................................................................42 3.2.5 测试编译能否成功.....................................................................................................42 3.2.6 修改 lowlevel_init.S 文件...........................................................................................43 3.2.9 UBOOT 的 Nand Flash 移植......................................................................................45 3.2.8 重新编译u­boot..........................................................................................................45 3.2.9 把 u­boot烧入flash....................................................................................................45 4  U­BOOT 命令的使用................................................................................................................46 4.1 U­BOOT命令的介绍.........................................................................................................46 4.1.1 获得帮助信息.............................................................................................................46 4.2 常用命令使用说明.............................................................................................................47 4.2.1 askenv(F).....................................................................................................................47 4.2.2 autoscr.........................................................................................................................47 4.2.3 base   ...........................................................................................................................47 4.2.4 bdinfo...........................................................................................................................47 4.2.5 bootp............................................................................................................................47 4.2.8 tftp(tftpboot)................................................................................................................48 4.2.9 bootm...........................................................................................................................48 4.2.10 go...............................................................................................................................48 4.2.11 cmp   .........................................................................................................................48 4.2.12 coninfo  .....................................................................................................................48 4.2.13 cp...............................................................................................................................48 4.2.14 date............................................................................................................................49 4.2.15 erase(F)......................................................................................................................49 4.2.16 flinfo(F).....................................................................................................................49 4.2.17 iminfo........................................................................................................................49 4.2.18 loadb..........................................................................................................................49 4.2.19 md..............................................................................................................................49 4.2.20 mm ............................................................................................................................50 4.2.21 mtest   .......................................................................................................................50 4.2.22 mw.............................................................................................................................50 4.2.23 nm   ...........................................................................................................................50 4.2.24 printenv......................................................................................................................50 4.2.25 ping  ..........................................................................................................................51 4.2.26 reset...........................................................................................................................51 4.2.27 run   ...........................................................................................................................51 4.2.28 saveenv(F).................................................................................................................51 4.2.29 setenv.........................................................................................................................51 4.2.30 sleep...........................................................................................................................51 4.2.31 version.......................................................................................................................51 4.2.32 nand info....................................................................................................................51 4.2.33 nand device ........................................................................................................51 4.2.34 nand bad....................................................................................................................51 4.2.35 nand read...................................................................................................................52 4.2.36 nand erease................................................................................................................52 4.2.37 nand write..................................................................................................................52 4.3 命令简写说明.....................................................................................................................52 4.4 把文件写入NandFlash.......................................................................................................53 4.5 下载提供.............................................................................................................................53 5 参考资料....................................................................................................................................53 第五部分 linux 2.6 内核的移植.......................................................................................................53 1 内核移植过程............................................................................................................................53 1.1 下载linux 内核...................................................................................................................53 1.2 修改Makefile.....................................................................................................................53 1.3 设置flash 分区...................................................................................................................54 1.3.1 指明分区信息.............................................................................................................54 1.3.2 指定启动时初始化.....................................................................................................56 1.3.3 禁止 Flash ECC校验 ................................................................................................56 1.4 配置内核.............................................................................................................................56 1.4.1 支持启动时挂载 devfs................................................................................................56 1.4.2 配置内核产生.config 文件.........................................................................................57 1.4.3 编译内核.....................................................................................................................58 1.4.4 下载 zImage到开发板................................................................................................58 2 创建 uImage................................................................................................................................61 2.1 相关技术背景介绍.............................................................................................................61 2.2 在内核中创建uImage 的方法...........................................................................................61 2.2.1 获取 mkimage工具.....................................................................................................61 2.2.2 修改内核的 Makefile文件.........................................................................................61 3 追加实验记录.............................................................................................................................62 3.1 移植 linux­2.6.15.7..............................................................................................................62 3.2 移植 linux­2.6.16.21............................................................................................................62 3.3 移植linux­2.6.17................................................................................................................62 4 参考资料....................................................................................................................................62 第六部分 应用程序的移植..............................................................................................................63 1 构造目标板的根目录及文件系统.............................................................................................63 1.1 建立一个目标板的空根目录.............................................................................................63 1.2 在 my_rootfs 中建立Linux 目录树...................................................................................63 1.3 创建linuxrc文件................................................................................................................63 2 移植 Busybox.............................................................................................................................64 2.1 下载busybox......................................................................................................................64 2.3 编译并安装Busybox..........................................................................................................65 3 移植 TinyLogin...........................................................................................................................66 3.1 下载.....................................................................................................................................66 3.2 修改tinyLogin 的 Makefile................................................................................................66 3.3 编译并安装.........................................................................................................................66 4 相关配置文件的创建................................................................................................................66 4.1 创建帐号及密码文件.........................................................................................................66 4.2 创建profile文件................................................................................................................67 4.4 创建fstab 文件...................................................................................................................67 4.5 创建inetd.conf 配置文件...................................................................................................67 5 移植 inetd....................................................................................................................................67 5.1 inetd 的选择及获取............................................................................................................67 5.1.1 获取 inetd....................................................................................................................67 5.2 编译inetd............................................................................................................................67 5.2.1 修改 configure文件....................................................................................................67 5.2.2 编译 ...........................................................................................................................68 5.3 配置inetd............................................................................................................................68 5.3.1 拷贝 inetd 到根文件系统的usr/sbin 目录中.............................................................68 6 移植 thttpd Web 服务器.............................................................................................................69 6.1 下载.....................................................................................................................................69 6.2 编译thttpd...........................................................................................................................69 6.3 配置.....................................................................................................................................69 6.3.1 拷贝 thttpd 二进制可执行文件到根文件系统/usr/sbin/目录中...............................69 6.3.2 修改 thttpd 配置文件..................................................................................................69 6.3.3 转移到根文件系统目录,创建相应的文件.............................................................69 7 建立根目录文件系统包............................................................................................................70 7.1 建立CRAMFS 包...............................................................................................................70 7.1.1 下载 cramfs 工具........................................................................................................70 7.1.2 制作 cramfs 包............................................................................................................70 7.1.3 写 cramfs 包到Nand Flash.........................................................................................70 8 参考资料....................................................................................................................................70 第七部分 Nand flash 驱动的编写与移植........................................................................................71 1 Nand flash 工作原理..................................................................................................................71 1.1 Nand flash 芯片工作原理..................................................................................................71 1.1.1 芯片内部存储布局及存储操作特点.........................................................................71 1.1.2 重要芯片引脚功能.....................................................................................................71 1.1.3 寻址方式.....................................................................................................................71 1.1.4 Nand flash 主要内设命令详细介绍...........................................................................72 1.2 Nand Flash 控制器工作原理.............................................................................................72 1.2.1 Nand Flash 控制器特性..............................................................................................72 1.2.2 Nand Flash 控制器工作原理......................................................................................72 1.3 Nand flash 控制器中特殊功能寄存器详细介绍 ............................................................72 1.4 Nand Flash 控制器中的硬件ECC介绍............................................................................73 1.4.1 ECC产生方法............................................................................................................73 1.4.2 ECC生成器工作过程................................................................................................74 1.4.3 ECC的运用................................................................................................................74 2 在 ADS下flash 烧写程序.........................................................................................................74 2.1 ADS 下 flash 烧写程序原理及结构...................................................................................74 2.2 第三层实现说明.................................................................................................................74 2.1.1 特殊功能寄存器定义.................................................................................................74 2.1.2 操作的函数实现.........................................................................................................74 2.3 第二层实现说明.................................................................................................................75 2.3.1 Nand Flash 初始化......................................................................................................75 2.3.3 获取 Nand flash ID......................................................................................................75 2.3.4 Nand flash 写入...........................................................................................................76 2.3.5 Nand flash 读取...........................................................................................................77 2.3.6 Nand flash 标记坏块...................................................................................................78 2.3.7 Nand Flash 检查坏块..................................................................................................79 2.3.8 擦除指定块中数据.....................................................................................................79 2.4  第一层的实现....................................................................................................................80 3 在 U­BOOT 对Nand Flash 的支持............................................................................................82 3.1 U­BOOT对从 Nand Flash 启动的支持.............................................................................82 3.1.1 从 Nand Flash 启动U­BOOT 的基本原理................................................................82 3.1.2 支持 Nand Flash 启动代码说明.................................................................................82 3.2 U­BOOT对 Nand Flash 命令的支持.................................................................................84 3.2.1 主要数据结构介绍.....................................................................................................84 3.2.2 支持的命令函数说明.................................................................................................85 4 在 Linux 对Nand Flash 的支持.................................................................................................87 4.1 Linux 下Nand Flash 调用关系..........................................................................................87 4.1.1 Nand Flash 设备添加时数据结构包含关系..............................................................87 4.1.2 Nand Flash 设备注册时数据结构包含关系..............................................................87 4.2 Linux 下Nand Flash 驱动主要数据结构说明..................................................................88 4.2.1 s3c2410 专有数据结构...............................................................................................88 4.2.2 Linux 通用数据结构说明..........................................................................................89 4.3.1 注册 driver_register....................................................................................................94 4.3.2 探测设备 probe...........................................................................................................94 4.3.3 初始化 Nand Flash 控制器.........................................................................................94 4.3.4 移除设备.....................................................................................................................94 4.3.5 Nand Flash 芯片初始化..............................................................................................94 4.3.6  读 Nand  Flash............................................................................................................95 4.3.7  写 Nand Flash.............................................................................................................95 第八部分 Cs8900a网卡驱动的编写与移植...................................................................................95 1 Cs8900a工作原理......................................................................................................................95 2 在 ADS下cs8900a的实现........................................................................................................95 2.1 在 cs8900a下实现的ping 工具.........................................................................................95 3 在 u­boot下cs8900a的支持......................................................................................................96 3.1 u­boot 下cs8900a的驱动介绍...........................................................................................96 3.2 u­boot 下cs8900a的移植说明...........................................................................................96 4 在 linux 下cs8900a驱动的编写与移植....................................................................................96 4.1 Linux 下cs8900a的驱动说明............................................................................................96 4.2 Linux 下 cs8900a的移植说明...........................................................................................96 4.2.1 为 cs8900a建立编译菜单..........................................................................................96 4.2.2 修改 S3C2410相关信息............................................................................................97 序 该文档的目的是总结我们在工作中的一些经验,并把它们分享给喜欢 ARM 和 Linux 的朋友, 如有错误 之处,请大家多多指点. 同样, 我们也希望更多人能把自己的工作经验和体会加入该文档,让大家共同进步. 该文档是一份交流性文档, 只供个人学习与交流,不允许公司和企业用于商业行为

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leon_George

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值