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


原创粉丝点击