vivi的代码包括arch,init,lib,drivers和include等几个目录,共200多条文件。
vivi主要包括下面几个目录:
arch:此目录包括了所有vivi支持的目标板的子目录,例如s3c2410,s3c2440目录。
drivers:其中包括了引导内核需要的设备的驱动程序(MTD和串口)。MTD目录下分map、nand和nor三个目录。
init:这个目录只有main.c和version.c两个文件。和普通的C程序一样,vivi将从main函数开始执行。
lib:一些平台公共的接口代码,比如time.c里的udelay()和mdelay()。
include:头文件的公共目录,其中的s3c24xx.h定义了这块处理器的一些寄存器。Platform/smdk24xx.h定义了与开发板相关的资源配置参数,我们往往只需要修改这个文件就可以配置目标板的参数,如波特率、引导参数、物理内存映射等。
vivi的运行可以分为两个阶段:
vivi的第一阶段
完成含依赖于CPU的体系结构硬件初始化的代码,包括禁止中断、初始化串口、复制自身到RAM等。相关代码集中在head.S(viviarchs3c24xx目录下):Head.S:
vivi的第二阶段
vivi的第二阶段是从main()函数开始,同一般的C语言程序一样,该函数在/init/main.c文件中,总共可以分为8个步骤。
(1)函数开始,通过putstr(vivi_banner)打印出vivi的版本。Vivi_banner在/init/version.c文件中定义。执行reset_handler,用于将内存清零,代码在/lib/reset_handle.c中
(2)对开发板进行初始化(board_init函数),board_init是与开发板紧密相关的,这个函数在/arch/s3c24xx/smdk.c文件中。开发板初始化主要完成两个功能,时钟初始化(init_time())和通用IO口设置(set_gpios())。其中,GPIO口在smdk24xx.h(vivi/include/platform目录下)文件中定义。
(3)内存映射初始化和内存管理单元的初始化工作:这两个函数都在/arch/s3c24xx/mmu.c文件中。
(4)初始化堆栈,heap_init()。(定义在vivi/lib/heap.c文件中)
(5)初始化mtd设备,mtd_dev_init()。这几个函数可以在/drivers/mtd/maps/s3c24xx_flash.c里找到。(drivers/mtd/mtdcore.c)
(6) 初始化私有数据,init_priv_data()。(定义在vivi/lib/priv_data/rw.c文件中)
(7) 初始化内置命令,init_builtin_cmds()。通过add_command函数,加载vivi内置的几个命令。(lib/command.c)
(8)启动boot_or_vivi()。(main.c)
启动成功后,将通过vivi_shell()启动一个shell(如果配置了CONFIG_SERIAL_TERM),此时vivi的任务完成。
Vivi的初始配置文件位置:/vivi/arch/def-configs/smkd24xx, 通过make menuconfig 修改后的配置保存在这个文件中,我们也可以载入一个自己的配置文件来进行编译。
int main(int argc, char *argv[]) /*/init/main.c */
{
int ret;
putstr("/r/n");
putstr(vivi_banner);/* 通过putstr(vivi_banner)打印出vivi的版本。Vivi_banner在/init/version.c文件中定义。*/
reset_handler(); /*lib/reset_handle.c 执行reset_handler,用于将内存清零,代码 在/lib/reset_hand .c */
/* 开发板初始化主要完成两个功能,时钟初始化(init_time())和通用IO口设置(set_gpios())。其中,GPIO口在smdk24xx.h(vivi/include/platform目录下)文件中定义。*/
ret = board_init(); /*arch/s3c2410/smdk.c*/ //对开发板初始化
if (ret) {
putstr("Failed a board_init() procedure/r/n");
error();
}
/*内存映射初始化和内存管理单元的初始化*/
mem_map_init(); /*arch/s3c2410/mmu.c line194*/
mmu_init(); /*arch/s3c2410/mmu.c line120*/
putstr("Succeed memory mapping./r/n");
/*初始化堆栈*/
ret = heap_init(); /*lib/heap.c*/
if (ret) {
putstr("Failed initailizing heap region/r/n");
error();
}
/*初始化mtd设备*/
ret = mtd_dev_init(); /*drivers/mtd/mtdcore.c*/
misc(); /*arch/s3c2410/smdk.c*/
/* 初始化内置命令*/
init_builtin_cmds(); /*lib/command.c*/
/*启动boot_or_vivi()。(main.c)*/
boot_or_vivi(); /*call vivi_shell() or run_autoboot.*/
return 0;
}