uboot第二阶段启动流程

来源:互联网 发布:通达信证券交易软件 编辑:程序博客网 时间:2024/05/19 18:14
#include <stdio.h>typedef unsigned long ulong;typedefstruct environment_s {} env_t;typedef struct bd_info {    intbi_baudrate;/* serial console baudrate */    unsigned longbi_ip_addr;/* IP Address */    struct environment_s       *bi_env;    ulong        bi_arch_number;/* unique id for this board */    ulong        bi_boot_params;/* where this board expects params */    struct/* RAM configuration */    {   ulong start;   ulong size;    }bi_dram[1];} bd_t;int main(int argc, const char *argv[]){printf("sizeof(bd_t) = %d\n",sizeof(bd_t));return 0;}


#include <stdio.h>typedefstructglobal_data {void*bd;unsigned longflags;unsigned longbaudrate;unsigned longhave_console;/* serial_init() was called */unsigned longenv_addr;/* Address  of Environment struct */unsigned longenv_valid;/* Checksum of Environment valid? */unsigned longfb_base;/* base address of frame buffer */void**jt;/* jump table */} gd_t;int main() {printf("sizeof(gd_t) : %d\n",(int)sizeof(gd_t));return 0;}

typedefstruct environment_s {uint32_tcrc;/* CRC32 over data bytes*/unsigned charflags;/* active/obsolete flags*/unsigned chardata[ENV_SIZE]; /* Environment data*/} env_t;typedef struct bd_info {//串口通讯波特率    intbi_baudrate;/* serial console baudrate */    //IP 地址unsigned longbi_ip_addr;/* IP Address */    //环境变量起始地址struct environment_s       *bi_env;    //开发板的机器码ulong        bi_arch_number;/* unique id for this board */    //uboot传递给内核参数的起始地址ulong        bi_boot_params;/* where this board expects params */    //内存信息struct/* RAM configuration */    {   ulong start;//内存的起始地址   ulong size;//内存大小    }bi_dram[1];} bd_t;typedefstructglobal_data {bd_t*bd;unsigned longflags; //uboot是否重定向的标志//串口波特率unsigned longbaudrate;//是否有一个控制台标志unsigned longhave_console;/* serial_init() was called *///环境变量所在的地址unsigned longenv_addr;/* Address  of Environment struct *///环境变量是否有效unsigned longenv_valid;/* Checksum of Environment valid? */unsigned longfb_base;/* base address of frame buffer */void**jt;/* jump table */} gd_t;typedef int (init_fnc_t) (void);register volatile gd_t *gd asm ("r8");ulong monitor_flash_len;init_fnc_t *init_sequence[] = {//初始化CPU相关设置:系统时钟操作函数arch_cpu_init,/* basic arch cpu dependent setup *///初始化开发板相关设置:开发板的机器码 board_init,/* basic board dependent setup *///初始化定时器timer_init,/* initialize timer *///初始化环境变量env_init,/* initialize environment *///初始化波特率 init_baudrate,/* initialze baudrate settings *///串口初始化serial_init,/* serial communications setup *///控制台设备一级初始化console_init_f,/* stage 1 init of console *///打印u-boot版本、编译时间 display_banner,/* say that we are here *///打印CPU类型和当前运行频率print_cpuinfo,/* display cpu info (and speed) *///打印开发板名称checkboard,   /* display board info *///配置可用的内存dram_init,   /* configure available RAM banks *///显示当前内存大小display_dram_config,NULL,};void start_armboot (void){init_fnc_t **init_fnc_ptr;char *s;/* Pointer is writable since we allocated a register for it  * _armboot_start :0x20f00044 * CONFIG_SYS_MALLOC_LEN:0x120000 * sizeof(gd_t)   :0x40 [64byte] * * gd : 0x20de0004 */gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));/* compiler optimization barrier needed for GCC >= 3.4 */__asm__ __volatile__("": : :"memory");memset ((void*)gd, 0, sizeof (gd_t));//gd->bd :0x20de0004 -  0x38 = 0x20ddffccgd->bd = (bd_t*)((char*)gd - sizeof(bd_t));memset (gd->bd, 0, sizeof (bd_t));gd->flags |= GD_FLG_RELOC;//uboot去掉bss段的大小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 ();}}//将堆区初始化为0/* armboot_start is defined in the board-specific linker script */mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,CONFIG_SYS_MALLOC_LEN);puts ("NAND:  ");//NAND FALSH 初始化nand_init();/* go init the NAND *//*读取Nand Flash的环境变量,然后做CRC校验,如果错误则使用默认的环境变量*/env_relocate ();/*获得IP 地址*/gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");//初始化输入、输出设备列表stdio_init ();/* get the devices list going. */jumptable_init ();//初始化标准输入、输出、出错console_init_r ();/* fully init console as a device *//* 使能IRQ异常 */enable_interrupts ();/* Initialize from environment */if ((s = getenv ("loadaddr")) != NULL) {load_addr = simple_strtoul (s, NULL, 16);}//初始化网卡设备eth_initialize(gd->bd);/* 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 */}void hang (void){puts ("### ERROR ### Please RESET the board ###\n");for (;;);}

struct serial_device {char name[NAMESIZE];char ctlr[CTLRSIZE];int  (*init) (void);void (*setbrg) (void);int (*getc) (void);int (*tstc) (void);void (*putc) (const char c);void (*puts) (const char *s);struct serial_device *next;};static struct serial_device *serial_current = NULL;struct serial_device *default_serial_console(void) __attribute__((weak, alias("__default_serial_console")));int serial_init (void){if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {struct serial_device *dev = default_serial_console ();return dev->init ();}return serial_current->init ();}struct serial_device *__default_serial_console (void){return &s5pc1xx_serial0_device;}int s5p_serial0_init(void) { return serial_init_dev(0); }void s5p_serial0_setbrg(void) {serial_setbrg_dev(0); } int s5p_serial0_getc(void) { return serial_getc_dev(0); } int s5p_serial0_tstc(void) {return serial_tstc_dev(0); } void s5p_serial0_putc(const char c) { serial_putc_dev(c, 0); } void s5p_serial0_puts(const char *s) { serial_puts_dev(s, 0); }struct serial_device s5pc1xx_serial0_device = {"s5pser0","S5PUART0",s5p_serial0_init, s5p_serial0_setbrg, s5p_serial0_getc, s5p_serial0_tstc, s5p_serial0_putc, s5p_serial0_puts, };/* * Initialise the serial port with the given baudrate. The settings * are always 8 data bits, no parity, 1 stop bit, no start bits. */int serial_init_dev(const int dev_index){struct s5pc1xx_uart *const uart = s5pc1xx_get_base_uart(dev_index);/* reset and enable FIFOs, set triggers to the maximum */writel(0, &uart->ufcon);writel(0, &uart->umcon);/* 8N1 */writel(0x3, &uart->ulcon);/* No interrupts, no DMA, pure polling */writel(0x245, &uart->ucon);serial_setbrg_dev(dev_index);return 0;}void serial_setbrg_dev(const int dev_index){DECLARE_GLOBAL_DATA_PTR;struct s5pc1xx_uart *const uart = s5pc1xx_get_base_uart(dev_index);u32 pclk = get_pclk();u32 baudrate = gd->baudrate;u32 val;val = pclk / baudrate;writel(val / 16 - 1, &uart->ubrdiv);writew(udivslot[val % 16], &uart->udivslot);}

void main_loop (void){char *s;int bootdelay;u_boot_hush_start ();s = getenv ("bootdelay");bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);s = getenv ("bootcmd");debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");if (bootdelay >= 0 && s && !abortboot (bootdelay)) {parse_string_outer(s, FLAG_PARSE_SEMICOLON |    FLAG_EXIT_FROM_LOOP);/* * Main Loop for Monitor Command Processing */parse_file_outer();/* This point is never reached */for (;;);}static __inline__ int abortboot(int bootdelay){int abort = 0;printf("Hit any key to stop autoboot: %2d ", bootdelay);/* * Check if key already pressed * Don't check if bootdelay < 0 */if (bootdelay >= 0) {if (tstc()) {/* we got a key press*/(void) getc();  /* consume input*/puts ("\b\b\b 0");abort = 1;/* don't auto boot*/}}while ((bootdelay > 0) && (!abort)) {int i;--bootdelay;/* delay 100 * 10ms */for (i=0; !abort && i<100; ++i) {if (tstc()) {/* we got a key press*/abort  = 1;/* don't auto boot*/bootdelay = 0;/* no more delay*/(void) getc();  /* consume input*/break;}udelay(10000);}printf("\b\b\b%2d ", bootdelay);}putc('\n');return abort;}


0 0