嵌入式Linux启动过程

本文详细介绍了嵌入式Linux设备的启动过程,包括BootLoader、Kernel和应用程序的执行步骤。深入探讨了Kernel启动的两个主要阶段:start_kernel和init()函数的执行,以及Init进程如何读取/etc/inittab文件来指导后续操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天看到了/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作为用户的命令解释器



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值