uboot第二阶段启动流程
2015-07-07 10:25
344 查看
#include <stdio.h> typedef unsigned long ulong; typedef struct environment_s { } env_t; typedef struct bd_info { int bi_baudrate; /* serial console baudrate */ unsigned long bi_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> typedef struct global_data { void *bd; unsigned long flags; unsigned long baudrate; unsigned long have_console; /* serial_init() was called */ unsigned long env_addr; /* Address of Environment struct */ unsigned long env_valid; /* Checksum of Environment valid? */ unsigned long fb_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; }
typedef struct environment_s { uint32_t crc; /* CRC32 over data bytes */ unsigned char flags; /* active/obsolete flags */ unsigned char data[ENV_SIZE]; /* Environment data */ } env_t; typedef struct bd_info { //串口通讯波特率 int bi_baudrate; /* serial console baudrate */ //IP 地址 unsigned long bi_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; typedef struct global_data { bd_t *bd; unsigned long flags; //uboot是否重定向的标志 //串口波特率 unsigned long baudrate; //是否有一个控制台标志 unsigned long have_console; /* serial_init() was called */ //环境变量所在的地址 unsigned long env_addr; /* Address of Environment struct */ //环境变量是否有效 unsigned long env_valid; /* Checksum of Environment valid? */ unsigned long fb_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 = 0x20ddffcc gd->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; }
相关文章推荐
- 微博开发第一步
- nyoj阶乘分解因式(1)
- HOG特征
- 关于C++builder中精度丢失的问题
- CAN总线基础知识(一)
- DSO missing from command line
- LVS的DR模式
- C#开发Unity游戏教程之Scene视图与脚本的使用
- 算法基础:删除字符串中出现次数最少的字符(Golang实现)
- 华为S8508交换机的问题
- Delphi与各种装置设备之间的开发整合及应用实例
- 用户体验之如何优化你的APP
- 二叉树路径的和(算法)
- 如何在Oracle中建立表和表空间?
- 上下无缝滚动(应用高级盒子模型)
- leetCode(31):Combination Sum III
- 关于SQL Server数据库中的注释---扩展属性的使用
- 加载storyboard和xib文件
- leetCode(31):Combination Sum III 分类: leetCode 2015-07-07 10:23 163人阅读 评论(0) 收藏
- javascript笔记01:javascript入门介绍