uboot移植之start_armboot()函数分析

/********************************

uboot的第二阶段就是初始化剩下的还没在第一阶段初始化的硬件。主要是SoC外部硬件(譬如 iNand 网卡芯片....... )uboot本身的一些东西(uboot的命令 环境变量等.....)。然后最终初始化完必要的东西后进入到uboot的命令行准备接受命令。

***********************************/

void start_armboot (void)       //这个函数构成了uboot启动的第二阶段

{

/************************************

typedef int (init_fnc_t) (void);这是一个函数类型,所以init_fnc_t_ptr是一个二重函数指针,二重指针的作用有两个,(一个是用来指向一重指针(指针的指针)),一个用来指向一个指针数组。因此这里的init_fnc_t_ptr可以用来指向一个函数指针数组。

****************************************/

init_fnc_t **init_fnc_ptr;

char *s;

int mmc_exist = 0;

#if !defined(CFG_NO_FLASH) || defined (CONFIG_VFD) || defined(CONFIG_LCD)

ulong size;

#endif

#if defined(CONFIG_VFD) || defined(CONFIG_LCD)

unsigned long addr;

#endif

#if defined(CONFIG_BOOT_MOVINAND)

uint *magic = (uint *) (PHYS_SDRAM_1);

#endif

/* Pointer is writable since we allocated a register for it */

#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */

ulong gd_base;       //gd在DDR内存分配中的起始地址

/************************gd(global data)的由来******************

每个用到文件的开头都有DECLARE_GLOBAL_DATA_PTR;这句,而这个宏在我们的uboot/include/asm-arm/Global_data.h中有定义(gd_t也定义在这个文件中)

#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")

定义了一个全局变量名字为gd,这个全局变量是一个指针类型,占4个字节,用volatile修饰表示可变的;用register修饰表示这个变量要尽量放到寄存器中;asm("r8")是gcc支持的一种语法,意思是要把gd放到寄存器r8中。

综合分析:DECLARE_GLOBAL_DATA_PTR就是定义了一个要放在寄存器r8中的全局变量,名字叫gd,类型是一个指向gd_t类型变量的指针。gd_t中定义了很多全局变量,都是整个uboot使用的,其中有一个bd_t类型的指针bd,指向结构体bd_info,这个结构体里面定义的是和开发板硬件相关的全局变量(譬如 ip地址  串口波特率 等)

全局变量gd是uboot中很重要的一个全局变量(准确的说这个全局变量是一个结构体,里面有很多内容,这些内容加起来构成的结构体就是uboot中常用的所有全局变量),由于gd经常被访问,因此放在寄存器中提升访问效率。

**************************/

/***************************************************

typedef    struct    global_data {

bd_t        *bd;   //指向bd_t的指针

unsigned long    flags;

unsigned long    baudrate;  //波特率

unsigned long    have_console; 是否有控制台(终端,或串口之类的)

unsigned long    reloc_off;    /* Relocation Offset */

unsigned long    env_addr;  //  环境变量的地址

unsigned long    env_valid;   //环境变量checksum是否有效

unsigned long    fb_base;    //frame buffer的基地址

void        **jt;        /* jump table */

} gd_t;

******************************************/

gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);

/******************************************

//uboot区:CFG_UBOOT_BASE (33e00000)+CFG_UBOOT_SIZE (uboot的实际大小,我们这里给了2M)

堆区:长度为CFG_MALLOC_LEN ,实际长度为912KB

栈区:长度为CFG_STACK_SIZE,实际长度为512KB

gd:长度为sizeof(gd_t),实际为36字节

bd:长度为sizeof(bd_t),实际长度为44字节左右

所以gd_base的大概位置是离uboot起始地址(33e00000)往上走624KB的位置处

**************************************/

#ifdef CONFIG_USE_IRQ

gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);

#endif   //CONFIG_USE_IRQ

gd = (gd_t*)gd_base;  //上面已经得到gd_base是一个内存地址,然后通过强制类型转换使其变为一个指针,并赋给gd,使得gd指向这段内存空间

#else  //CONFIG_MEMORY_UPPER_CODE

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

#endif   //CONFIG_MEMORY_UPPER_CODE

/* compiler optimization barrier needed for GCC >= 3.4 */  //避免高版本的gcc的过度优化造成错误

__asm__ __volatile__("": : :"memory");     //内嵌汇编

/*

__asm__ :用于指示编译器在此插入汇编语句

__volatile__:用于告诉编译器,严禁将此处的汇编语句与其它的语句重组合优化。即:原原本本按原来的样子处理这这里的汇编。

memory:强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中的registers和cache中已缓存的内存单元中的数据将作废。cpu将不得不在需要的时候重新读取内存中的数据。这就阻止了cpu又将registers,cache中的数据用于去优化指令,而避免去访问内存。

*/

/*需要注意的是:

(1)这里的#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")只是定义了一个指针,也就说gd里的这些全局变量并没有分配内存,我们在使用gd之前要给他分配内存,否则gd只是一个野指针

(2)gd和bd需要内存,内存当前没有被人管理(因为没有操作系统统一管理内存),大片的DDR内存(0x30000000-0x4fffffff共512MB)散放着可以随意使用(只要使用内存地址直接去访问内存即可),但是因为后面的uboot还需要大片内存,所以这里要本着够用,紧凑排布的原则

****************************************************/

memset ((void*)gd, 0, sizeof (gd_t));    //申请的内存使用之前先进行清零

gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));   //根据bd的大小计算bd的起始地址,在gd下面紧挨着

//假如改为(int *)gd - sizeof(bd_t),则实际int * 类型指针-1相当于地址-4*1,这样就会浪费一部分内存(虽然很   //小,因为这里的sizeof(bd_t)里面的就是bd的大小,所以地址直接减去这段内存即可。所以是char * gd)

memset (gd->bd, 0, sizeof (bd_t));     //申请的内存使用之前先进行清零

monitor_flash_len = _bss_start - _armboot_start;

/********************************************************

前面已经讲到过init_fnc_ptr 是一个二重函数指针,可以指向init_sequence这个函数指针数组,而 init_sequence是一个函数指针数组,所以这个数组存放了很多函数指针,这些函数的类型都是init_fnc_ptr类型(typedef int (init_fnc_t) (void);)特殊是接收参数是void类型,返回值是int类型。这里面的内容都是函数名,也就是函数指针,这些函数都是板级初始化的代码。

*init_fnc_ptr:解引用,得到的就是一个函数指针

这个for循环的作用就是去遍历init_sequence这个函数指针数组,而遍历的目的就是去执行这个函数指针数组里面的全部函数。

和普通数组类似,函数指针数组也可以通过下标个数组里面的元素个数去遍历这个数组(for(i=0;i<n;i++  a[i])),但是这里使用的是另一种思路:通过在数组的最后设置一个标志(NULL),遍历的时候从开头开始,直到检测到标志(NULL)结束,这样的好处是不需要去确定数组元素的个数。

*****************************************/

/*

用函数指针去调用函数(得到的是函数的返回值),数组里面的函数正确执行时返回值都是0,如果错误是则挂起(hang();)启动失败

*/

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

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

hang ();

}

}

#ifndef CFG_NO_FLASH

/*

Nor_FLASH初始化,但是我们的开发板上面接的是NandFlash,所以这个是无效的,可以拿去

*/

/* configure available FLASH banks */

size = flash_init ();

display_flash_config (size);

#endif /* CFG_NO_FLASH */

#ifdef CONFIG_VFD

/*

uboot中自带的LCD显示架构,但是我们没有使用uboot的LCD显示架构,而是自己添加了一套LCD显示架构

*/

#    ifndef PAGE_SIZE

#      define PAGE_SIZE 4096

#    endif

/*

* reserve memory for VFD display (always full pages)

*/

/* bss_end is defined in the board-specific linker script */

addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);

size = vfd_setmem (addr);

gd->fb_base = addr;

#endif /* CONFIG_VFD */

#ifdef CONFIG_LCD

/* board init may have inited fb_base */

if (!gd->fb_base) {

#        ifndef PAGE_SIZE

#          define PAGE_SIZE 4096

#        endif

/*

* reserve memory for LCD display (always full pages)

*/

/* bss_end is defined in the board-specific linker script */

addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);

size = lcd_setmem (addr);

gd->fb_base = addr;

}

#endif /* CONFIG_LCD */

/* armboot_start is defined in the board-specific linker script */

#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */

mem_malloc_init (CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE);

/*

(1)mem_malloc_init函数用来初始化uboot的堆管理器。

(2)uboot中自己维护了一段堆内存,肯定自己就有一套代码来管理这个堆内存。有了这些东西uboot中你也可以malloc、free这套机制来申请内存和释放内存。我们在DDR内存中给堆预留了896KB的内存。

*/

#else

mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);

#endif

//******************************//

// Board Specific  开发板独有的配置

三星用一套uboot满足了多套开发板,开发板之间的差别就在这里分析

// #if defined(CONFIG_SMDKXXXX)

//******************************//

#if defined(CONFIG_SMDK6410)

#if defined(CONFIG_GENERIC_MMC)

puts ("SD/MMC:  ");

mmc_exist = mmc_initialize(gd->bd);

/***********************************************************

(1)mmc_initialize():MMC相关的一些基础的初始化,其实就是用来初始化SoC内部的SD/MMC控制器的。函数在uboot/drivers/mmc/mmc.c里。

(2)mmc_initialize():是具体硬件架构无关的一个MMC初始化函数,

所有的使用了这套架构的代码都掉用这个函数来完成MMC的初始化。

mmc_initialize中再调用board_mmc_init和cpu_mmc_init来完成具体的硬件的MMC控制器初始化工作。

****************************************************/

if (mmc_exist != 0)

{

puts ("0 MB\n");

}

#else

#if defined(CONFIG_MMC)

puts("SD/MMC:  ");

if (INF_REG3_REG == 0)

movi_ch = 0;

else

movi_ch = 1;

movi_set_capacity();

movi_init();

movi_set_ofs(MOVI_TOTAL_BLKCNT);

#endif

#endif

if (INF_REG3_REG == BOOT_ONENAND) {

#if defined(CONFIG_CMD_ONENAND)

puts("OneNAND: ");

onenand_init();

#endif

/*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/

} else {

puts("NAND:    ");

nand_init();

if (INF_REG3_REG == 0 || INF_REG3_REG == 7)

setenv("bootcmd", "movi read kernel c0008000;movi read rootfs c0800000;bootm c0008000");

else

setenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");

}

#endif    /* CONFIG_SMDK6410 */

#if defined(CONFIG_SMDKC100)

//210SD卡相关配置

#if defined(CONFIG_GENERIC_MMC)

puts ("SD/MMC:  ");

mmc_exist = mmc_initialize(gd->bd);

if (mmc_exist != 0)

{

puts ("0 MB\n");

}

#endif

#if defined(CONFIG_CMD_ONENAND)

puts("OneNAND: ");

onenand_init();

#endif

#if defined(CONFIG_CMD_NAND)

puts("NAND:    ");

nand_init();

#endif

#endif /* CONFIG_SMDKC100 */

#if defined(CONFIG_X210)

//结束

#if defined(CONFIG_GENERIC_MMC)

puts ("SD/MMC:  ");

mmc_exist = mmc_initialize(gd->bd);

if (mmc_exist != 0)

{

puts ("0 MB\n");

#ifdef CONFIG_CHECK_X210CV3

check_flash_flag=0;//check inand error!

#endif

}

#ifdef CONFIG_CHECK_X210CV3

else

{

check_flash_flag=1;//check inand ok!

}

#endif

#endif

#if defined(CONFIG_MTD_ONENAND)

puts("OneNAND: ");

onenand_init();

/*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/

#else

//puts("OneNAND: (FSR layer enabled)\n");

#endif

#if defined(CONFIG_CMD_NAND)

puts("NAND:    ");

nand_init();

#endif

#endif /* CONFIG_X210 */

#if defined(CONFIG_SMDK6440)

#if defined(CONFIG_GENERIC_MMC)

puts ("SD/MMC:  ");

mmc_exist = mmc_initialize(gd->bd);

if (mmc_exist != 0)

{

puts ("0 MB\n");

}

#else

#if defined(CONFIG_MMC)

if (INF_REG3_REG == 1) {    /* eMMC_4.3 */

puts("eMMC:    ");

movi_ch = 1;

movi_emmc = 1;

movi_init();

movi_set_ofs(0);

} else if (INF_REG3_REG == 7 || INF_REG3_REG == 0) {    /* SD/MMC */

if (INF_REG3_REG & 0x1)

movi_ch = 1;

else

movi_ch = 0;

puts("SD/MMC:  ");

movi_set_capacity();

movi_init();

movi_set_ofs(MOVI_TOTAL_BLKCNT);

} else {

}

#endif

#endif

if (INF_REG3_REG == 2) {

/* N/A */

} else {

puts("NAND:    ");

nand_init();

//setenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");

}

#endif /* CONFIG_SMDK6440 */

#if defined(CONFIG_SMDK6430)

#if defined(CONFIG_GENERIC_MMC)

puts ("SD/MMC:  ");

mmc_exist = mmc_initialize(gd->bd);

if (mmc_exist != 0)

{

puts ("0 MB\n");

}

#else

#if defined(CONFIG_MMC)

puts("SD/MMC:  ");

if (INF_REG3_REG == 0)

movi_ch = 0;

else

movi_ch = 1;

movi_set_capacity();

movi_init();

movi_set_ofs(MOVI_TOTAL_BLKCNT);

#endif

#endif

if (INF_REG3_REG == BOOT_ONENAND) {

#if defined(CONFIG_CMD_ONENAND)

puts("OneNAND: ");

onenand_init();

#endif

/*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/

} else if (INF_REG3_REG == BOOT_NAND) {

puts("NAND:    ");

nand_init();

} else {

}

if (INF_REG3_REG == 0 || INF_REG3_REG == 7)

setenv("bootcmd", "movi read kernel c0008000;movi read rootfs c0800000;bootm c0008000");

else

setenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");

#endif    /* CONFIG_SMDK6430 */

#if defined(CONFIG_SMDK6442)

#if defined(CONFIG_GENERIC_MMC)

puts ("SD/MMC:  ");

mmc_exist = mmc_initialize(gd->bd);

if (mmc_exist != 0)

{

puts ("0 MB\n");

}

#else

#if defined(CONFIG_MMC)

puts("SD/MMC:  ");

movi_set_capacity();

movi_init();

movi_set_ofs(MOVI_TOTAL_BLKCNT);

#endif

#endif

#if defined(CONFIG_CMD_ONENAND)

if (INF_REG3_REG == BOOT_ONENAND) {

puts("OneNAND: ");

onenand_init();

}

#endif

#endif    /* CONFIG_SMDK6442 */

#if defined(CONFIG_SMDK2416) || defined(CONFIG_SMDK2450)

#if defined(CONFIG_NAND)

puts("NAND:    ");

nand_init();

#endif

#if defined(CONFIG_ONENAND)

puts("OneNAND: ");

onenand_init();

#endif

#if defined(CONFIG_BOOT_MOVINAND)

puts("SD/MMC:  ");

if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) {

printf("Boot up for burning\n");

} else {

movi_init();

movi_set_ofs(MOVI_TOTAL_BLKCNT);

}

#endif

#endif    /* CONFIG_SMDK2416 CONFIG_SMDK2450 */

#ifdef CONFIG_HAS_DATAFLASH

AT91F_DataflashInit();

dataflash_print_info();

#endif

/* initialize environment */

env_relocate ();

/******************************************

环境变量的重定位,将SD卡中的环境变量搬移到DDR中

****************************************/

#ifdef CONFIG_VFD

/* must do this after the framebuffer is allocated */

drv_vfd_init();

#endif /* CONFIG_VFD */

#ifdef CONFIG_SERIAL_MULTI

serial_initialize();

#endif

/* IP Address  IP地址设置 */

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

/* MAC 地址设置 */

{

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 list going. */

#ifdef CONFIG_CMC_PU2

load_sernum_ethaddr ();

#endif /* CONFIG_CMC_PU2 */

/*跳转表*/

jumptable_init ();

#if !defined(CONFIG_SMDK6442)

/********************************************

控制台初始化的第二阶段,之前讲过console_init_f是第一阶段初始化,实际上第一阶段没有做什么实际的事情(只是执行了gd->have_console = 1;将这个变量设置为1),而控制台的初始化代码是在第二阶段完成的

**********************************/

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

#endif

#if defined(CONFIG_MISC_INIT_R)

/* miscellaneous platform dependent initialisations */

misc_init_r ();

#endif

/* enable exceptions CPSR中的总中断标志位使能,,通过条件编译来选择函数的实体,也就是说uboot中有多个enable_interrupts ();函数,然后通过宏来决定使用哪个*/

enable_interrupts ();

/* Perform network card initialisation if necessary */

#ifdef CONFIG_DRIVER_TI_EMAC

extern void dm644x_eth_set_mac_addr (const u_int8_t *addr);

if (getenv ("ethaddr")) {

dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);

}

#endif

#ifdef CONFIG_DRIVER_CS8900

cs8900_get_enetaddr (gd->bd->bi_enetaddr);

#endif

#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)

if (getenv ("ethaddr")) {

smc_set_mac_addr(gd->bd->bi_enetaddr);

}

#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */

/* Initialize from environment loadaddr:内核启动有关的环境变量 */

if ((s = getenv ("loadaddr")) != NULL) {

load_addr = simple_strtoul (s, NULL, 16);

}

#if defined(CONFIG_CMD_NET)

/*   bootfile:内核启动有关的环境变量  */

if ((s = getenv ("bootfile")) != NULL) {

copy_filename (BootFile, s, sizeof (BootFile));

}

#endif

#ifdef BOARD_LATE_INIT

board_late_init ();   //开发板后期(剩余部分)的初始化

#endif

#if defined(CONFIG_CMD_NET)

#if defined(CONFIG_NET_MULTI)

puts ("Net:   ");

#endif

eth_initialize(gd->bd);

#if defined(CONFIG_RESET_PHY_R)

debug ("Reset Ethernet PHY\n");

reset_phy();

#endif

#endif

#if defined(CONFIG_CMD_IDE)

puts("IDE:   ");

ide_init();

#endif

/****************lxg added**************/

#ifdef CONFIG_MPAD

extern int x210_preboot_init(void);

x210_preboot_init();

#endif

/****************end**********************/

/* check menukey to update from sd */

/*****************************************************

(1)uboot启动的最后阶段设计了一个自动更新的功能。就是:我们可以将要升级的镜像放到SD卡的固定目录中,然后开机时在uboot启动的最后阶段检查升级标志(是一个按键。按键中标志为"LEFT"的那个按键,这个按键如果按下则表update mode,如果启动时未按下则表示boot mode)。如果进入update mode则uboot会自动从SD卡中读取镜像文件然后烧录到iNand中;如果进入boot mode则uboot不执行update,直接启动正常运行。

(2)这种机制能够帮助我们快速烧录系统,常用于量产时用SD卡进行系统烧录部署。

********************************************************/

extern void update_all(void);

if(check_menu_update_from_sd()==0)//update mode

{

puts ("[LEFT DOWN] update mode\n");

run_command("fdisk -c 0",0);

update_all();

}

else

puts ("[LEFT UP] boot mode\n");

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

for (;;) {

main_loop ();

}

/* NOTREACHED - no way out of command loop except booting */

}

时间: 2024-10-27 03:07:12

uboot移植之start_armboot()函数分析的相关文章

uboot移植之start.S分析

uboot的函数入口要查看链接脚本中ENTTRY的入口参数,我们这里的链接脚本在board/samsung/x210/u-boot.lds,这个文件里面的开头有一句ENTRY(_start),所以uboot的入口就是在_start这个标识的地方. * Base codes by scsuh (sc.suh) */ //x210_sd.h对开发板的宏定义配置文件,这个文件会被用来生成一个autoconfig.mk文件,这个文件会被主Makefile引入,指导整个编译过程 #include <con

uboot移植之do_bootm函数和do_bootm_linux函数解析

一:do_bootm函数 (1)内核启动的时候通过bootm  30008000来启动内核,bootm这个命令对应的函数就是do_bootm. (2) #define LINUX_ZIMAGE_MAGIC    0x016f2818 LINUX_ZIMAGE_MAGIC是一个魔数,其值等于0x016f2818.在zImage的头信息中,有特定的位存放了一个魔数,这个魔数就是用来表示该镜像是zImage,在启动过程中,通过读取头信息的特定位和该魔数进行比较,用于判断该镜像是不是zImage. (3

u-boot移植启动流程详细分析(2)

学习底层的东西,首要的就是去了解他的架构,整体的思路知道了,就会在出现问题的时候有很清晰的思路,知道哪里出的问题,以及程序是如何执行的,相信做到上面的,所遇到的问题,大都会迎刃而解了吧,高手是有很多的,所谓的高手,不过也就那样吧,努力努力也是可以赶超的. 之前,介绍了u-boot的第一阶段的启动流程,那么接下来就来说说第二阶段的具体执行流程: (1)初始化gloabl data和board data,这里所谓的初始化就是给他们分配一块内存空间. (2)初始化序列(init_sequence) 在

uboot启动第二阶段--start_armboot函数

uboot第二阶段应该做什么? uboot的第二阶段就是要初始化剩下的还没被初始化的硬件,主要是SOC外部硬件(譬如inand.网卡芯片).uboot本身的一些东西(uboot的命令.环境变量等),然后最终初始化完必要的东西后进入uboot的命令行准备接受命令. uboot第二阶段完结于何处? uboot启动后自动运行打印出很多信息,这些信息就是uboot第一和第二阶段不断进行初始化时,打印出来的信息,然后uboot进入了bootdelay然后执行bootcmd对应的启动命令,如果这时候用户不干

uboot移植之主Makefile分析

1:#uboot 的版本号 VERSION      = 1                        #主版本号 PATCHLEVEL   = 3                   #次版本号 SUBLEVEL     = 4                     #再次版本号 EXTRAVERSION =                     #关于uboo的一些另外的描述 #变量U_BOOT_VERSION用来保存uboot的版本信息 U_BOOT_VERSION = $(VER

嵌入式linux开发uboot移植(三)——uboot启动过程源码分析

嵌入式linux开发uboot移植(三)--uboot启动过程源码分析 一.uboot启动流程简介 与大多数BootLoader一样,uboot的启动过程分为BL1和BL2两个阶段.BL1阶段通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常用汇编语言来实现:BL2阶段主要是对外部设备如网卡.Flash等的初始化以及uboot命令集等的自身实现,通常用C语言来实现. 1.BL1阶段 uboot的BL1阶段代码通常放在start.s文件中,用汇编语言实现,其主要代码功能如下:

U-Boot移植之前期分析(下)

接U-Boot移植之前期分析(上): 2. 顶层目录下mkconfig的分析过程 在上面的分析中知道了语句:"@$(MKCONFIG) $(@:_config=) arm arm920t MY_JZ2440 sumsung s3c24x0"对应于执行顶层目录下的mkconfig文件并传递了六个参数 ($0-$6):100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0.下面分析这句话的到底做了什么事情,具体可以阅读源码,由于比较简单这里直接列出具体

U-Boot移植之前期分析(上)

老是看别人移植uboot,用别人移植好的uboot,今天终于下定决心自己移植一个uboot来玩玩,好歹我也是个软件开发人员啊. 第一步:去ftp://ftp.denx.de/pub/u-boot/网站下载个uboot工程源码,为了防止环境出问题,我决定用个老一点的,于是就下了:u-boot-1.1.6.tar.bz2. 第二步:解压源码:tar  jxvf  u-boot-1.1.6.tar.bz2. 第三步:建立source insight工程 好了完成以上三步之后,我们需要的前提条件都准备好

uboot移植——uboot源码目录分析

uboot移植(一)--uboot源码目录分析 本文分析的uboot是九鼎官方提供的,是对应s5pv210开发板x210bv3的uboot 一:uboot的概念及移植的原理. uboot就是在内核运行前的一段小程序,用来初始化硬件设备,建立内存空间映射图.从而将系统的软硬件带到合适的状态,主要功能就是为了启动内核,它将内核从flash中拷贝到ddr中,然后跳转到内核入口中,交由内核控制权,uboot严重依赖硬件,因此一个通用的uboot不太可能. 移植原理:uboot中有很多平行代码,各自属于各