概述
1 Bootloader
CPU上电复位, 从NOR Flash物理地址0x00000000启动
拷贝内核镜像到ram高位地址
传dtb给内核,
传启动参数给内核
跳转到压缩镜像入口
2 linux/arch/nios2/boot/compressed/head.S
进入__start
关闭中断
使指令和数据cache无效
解压内核镜像到低地址
初始化指令和数据cache
初始化MMU, 开始使用虚拟地址
jump到kernel address
3 linux-2.6/arch/nios2/kernel/head.S
__start入口
Disable interrupts
刷新指令cache
中断异常入口
刷新data cache
屏蔽所有interrupts
clear .BSS
call start_kernel函数
4 linux-2.6/init/main.c start_kernel()函数
调用setup_arch()
调用rest_init()
5 linux-2.6/arch/nios2/kernel setup_arch()函数
6 linux-2.6/init/main.c rest_init()函数
主要功能是创建并启动内核线程init
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);//创建kernel_init内核线程,PID=1
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);//创建kthread内核线程,PID=2
cpu_idle(); //内核本体进入idle状态,用循环消耗空闲的CPU时间
7 linux-2.6/init/main.c kernel_init()函数
do_basic_setup(); //重要函数,主要是初始化设备驱动程序
init_post(); //启动用户空间init进程
8 linux-2.6/init/main.c do_basic_setup()函数
init_tmpfs(); //
driver_init(); //初始化驱动模型中的各个子系统
9 linux-2.6/drivers/base/init.c driver_init()函数
devtmpfs_init(); //初始化devtmpfs文件系统
devices_init(); //初始化驱动模型中的部分子系统和kobject
buses_init(); //初始化驱动模型中的bus子系统
classes_init(); //初始化驱动模型中的class子系统
firmware_init(); //初始化驱动模型中的firmware子系统
hypervisor_init(); //初始化驱动模型中的hypervisor子系统
platform_bus_init(); //初始化驱动模型中的bus/platform子系统
system_bus_init(); //初始化驱动模型中的devices/system子系统
cpu_dev_init(); //初始化驱动模型中的devices/system/cpu子系统
memory_dev_init(); //初始化驱动模型中的devices/system/memory子系统
10 linux-2.6/init/main.c init_post()函数
启动用户init进程(1号进程)
11 执行/etc/rc
12 init进程读取/etc/inittab文件, 启动更多子进程
参考
http://blog.chinaunix.net/uid-20746260-id-3176497.html
NIOS2 Linux 启动时终端输出
Linux version 2.6.39-01079-g938653e-dirty (root@localhost.localdomain) (gcc version 4.1.2) #207 Wed Apr 16 07:56:21 PDT 2014
//linux-2.6/init/main.c start_kernel()
printk(KERN_NOTICE "%s", linux_banner);
bootconsole [early0] enabled
early_console initialized at 0xe0401440
//linux-2.6/init/main.c start_kernel()-->
//linux-2.6/arch/nios2/kernel/setup.c setup_arch()-->
//linux-2.6/arch/nios2/kernel/early_printk.c setup_early_printk()-->
register_console(&early_console);
printk(KERN_INFO "early_console initialized at 0x%08lx\n", base_addr);
//linux-2.6/kernel/printk.c register_console()
if (bcon &&
((newcon->flags & (CON