嵌入式Linux2.6内核启动步骤)

合集下载

嵌入式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 kernel内核升级全过程,教你一次成功

Linux kernel内核升级全过程,教你一次成功

序言由于开发环境需要在linux-2.6内核上进行,于是准备对我的虚拟机上的Linux系统升级。

没想到这一弄就花了两天时间(反复装系统,辛苦啊~~),总算把Linux系统从2.4.20-8内核成功升级到了2.6.18内核。

网上虽然有很多介绍Linux内核升级的文章,不过要么过时,下载链接失效;要么表达不清,不知所云;更可气的是很多文章在转载过程中命令行都有错误。

刚开始我就是在这些“攻略”的指点下来升级的,以致于浪费了很多时间。

现在,费尽周折,升级成功,心情很爽,趁性也来写个“升级攻略”吧!于是特意又在虚拟机上重新安装一个Linux系统,再来一次完美的升级,边升级边记录这些步骤,写成一篇Linux内核升级记实录(可不是回忆录啊!),和大家一起分享~~!一、准备工作首先说明,下面带#号的行都是要输入的命令行,且本文提到的所有命令行都在终端里输入。

启动Linux系统,并用根用户登录,进入终端模式下。

1、查看Linux内核版本# uname -a如果屏幕显示的是2.6.x,说明你的已经是2.6的内核,也用不着看下文了,该干什么干什么去吧!~~~如果显示的是2.4.x,那恭喜你,闯关通过,赶快进行下一步。

2、下载2.6内核源码下载地址:/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz23、下载内核升级工具(1)下载module-init-tools-3.2.tar.bz2/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.2.tar.bz2(2)下载mkinitrd-4.1.18-2.i386.rpm/fedora/linux/3/i386/RPMS.core/mkinitrd-4.1.18-2.i386.rpm(3)下载lvm2-2.00.25-1.01.i386.rpm/fedora/linux/3/i386/RPMS.core/lvm2-2.00.25-1.01.i386.rpm(4)下载device-mapper-1.00.19-2.i386.rpm/fedora/linux/3/i386/RPMS.core/device-mapper-1.00.19-2.i386.rpm(2.6.18内核和这4个升级工具我都有备份,如果以上下载地址失效,请到/guestbook留下你的邮箱,我给你发过去)好啦,2.6内核和4个升级工具都下载完了(少一个也不行,如果没有下载齐全,请不要尝试下面的步骤,升级是不会成功的),下面回到Linux系统中开始配置工作吧。

Linux kernel内核升级全过程,教你一次成功

Linux kernel内核升级全过程,教你一次成功

序言由于开发环境需要在linux-2.6内核上进行,于是准备对我的虚拟机上的Linux系统升级。

没想到这一弄就花了两天时间(反复装系统,辛苦啊~~),总算把Linux系统从2.4.20-8内核成功升级到了2.6.18内核。

网上虽然有很多介绍Linux内核升级的文章,不过要么过时,下载链接失效;要么表达不清,不知所云;更可气的是很多文章在转载过程中命令行都有错误。

刚开始我就是在这些“攻略”的指点下来升级的,以致于浪费了很多时间。

现在,费尽周折,升级成功,心情很爽,趁性也来写个“升级攻略”吧!于是特意又在虚拟机上重新安装一个Linux系统,再来一次完美的升级,边升级边记录这些步骤,写成一篇Linux内核升级记实录(可不是回忆录啊!),和大家一起分享~~!一、准备工作首先说明,下面带#号的行都是要输入的命令行,且本文提到的所有命令行都在终端里输入。

启动Linux系统,并用根用户登录,进入终端模式下。

1、查看Linux内核版本# uname -a如果屏幕显示的是2.6.x,说明你的已经是2.6的内核,也用不着看下文了,该干什么干什么去吧!~~~如果显示的是2.4.x,那恭喜你,闯关通过,赶快进行下一步。

2、下载2.6内核源码下载地址:/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz23、下载内核升级工具(1)下载module-init-tools-3.2.tar.bz2/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.2.tar.bz2(2)下载mkinitrd-4.1.18-2.i386.rpm/fedora/linux/3/i386/RPMS.core/mkinitrd-4.1.18-2.i386.rpm(3)下载lvm2-2.00.25-1.01.i386.rpm/fedora/linux/3/i386/RPMS.core/lvm2-2.00.25-1.01.i386.rpm(4)下载device-mapper-1.00.19-2.i386.rpm/fedora/linux/3/i386/RPMS.core/device-mapper-1.00.19-2.i386.rpm(2.6.18内核和这4个升级工具我都有备份,如果以上下载地址失效,请到/guestbook留下你的邮箱,我给你发过去)好啦,2.6内核和4个升级工具都下载完了(少一个也不行,如果没有下载齐全,请不要尝试下面的步骤,升级是不会成功的),下面回到Linux系统中开始配置工作吧。

linux内核启用参数

linux内核启用参数

linux内核启用参数Linux内核启用参数是指在Linux系统启动时,可以通过设置参数来改变内核的行为和配置。

这些参数可以通过修改启动脚本或者在引导时通过命令行参数传递给内核。

我们来介绍一些常用的Linux内核启用参数。

1. root:指定根文件系统所在的设备或分区。

在启动时,内核会将根文件系统挂载到这个设备上,成为系统的根目录。

可以使用设备名称(如/dev/sda1)或者UUID(Universally Unique Identifier)来指定。

2. init:指定系统初始化进程的路径。

这个进程是系统启动后的第一个用户空间进程,负责初始化系统环境、启动其他进程等。

一般情况下,它的路径是/bin/init。

3. quiet:禁用内核启动时的冗长输出信息。

默认情况下,内核会将启动过程中的详细信息输出到控制台上,使用quiet参数可以减少这些输出,使启动过程更加简洁。

4. vga:指定启动时的图形模式。

可以通过设置不同的参数值来改变显示分辨率和颜色深度。

例如,vga=791表示使用1024x768分辨率,颜色深度为16位。

5. acpi:启用或禁用ACPI(Advanced Configuration and PowerInterface)功能。

ACPI是一种能够管理电源、温度、风扇等硬件的标准,通过设置acpi参数,可以控制是否启用ACPI功能。

6. noapic:禁用APIC(Advanced Programmable Interrupt Controller)功能。

APIC是用于处理系统中断的硬件设备,通过设置noapic参数,可以禁用APIC功能,解决一些不兼容的硬件问题。

7. nomodeset:禁用内核对图形模式的自动设置。

有些显卡驱动在启动时可能会导致系统冻结或无法启动,通过设置nomodeset参数,可以强制内核使用基本的VGA模式运行。

8. mem:指定系统可用的物理内存大小。

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

Linux2.6内核移植系列教程

Linux2.6内核移植系列教程

Linux2.6内核移植系列教程第一:Linux 2.6内核在S3C2440平台上移植此教程适合2.6.38之前的版本,其中2.6.35之前使用同一yaffs补丁包,2.6.36--2.6.28 yaffs文件系统有所改变,2.6.39之后的暂时不支持,源码下载请到:/1.解压linux-2.6.34.tar.bz2源码包#tar jxvf linux-2.6.34.tar.bz22.修改linux-2.6.34/Makefile文件,在makefile中找到以下两条信息并做修改ARCH ? =armCROSS_COMPILE?=/usr/local/arm/4.3.2/bin/arm-linux-注意:交叉编译器的环境变量也需要改为4.3.2#export PATH=/usr/local/arm/4.3.2/bin/:$PATH其中ARCH变量用来决定:配置、编译时读取Linux源码arch目录下哪个体系结构的文件PATH 用来决定交叉编译器版本3.修改机器类型ID号Linux源码中支持多种平台的配置信息,内核会根据bootloader传进来的mach-types决定那份平台的代码起作用,本人手里的板子是仿照三星公司官方给出的demo板改版而来,所以采用arch/arm/mach-s3c2440/mach-smdk2440.c此配置文件,打开此文件,翻到最后,有以下信息:MACHINE_START(S3C2440, "SMDK2440")/* Maintainer: Ben Dooks <ben@> */.phys_io= S3C2410_PA_UART,.io_pg_offst= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,.boot_params= S3C2410_SDRAM_PA + 0x100,.init_irq= s3c24xx_init_irq,.map_io= smdk2440_map_io,.init_machine= smdk2440_machine_init,.timer= &s3c24xx_timer,MACHINE_ENDMACHINE_START(S3C2440, "SMDK2440")决定了此板子的mach-types,可以在以下文件中找到S3C2440对应的具体数字,"arch/arm/tools/mach-types"文件查找S3C2440,362,这里刚好与我们的bootloader相同,所以不用做修改,直接保存退出即可,如果不同则根据bootloader的内容修改此文件,或根据此文件修改boorloader的内容(在vivi中可通过param show查看,u-boot在Y:\test\u-boot_src\u-boot_edu-2010.06\board\samsung\unsp2440\unsp2440.c文件:gd->bd->bi_arch_number = MACH_TYPE_S3C2440;中决定)。

多处理器平台下Linux2.6启动过程中的位图分析

多处理器平台下Linux2.6启动过程中的位图分析
出 了在多处理器及多核平 台下进 行 Lnx操作系统移植的总体思路。 iu
关 键
词: 计算机应 用技 术; 入式 系统 ; 嵌 对称 多处理器 ; 启动过程 ; 图 位
文献标识码: A
中图分类号: P 6 . T 382
1 引 言
顺 应对称 多处 理 器 ( y S mmer l.rcs rS ) 多 核 的 出现 ,tiMutPoes ,MP 及 c i o Ln u
s r kre ) t t e l 中进行 自身的初始化工作 , a— n( 并设置好 自己相 应的 cu ol e ma 位 图和 cu clu— a p — n n— p i p — aot m p位 l
图[l p — nie ma 2。cu ol — p表示 当前 联机 的 C U, n P 仅在 C U 已经 可 以用 于 内 核调 度 或 接 收设 备 中断 时 设 置 。而 P
收 稿 日期 :0 90 2 修 订 日期 :0 90 —3 20 —70 ; 2 0 .92
4 2
始化 [ ; 1 ]



息 工

学 院 学

第2 5卷
() 4进入执 行 内核 中的 s r— enl) t t kre(函数 , 系统 的各 种资源 进行初 始化 , a 对 创建 B P的空 闲进程 ; S () i ) 5i t 函数 的执行 , 先完成对 S n( 首 MP系统 的初始化 , 再进行 上层应用 的初 始化 。
多 处 理 器 平 台 下 L n x2 6启 动 过 程 中 的位 图分 析 iu .
陈小兰, 杨 斌
( 西南交通大学信息科学与技 术学院, 四川 成都 6 03 ) 10 1

linux嵌入式面试题

linux嵌入式面试题

linux嵌入式面试题Linux嵌入式系统是一种基于Linux内核的操作系统,被广泛应用于各种嵌入式设备中。

随着物联网和智能设备的兴起,对于具备Linux 嵌入式系统开发经验的人才需求也越来越高。

本文将分享一些常见的Linux嵌入式面试题,希望能够帮助您更好地准备面试。

第一部分:基础知识1. 请解释一下Linux嵌入式系统是什么?Linux嵌入式系统是指在嵌入式设备中使用Linux内核作为操作系统的系统。

它具有开源、可裁剪、稳定可靠等特点,广泛应用于各种嵌入式设备,如智能手机、路由器、智能家居等。

2. Linux内核和Linux嵌入式系统有何区别?Linux内核是操作系统的核心部分,负责管理硬件资源和提供系统调用接口。

而Linux嵌入式系统是在Linux内核的基础上,集成了其他组件和工具链,用于嵌入式设备的开发和运行。

3. 请列举一些常见的Linux嵌入式系统的发行版?常见的Linux嵌入式系统发行版包括:Buildroot、OpenWrt、Yocto Project等。

4. 什么是交叉编译?为什么在嵌入式开发中需要用到交叉编译?交叉编译是指在一台主机上使用特定的工具链,为另一种不同体系结构的目标平台生成可执行文件。

在嵌入式开发中,由于嵌入式设备的硬件平台和开发主机的平台不同,需要通过交叉编译生成适用于目标平台的可执行文件。

5. 如何进行Linux内核的裁剪?Linux内核的裁剪可以通过修改内核配置选项来实现。

可以使用make menuconfig、make xconfig等命令打开内核配置界面,根据需求选择需要编译的模块和功能。

第二部分:系统开发1. 如何进行Linux嵌入式系统的启动顺序?Linux嵌入式系统的启动通常分为BootLoader阶段、内核启动阶段和用户空间启动阶段。

首先,BootLoader负责引导加载内核并进行基本的硬件初始化;然后,内核启动,进行硬件初始化、设备驱动加载等操作;最后,用户空间启动,用户空间中的init进程负责加载用户应用程序和服务。

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

Linux内核构成(国嵌)Linux/arch/arm/boot/compressed/head.s1.解压缩2.初始化3.启动应用程序1 arch/arm/boot/compressed/Makefile arch/arm/boot/compressed/vmlinux.lds2. arch/arm/kernel/vmlinux.ldsLinux内核启动流程(国嵌)arch/arm/boot/compressed/start.S(head.s—负责解压缩)Start:.type start,#function.rept 8mov r0, r0.endrb 1f.word 0x016f2818 @ Magic numbers to help the loader.word start @ absolute load/run zImage address.word _edata @ zImage end address1: mov r7, r1 @ save architecture IDmov r8, r2 @ save atags pointer这也标志着u-boot将系统完全的交给了OS,bootloader生命终止。

之后代码在133行会读取cpsr并判断是否处理器处于supervisor模式——从u-boot进入kernel,系统已经处于SVC32模式;而利用angel进入则处于user模式,还需要额外两条指令。

之后是再次确认中断关闭,并完成cpsr写入mrs r2, cpsr @ get current modetst r2, #3 @ not user?bne not_angelmov r0, #0x17 @ angel_SWIreason_EnterSVCswi 0x123456 @ angel_SWI_ARMnot_angel:mrs r2, cpsr @ turn off interrupts toorr r2, r2, #0xc0 @ prevent angel from runningmsr cpsr_c, r2然后在LC0地址处将分段信息导入r0-r6、ip、sp等寄存器,并检查代码是否运行在与链接时相同的目标地址,以决定是否进行处理。

由于现在很少有人不使用loader和tags,将zImage 烧写到rom直接从0x0位置执行,所以这个处理是必须的(但是zImage的头现在也保留了不用loader也可启动的能力)。

arm架构下自解压头一般是链接在0x0地址而被加载到0x30008000运行,所以要修正这个变化。

涉及到r5寄存器存放的zImage基地址r6和r12(即ip寄存器)存放的got(global offset table)r2和r3存放的bss段起止地址sp栈指针地址很简单,这些寄存器统统被加上一个你也能猜到的偏移地址0x30008000。

该地址是s3c2410相关的,其他的ARM处理器可以参考下表PXA2xx是0xa0008000IXP2x00和IXP4xx是0x00008000Freescale i.MX31/37是0x80008000TI davinci DM64xx是0x80008000TI omap系列是0x80008000AT91RM/SAM92xx系列是0x20008000Cirrus EP93xx是0x00008000这些操作发生在代码172行开始的地方,下面只粘贴一部分add r5, r5, r0add r6, r6, r0add ip, ip, r0后面在211行进行bss段的清零工作not_relocated: mov r0, #01: str r0, [r2], #4 @ clear bssstr r0, [r2], #4str r0, [r2], #4str r0, [r2], #4cmp r2, r3blo 1b然后224行,打开cache,并为后面解压缩设置64KB的临时malloc空间bl cache_onmov r1, sp @ malloc space above stackadd r2, sp, #0x10000 @ 64k max 接下来238行进行检查,确定内核解压缩后的Image目标地址是否会覆盖到zImage头,如果是则准备将zImage 头转移到解压出来的内核后面cmp r4, r2bhs wont_overwritesub r3, sp, r5 @ > compressed kernel sizeadd r0, r4, r3, lsl #2 @ allow for 4x expansioncmp r0, r5bls wont_overwritemov r5, r2 @ decompress after malloc spacemov r0, r5mov r3, r7bl decompress_kernel真实情况——在大多数的应用中,内核编译都会把压缩的zImage和非压缩的Image链接到同样的地址,s3c2410平台下即是0x30008000。

这样做的好处是,人们不用关心内核是Image 还是zImage,放到这个位置执行就OK,所以在解压缩后zImage头必须为真正的内核让路。

在250行解压完毕,内核长度返回值存放在r0寄存器里。

在内核末尾空出128字节的栈空间用,并且使其长度128字节对齐。

add r0, r0, #127 + 128 @ alignment + stackbic r0, r0, #127 @ align the kernel length算出搬移代码的参数:计算内核末尾地址并存放于r1寄存器,需要搬移代码原来地址放在r2,需要搬移的长度放在r3。

然后执行搬移,并设置好sp指针指向新的栈(原来的栈也会被内核覆盖掉)add r1, r5, r0 @ end of decompressed kerneladr r2, reloc_startldr r3, LC1add r3, r2, r31: ldmia r2!, {r9 - r14} @ copy relocation codestmia r1!, {r9 - r14}ldmia r2!, {r9 - r14}stmia r1!, {r9 - r14}cmp r2, r3blo 1badd sp, r1, #128 @ relocate the stack搬移完成后刷新cache,因为代码地址变化了不能让cache再命中被内核覆盖的老地址。

然后跳转到新的地址继续执行bl cache_clean_flushadd pc, r5, r0 @ call relocation code注意——zImage在解压后的搬移和跳转会给gdb调试内核带来麻烦。

因为用来调试的符号表是在编译是生成的,并不知道以后会被搬移到何处去,只有在内核解压缩完成之后,根据计算出来的参数“告诉”调试器这个变化。

以撰写本文时使用的zImage为例,内核自解压头重定向后,reloc_start地址由0x30008360变为0x30533e60。

故我们要把vmlinux的符号表也相应的从0x30008000后移到0x30533b00开始,这样gdb就可以正确的对应源代码和机器指令。

随着头部代码移动到新的位置,不会再和内核的目标地址冲突,可以开始内核自身的搬移了。

此时r0寄存器存放的是内核长度(严格的说是长度外加128Byte的栈),r4存放的是内核的目的地址0x30008000,r5是目前内核存放地址,r6是CPU ID,r7是machine ID,r8是atags 地址。

代码从501行开始reloc_start: add r9, r5, r0sub r9, r9, #128 @ do not copy the stackdebug_reloc_startmov r1, r41:.rept 4ldmia r5!, {r0, r2, r3, r10 - r14} @ relocate kernelstmia r1!, {r0, r2, r3, r10 - r14}.endrcmp r5, r9blo 1badd sp, r1, #128 @ relocate the stack接下来在516行清除并关闭cache,清零r0,将machine ID存入r1,atags指针存入r2,再跳入0x30008000执行真正的内核Imagecall_kernel: bl cache_clean_flushbl cache_offmov r0, #0 @ must be zeromov r1, r7 @ restore architecture numbermov r2, r8 @ restore atags pointermov pc, r4 @ call kernel内核代码入口在arch/arm/kernel/head.S文件的83行。

首先进入SVC32模式,并查询CPU ID,检查合法性msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode@ and irqs disabled mrc 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'接着在87行进一步查询machine ID并检查合法性bl __lookup_machine_type @ r5=machinfomovs r8, r5 @ invalid machine (r5=0)?beq __error_a @ yes, error 'a'其中__lookup_processor_type在linux-2.6.24-moko-linuxbj/arch/arm/kernel/head-common.S文件的149行,该函数首将标号3的实际地址加载到r3,然后将编译时生成的__proc_info_begin虚拟地址载入到r5,__proc_info_end虚拟地址载入到r6,标号3的虚拟地址载入到r7。

由于adr 伪指令和标号3的使用,以及__proc_info_begin等符号在linux-2.6.24-moko-linuxbj/arch/arm/kernel/vmlinux.lds而不是代码中被定义,此处代码不是非常直观,想弄清楚代码缘由的读者请耐心阅读这两个文件和adr伪指令的说明。

相关文档
最新文档