今天看到了/etc/inittab,找了一通资料总结如下:
一般来说嵌入式Linux设备启动过程包括:
1、执行BootLoader
2、执行Kernel
3、执行应用程序
BootLoader的主要任务实际上是为了执行接下来的Kernel,它需要初始化最小系统(CPU+内存+Flash),为了调试信息初始化串口和显示屏。执行的最后阶段,将Kernel从Flash读取到RAM,验证+解压,送入参数,开始Kernel的引导了。
Kernel的主要任务是启动所有的外设,为执行应用程序准备。引导分为两步:
A:start_kernel,建立核心环境。
一般包括:CPU,Memory, RTC, CACHE,串口设备的初始化,最终会得到第一个核心线程Init。
整个工作在start_kernel()函数中实现,具体工作包括:
打印Linux版本信息(printk(linux_banner))
设置与体系结构相关的信息(setup_arch())
页表结构初始化(paging_init())
使用"arch/alpah/kernel/entry.S"的入口点设置系统的自陷入口(trap_init())
使用alpha_mv结构和entry.S入口初始化系统IRQ(init_IRQ())
核心进程调度器初始化(包括初始化几个缺省的Bottom-half, sched_init())
时间, 定时器初始化(包括读取CMOS时钟,估测主频,初始化定时器中断等,time_init())
提取并分析核心启动参数(从环境变量中读取参数,设置相应标志位等待处理,parse_options())
控制台初始化(为输出信息而优先PCI初始化,console_init())
剖析器数据结构初始化(prof_buffer和prof_len变量)
核心Cache初始化(描述Cahce信息的Cache,kemem_cache_init())
延迟校准(获得始终jiffies与CPU主频ticks的延迟,calibrate_delay())
内存初始化(社会子内存上下界和页表项初始值,mem_init())
创建和设置内部及通用cache(“slab_cache”,kmem_cache_sizes_init())
创建uid_taskcount SLAB cache(“uid_cache",uidcache_init())
创建文件cache(”files_cache",filescache_init())
创建目录cache(“dentry_cache",dcache_init())
创建与虚拟内存相关的cache(“vm_area_struct”,”mm_struct“,vam_init())
块设备读取缓冲区初始化(同时创建”buffer_head"cache用户加速访问,buffer_init())
创建页cache(内存页hash表初始化page_cache_init())
创建信号队列cache(“signal_queue",signals_init())
创建内存inode表(inode_init())
创建内存文件描述符表(”filp_cache“,file_table_init())
检查体系结构漏洞(check_bugs())
SMP机器其余CPU(除当前引导CPU)初始化(对于没有配置SMP的内核,此函数为空,smp_init())
启动init过程(创建第一个核心线程,调用init())函数,原执行序列调用cpu_idle())等待调度,init())
第二部分(init()函数执行)
锁定内核(SMP)
do_basic_setup() 完成外设及驱动程序的加载和初始化:
总线初始化(例如pci_init())
网络初始化(sk_init(),skb_init() proto_init())
创建bdflush核心线程(常驻核心空间,核心唤醒,用于清理被写过的内存缓冲区)
创建kupdate核心线程(常驻核心空间,定时执行,用于将缓冲区的信息更新到磁盘中)
启动核心调页线程kswapd
创建keventd(时间管理核心线程)
设备初始化(并口parport_init(),字符设备chr_dev_init(),块设备blk_dev_init(),SCSI设备scsi_dev_init(),网络设备net_dev_init(),磁盘初始化及分区检查,device_setup())
执行文件格式设置(binfmt_setup())
启动所有__initcall表示的函数(方便核心开发者添加启动函数,do_initcalls())
文件系统初始化(filesystem_setup())
安装root文件系统(mount_root())
释放启动内存段(free_initmem())并解锁内核。
打开/dev/console设备,重定向stdin,stdout,stderr到控制台
搜索文件系统中的init程序(或者由init=命令行参数指定的程序),并使用execve()系统调用家挨执行init程序
Init进程执行过程
init进程是所有进程的起点,它读取/etc/inittab文件作为其行为指针,inittab文件每行格式:
id:runlevel:action:process
id:标识符
runlevel:运行级别。0-6及S或者s。0:系统关闭,1:重启至单用户模式,6:重启;S或者s表示单用户。 3:最常用级别,表示多用户模式
对于用户登录登录来说,整个过程包括:
打开终端,设置模式
输出登录界面和提示,接受用户名的输入(缺省的登录提示在/etc/issue文件中,远程登录提示在/etc/issue.net中)
以该用户名作为login的参数,加载login程序。
(如果用户名不是root,且存在/etc/nologin文件,login将输出nologin文件的内容,然后退出,这通常是用来系统维护时防止非root用户登录)
(只有在/etc/securetty中登记的终端才允许root用户登录,若不存在,可以在任何终端中登录)
当用户登录检查后,login将搜索/etc/passwd文件(可能还会搜索/etc/shadow文件)比对密码,设置主目录和加载shell
执行shell并登录shell
(执行/etc/profile)
(~/.bash_profile)
(~/.bash_login)
(~/.profile)
(~/.bashrc)
至此,系统中运行着init进程和由rc启动脚本激活的守护进程(如inetd等),运行着一个bash作为用户的命令解释器