CFE Bootloader详解 — 引导过程
CFE命令
CFE引导过程
系统加电后,CFE从boot.S (src/shared/boot.S)开始执行,完成判断芯片类型、设置时钟、初始化缓存、把自身加载进RAM等任务后,跳转到c_main()(src/shared/load.c)
1 void c_main (unsigned long ra) 2 { 3 …… 4 /* Load binary */ 5 load (); /* 加载CFE,并解压 */ 6 …… 7 ((void (*) (void)) LOADADDR) (); /* 跳转到CFE中执行cfe_main() */ 8 }
在执行cfe_main () (cfe/cfe/main/cfe_main.c)前,更低级别的初始化工作已经完成,而此函数主要完成硬件初始化,包括ether driver,PCI,Console等外部设备的初始化,image更新,引导kernel等任务。
1 void cfe_main (int a, int b) 2 { 3 /* 4 * By the time this routine is called, the following things have 5 * already been done: 6 * 7 * 1. The processor(s) is(are) initialized. 8 * 2. The caches are initialized. 9 * 3. The memory controller is initialized. 10 * 4. BSS has been zeroed. 11 * 5. The data has been moved to R/W space. 12 * 6. The "C" Stack has been initialized. 13 */ 14 …… 15 cfe_bg_init(); /* 后台处理初始化 */ 16 cfe_attach_init (); /* 初始化CFE device list */ 17 cfe_timer_init (); 18 cfe_bg_add (cfe_device_poll, NULL); 19 20 board_console_init (); /* 硬件初始化,包括LED的初始化 */ 21 cfe_say_hello (); /* CFE开始信息 */ 22 cfe_arena_init (); /* 创建物理内存的初始映射 */ 23 board_device_init (); /* 设备初始化 */ 24 cfe_startup_info (); /* 输出信息,例如存储空间使用情况 */ 25 cfe_init_ui (); /* 接口初始化,包括Console命令行初始化 */ 26 board_final_init (); /* 硬件部分初始化 */ 27 cfe_autostart (); /* image更新,加载kernel */ 28 cfe_command_loop (); /* 如果上一步按了Ctrl-C,则进入CFE命令行模式 */ 29 …… 30 }
后台轮询
CFE没有使用中断做任何事情,而是使用轮询的方式。后台维护一个叫cfe_bg_tasklist的函数指针数组,数组元素中的函数指针指向后台任务处理函数的首地址,后台的任务数量是16。cfe_bg_init()初始化后台任务列表,cfe_bg_add()、cfe_bg_remove()负责在后台的定期轮询循环中添加或删除任务。
1 #define MAX_BACKGROUND_TASK 16 2 static void (*cfe_bg_tasklist [MAX_BACKGROUND_TASKS]) (void *)
CFE设备管理
cfe_attach_init()用于初始化CFE设备列表,这是一条双向队列,用来保存外部设备的信息。在设备嗅探时,cfe_attach ()将被调用,用于把设备添加进CFE设备列表中。在CFE中,用cfe_device_t (cfe/cfe/include/cfe_device.h)这个结构体来描述一个设备示例。
1 /* 2 * The Device structure defines a particular instance of a device. 3 * They are generated as a result of calling the cfe_attach call. 4 */ 5 6 typedef struct cfe_device_s { 7 queue_t dev_next; 8 char *dev_fullname; 9 void *dev_softc; 10 int dev_class; 11 const cfe_devdisp_t *dev_dispatch; 12 int dev_opencount; 13 char *dev_description; 14 } cfe_device_t;
cfe_devdisp_s (cfe/cfe/include/cfe_device.h)这个结构体由一系列函数指针构成,定义了对设备的常规操作。
1 struct cfe_devdisp_s { 2 int (*dev_open)(cfe_devctx_t *ctx); 3 int (*dev_read)(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 4 int (*dev_inpstat)(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat); 5 int (*dev_write)(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 6 int (*dev_ioctl)(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 7 int (*dev_close)(cfe_devctx_t *ctx); 8 void (*dev_poll)(cfe_devctx_t *ctx,int64_t ticks); 9 void (*dev_reset)(void *softc); /* called when device is closed, so no devctx_t */ 10 };