码迷,mamicode.com
首页 > 其他好文 > 详细

uboot

时间:2021-04-09 12:50:57      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:watchdog   ||   tran   put   text   ogre   finally   寄存器   via   

uboot启动代码流程

board.c文件__attribute__((nomips16)) void board_init_r (gd_t *id, ulong dest_addr)函数

1、调用do_bootm 

if(BootType == ‘3‘) {
char *argv[2];
sprintf(addr_str, "0x%X", CFG_KERN_ADDR);
argv[1] = &addr_str[0];
printf(" \n3: System Boot system code via Flash.\n");
do_bootm(cmdtp, 0, 2, argv);
}

 

board.c文件__attribute__((nomips16)) void board_init_f(ulong bootflag)

1、初始化RT2880 SOC

给寄存器赋值,初始化。

2、初始化gd结构体

/* Pointer is writable since we allocated a register for it.
*/
gd = &gd_data;
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
memset ((void *)gd, 0, sizeof (gd_t));

3、执行init_fnc_ptr函数指针数组中的各个初始化函数

#if 0
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {

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

执行init_fnc_ptr函数指针数组中的各个初始化函数,如下
board_early_init_f    , timer_init       , env_init       init_baudrate serial_init     
console_init_f       display_banner           dram_init

#endif

MTK把它屏蔽拆出来

#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
watchdog_reset();
#endif
timer_init();
env_init(); /* initialize environment */
init_baudrate(); /* initialze baudrate settings */
serial_init(); /* serial communications setup */
console_init_f();

display_banner(); /* say that we are here */
checkboard();

init_func_ram();

4、给寄存器赋值

/* reset Frame engine */
value = le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0034));

*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0034) = cpu_to_le32(value);

5、分配DRAM有顶部到底部

/*
* Now that we have DRAM mapped and working, we can
* relocate the code and continue running from DRAM.
*/

得到内存大小

addr = CFG_SDRAM_BASE + gd->ram_size;

预留4K内存

/* round down to next 4 kB limit.
*/
addr &= ~(4096 - 1);
#ifdef DEBUG
debug ("Top of RAM usable for U-Boot at: %08lx\n", addr);
#endif

分配16k内存给U-boot代码,数据段,BSS段

/* Reserve memory for U-Boot code, data & bss
* round down to next 16 kB limit
*/
addr -= len;
addr &= ~(16 * 1024 - 1);
#ifdef DEBUG
debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
#endif

分配堆空间

/* Reserve memory for malloc() arena.
*/
addr_sp = addr - TOTAL_MALLOC_LEN;
#ifdef DEBUG
debug ("Reserving %dk for malloc() at: %08lx\n",
TOTAL_MALLOC_LEN >> 10, addr_sp);
#endif

分配board info空间,参数空间,gd(global data)

/*
* (permanently) allocate a Board Info struct
* and a permanent copy of the "global" data
*/
addr_sp -= sizeof(bd_t);
bd = (bd_t *)addr_sp;
gd->bd = bd;
#ifdef DEBUG
debug ("Reserving %d Bytes for Board Info at: %08lx\n",
sizeof(bd_t), addr_sp);
#endif
addr_sp -= sizeof(gd_t);
id = (gd_t *)addr_sp;
#ifdef DEBUG
debug ("Reserving %d Bytes for Global Data at: %08lx\n",
sizeof (gd_t), addr_sp);
#endif
/* Reserve memory for boot params.
*/
addr_sp -= CFG_BOOTPARAMS_LEN;
bd->bi_boot_params = addr_sp;
#ifdef DEBUG
debug ("Reserving %dk for boot params() at: %08lx\n",
CFG_BOOTPARAMS_LEN >> 10, addr_sp);
#endif

分配栈空间,预留16K隔离区,剩下的都是

/*
* Finally, we set up a new (bigger) stack.
*
* Leave some safety gap for SP, force alignment on 16 byte boundary
* Clear initial stack frame
*/
addr_sp -= 16;
addr_sp &= ~0xF;
s = (ulong *)addr_sp;
*s-- = 0;
*s-- = 0;
addr_sp = (ulong)s;

#ifdef DEBUG
debug ("Stack Pointer at: %08lx\n", addr_sp);
#endif

拷贝代码到栈空间

/* On the purple board we copy the code in a special way
* in order to solve flash problems
*/
#ifdef CONFIG_PURPLE
copy_code(addr);
#endif

调用内存分配函数

relocate_code (addr_sp, id, /*TEXT_BASE*/ addr);

 

 

=================================================

 

cmd_bootm.c文件do_bootm函数

int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

1、得到image的起始地址

printf ("## Booting image at %08lx ...\n", addr);

2、读取image头

raspi_read(&header, (char *)(addr - CFG_FLASH_BASE), sizeof(image_header_t));

3、校验image头是否正确

image头结构体

typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;

校验image头代码

checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;

if (crc32 (0, (char *)data, len) != checksum) {
puts ("Bad Header Checksum\n");
SHOW_BOOT_PROGRESS (-2);
return 1;
}

print_image_hdr ((image_header_t *)hdr);

4、根据image头部信息读取image(去不同型号的FLASH读取)

#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash(addr)){
read_dataflash(data, len, (char *)CFG_LOAD_ADDR);
data = CFG_LOAD_ADDR;
}
#endif

#if defined (CFG_ENV_IS_IN_NAND)
if (addr >= CFG_FLASH_BASE) {
ulong load_addr = CFG_SPINAND_LOAD_ADDR;
ranand_read(load_addr, data - CFG_FLASH_BASE, len);
data = load_addr;
}
#elif defined (CFG_ENV_IS_IN_SPI)
if (addr >= CFG_FLASH_BASE) {
ulong load_addr = CFG_SPINAND_LOAD_ADDR;
raspi_read(load_addr, data - CFG_FLASH_BASE, len);
data = load_addr;
}
#else //CFG_ENV_IS_IN_FLASH
#endif

5、校验image是否正确

if (verify) {
puts (" Verifying Checksum ... ");
if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
printf ("Bad Data CRC\n");
SHOW_BOOT_PROGRESS (-3);
return 1;
}
puts ("OK\n");
}

6、检测是否支持该芯片型号、镜像类型、是否压缩(ih_arch、ih_type、ih_comp)

if (hdr->ih_arch != IH_CPU_NIOS2)
#else
# error Unknown CPU type
#endif
{
printf ("Unsupported Architecture 0x%x\n", hdr->ih_arch);
SHOW_BOOT_PROGRESS (-4);
return 1;
}

 

7、将控制权交给内核

#ifdef DEBUG
printf ("## Transferring control to Linux (at address %08lx) ...\n",
(ulong) theKernel);
#endif

 

uboot

标签:watchdog   ||   tran   put   text   ogre   finally   寄存器   via   

原文地址:https://www.cnblogs.com/EA-Coke/p/13601900.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!