uboot学习笔记3

来源:互联网 发布:matlab2017b mac 破解 编辑:程序博客网 时间:2024/06/04 18:36

UBOOT源码分析(uboot-1.1.6)第二阶段

Lib_arm/board.c——start_armboot开始执行

 1、设置gd

2、init_sequence数组预先定义的初始化函数

3、flash_init

4、env_relocate将环境参数读入内核指定位置

5、获取IPMAC  初始化网络设备

6、调用main_loop,执行U_BOOT_CMD命令

s=getnv('bootcmd')

启动命令bootcmd =nand read.jffs2 0x30007f00 kernel(分区);bootm 0x30007f00  (.jffs2 长度不需要对齐-页对齐)

其中bootm 从内存、rom、norflash中启动内核

bootp 从网络启动内核

nboot 从nand启动内核

 

源码中include/config/100ask24x0.h中将flash分区设置,例如

nand read.jffs2 0x30007f00 0x6000000x500000

(kernel分区起始地址为0x600000,大小为5MB)

 

NAND分区示意图

boot  env   kernel rootfs

 

源码如下:

void start_armboot (void)

{

。。。

/* Pointer is writablesince we allocated a register for it */

gd =(gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));

/* compiler optimizationbarrier needed for GCC >= 3.4 */

__asm____volatile__("": : :"memory");

 

memset ((void*)gd, 0,sizeof (gd_t));

gd->bd =(bd_t*)((char*)gd - sizeof(bd_t));

memset (gd->bd, 0,sizeof (bd_t));

 

monitor_flash_len =_bss_start - _armboot_start;

 

for (init_fnc_ptr = init_sequence;*init_fnc_ptr; ++init_fnc_ptr) {

if ((*init_fnc_ptr)() !=0) {

hang ();

}

}

 

#ifndef CFG_NO_FLASH

/* configure availableFLASH banks */

size = flash_init ();

display_flash_config(size);

#endif /* CFG_NO_FLASH */

 

。。。

。。。

 

/* armboot_start isdefined in the board-specific linker script */

mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);初始化malloc的堆空间

 

#if (CONFIG_COMMANDS &CFG_CMD_NAND)

puts ("NAND:  ");

nand_init();                /*go init the NAND */

#endif

 

 

/* initialize environment*/

env_relocate ();环境变量。boot输入print出来的就是环境变量和对应值

环境变量       1默认的,代码里写死的    2 flash上保存的

 

#ifdef CONFIG_VFD

/* must do this after theframebuffer is allocated */

drv_vfd_init();

#endif /* CONFIG_VFD */

 

/* IP Address */

gd->bd->bi_ip_addr =getenv_IPaddr ("ipaddr");

 

/* MAC Address */

{

int i;

ulong reg;

char *s, *e;

char tmp[64];

 

i = getenv_r("ethaddr", tmp, sizeof (tmp));

s = (i > 0) ? tmp : NULL;

 

for (reg = 0; reg < 6;++reg) {

gd->bd->bi_enetaddr[reg]= s ? simple_strtoul (s, &e, 16) : 0;

if (s)

s = (*e) ? e + 1 : e;

}

 

#ifdef CONFIG_HAS_ETH1

i = getenv_r("eth1addr", tmp, sizeof (tmp));

s = (i > 0) ? tmp :NULL;

 

for (reg = 0; reg < 6; ++reg){

gd->bd->bi_enet1addr[reg]= s ? simple_strtoul (s, &e, 16) : 0;

if (s)

s = (*e) ? e + 1 : e;

}

#endif

}

 

devices_init();        /* get the devices listgoing. */

 

。。。

 

jumptable_init ();

 

console_init_r ();        /*fully init console as a device */

 

#ifdefined(CONFIG_MISC_INIT_R)

/* miscellaneous platformdependent initialisations */

misc_init_r ();

#endif

 

Port_Init();

if (!PreLoadedONRAM) {

/* enable exceptions */

enable_interrupts ();

    

    usb_init();

}

 

    /* Perform network card initialisation ifnecessary */

#ifdefCONFIG_DRIVER_CS8900

cs8900_get_enetaddr(gd->bd->bi_enetaddr);

#endif

 

。。。

 

#ifdef BOARD_LATE_INIT

board_late_init ();

#endif

#if (CONFIG_COMMANDS &CFG_CMD_NET)

#ifdefined(CONFIG_NET_MULTI)

puts ("Net:   ");

#endif

eth_initialize(gd->bd);

#endif

/* main_loop() can returnto retry autoboot, if so just run it again. */

for (;;) {

main_loop ();

}

 

/* NOTREACHED - no way outof command loop except booting */

}

其中

init_fnc_t*init_sequence[] = {

cpu_init,                /*basic cpu dependent setup */配置irq fiq空间起始地址

board_init,                /*basic board dependent setup */初始化单板配置,寄存器配置和机器ID

interrupt_init,                /*set up exceptions */定时器配置

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 */

#ifdefined(CONFIG_DISPLAY_CPUINFO)

print_cpuinfo,                /*display cpu info (and speed) */

#endif

#ifdefined(CONFIG_DISPLAY_BOARDINFO)

checkboard,                /*display board info */

#endif

dram_init,                /*configure available RAM banks */ram空间配置

display_dram_config,

NULL,

};

2017101118:00

执行bootcmd命令。Bootcmd命令如下:

Nandread.jffs2 0x30007f00 kernel

Bootm 0x30007f00

1)  从nand读出内核,根据头部移动内核到合适的地方去nand read

Nand读取内核到0x30007fc0地址。

因为内核uimage文件组成为头部(64B)+真正的内核

                         0x30007fc0(+64 B)    0x30008000

注意两个变量

in_load  加载地址----0x30008000

in_ep   入口地址

2)  启动do_bootm_linuxbootm

a.      告诉内核一些参数------设置启动参数------在某个地址(0x30001000)按某种格式保存数据(TAG)

b.      跳到入口地址启动内核----the kernel(in_ep)