Linux开机启动顺序分析
嵌入式linux系统的启动流程

嵌入式linux系统的启动流程
嵌入式Linux系统的启动流程一般包括以下几个步骤:
1.硬件初始化:首先会对硬件进行初始化,例如设置时钟、中
断控制等。
这一步骤通常是由硬件自身进行初始化,也受到系统的BIOS或Bootloader的控制。
2.Bootloader引导:接下来,系统会从存储介质(如闪存、SD
卡等)的Bootloader区域读取引导程序。
Bootloader是一段程序,可以从存储介质中加载内核镜像和根文件系统,它负责进行硬件初始化、进行引导选项的选择,以及加载内核到内存中。
3.Linux内核加载:Bootloader会将内核镜像从存储介质中加载到系统内存中。
内核镜像是包含操作系统核心的一个二进制文件,它由开发者编译并与设备硬件特定的驱动程序进行连接。
4.内核初始化:一旦内核被加载到内存中,系统会进入内核初
始化阶段。
在这个阶段,内核会初始化设备驱动程序、文件系统、网络协议栈等系统核心。
5.启动用户空间:在内核初始化完毕后,系统将启动第一个用
户空间进程(init进程)。
init进程会读取并解析配置文件(如
/etc/inittab)来决定如何启动其他系统服务和应用程序。
6.启动其他系统服务和应用程序:在用户空间启动后,init进
程会根据配置文件启动其他系统服务和应用程序。
这些服务和应用程序通常运行在用户空间,提供各种功能和服务。
以上是嵌入式Linux系统的基本启动流程,不同的嵌入式系统可能会有一些差异。
同时,一些特定的系统也可以添加其他的启动流程步骤,如初始化设备树、加载设备固件文件等。
arm版本linux系统的启动流程

arm版本linux系统的启动流程ARM架构是一种常见的处理器架构,被广泛应用于嵌入式设备和移动设备中。
在ARM版本的Linux系统中,启动流程是非常重要的,它决定了系统如何从开机到正常运行。
本文将详细介绍ARM版本Linux系统的启动流程。
一、引导加载程序(Bootloader)引导加载程序是系统启动的第一阶段,它位于系统的固化存储器中,比如ROM或Flash。
在ARM版本的Linux系统中,常用的引导加载程序有U-Boot和GRUB等。
引导加载程序的主要功能是加载内核镜像到内存中,并将控制权转交给内核。
二、内核初始化引导加载程序将内核镜像加载到内存后,控制权被转交给内核。
内核初始化是系统启动的第二阶段,它主要完成以下几个步骤:1. 设置异常向量表:ARM架构中,异常是指硬件产生的中断或故障,比如系统调用、中断请求等。
内核需要设置异常向量表,以便正确处理异常。
2. 初始化处理器:内核对处理器进行初始化,包括设置页表、启用缓存、初始化中断控制器等。
3. 启动第一个进程:内核创建第一个用户进程(一般是init进程),并将控制权转交给它。
init进程是系统中所有其他进程的父进程,负责系统的初始化工作。
三、设备树(Device Tree)设备树是ARM版本Linux系统中的一种机制,用于描述硬件设备的相关信息。
在内核初始化过程中,内核会解析设备树,并建立设备树对象,以便后续的设备驱动程序使用。
设备树描述了硬件设备的类型、地址、中断等信息,以及设备之间的连接关系。
它使得内核能够在运行时自动识别和配置硬件设备,大大提高了系统的可移植性和灵活性。
四、启动初始化(Init)启动初始化是系统启动的第三阶段,它是用户空间的第一个进程(init进程)接管系统控制权后的操作。
启动初始化主要完成以下几个任务:1. 挂载根文件系统:启动初始化会挂载根文件系统,使得用户可以访问文件系统中的文件和目录。
2. 加载系统服务:启动初始化会加载并启动系统服务,比如网络服务、日志服务、时间同步服务等。
3、linux系统启动过程分析(下)

例子的解释
上面两个汇编程序采用的语法虽然完全不同, 但功能却都是调用 Linux 内核提供的 sys_write 来显示一个字符串,然后再调用 sys_exit 退出 程序。 Linux系统有效的系统调用列表安装在: /usr/man/man2/unistd.h /usr/include/sys/syscall.h. /usr/include/asm/unistd.h ,可以找到所有系统 调用的定义
操作系统引导流程
0.01版内核,以软盘启动为例:
1 开机 2 BIOS 加电自检 ( Power On Self Test,POST ),内存地址为 0ffff:0000 3 将软盘第一个扇区 (0头0道1扇区, 也就是Boot Sector)读入内存地址 0000:7c00 处。 4 检查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于则转去尝试其他启动 介质, 如果没有其他启动介质则显示"No ROM BASIC" 然后死机。 5 跳转到 0000:7c00 处执行 MBR 中的程序。 6 MBR将自己移动到9000:0000 7 将内核模块从软盘读入到1000:0000 8 将内核模块移动到0000:0000 9 进入保护模式 10 读取COMS信息,设置有关表格,然后调用操作系统初始化程序MAIN.C 1-5完全由BIOS完成,6-10由 BOOT\BOOT.S HEAD.S完成 其中BOOT.S的目标代码就是MBR(主引导记录Master Boot Record)中的程序
计算机加电过程
当机算机的电源键被按下时,同这个键相联的电信号线就会送出 一个电信号给主板,主板将此电信号传给供电系统,供电系统开 始工作,为整个系统供电,并送出一个电信号给BIOS,通知 BIOS 供电系统已经准备完毕。随后BIOS 启动一个程序,进行主 机自检,主机自检的主要工作是确保系统的每一个部分都得到了 电源支持,内存储器、主板上的其它芯片、键盘、鼠标、磁盘控 制器及一些I/O 端口正常可用,此后,自检程序将控制权还给 BIOS。 接下来BIOS 读取BIOS 设置,得到引导驱动器的顺序,然后依次 检查,直到找到可以用来引导的驱动器(或说可以用来引导的磁 盘,包括软盘、硬盘、光盘等),然后调用这个驱动器上磁盘的 引导扇区进行引导。
剖析Linux系统引导流程

MB ManB o cr 主引导扇 区 R( i o t o Re d)
①位置: 道 0面第一扇区。 0 ②产生时间 : 硬盘分区时创建。 ③读取方法 :
一
’
步 : N 8启动 盘启 动 A D B G 回车 WI 9 EU
MOV AX,2 0 01 MOV BX,0 1 0 MOV CX, 1
MOV DX,0 8 I 3 NT 1
回 车
. oE 回 车 G_
一
D2 0 显 示 数 据 B
④主引导扇区内容(1 字节) 52
●主 引导扇 区引导程序 (4 4 6字节 ) ● 分 区 表 数 据 ( " 6字 节 ) 41 ● 分 区 表 标 志 5 A 2字 节 ) 5 A(
重 新 引 导 系 统 。 C U执 行 1H 号 中 断 的初 始 引 导 程 P 9
序 ,以便从 启动 盘 读 取 加 载 操 作 系 统 的 引 导 程 序
B osc.。 初始 引导程序是 按照 C S里 设置 的启 ot t 该 e S MO
动盘启 动顺序查 找相 应盘 的 MB R.如找 到 了引导 程 序, 则将 MB R中的引导程序 读到 内存 0 0 7 0 0 0:C 0处 , 并执行这个 引导程序 再将 内核 代码全 部装人 内存 。 这 里 主要 涉及 与 系统 启 动 有关 的 概 念是 MB R,
维普资讯
研 究 与开 发
数据 数据 数据 数据 6 分区结束 磁道号 : 7 分 区结束 扇区号 : 8 1 :2位本 分 区之 前的扇 区数 - 13 1— 5 3 2 1 :2位本分 区之后 的扇区数
2 第二阶段 : B — L 0 H L — 活动分 区引导 R I
Linux命令行使用技巧如何查看和管理系统进程优先级

Linux命令行使用技巧如何查看和管理系统进程优先级在Linux操作系统中,进程优先级是指操作系统对运行中的进程进行调度和分配资源的重要参数之一。
通过合理地设置进程优先级,能够有效地提高系统的性能和稳定性。
本文将介绍一些Linux命令行使用技巧,帮助你查看和管理系统进程优先级。
一、查看系统进程1. top命令:top命令是Linux下常用的查看系统进程的命令。
通过top命令,你可以实时地查看各个进程的运行情况、进程ID、CPU使用率等信息。
2. ps命令:ps命令也是查看系统进程的常用命令。
通过ps命令,你可以查看当前用户的进程情况、各个进程的状态、进程ID等信息。
二、了解进程优先级在Linux系统中,进程的优先级用一个范围为-20到19的数值表示,其中-20表示最高优先级,19表示最低优先级。
默认情况下,普通用户创建的进程的优先级为0,系统进程的优先级通常较高。
三、修改进程优先级1. renice命令:renice命令用于修改已经运行的进程的优先级。
通过renice命令,你可以提高或降低进程的优先级。
假设你想将进程ID为12345的进程的优先级提高到10,你可以使用以下命令:```renice 10 12345```2. nice命令:nice命令用于在启动进程时指定进程的优先级。
通过nice命令,你可以创建一个具有较高或较低优先级的进程。
假设你想在运行一个新的进程时将其优先级设置为5,你可以使用以下命令:```nice -n 5 command```其中,command表示你要运行的命令或程序。
四、管理系统进程优先级1. taskset命令:taskset命令用于将进程绑定到指定的CPU或CPU 集。
通过taskset命令,你可以管理进程的调度情况。
假设你想将进程ID为12345的进程绑定到CPU 0上,你可以使用以下命令:```taskset -p 0x1 12345```2. chrt命令:chrt命令用于修改进程的调度策略和优先级。
Linux命令行中的系统启动和服务管理

Linux命令行中的系统启动和服务管理在Linux操作系统中,系统启动和服务管理是非常重要的任务。
正确地管理系统启动和服务可以保证系统的稳定性和安全性。
本文将介绍Linux命令行中的系统启动和服务管理的方法和技巧。
一、系统启动1. 启动顺序系统启动的顺序是按照一定的步骤进行的。
首先是UEFI/BIOS进行硬件自检,然后加载引导程序(如GRUB),然后引导程序加载内核,并且初始化系统的第一个进程init。
在init进程中,根据配置文件(如/etc/inittab)来启动其他进程和服务。
2. 系统运行级别Linux系统有不同的运行级别,每个运行级别对应着一组不同的服务。
根据需要,用户可以在运行级别之间切换。
常见的运行级别有:- 运行级别0:关机- 运行级别1:单用户模式(救援模式)- 运行级别2:多用户模式(没有NFS)- 运行级别3:完全的多用户模式- 运行级别4:保留(不常用)- 运行级别5:图形模式- 运行级别6:重启要切换运行级别,可以使用命令`init <运行级别>`或者`telinit <运行级别>`。
3. 查看系统启动日志系统启动过程中的日志信息被记录在/var/log目录下的一些文件中。
要查看启动日志,可以使用命令`dmesg`或者查看相关日志文件(如/var/log/messages)。
二、服务管理1. 查看服务状态要查看当前系统上正在运行的服务,可以使用命令`systemctl list-units`。
该命令将列出所有正在运行的服务及其状态。
2. 启动和停止服务要启动一个服务,可以使用命令`systemctl start <服务名>`。
要停止一个服务,可以使用命令`systemctl stop <服务名>`。
例如,要启动Apache Web服务器,可以使用命令`systemctl start httpd`。
3. 设置服务开机启动要设置一个服务在系统启动时自动启动,可以使用命令`systemctl enable <服务名>`。
grub启动过程

第二阶段:
BIOS通过下面两种方法之一来传递引导记录:
第一, 将控制权传递给initial program loader(IPL),该程序安装在磁盘主引导记录(MBR)中
/boot/grub/stage2 /etc/rc.d/rc<#>.d
/etc/rc.d/init.d/*
stage 1:MBR(512 字节,0头0道1扇区),前446字节存放的是 stage1,后面存放硬盘分区表信息,BIOS将stag1载入内存中0x7c00处并跳转执行。stage1(/stage1/start.S)的任务非常单纯,仅仅是将硬盘0头0道2扇区读入内存。0头0道2扇区内容是源代码中的/stage2/start.S,编译后512字节,它是stage2或者stage1_5的入口。
BIOS启动引导阶段 GRUB启动引导阶段 内核阶段 /init/sysinit阶段
==================================================================================================
读取/boot/grub.conf文件并显示启动菜单;
装载所选的kernel和initrd文件到内存中
第三阶段:内核阶段:
运行内核启动参数;
解压initrd文件并挂载initd文件系统,装载必须的驱动;
start.S的主要功能是将stage2或stage1_5从硬盘载入内存,如果是stage2,则载入0x820处;如果是 stage1_5,则载入0x2200处。
linux_mips启动流程_存储相关

Linux-mips启动流程-存储相关linux内核启动的第一个阶段是从/arch/mips/kernel/head.s文件开始的。
而此处正是内核入口函数kernel_entry(),该函数定义在/arch/mips/kernel/head.s文件里。
kernel_entry()函数是体系结构相关的汇编语言,它首先初始化内核堆栈段,来为创建系统中的第一个进程进行准备,接着用一段循环将内核映像的未初始化数据段(bss段在_edata和_end之间)清零,最后跳转到/arch/mips/kernel/setup.c 中的start_kernel()初始化硬件平台相关的代码。
下面讲述start_kernel() 函数。
在这个函数中跟内存初始化的函数是setup_arch()。
第一部分:以函数调用关系为线索下面是函数之间调用关系的框图:(1):start_kenel()->setup_arch()setup_arch(&command_line);每种体系结构都有自己的setup_arch() 函数,这些是体系结构相关的。
【如何确定编译那个体系结构的setup_arch() 函数呢?主要由linux 源码树顶层Makefile 中ARCH 变量来决定的。
例如:MIPS 体系结构的SUBARCH := mipsARCH ?= $(SUBARCH)】。
void __init setup_arch(char **cmdline_p){cpu_probe();调用函数cpu_probe(),该函数通过MIPS CPU的PRID寄存器来确定CPU类型,从而确定使用的指令集和其他一些CPU参数,如TLB等prom_init();prom_init() 函数是和硬件相关的,做一些低层的初始化,接受引导装载程序传给内核的参数,确定mips_machgroup,mips_machtype 这两个变量,这两个变量分别对应着相应的芯片组合开发板;cpu_report();打印cpu_probe() 函数检测到的CPU 的Processor ID。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
开机过程指的是从打开计算机电源直到LINUX显示用户登录画面的全过程。
分析LINUX开机过程也是深入了解LINUX核心工作原理的一个很好的途径。
启动第一步--加载BIOS当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。
这是因为BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。
在此之后,计算机心里就有谱了,知道应该去读取哪个硬件设备了。
在BIOS将系统的控制权交给硬盘第一个扇区之后,就开始由Linux来控制系统了。
启动第二步--读取MBR硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,可里面却存放了预启动信息、分区表信息。
可分为两部分:第一部分为引导(PRE-BOOT)区,占了446个字节;第二部分为分区表(PARTITION PABLE),共有66个字节,记录硬盘的分区信息。
预引导区的作用之一是找到标记为活动(ACTIVE)的分区,并将活动分区的引导区读入内存。
系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。
其实被复制到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是lilo或者grub了。
启动第三步--Boot LoaderBoot Loader 就是在操作系统内核运行之前运行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。
通常,BootLoade:是严重地依赖于硬件而实现的,不同体系结构的系统存在着不同的Boot Loader。
Linux的引导扇区内容是采用汇编语言编写的程序,其源代码在arch/i386 /boot中(不同体系的CPU有其各自的boot目录),有4个程序文件:◎bootsect.S,引导扇区的主程序,汇编后的代码不超过512字节,即一个扇区的大小。
◎setup.S,引导辅助程序。
◎edd.S,辅助程序的一部分,用于支持BIOS增强磁盘设备服务。
◎video.S,辅助程序的另一部分,用于引导时的屏幕显示。
Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的Loader,这里以Grub为例来讲解吧。
系统读取内存中的grub配置信息(一般为menu.lst或grub.lst),并依照此配置信息来启动不同的操作系统。
启动第四步--加载内核根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。
此时,屏幕一般会输出“Uncompressing Linux”的提示。
当解压缩内核完成后,屏幕输出“OK, booting the kernel”。
系统将解压后的内核放置在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。
至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。
start_kenrel()定义在init/main.c中,它就类似于一般可执行程序中的mai n()函数,系统在此之前所做的仅仅是一些能让内核程序最低限度执行的初始化操作,真正的内核初始化过程是从这里才开始。
函数start_kerenl()将会调用一系列的初始化函数,用来完成内核本身的各方面设置,目的是最终建立起基本完整的Linux核心环境。
start_kernel()中主要执行了以下操作:(1) 在屏幕上打印出当前的内核版本信息。
(2) 执行setup_arch(),对系统结构进行设置。
(3)执行sched_init(),对系统的调度机制进行初始化。
先是对每个可用CP U上的runqueque进行初始化;然后初始化0号进程(其task struct和系统空M堆栈在startup_32()中己经被分配)为系统idle进程,即系统空闲时占据CPU的进程。
(4)执行parse_early_param()和parsees_args()解析系统启动参数。
(5)执行trap_initQ,先设置了系统中断向量表。
0-19号的陷阱门用于C PU异常处理;然后初始化系统调用向量;最后调用cpu_init()完善对CPU的初始化,用于支持进程调度机制,包括设定标志位寄存器、任务寄存器、初始化程序调试相关寄存器等等。
(6)执行rcu_init(),初始化系统中的Read-Copy Update互斥机制。
(7)执行init_IRQ()函数,初始化用于外设的中断,完成对IDT的最终初始化过程。
(8)执行init_timers(), softirq_init()和time_init()函数,分别初始系统的定时器机制,软中断机制以及系统日期和时间。
(9)执行mem_init()函数,初始化物理内存页面的page数据结构描述符,完成对物理内存管理机制的创建。
(10)执行kmem_cache_init(),完成对通用slab缓冲区管理机制的初始化工作。
(11)执行fork_init(),计算出当前系统的物理内存容量能够允许创建的进程(线程)数量。
(12)执行proc_caches_init() , bufer_init(), unnamed_dev_init() ,vfs_cac hes_init(), signals_init()等函数对各种管理机制建立起专用的slab缓冲区队列。
(13 )执行proc_root_init()Wl数,对虚拟文件系统/proc进行初始化。
在start_kenrel()的结尾,内核通过kenrel_thread()创建出第一个系统内核线程(即1号进程),该线程执行的是内核中的init()函数,负责的是下一阶段的启动任务。
最后调用cpues_idle()函数:进入了系统主循环体口默认将一直执行default_idle()函数中的指令,即CPU的halt指令,直到就绪队列中存在其他进程需要被调度时才会转向执行其他函数。
此时,系统中唯一存在就绪状态的进程就是由kerne_hread()创建的init进程(内核线程),所以内核并不进入default_idle()函数,而是转向init()函数继续启动过程。
启动第五步--用户层init依据inittab文件来设定运行等级内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/initta b文件,并依据此文件来进行初始化工作。
其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。
Linux的运行等级设定如下:0:关机1:单用户模式2:无网络支持的多用户模式3:有网络支持的多用户模式4:保留,未使用5:有网络支持有X-Window支持的多用户模式6:重新引导系统,即重启启动第六步--init进程执行rc.sysinit在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/r c.sysinit脚本程序,它做的工作非常多,包括设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。
如果你有兴趣,可以到/etc/rc.d中查看一下rc.sysinit文件。
线程init的最终完成状态是能够使得一般的用户程序可以正常地被执行,从而真正完成可供应用程序运行的系统环境。
它主要进行的操作有:(1) 执行函数do_basic_setup(),它会对外部设备进行全面地初始化。
(2) 构建系统的虚拟文件系统目录树,挂接系统中作为根目录的设备(其具体的文件系统已经在上一步骤中注册)。
(3) 打开设备/dev/console,并通过函数sys_dup()打开的连接复制两次,使得文件号0,1 ,2 全部指向控制台。
这三个文件连接就是通常所说的“标准输入”stdin,“标准输出”stdout和“标准出错信息”stderr这三个标准I/O通道。
(4) 准备好以上一切之后,系统开始进入用户层的初始化阶段。
内核通过系统调用execve()加载执T子相应的用户层初始化程序,依次尝试加载程序"/sbin/initl"," /etc/init"," /bin/init',和“/bin/sh。
只要其中有一个程序加载获得成功,那么系统就将开始用户层的初始化,而不会再回到init()函数段中。
至此,init()函数结束,Linux内核的引导部分也到此结束。
启动第七步--启动内核模块具体是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块。
启动第八步--执行不同运行级别的脚本程序根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。
启动第九步--执行/etc/rc.d/rc.local你如果打开了此文件,里面有一句话,读过之后,你就会对此命令的作用一目了然:# This script will be executed *after* all the other init scripts.# You can put your own initialization stuff in here if you don’t# want to do the full Sys V style init stuff.rc.local就是在一切初始化工作后,Linux留给用户进行个性化的地方。
你可以把你想设置和启动的东西放到这里。
启动第十步--执行/bin/login程序,进入登录状态此时,系统已经进入到了等待用户输入username和password的时候了,你已经可以用自己的帐号登入系统了。