arm-linux启动流程分析
- 格式:doc
- 大小:31.50 KB
- 文档页数:3
Arm linux 启动分析(1)王利明 walimi@ 宋振宇zhenyusong@ 2003-3-201.概述:在内核运行之前需要系统引导程序(Bootloader)完成加载内核和一些辅助性的工作,然后跳转到内核代码的起始地址并执行。
本文先分析了Bootloader 的初始化工作,接着从内核镜像的起始地址进行分析。
整个arm linux 内核的启动可分为三个阶段:第一阶段主要是进行cpu 和体系结构的检查、cpu 本身的初始化以及页表的建立等;第二阶段主要是对系统中的一些基础设施进行初始化;最后则是更高层次的初始化,如根设备和外部设备的初始化。
第一阶段的初始化是从内核入口(ENTRY(stext))开始到start_kernel 前结束。
这一阶段的代码在/arch/arm/head_armv.S 中。
2.Bootloader 2.1简介 本处介绍主要来自内核源代码下的Documentation/arm/Booting 文件,适合于arm linux 2.4.18-rmk6及以上版本。
Bootloader 主要作用是初始化一些必要的设备,然后调用内核,同时传递参数给内核。
主要完成如下工作:1. 建立和初始化RAM 。
2. 初始化一个串口。
3.4.建立内核的5. 调用内核镜像。
2.2功能详细介绍 1.建立和初始化RAM 。
要求:必须功能:探测所有的RAM 位置和大小,并对RAM 进行初始化。
2.初始化一个串口。
要求:可选,建议功能:Bootloader 应该初始化并启动一个串口。
这可以让内核的串口驱动自动探测哪个串口作为内核的控制台。
另外也可以通过给内核传递“console=”参数完成此工作。
3.检测机器的系统结构。
要求:必须功能:Bootloader 应该通过某种方法探测机器类型,最后传递给内核一个MACH_TYPE_xxx 值,这些值参看4要求:必须功能:Bootloader 必须创建和初始化内核的tagged list 。
Linux开发驱动底层环境启动流程Uboot编译:rm -rf 删除命令tar xjf 解压uboot文件patch -p1 < ../u-boot-1.1.6.jz2440.patch 打补丁 -p1 指示忽略第一个斜杠前因为已经在当前目录。
打好补丁之后配置文件make 100ask24x0_config之后make配置文件是厂家提供好的。
Make后生成bin文件,在Windows下进入oflash目录烧写这个文件。
选择Open jtag S2C2440 nand flash 0块0 2 0 0 0这几个数字烧写之后进入启动界面之后uboot命令按help查看支持哪些命令。
?Md 查看 md命令Print 命令查看环境变量设置环境变量 set xxxx xx savereset重启Uboot 的终极目的就是要启动内核。
Make config 就相当于执行命令100ask24x0_config : unconfig@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0NULL s3c24x0MKCONFIG := $(SRCTREE)/mkconfig$(@:_config=) $(@ 表示目标文件100ask24x0 _config=) 表示替换掉他用后面的arm arm920t 100ask24x0 NULL s3c24x0 100ask24x0最后就执行这个命令Mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0找到脚本文件mkconfig #!/bin/sh表示他是用bin目录下sh解释执行,后面是传入的参数。
这个配置过程它做了一些连接工作,把arm board arch 链接到现在的文件。
编译时的make 做的工作:用到了上面配置的config.mk(.a文件表示所有编译好的文件打包成成的一个库)OBJS = cpu/arm920/xxxxLib +=xxxx.aALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)依赖$(obj)u-boot.bin文件$(obj)u-boot.bin他又依赖于$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \-Map u-boot.map -o u-boot得到的bin文件就是这个.a文件如何组织连接在lds连接文件有说明链接地址在0x33f80000就是说应该在这个地址运行比如从0x00000000 到0x08000000是128M空间2^27次方=2^7*2^10*2^10=128M搜索命令 grep “” - nR内存一共64M0x33f80000空出512KUBOOT做一些工作:进入管理模式、关看门狗中断、初始化存储控制器、设置栈IRQFIQ、重定位(NORflash不能像内存一样写)、从flash拷到sdram、到他该运行的地址0x33f80000、清BSS段、调用C函数从上往下依次是512K UBOOT 然后是用来实现malloc接下来是全局参数,在接下来就是各种模式的栈。
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. 加载系统服务:启动初始化会加载并启动系统服务,比如网络服务、日志服务、时间同步服务等。
优选(VR虚拟现实)ARMLinux启动过程分析ARM Linux启动过程分析赵楠本章学习目标:●了解Linux结构及平台属性●了解bootloader的相关知识●熟悉并掌握启动过程摘要:从嵌入式系统到超级服务站,嵌入式Linux 的可移植性使得我们可以在各种电子产品上看到它的身影。
Linux 是一个完整通用的Unix 类分布式操作系统,它的结构紧凑、功能强、效率高、可移植性好且在Internet 上可自由取用。
对于不同体系结构的处理器来说Linux的启动过程也有所不同。
本文以S3C2410 ARM处理器为例,详细分析了系统上电后bootloader的执行流程及ARM Linux的启动过程。
关键词:ARM Linux bootloader 启动过程Abstract: from the embedded system to super service station, embedded Linux portability allows us to various electronic products in the form of seeing it. Linux is a complete general Unix class distributed operating system, it's structure compact, the function is strong, high efficiency, good portability and in the Internet can be free to take. For different system structure of the processor is the start of the Linux process is also different. Based on the ARM processor S3C2410 as an example, the paper analyses system after the execution flow of electric bootloader and ARM Linux start-up process.Keywords: ARM Linux bootloader start-up process1. 引言Linux 最初是由瑞典赫尔辛基大学的学生Linus Torvalds在1991 年开发出来的,之后在GNU的支持下,Linux 获得了巨大的发展。
ARM Linux启动过程分析(1)摘要:嵌入式 Linux 的可移植性使得我们可以在各种电子产品上看到它的身影。
对于不同体系结构的处理器来说Linux的启动过程也有所不同。
本文以S3C2410 ARM处理器为例,详细分析了系统上电后 bootloader的执行流程及 ARM Linux的启动过程。
关键词:ARM Linux bootloader 启动过程Abstract:We can see embedded Linux in kinds of electronic productsb ecause of its portability. Linux’s start-up procedure for different processors is also different. This paper provides the analysis ofbootloader execution process and Linux kernel start-up procedure - taking the S3C2410 ARM processor as example. Keywords: ARM Linux bootloader start-up procedure 1. 引言 Linux 最初是由瑞典赫尔辛基大学的学生 Linus Torvalds在1991 年开发出来的,之后在 GNU的支持下,Linux 获得了巨大的发展。
虽然 Linux 在桌面 PC 机上的普及程度远不及微软的Windows 操作系统,但它的发展速度之快、用户数量的日益增多,也是微软所不能轻视的。
而近些年来 Linux 在嵌入式领域的迅猛发展,更是给 Linux 注入了新的活力。
一个嵌入式 Linux 系统从软件角度看可以分为四个部分:引导加载程序(bootloader), Linux 内核,文件系统,应用程序。
其中bootloader是系统启动或复位以后执行的第一段代码,它主要用来初始化处理器及外设,然后调用 Linux 内核。
ARM体系架构下的linux启动之一,从bootloader到linux内核1. bootloader 的启动bootloader 本身叫做嵌入式系统的引导程序。
但是,它支持X86,MIPS,PowerPC,ARM 等多种体系架构。
对于操作系统的启动来讲,当机器开始上电时,首先加载bootloader,它用来完成最基本的硬件的初始化,然后加载Linux 内核。
用于ARM 的bootloader 一般为U-BOOT,用它来完成对linux 内核的加载设置,一般bootloader 烧写在开发板的Flash 里,包括Nor Flash 或Nand Flash,其中由于NorFlash 支持芯片内执行XIP(eXcute In Place),代码可以直接在FLASH 上执行,而NandFlash 需要把代码拷到RAM 中再去执行。
但是RAM 的处理速度比Flash 的处理速度要快得多,一般仍然把代码放在RAM 中执行。
一般的bootloader 需要完成以下五种功能:1)RAM 的初始化:为调用linux 内核做准备。
2)串口的初始化:由于一般的嵌入式系统开发板上没有视频终端,只能用串口进行开发,串口的初始化非常重要。
3)检测处理器类型:用来预处理加载内核的处理器类型的传递工作。
4)设置Linux 的启动参数:包括加载地址,启动方式(从本地分区或NFS 进行根文件系统加载),以及Linux 根文件系统的加载方式。
通常用一个标记列表来记录linux 内核启动的各个参数。
5)调用linux 内核镜像:此时ARM 的处理器中的几个特殊的寄存器值:r0=0,r1=处理器类型,r2=标记列表在RAM 中的位置。
2. linux kernel 的启动分析。
基于Arm 的linux 的启动分析(转)目录:一Makefile 的分析 (2)1.1 启动方案 (2)1.2 zImage 代码结构 (2)1.2.1 顶层vmlinux 的生成过程 (2)1.2.2 zImage 的生成 (6)二zImage 的启动过程 (12)2.1 compressed/vmlinux.lds 文件的分析 (12)2.2 compressed/head.s 文件的分析 (12)2.3inux/arch/arm/kernel/head.S 文件的分析 (18)2.4 arch/arm/kernel/common.s 文件的分析 (19)(看这个文章把握住两点:本文第一个过程是make zImage的过程,是在配置生成时候的过程,这个时候内核还没有往板子上下载呢,第二个过程是拷贝到板子上以后,从flash再拷贝到内存中,解压并且执行内核的第一阶段的启动)注:目录均设有超级链接,可以按住CTRL 并单击鼠标进行跟踪链接。
一Makefile 的分析1.1 启动方案在/arch/arm 文件夹下的Makefile 文件第215 行得到语句(有的在顶层目录中就有)define archhelpecho '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'echo ' bootpImage - Combined zImage and initial RAM disk'由此可以知道基于ARM 的启动方案有Image 、zImage 、xipImage 和bootpImage 四种。
ARM-Linux内核移植之(一)——内核启动流程分析Y-Kee转载请注明来自于衡阳师范学院08电2 Y-Kee /ayangke, QQ:843308498内核版本:2.6.22 为什么要采用这样一个较低的版本进行移植了,因为韦东山大牛说了,低版本的才能学到东西,越是高版本需要移植时做的工作量越少,学的东西越少。
内核启动分为三个阶段,第一是运行head.S文件和head-common.S,第三个阶段是允许第二是运行main.c文件对于ARM的处理器,内核第一个启动的文件是arc/arm/kernel下面的head.S文件。
当然arc/arm/boot/compress下面也有这个文件,这个文件和上面的文件略有不同,当要生成压缩的内核时zImage时,启动的是后者,后者与前者不同的时,它前面的代码是做自解压的,后面的代码都相同。
我们这里这分析arc/arm/kernel下面的head.S文件。
当head.S所作的工作完成后它会跳到init/目录下跌的main.c的start_kernel函数开始执行。
第一阶段:首先截取部分head.S文件,将后面重点要分析的代码高亮显示。
ENTRY(stext)msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode@ and irqs disabledmrc p15, 0, r9, c0, c0 @ get processor idbl __lookup_processor_type @ r5=procinfo r9=cpuidmovs r10, r5 @ invalid processor (r5=0)?beq __error_p @ yes, error 'p'bl __lookup_machine_type @ r5=machinfomovs r8, r5 @ invalid machine (r5=0)?beq __error_a @ yes, error 'a'bl __create_page_tables/** The following calls CPU specific code in a position independent* manner. See arch/arm/mm/proc-*.S for details. r10 = base of* xxx_proc_info structure selected by __lookup_machine_type* above. On return, the CPU will be ready for the MMU to be* turned on, and r0 will hold the CPU control register value.*/ldr r13, __switch_data @ address to jump to after@ mmu has been enabledadr lr, __enable_mmu @ return (PIC) address第一步,执行的是__lookup_processor_type,这个函数是检查处理器型号,它读取你的电路板的CPU型号与内核支持的处理器进行比较看是否能够处理。
ARM linux内核启动分析[原创 2007-06-11 10:35:46 ] 发表者: jimmy_leehead-armv.S主支分析head-armv.S是解压后(或未压缩的内核最先执行的一个文件,这个文件位于arch/arm/kernel/head-armv.S,在与这个文件同目录下还有一个文件head-armo.S与head-armv.S 很相似,但从arch/arm/下的Makefile中可以看到区别在哪里:ifeq ($(CONFIG_CPU_26,yPROCESSOR := armoifeq ($(CONFIG_ROM_KERNEL,yDATAADDR = 0x02080000TEXTADDR = 0x03800000LDSCRIPT = arch/arm/vmlinux-armo-rom.lds.inelseTEXTADDR = 0x02080000LDSCRIPT = arch/arm/vmlinux-armo.lds.inendifendififeq ($(CONFIG_CPU_32,yPROCESSOR = armvTEXTADDR = 0xC0008000LDSCRIPT = arch/arm/vmlinux-armv.lds.inendif……HEAD :=arch/arm/kernel/head-$(PROCESSOR.o \arch/arm/kernel/init_task.o闲话少说,在进入分析head-armv.S之前,交待一下我所分析的内核版本号以及硬件平台,内核是2.4.19-rmk7-pxa2,对应的硬件平台为pxa 270。
开篇说到,head-armv.S是进入内核最先执行的文件,为什么呢?内核可执行文件由许多链接在一起的对象文件组成。
对象文件有许多节,如文本、数据、init 数据、bass 等等。
这些对象文件都是由一个称为link script的文件链接并装入的。
arm-linux启动流程分析
一.概述 (1)
二.init进程 (1)
三.inittab文件简要说明 (1)
四.arm-linux系统的启动分析 (3)
一.概述
本文将讲述arm-linux内核启动后到进入用户shell模式这段时间的启动流程,从上电到进入kernel的过程请参见sourcesafe下“personal/yangxiyuan/资料”目录下的“ARM-linux启动流程.htm”文档。
二.init进程
init进程是内核启动后的第一个用户级进程,是系统中所有进程的父进程,init进程的主要任务是按照inittab文件所提供的信息创建进程,init进程繁衍出完成通常操作所需的子进程,这些操作包括:设置机器名、检查和安装磁盘及文件系统、启动系统日志、配置网络接口并启动网络和邮件服务,启动打印服务等。
三.inittab文件简要说明
inittab文件中每一记录都从新的一行开始,每个记录项最多可有512个字符,每一项的格式通常如下:id: run level:action:process,解释如下:
id字段:是最多4个字符的字符串,用来唯一标志表项。
run level字段:定义该记录项被调用时的运行级别,run level可以由一个或多个运行级别构成,也可以是空,空则代表运行级别0~6。
# 0 - halt (Do NOT set initdefault to this)
# - 关闭计算机,安全关闭电源
# 1 - Single user mode
# - 进入单用户维护模式,卸下除root以外的所有文件系统并杀死所有用户进程
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# - 多用户模式,无网络连接
# 3 - Full multiuser mode
# - 多用户模式,并以文本方式作为登陆方式
# 4 - unused
# 5 - X11
# - 多用户模式,并以图形方式作为登陆方式
# 6 - reboot (Do NOT set initdefault to this)
# - 停止linux系统,并按照/etc/inittab默认的登记项重新引导系统。
当请求init改变运行级别时,那些run level字段中不包括新运行级别的进程将收到SIGTERM警告信号,并且最后被杀死;只有a、b、c启动的命令外(a、b、c不是真正的运行级别)。
busybox会忽略这个字段。
action字段:告诉init执行的动作,即如何处理process字段指定的进程,action字段允许的值及对应的动作分别为:
1)respawn:如果process字段指定的进程不存在,则启动该进程,init不等待处理结束,而是继续扫描inittab文件中的后续进程,当这样的进程终止时,init会重新启动它,如果这样的进程已存在,则什么也不做。
2)wait:启动process字段指定的进程,并等到处理结束才去处理inittab中的下一记录项。
3)once:启动process字段指定的进程,不等待处理结束就去处理下一记录项。
当这样的进程终止时,也不再重新启动它,在进入新的运行级别时,如果这样的进程仍在运行,init也不重新启动它。
4)boot:只有在系统启动时,init才处理这样的记录项,启动相应进程,并不等待处理结束就去处理下一个记录项。
当这样的进程终止时,系统也不重启它。
5)bootwait:系统启动后,当第一次从单用户模式进入多用户模式时处理这样的记录项,init启动这样的进程,并且等待它的处理结束,然后再进行下一个记录项的处理,当这样的进程终止时,系统也不重启它。
6)powerfail:当init接到断电的信号(SIGPWR)时,处理指定的进程。
7)powerwait:当init接到断电的信号(SIGPWR)时,处理指定的进程,并且等到处理结束才去检查其他的记录项。
8)off:如果指定的进程正在运行,init就给它发SIGTERM警告信号,在向它发出信号SIGKILL强制其结束之前等待5秒,如果这样的进程不存在,则忽略这一项。
9)ondemand:功能通respawn,不同的是,与具体的运行级别无关,只用于rstate 字段是a、b、c的那些记录项。
10)sysinit:指定的进程在访问控制台之前执行,这样的记录项仅用于对某些设备的初始化,目的是为了使init在这样的设备上向用户提问有关运行级别的问题,init需要等待进程运行结束后才继续。
11)initdefault:指定一个默认的运行级别,只有当init一开始被调用时才扫描这一项,如果rstate字段指定了多个运行级别,其中最大的数字是默认的运行级别,如果rstate字段是空的,init认为字段是0123456,于是进入级别6,这样便陷入了一个循环,如果inittab文件中没有包含initdefault的记录项,则在系统启动时请求用户为它指定一个初始运行级别。
Process字段:Process字段中进程可以是任意的守护进程、可执行脚本或程序。
另外:在任何时候,可以在文件inittab中添加新的记录项,级别Q/q不改变当前的运行级别,重新检查inittab文件,可以通过命令init Q或init q使init
进程立即重新读取并处理文件inittab。
四.arm-linux系统的启动分析
当内核启动后,会在几个位置上来查寻init,这几个位置以前常用来放置init,但是init的最适当的位置(在Linux系统上)是/sbin/init。
如果内核没有找到init,它就会试着运行/bin/sh,如果还是失败了,那么系统的启动就宣告失败了。
busybox是嵌入式系统常用的工具软件集,它集合了几十个linux通用的命令,并最终生成一个可执行程序,这其中就包括init程序。
init启动后会查找/etc/inittab文件,并按规则启动inittab文件中的每一项。
第一个要执行的程序在sysinit字段中定义,一般是一个脚本程序,写成下面的形式:::sysinit:/etc/init.d/rcS,然后系统就会到/etc/init.d/目录下执行rcS脚本,这个脚本里一般做进入用户界面前的一些准备工作,如加载一些必要的设备,创建设备节点等。
执行完上面的脚本程序,init会按照action字段的定义一步一步执行下面的程序,busybox会忽略运行级别字段,如果需要启动一个守护进程,可以在respawn字段中指定,如果没有找到inittab文件,busybox会按照以下的默认规则启动系统
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
如果busybox检测到/dev/console设备不是一个serial console,它会执行下面的操作:
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
至此,系统启动阶段结束,将进入用户操作界面。