Linux内核启动流程分析(一)

合集下载

嵌入式linux系统的启动流程

嵌入式linux系统的启动流程

嵌入式linux系统的启动流程
嵌入式Linux系统的启动流程一般包括以下几个步骤:
1.硬件初始化:首先会对硬件进行初始化,例如设置时钟、中
断控制等。

这一步骤通常是由硬件自身进行初始化,也受到系统的BIOS或Bootloader的控制。

2.Bootloader引导:接下来,系统会从存储介质(如闪存、SD
卡等)的Bootloader区域读取引导程序。

Bootloader是一段程序,可以从存储介质中加载内核镜像和根文件系统,它负责进行硬件初始化、进行引导选项的选择,以及加载内核到内存中。

3.Linux内核加载:Bootloader会将内核镜像从存储介质中加载到系统内存中。

内核镜像是包含操作系统核心的一个二进制文件,它由开发者编译并与设备硬件特定的驱动程序进行连接。

4.内核初始化:一旦内核被加载到内存中,系统会进入内核初
始化阶段。

在这个阶段,内核会初始化设备驱动程序、文件系统、网络协议栈等系统核心。

5.启动用户空间:在内核初始化完毕后,系统将启动第一个用
户空间进程(init进程)。

init进程会读取并解析配置文件(如
/etc/inittab)来决定如何启动其他系统服务和应用程序。

6.启动其他系统服务和应用程序:在用户空间启动后,init进
程会根据配置文件启动其他系统服务和应用程序。

这些服务和应用程序通常运行在用户空间,提供各种功能和服务。

以上是嵌入式Linux系统的基本启动流程,不同的嵌入式系统可能会有一些差异。

同时,一些特定的系统也可以添加其他的启动流程步骤,如初始化设备树、加载设备固件文件等。

Linux 系统引导过程

Linux 系统引导过程

启动流程启动时要加载核心,让核心来驱动整个硬件。

整个启动过程:1.加载BIOS的硬件信息,并获得第一个启动设备的代号(CMOS中设定的启动项)。

2.读取第一个启动设备的MBR的引导加载程序(lilo、grub、spfdisk)3.加载核心操作系统的核心信息,核心开始解压缩,并且尝试驱动所有硬件设备。

4.核心执行init程序并获取运行信息。

5.Init执行/etc/rc.d/rc.sysinit文件6.启动核心的外挂模块(/etc/modprobe.conf)7.Init 执行各个批处理文件(根据运行级别)。

8.Init 执行/etc/rc.d/rc.local文件9.执行/bin/login程序,等待用户登录。

10.登录之后开始以shell控制主机。

引导加载程序与核心的载入主机读取BIOS,并且了解主要的主机硬件信息后,主机便开始尝试加载操作系统。

主机首先读取的就是硬盘的主引导记录(MBR),在MBR中装有引导加载程序(比如说grub)。

主机刚启动时是不认识磁盘文件系统的,这就需要引导加载程序帮忙。

但我们知道MBR是整个硬盘的第一个扇区,整个大小为一个扇区的大小(512KB),而我们的加载程序却远远大于这个容量。

怎么办?引导加载程序分成两个阶段来执行:1,执行引导加载程序的主程序,这个主程序放在MBR或超级块中。

2,载入引导加载程序的所有设置文件与相关的环境参数文件。

一般来说,设置文件都放在/boot目录下。

引导加载程序必须能做到:●引导加载程序可以直接指定并取用核心文件,并加载到主存储器中。

●也可以将加载程序的控制权移交给下一个加载程序(超级块中的引导加载程序)。

grub是如何被载入的呢?grub有几个重要文档,stage1,stage2,以及stage1.5,这些文档都在/boot/grub下,grub被载入时有以下几个步骤。

Stage1阶段装载基本的引导程式(stage1),这也是安装在MBR中的内容,大小为512字节,但这并不意味着占用的空间为512字节,这还要看块的大小以及inode控制的块数。

Linux 内核启动分析

Linux 内核启动分析

Linux 内核启动分析1. 内核启动地址1.1. 名词解释ZTEXTADDR解压代码运行的开始地址。

没有物理地址和虚拟地址之分,因为此时MMU处于关闭状态。

这个地址不一定时RAM的地址,可以是支持读写寻址的flash等存储中介。

Start address of decompressor. here's no point in talking about virtual or physical addresses here, since the MMU will be off at the time when you call the decompressor code. Y ou normally call the kernel at this address to start it booting. This doesn't have to be located in RAM, it can be in flash or other read-only or read-write addressable medium.ZRELADDR内核启动在RAM中的地址。

压缩的内核映像被解压到这个地址,然后执行。

This is the address where the decompressed kernel will be written, and eventually executed. The following constraint must be valid:__virt_to_phys(TEXTADDR) == ZRELADDRThe initial part of the kernel is carefully coded to be position independent.TEXTADDR内核启动的虚拟地址,与ZRELADDR相对应。

一般内核启动的虚拟地址为RAM的第一个bank地址加上0x8000。

arm版本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. 加载系统服务:启动初始化会加载并启动系统服务,比如网络服务、日志服务、时间同步服务等。

嵌入式系统第七讲 嵌入式Linux系统启动分析

嵌入式系统第七讲 嵌入式Linux系统启动分析

嵌入式LINUX内核的版本控制 (2)
嵌入式Linux的版本号后面还会加一个后缀,如 “rmk4-mx1bsp0.3.6” ,该后缀往往表示针对某 个开发平台的补丁。几个常用的后缀:
– – –

rmk:表示由Russell King维护的ARM Linux; np:表示由Nicolas Pitre维护的基于StrongARM和 Xscale的ARM Linux; ac:表示由Alan Cox(Alan Cox是仅次于Linus的 Linux维护人员,主要负责网络部分和OSS等的维护 工作)维护的Linux代码; hh : 表 示 由 网 站 发 布 的 ARM Linux代码,主要是基于Xscale的,它包括工具链 、内核补丁、嵌入式图形系统等。
Bootloader空间位置
在flash中的典型空间分配情况
BootLoader 的主要功能(1/2)
初始化系统在启动阶段必需的硬件设备; 准备后续软件系统(如操作系统)运行所需 的软件环境,如复制操作系统内核代码到 RAM中等。 向内核传递启动参数; [可选]配置系统各种参数;
BootLoader 的主要功能(2/2)
BootLoader的特点
BootLoader是操作系统内核运行前的核心程 序,它具有如下特点: 代码量大; 由C语言写成,大多数时候需要嵌入式汇编 语言; 运行于SDRAM等随机存储器 由于它是启动内核前运行的最后一个程序, 它必须把控制权交给内核,因此它最后是一 条跳转到系统内核的语句。
嵌入式LINUX的内核源代码结构 (1)


COPYING
– GPL版权申明。
CREDITS
– 光荣榜。对Linux做出过重大贡献的人员信息。

Linux启动过程详解_MBR和GRUB概述

Linux启动过程详解_MBR和GRUB概述

MBR和GRUB概述Linux 的启动流程目前比较流行的方式主要是以下步骤:1、引导器(例如 GRUB)启动;2、内核启动;3、系统进程启动与配置。

本文以 GRUB 为研究对象,对 GRUB 启动与内核启动两个部分进行描述,关于系统进程的进一步启动与配置将用另一篇文章来说明。

常见的目录结构(以 CentOS 5.3 为例):/boot|-- System.map-2.6.18-128.el5|-- System.map-2.6.18-128.el5xen|-- config-2.6.18-128.el5|-- config-2.6.18-128.el5xen|-- initrd-2.6.18-128.el5.img|-- initrd-2.6.18-128.el5xen.img|-- lost+found|-- memtest86+-1.65|-- message|-- symvers-2.6.18-128.el5.gz|-- symvers-2.6.18-128.el5xen.gz|-- vmlinuz-2.6.18-128.el5|-- vmlinuz-2.6.18-128.el5xen|-- xen-syms-2.6.18-128.el5|-- xen.gz-2.6.18-128.el5`-- grub|-- device.map|-- e2fs_stage1_5|-- fat_stage1_5|-- ffs_stage1_5|-- grub.conf|-- iso9660_stage1_5|-- jfs_stage1_5|-- menu.lst -> ./grub.conf|-- minix_stage1_5|-- reiserfs_stage1_5|-- splash.xpm.gz|-- stage1|-- stage2|-- ufs2_stage1_5|-- vstafs_stage1_5`-- xfs_stage1_5图一: CentOS 5.3 的 /boot 目录目录分作两大部分,一个是 /boot 目录下除 grub 目录以外的所有文件,这些是 Linux 的内核以及内核启动相关的一些文件;另一个就是 grub 下的所有文件, GRUB 引导器启动所需要的所有文件都在 grub 目录下。

linux_mips启动流程_存储相关

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()。

第一部分:以函数调用关系为线索下面是函数之间调用关系的框图:第一章: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。

Linux内核分析_课程设计

Linux内核分析_课程设计

Linux内核分析_课程设计计算机科学与⼯程学院课程设计报告题⽬全称:Linux内核初起代码分析学⽣学号:姓名:指导⽼师:职称:指导⽼师评语:签字:课程设计成绩:⽬录摘要 (2)第⼀章引⾔ (1)1.1 问题的提出 (1)1.2任务与分析 (1)第⼆章代码分析 (2)2.1系统初始化过程流程 (2)2.2数据结构 (2)2.3常量和出错信息的意义 (4)2.4调⽤关系图 (4)2.5各模块/函数的功能及详细框图 (5)2.5.1 static void time_init(void)分析 (6)2.5.2 void main(void)分析 (6)2.5.3 pause()分析 (8)2.5.4 static int printf(const char *fmt, ...)分析 (8)2.5.5 void init(void)分析 (9)第三章内核调试 (12)3.1运⾏环境 (12)3.2编译内核过程 (12)第四章总结与体会 (15)致谢 (16)参考⽂献 (17)摘要随着计算机的普及,计算机发挥着越来越重要的作⽤,计算机的使⽤也越来越普遍,所以让更多的⼈能够更好的使⽤和掌握⼀些计算机⽅法显得⼗分重要。

充分发挥计算机的作⽤也显得⼗分重要。

操作系统应运⽽⽣。

操作系统是⼀种软件,⽤来帮助其他的程序控制计算机并和⽤户进⾏交互。

因⽽,对操作系统的研究是很有必要的。

操作系统包含了多个部分或者组件,最核⼼的部分是内核。

其他的部分⽤来帮助内核完成计算机资源的管理和应⽤程序的控制。

Linux操作系统是使⽤很⼴泛的,⾼质量的⼀个操作系统。

此次起始代码分析,我分析了init/main.c⽂件中的main()、init()以及编译内核代码。

main()中主要是关于起始的调⽤和设备和系统信息初始化,以及创建进程。

此时中断仍被禁⽌着,做完必要的设置后就将其开启init()是创建进程,并检测是否出错,出错则再次创建执⾏并打印出出错信息。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

很久以前分析的,一直在电脑的一个角落,今天发现贴出来和大家分享下。

由于是word直接粘过来的有点乱,敬请谅解!S3C2410 Linux 2.6.35.7启动分析(第一阶段) arm linux 内核生成过程1. 依据arch/arm/kernel/vmlinux.lds 生成linux内核源码根目录下的vmlinux,这个vmlinux属于未压缩,带调试信息、符号表的最初的内核,大小约23MB;命令:arm-linux-gnu-ld -o vmlinux -T arch/arm/kernel/vmlinux.ldsarch/arm/kernel/head.oinit/built-in.o--start-grouparch/arm/mach-s3c2410/built-in.okernel/built-in.omm/built-in.ofs/built-in.oipc/built-in.odrivers/built-in.onet/built-in.o--end-group .tmp_kallsyms2.o2. 将上面的vmlinux去除调试信息、注释、符号表等内容,生成arch/arm/boot/Image,这是不带多余信息的linux内核,Image的大小约3.2MB;命令:arm-linux-gnu-objcopy -O binary -S vmlinux arch/arm/boot/Image3.将 arch/arm/boot/Image 用gzip -9 压缩生成arch/arm/boot/compressed/piggy.gz大小约1.5MB;命令:gzip -f -9 < arch/arm/boot/compressed/../Image > arch/arm/boot/compressed/piggy.gz 4. 编译arch/arm/boot/compressed/piggy.S 生成arch/arm/boot/compressed/piggy.o大小约1.5MB,这里实际上是将piggy.gz通过piggy.S编译进piggy.o文件中。

而piggy.S文件仅有6行,只是包含了文件piggy.gz;命令:arm-linux-gnu-gcc -o arch/arm/boot/compressed/piggy.o arch/arm/boot/compressed/piggy.S5. 依据arch/arm/boot/compressed/vmlinux.lds 将arch/arm/boot/compressed/目录下的文件head.o 、piggy.o 、misc.o链接生成arch/arm/boot/compressed/vmlinux,这个vmlinux是经过压缩且含有自解压代码的内核,大小约1.5MB;命令:arm-linux-gnu-ld zreladdr=0x30008000 params_phys=0x30000100 -T arch/arm/boot/compressed/vmlinux.lds a rch/arm/boot/compressed/head.o arch/arm/boot/compressed/piggy.o arch/arm/boot/compressed/misc.o -o arch/arm/boot/compressed/vmlinux6.将arch/arm/boot/compressed/vmlinux去除调试信息、注释、符号表等内容,生成arch/arm/boot/zImage 大小约1.5MB;这已经是一个可以使用的linux内核映像文件了;命令:arm-linux-gnu-objcopy -O binary -S arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage7. 将arch/arm/boot/zImage添加64Bytes的相关信息打包为arch/arm/boot/uImage大小约1.5MB;命令: ./mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -n 'Linux-2.6.35.7' -d arch/arm/ boot/zImage arch/arm/boot/uImage内核启动分析:本文着重分析S3C2410 linux-2.6.35.7内核启动的详细过程,主要包括: zImage 解压缩阶段、 vmlinux 启动汇编阶段、 startkernel 到创建第一个进程阶段三个部分,一般将其称为 linux 内核启动一、二、三阶段,本文也将采用这种表达方式。

对于 zImage 之前的启动过程,本文不做表述,可参考前面正亮讲得“ u-boot的启动过程分析”。

本文中涉及到的术语约定如下:基本内核映像:即内核编译过程中最终在内核源代码根目录下生成的 vmlinux 映像文件,并不包含任何内核解压缩和重定位代码;zImage 内核映像:包含了内核piggy.o及解压缩和重定位代码,通常是目标板 bootloader 加载的对象;zImage 下载地址:即 bootloader 将 zImage 下载到目标板内存的某个地址或者 nand read 将 zImage 读到内存的某个地址;zImage 加载地址:由 Linux 的 bootloader 完成的将 zImage 搬移到目标板内存的某个位置所对应的地址值,默认值 0x30008000 。

1、Linux 内核启动第一阶段:内核解压缩和重定位该阶段是从u-boot引导进入内核执行的第一阶段,我们知道u-boot引导内核启动的最后一步是:通过一个函数指针thekernel()带三个参数跳转到内核(zImage)入口点开始执行,此时,u-boot的任务已经完成,控制权完全交给内核(zImage)。

稍作解释,在u-boot的文件arch\arm\lib\bootm.c(uboot-2010.9)中定义了thekernel,并在do_bootm_linux的最后执行thekernel.定义如下:void (*theKernel)(int zero, int arch, uint params);theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);//hdr->ih_ep----Entry Point Address uImage 中指定的内核入口点,这里是0x30008000。

theKernel (0, bd->bi_arch_number, bd->bi_boot_params);其中第二个参数为机器ID,第三参数为u-boot传递给内核参数存放在内存中的首地址,此处是0x30000100。

由上述zImage的生成过程我们可以知道,第一阶段运行的内核映像实际就是arch/arm/boot/compressed/vmlinux,而这一阶段所涉及的文件也只有三个:(1)arch/arm/boot/compressed/vmlinux.lds(2)arch/arm/boot/compressed/head.S(3)arch/arm/boot/compressed/misc.c下面的图是使用64MRAM时,通常的内存分布图:下面我们的分析集中在 arch/arm/boot/compressed/head.S, 适当参考 vmlinux.lds 。

从linux/arch/arm/boot/compressed/vmlinux.lds文件可以看出head.S的入口地址为ENTRY(_start),也就是head.S汇编文件的_start标号开始的第一条指令。

下面从head.S中得_start 标号开始分析。

(有些指令不影响初始化,暂时略去不分析)代码位置在/arch/arm/boot/compressed/head.S中:start:.type start,#function /*uboot跳转到内核后执行的第一条代码*/.rept 8 /*重复定义8次下面的指令,也就是空出中断向量表的位置*/mov r0, r0 /*就是nop指令*/.endrb 1f @ 跳转到后面的标号1处.word 0x016f2818 @ 辅助引导程序的幻数,用来判断镜像是否是zImage.word start @ 加载运行zImage的绝对地址,start表示赋的初值.word _edata @ zImage结尾地址,_edata是在vmlinux.lds.S中定义的,表示init,text,data三个段的结束位置1: mov r7, r1 @ save architecture ID 保存体系结构ID 用r1保存mov r8, r2 @ save atags pointer 保存r2寄存器参数列表,r0始终为0mrs r2, cpsr @ get current mode 得到当前模式tst r2, #3 @ not user?,tst实际上是相与,判断是否处于用户模式bne not_angel @ 如果不是处于用户模式,就跳转到not_angel标号处/*如果是普通用户模式,则通过软中断进入超级用户权限模式*/mov r0, #0x17 @ angel_SWIreason_EnterSVC,向SWI中传递参数swi 0x123456 @ angel_SWI_ARM这个是让用户空间进入SVC空间not_angel: /*表示非用户模式,可以直接关闭中断*/mrs r2, cpsr @ turn off interrupts to 读出cpsr寄存器的值放到r2中orr r2, r2, #0xc0 @ prevent angel from running关闭中断msr cpsr_c, r2 @ 把r2的值从新写回到cpsr中/*读入地址表。

因为我们的代码可以在任何地址执行,也就是位置无关代码(PIC),所以我们需要加上一个偏移量。

下面有每一个列表项的具体意义。

LC0是表的首项,它本身就是在此head.s中定义的.type LC0, #objectLC0: .word LC0 @ r1 LC0表的起始位置.word __bss_start @ r2 bss段的起始地址在vmlinux.lds.S中定义.word _end @ r3 zImage(bss)连接的结束地址在vmlinux.lds.S中定义.word zreladdr @ r4 zImage的连接地址,我们在arch/arm/mach-s3c2410/makefile.boot中定义的.word _start @ r5 zImage的基地址,bootp/init.S中的_start函数,主要起传递参数作用.word _got_start @ r6 GOT(全局偏移表)起始地址,_got_start是在compressed/vmlinux.lds.in中定义的.word _got_end @ ip GOT结束地址.word user_stack+4096 @ sp 用户栈底 user_stack是紧跟在bss段的后面的,在compressed/vmlinux.lds.in中定义的@ 在本head.S的末尾定义了zImag的临时栈空间,在这里分配了4K的空间用来做堆栈。

相关文档
最新文档