C语言启动代码board.c分析
来源:互联网 发布:上海行知外国语小学 编辑:程序博客网 时间:2024/05/23 01:01
237 init_fnc_t *init_sequence[] = {
238 #if defined(CONFIG_ARCH_CPU_INIT)
239
240 /* 基本的处理器相关配置 -- cpu/arm920t/cpu.c */
241 arch_cpu_init, /* basic arch cpu dependent setup */
242 #endif
243
244 /* 基本的板级相关配置 -- board/smdk2410/smdk2410.c */
245 /* 是初始化与硬件平台有关的函数。它的工作很明显:时
246 *钟的设置,引脚 IO 口的设置,并且在这里把数据 cache 和指令 cache 也打开
247 *了。以上工作的完成,标志着板子已经准备好工作了。当然,考虑到可能系统会
248 * 因此 u-boot发生意外中断,所以我们还需要初始化中断, 让中断也准备好工作,
249 *代码中下一步就开始了中断的初始化。 */
250 board_init, /* basic board dependent setup */
251
252 #if defined(CONFIG_USE_IRQ)
253 /* 初始化中断处理 -- cpu/arm920t/s3c24x0/interrupt.c */
254 interrupt_init, /* set up exceptions */
255 #endif
256 timer_init, /* initialize timer */
257 env_init, /* initialize environment */
258 init_baudrate, /* initialze baudrate settings */
259 serial_init, /* serial communications setup */
260
261 /* 控制台初始化阶段1 -- common/console.c */
262 /* 这个函数的功能只有一个,就是指出我们目前是使
263 用串口的,因此有此句:gd->have_console = 1;然后直接返回 0。 */
264 console_init_f, /* stage 1 init of console */
265
266 /* 打印u-boot信息 -- lib_arm/board.c */
267 display_banner, /* say that we are here */
268 #if defined(CONFIG_DISPLAY_CPUINFO)
269 print_cpuinfo, /* display cpu info (and speed) */
270 #endif
271 #if defined(CONFIG_DISPLAY_BOARDINFO)
272 checkboard, /* display board info */
273 #endif
274 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
275 init_func_i2c,
276 #endif
277 /* 配置可用的RAM -- board/smdk2410/smdk2410.c */
278 dram_init, /* configure available RAM banks */
279 #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
280 arm_pci_init,
281 #endif
282 /* 显示RAM的配置大小 -- lib_arm/board.c */
283 display_dram_config,
284 NULL,
285 };
286
// C语言入口函数
287 void start_armboot (void)
288 {
289 init_fnc_t **init_fnc_ptr;
290 char *s;
291 #if defined(CONFIG_VFD) || defined(CONFIG_LCD)
292 unsigned long addr;
293 #endif
294
295 /*
296 *如同使用变量之前,需要声明定义一样,这里使用全局变量 gd 和 bd 之前,
297 *我们需要先设置它的地址,并用 memset 函数为它分配合适的空间。u-boot
298 *的注释告知我们,gd 和 bd 是一个可写的指针,实际上不过是一个地址而已。
299 *代码中的这句话:__asm__ __volatile__("": : :"memory");目的就是
300 *告诉编译器内存被修改过了。
301 */
302 /* Pointer is writable since we allocated a register for it */
303 gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
304 /* compiler optimization barrier needed for GCC >= 3.4 */
305 __asm__ __volatile__("": : :"memory");
306
307 memset ((void*)gd, 0, sizeof (gd_t));
308 gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
309 memset (gd->bd, 0, sizeof (bd_t));
310
311 gd->flags |= GD_FLG_RELOC;
312
313 monitor_flash_len = _bss_start - _armboot_start;
314
315 /*
316 *(函数指针) 指向的是 init_fnc_t指针数组的每个成员都对应着一个函数名 ,
317 *类型的函数。For 语句每次都会判断当前的函数是不是 NULL,如果是,则跳出
318 *for 语句,完成当前的板子初始化列表函数的功能。
319 * 可能大家都注意到了一个类型:init_fnc_t,它表示什么意思呢?我们看到
320 *了在初始化列表函数之前,有一个新的数据类型,它是个 typedef 语句:
321 * typedef int (init_fnc_t) (void);
322 *可能有的同学对此不太理解,为啥非得用一个 typedef 呢?笔者认为,可以不
323 *用 typedef,但是用了 init_fnc_t 后,团队中别的成员来看代码的时候,会很
324 *轻松地知道,这是一个初始化(init)的函数(fnc),增加了代码的可读性。
325 */
326 // init_sequence[]数组保存着基本的初始化函数指针。
327 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
328 if ((*init_fnc_ptr)() != 0) {
329 hang ();
330 }
331 }
332
333 /*初始化内存分配函数 _armboot_start 在u-boot.lds链接脚本中定义 */
334 /* armboot_start is defined in the board-specific linker script*/
335 /* mem_malloc_init 函数,这是非常关键的一步,请大家引起注意。我们必须配
336 置好内存的起始地址和结束地址,然后把这块区域清零,以便后续来使用它。 */
337 mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
338 CONFIG_SYS_MALLOC_LEN);
339
340 #ifndef CONFIG_SYS_NO_FLASH
341 /* configure available FLASH banks */
342 display_flash_config (flash_init ());
343 #endif /* CONFIG_SYS_NO_FLASH */
344
345 #ifdef CONFIG_VFD
346 # ifndef PAGE_SIZE
347 # define PAGE_SIZE 4096
348 # endif
349 /*
350 * reserve memory for VFD display (always full pages)
351 */
352 /* bss_end is defined in the board-specific linker script */
353 addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
354 vfd_setmem (addr);
355 gd->fb_base = addr;
356 #endif /* CONFIG_VFD */
357
358 #ifdef CONFIG_LCD
359 /* board init may have inited fb_base */
360 if (!gd->fb_base) {
361 # ifndef PAGE_SIZE
362 # define PAGE_SIZE 4096
363 # endif
364 /*
365 * reserve memory for LCD display (always full pages)
366 */
367 /* bss_end is defined in the board-specific linker script */
368 addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
369 lcd_setmem (addr);
370 gd->fb_base = addr;
371 }
372 #endif /* CONFIG_LCD */
373
374 #if defined(CONFIG_CMD_NAND)
375 puts ("NAND: ");
376 nand_init(); /* go init the NAND */
377 #endif
378
379 #if defined(CONFIG_CMD_ONENAND)
380 onenand_init();
381 #endif
382
383 #ifdef CONFIG_HAS_DATAFLASH
384 AT91F_DataflashInit();
385 dataflash_print_info();
386 #endif
387 /* 配置环境变量*/
388 /* initialize environment */
389 env_relocate ();
390
391 #ifdef CONFIG_VFD
392 /* must do this after the framebuffer is allocated */
393 drv_vfd_init();
394 #endif /* CONFIG_VFD */
395
396 #ifdef CONFIG_SERIAL_MULTI
397 serial_initialize();
398 #endif
399 /* 从环境变量中获取IP地址 */
400 /* IP Address */
401 gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
402
403 stdio_init (); /* get the devices list going. */
404
405 jumptable_init ();
406
407 #if defined(CONFIG_API)
408 /* Initialize API */
409 api_init ();
410 #endif
411
412 /* 完整地初始化控制台设备 */
413 console_init_r (); /* fully init console as a device */
414
415 #if defined(CONFIG_ARCH_MISC_INIT)
416 /* miscellaneous arch dependent initialisations */
417 arch_misc_init ();
418 #endif
419 #if defined(CONFIG_MISC_INIT_R)
420 /* miscellaneous platform dependent initialisations */
421 misc_init_r ();
422 #endif
423
424 /* enable exceptions */
425 enable_interrupts (); /* 使能中断处理 */
426
427 /* Perform network card initialisation if necessary */
427 /* Perform network card initialisation if necessary */
428 #ifdef CONFIG_DRIVER_TI_EMAC
429 /* XXX: this needs to be moved to board init */
430 extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
431 /* 通过环境变量初始化 */
432 if (getenv ("ethaddr")) {
433 uchar enetaddr[6];
434 eth_getenv_enetaddr("ethaddr", enetaddr);
435 davinci_eth_set_mac_addr(enetaddr);
436 }
437 #endif
- C语言启动代码board.c分析
- s3c2410 board.c分析
- s3c2410 board.c分析
- Uboot 启动流程分析:启动阶段2 board.c
- mini6410 uboot board.c 分析
- mini6410 uboot board.c 分析
- C程序启动代码分析
- board.c
- board.c
- u-boot 中board.c的分析
- U-BOOT/Board/flash.c 分析
- uboot-1.1.6 /lib_arm/board.c分析
- uboot-1.1.6 /lib_arm/board.c分析
- u-boot第二阶段board.c分析
- UBOOT之board.c分析(一)
- UBOOT之board.c分析(二)
- UBOOT之board.c分析(三)
- UBOOT之board.c分析(四)
- 学习XML之三:XML 树结构
- Java课程设计 矩阵类 实现加、减、乘法
- Spring框架的七个模块
- 第三章 运算符和控制流
- uva 103 (dp)Stacking Boxes
- C语言启动代码board.c分析
- 学习XML之四:XML 语法规则
- 我的博客史
- oracle 常用系统表与视图
- 归并排序的C++实现代码
- PCI 32,PCI 64和PCI-X,PCI-E图解差别
- 学习XML之五:XML 元素
- screen 使用方法 详解
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用14