仅以arm9的s3c2440/2410来分析。有什么问题,欢迎指正,jk_new@163.com
U-BOOT开始执行从 uboot/cpu/arm920T/start.S 的_start: b reset ...............开始执行。
Start.S是ARM的汇编,网上已经有很详细的资料了。
/****VFD linear frame buffer driver 屏幕线性帧缓存驱动定义***/
通过 ldr pc, _start_armboot
_start_armboot: .word start_armboot 这条指令跳转到C语言编写的start_armboot()函数,该函数在 uboot/lib_arm/board.c中定义 ,这个函数首先出现的是如下的一个宏定义:
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
typedef struct {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long have_console; /*调用serial_init()*/
unsigned long reloc_off; /* 重定向的偏移*/
unsigned long env_addr; /* 环境结构的地址 */
unsigned long env_valid; /* 环境是否合法的校验和 */
unsigned long cpu_clk; /* CPU clock in Hz! */
unsigned long bus_clk;
unsigned long ram_size; /* RAM size */
unsigned long reset_status; /* reset status register at boot */
void **jt; /* jump table */
} gd_t;
typedef struct bd_info {
unsigned long bi_memstart; /* start of DRAM memory */
unsigned long bi_memsize; /* size of DRAM memory in bytes */
unsigned long bi_flashstart; /* start of FLASH memory */
unsigned long bi_flashsize; /* size of FLASH memory */
unsigned long bi_flashoffset; /* reserved area for startup monitor */
unsigned long bi_sramstart; /* start of SRAM memory */
unsigned long bi_sramsize; /* size of SRAM memory */
unsigned long bi_ip_addr; /* IP Address */
unsigned char bi_enetaddr[6]; /* Ethernet adress */
unsigned long bi_baudrate; /* Console Baudrate */
} bd_t;
gd = &gd_data;
memset ((void *)gd, 0, sizeof (gd_t)); /***初始化gd指针=0***/
/********memset(需要初始化的指针首地址,初始化填充的内容,初始化的size大小)****** */
gd->bd = &bd_data;
memset (gd->bd, 0, sizeof (bd_t)); /**初始化bd=0**/
typedef int (init_fnc_t) (void);/***见typedef用法,定义int 类型的函数名**/
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */ /*定义在cpu/arm920t/cpu.c中*/
board_init, /* basic board dependent setup */ /*定义在board/smdk2440/smdk2440.c*/
interrupt_init, /* set up exceptions *//**定义在cpu/arm920t/interrupts.c**/
env_init, /* initialize environment *//*如果你使用的是flash,那么在common/env_flash.c中*/
init_baudrate, /* initialze baudrate settings *//**定义在lib_arm/board.c中**/
serial_init, /* serial communications setup */ /**定义在cpu/arm920t/serial.c中**/
console_init_f, /* stage 1 init of console *//*第一阶段的重定位之前调用此函数,定义在common/Console.c中*/
display_banner, /* say that we are here *//**显示版本号啊、IRQ,FIQ堆栈段位置等等信息,定义在lib_arm/boardbak.c中**/
dram_init, /* configure available RAM banks *//*定义在board/smdk2440/smdk2440.c中**/
display_dram_config,/**显示DRAM的信息,定义在lib_arm/board.c中**/
#if defined(CONFIG_VCMA9)
checkboard,
#endif
NULL,
};
其实在初始化完后就可以使用函数puts();来进行串口的信息打印了,其中串口的初始化函数为serial.c中的
void serial_setbrg (void)函数。
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
上面的语句作用就是进行init_sequence 这个init结构的函数初始化,返回都为0,不然就hang ();(死循环)
#if 0
/* configure available FLASH banks */
size = flash_init ();
display_flash_config (size);
#endif
/**上面的代码为测试Flash条件语句启动**/
/********以下是关于Flash的一些函数*******/
ulong flash_init(void);
先看一个Flash的结构体,FLASH Info: contains chip specific data, per FLASH bank
有关Flash的部分,查看我的博客里面的一份6.nand Flash的文档,结合了本uboot的函数相关进行分析。
typedef struct {
ulong size; /* total bank size in bytes */
ushort sector_count; /* number of erase units */
ulong flash_id; /* combined device & manufacturer code */
ulong start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */
uchar protect[CFG_MAX_FLASH_SECT]; /* sector protection status */
#ifdef CFG_FLASH_CFI
uchar portwidth; /* the width of the port */
uchar chipwidth; /* the width of the chip */
ushort buffer_size; /* # of bytes in write buffer */
ulong erase_blk_tout; /* maximum block erase timeout */
ulong write_tout; /* maximum write timeout */
ulong buffer_write_tout; /* maximum buffer write timeout */
#endif
} flash_info_t;
/********以上是关于Flash的一些函数*******/
U-BOOT开始执行从 uboot/cpu/arm920T/start.S 的_start: b reset ...............开始执行。
Start.S是ARM的汇编,网上已经有很详细的资料了。
/****VFD linear frame buffer driver 屏幕线性帧缓存驱动定义***/
通过 ldr pc, _start_armboot
_start_armboot: .word start_armboot 这条指令跳转到C语言编写的start_armboot()函数,该函数在 uboot/lib_arm/board.c中定义 ,这个函数首先出现的是如下的一个宏定义:
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
大概的意思是声明一个指向gd_t结构体变量的指针gd,并固定使用寄存器r8来存放该指针。
看下gd_t结构: 包含在:
include/common.h下面的----->
include/asm-arm/global_data.h
typedef struct {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long have_console; /*调用serial_init()*/
unsigned long reloc_off; /* 重定向的偏移*/
unsigned long env_addr; /* 环境结构的地址 */
unsigned long env_valid; /* 环境是否合法的校验和 */
unsigned long cpu_clk; /* CPU clock in Hz! */
unsigned long bus_clk;
unsigned long ram_size; /* RAM size */
unsigned long reset_status; /* reset status register at boot */
void **jt; /* jump table */
} gd_t;
typedef struct bd_info {
unsigned long bi_memstart; /* start of DRAM memory */
unsigned long bi_memsize; /* size of DRAM memory in bytes */
unsigned long bi_flashstart; /* start of FLASH memory */
unsigned long bi_flashsize; /* size of FLASH memory */
unsigned long bi_flashoffset; /* reserved area for startup monitor */
unsigned long bi_sramstart; /* start of SRAM memory */
unsigned long bi_sramsize; /* size of SRAM memory */
unsigned long bi_ip_addr; /* IP Address */
unsigned char bi_enetaddr[6]; /* Ethernet adress */
unsigned long bi_baudrate; /* Console Baudrate */
} bd_t;
gd = &gd_data;
memset ((void *)gd, 0, sizeof (gd_t)); /***初始化gd指针=0***/
/********memset(需要初始化的指针首地址,初始化填充的内容,初始化的size大小)****** */
gd->bd = &bd_data;
memset (gd->bd, 0, sizeof (bd_t)); /**初始化bd=0**/
typedef int (init_fnc_t) (void);/***见typedef用法,定义int 类型的函数名**/
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */ /*定义在cpu/arm920t/cpu.c中*/
board_init, /* basic board dependent setup */ /*定义在board/smdk2440/smdk2440.c*/
interrupt_init, /* set up exceptions *//**定义在cpu/arm920t/interrupts.c**/
env_init, /* initialize environment *//*如果你使用的是flash,那么在common/env_flash.c中*/
init_baudrate, /* initialze baudrate settings *//**定义在lib_arm/board.c中**/
serial_init, /* serial communications setup */ /**定义在cpu/arm920t/serial.c中**/
console_init_f, /* stage 1 init of console *//*第一阶段的重定位之前调用此函数,定义在common/Console.c中*/
display_banner, /* say that we are here *//**显示版本号啊、IRQ,FIQ堆栈段位置等等信息,定义在lib_arm/boardbak.c中**/
dram_init, /* configure available RAM banks *//*定义在board/smdk2440/smdk2440.c中**/
display_dram_config,/**显示DRAM的信息,定义在lib_arm/board.c中**/
#if defined(CONFIG_VCMA9)
checkboard,
#endif
NULL,
};
其实在初始化完后就可以使用函数puts();来进行串口的信息打印了,其中串口的初始化函数为serial.c中的
void serial_setbrg (void)函数。
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
上面的语句作用就是进行init_sequence 这个init结构的函数初始化,返回都为0,不然就hang ();(死循环)
#if 0
/* configure available FLASH banks */
size = flash_init ();
display_flash_config (size);
#endif
/**上面的代码为测试Flash条件语句启动**/
/********以下是关于Flash的一些函数*******/
ulong flash_init(void);
先看一个Flash的结构体,FLASH Info: contains chip specific data, per FLASH bank
有关Flash的部分,查看我的博客里面的一份6.nand Flash的文档,结合了本uboot的函数相关进行分析。
typedef struct {
ulong size; /* total bank size in bytes */
ushort sector_count; /* number of erase units */
ulong flash_id; /* combined device & manufacturer code */
ulong start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */
uchar protect[CFG_MAX_FLASH_SECT]; /* sector protection status */
#ifdef CFG_FLASH_CFI
uchar portwidth; /* the width of the port */
uchar chipwidth; /* the width of the chip */
ushort buffer_size; /* # of bytes in write buffer */
ulong erase_blk_tout; /* maximum block erase timeout */
ulong write_tout; /* maximum write timeout */
ulong buffer_write_tout; /* maximum buffer write timeout */
#endif
} flash_info_t;
/********以上是关于Flash的一些函数*******/