linux-2.6.22.6分析(二)启动流程之第一阶段

【Uboot】Uboot启动流程分析 第 68 行,调用 bootz_start 函数,该函数用于支持 zImage 镜像的启动,定义在文件 cmd/bootz.c 中,设置 images 的 ep 成员变量,也就是系统镜像的入口点,使用 bootz 命令启动系 统的时候就会设置系统在 DRAM 中的存储位置,调用 bootz_setup 函数,此函数会判断当前的系统镜像文件是否为 Linux 的镜像 文件,并且会打印出镜像相关信息bootz_start 主要用于初始化 images 的相关成员变量。此时会进行一些初始化工作。 阅读详情

内核的启动也可以分为两个阶段

第一阶段是用汇编写的,主要是判断是否支持CPU、单板、创建页表等

第二阶段是用C语言写的,主要是处理u-boot传递的参数,挂接根文件系统,调用应用程序等

 

本节简要分析启动流程的第一阶段,代码是内核链接的第一个文件arch/arm/kernel/head.S

1、判断内核是否支持cpu

	mrc	p15, 0, r9, c0, c0		@ get processor id	
	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid	 	

	/* 读取机器 id,判断内核是否支持	*/	
	movs	r10, r5				@ invalid processor (r5=0)?
	beq	__error_p			@ yes, error 'p'		

 

2、判断内核是否支持单板

要支持某块单板,要在内核的arch目录下提供一个machine_desc结构体,它的段属性是.arch.info.init,在判断是否支持单板的时候,内核会从这个段中查找相应结构体,如果找到,则表明支持单板

	bl	__lookup_machine_type		@ r5=machinfo
	movs	r8, r5				@ invalid machine (r5=0)?
	beq	__error_a			@ yes, error 'a'

其中__lookup_machine_type函数位于同目录下的head-common.S中,该文件部分代码如下

3:	.long	.	/*虚拟地址*/
	.long	__arch_info_begin		/*机器ID起始地址*/
	.long	__arch_info_end		/*机器ID结束地址*/

/*__arch_info_begin、__arch_info_end定义在链接脚本:*/
  __arch_info_begin = .;
  *(.arch.info.init)
 __arch_info_end = .;


__lookup_machine_type:
	/* 获得代码段标号3的地址(实际的物理地址),存入r3*/	
	adr	r3, 3b
	/* 取r3、r3+4、r3+8地内容存入r4、r5、r6 */
	ldmia	r3, {r4, r5, r6}	//r4、r5、r6都是虚拟地址
	/* 计算偏移量 */
	sub	r3, r3, r4			@ get offset between virt&phys
	/* 根据偏移量,把虚拟地址转换成实际地址 */
	add	r5, r5, r3			@ convert virt addresses to
	add	r6, r6, r3			@ physical address space
	/* 比较机器id */
1:	ldr	r3, [r5, #MACHINFO_TYPE]	@ get machine type
	teq	r3, r1				@ matches loader number?
	beq	2f				@ found
	add	r5, r5, #SIZEOF_MACHINE_DESC	@ next machine_desc
	cmp	r5, r6
	blo	1b
	mov	r5, #0				@ unknown machine
2:	mov	pc, lr

 

以arch/arm/mach-s3c2440/mach-smdk2440.c为例,其中定义的machine_desc结构体是:

MACHINE_START(S3C2440, "SMDK2440")
	/* Maintainer: Ben Dooks <ben@fluff.org> */
	.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_END

所用到的宏定义于include/asm-arm/mach/arch.h:

#define MACHINE_START(_type,_name)			\
static const struct machine_desc __mach_desc_##_type	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= MACH_TYPE_##_type,		\
	.name		= _name,

#define MACHINE_END				\
};

 

将宏展开后:

static const struct machine_desc __mach_desc_S3C2440	\
 __used							\
 __attribute__((__section__(".arch.info.init"))) = {	\
	.nr		= MACH_TYPE_S3C2440,		\
	.name		= “SMDK2440”,

	.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,
};

其中

.nr就是单板的ID,用于使内核支持该单板

 

3、创建页表

	bl	__create_page_tables

 

4、保存__mmap_switched的地址,使能mmu后跳转过去

	ldr	r13, __switch_data		@ address to jump to after
        /*使能mmu*/
	adr	lr, __enable_mmu		@ return (PIC) address

其中__switch_data:

__switch_data:
	.long	__mmap_switched
	.long	__data_loc			@ r4
	.long	__data_start			@ r5
	.long	__bss_start			@ r6
	.long	_end				@ r7
	.long	processor_id			@ r4
	.long	__machine_arch_type		@ r5
	.long	cr_alignment			@ r6
	.long	init_thread_union + THREAD_START_SP @ sp

 

而在__mmap_switched程序段,内核会调用start_kernel,进入启动的第二阶段

__mmap_switched:
	adr	r3, __switch_data + 4
        /* 拷贝数据段 */
	ldmia	r3!, {r4, r5, r6, r7}
	cmp	r4, r5				@ Copy data segment if needed
1:	cmpne	r5, r6
	ldrne	fp, [r4], #4
	strne	fp, [r5], #4
	bne	1b

        /* 清除bss段 */
	mov	fp, #0				@ Clear BSS (and zero fp)
1:	cmp	r6, r7
	strcc	fp, [r6],#4
	bcc	1b

        /* 保存CPU id、单板 id,清除累加器,保存控制寄存器的值 */
	ldmia	r3, {r4, r5, r6, sp}
	str	r9, [r4]			@ Save processor ID
	str	r1, [r5]			@ Save machine type
	bic	r4, r0, #CR_A			@ Clear 'A' bit
	stmia	r6, {r0, r4}			@ Save control register values
	b	start_kernel

 

 

 

 

制作Ubuntu22.04启动盘 现在越来越多程序代码都需要运行在linux环境下,运行这些代码的前提是安装一个稳定的linux操作系统。本文选择Ubuntu 22.04去制作系统启动盘。本文主要对ubuntu22.04的启动盘制作过程进行了详细的说明,希望能帮助到有需要的朋友。 阅读详情

相关推荐

根据log信息解读内核(linux-2.6.32.24)的启动流程

笔者已经移植该内核到板卡mini2440中,现在该内核已经在mini2440上能正常启动,控制台上也能输入命令,输出log。本文主要以linux-2.6.32.24内核为基础,分析内核在mini2440板卡终端输出的log,分析其启动过程中做了哪些具体的功能,这样能加深对内核的理解。

mftang的博客 1252

详解linux设备树全集

本课程属于嵌入式linux核心课程2期,是核心课程2期的技术专题之一,主要讲解设备树技术。秉持我们一贯课程风格和原则,从原理出发,从源码分析,边讲解边实验验证。本课程适合学习完核心课程1期,有一定linux基础,希望进一步学习高版本kernel的设备树技术的同学继续学习。

从SAR信号到洪涝地图:基于Sentinel-1数据的水体快速提取实战

本文详细介绍了如何利用Sentinel-1 SAR数据快速提取水体信息并生成洪涝地图的实战方法。通过预处理五部曲和SDWI指数计算,结合具体案例展示了SAR技术在洪涝灾害应急监测中的高效性和准确性,为救援决策提供关键支持。

weixin_29201313的博客 464

Linux系统启动过程分析

经过对Linux系统有了一定了解和熟悉后,想对其更深层次的东西做进一步探究。这当中就包括系统的启动流程、文件系统的组成结构、基于动态库和静态库的程序在执行时的异同、协议栈的架构和原理、驱动程序的机制等等。 本人在综合了现有网上大家智慧的基础上,结合对2.6.32的内核代码的研读,基于CentOS 6.0系统对Linux的启动流程做了些分析。由于才疏学浅,知...

weixin_30940783的博客 527

WSL2 Ubuntu复现FoundationPose项目(docker)

复现一个基于深度学习的物体姿态估计框架FoundationPose项目,使用docker,WSL2

woaidawangwang的博客 2000

告别Keil!用VSCode+PlatformIO玩转STC单片机(附自动下载配置)

本文详细介绍了如何从Keil迁移到VSCode+PlatformIO进行STC单片机开发,包括环境搭建、自动下载配置等实用技巧。通过对比传统IDE与现代工具链的差异,展示了VSCode+PlatformIO在代码编辑体验、跨平台支持和开发效率上的优势,帮助开发者实现更流畅的STC单片机开发流程。

weixin_27252001的博客 459

嵌入式Linux——分析kernel运行过程(1):kernel第一阶段

简介:         本章主要介绍在2.6.22.6内核中,代码的运行过程。而这里主要介绍kernel第一阶段的汇编代码部分。在这部分我们将讲解内核如何对单板控制器信息和机器ID的进行检测。同时也会讲解内核如何创建页表和使能mmu。 声明:         本文主要是看了韦东山老师的视频后所写,希望对你有所帮助。 u-boot版本 : u-boot-1.1.6 开发板 : JZ2440...

静祥阁 1054

手把手教你用分立元件搭建自举电路:解决高端MOS驱动难题

本文详细介绍了如何用分立元件搭建自举电路,解决高端MOS驱动中的栅源极电压不足问题。通过面包板实验,逐步讲解二极管、电容等关键元件的选型与电路搭建,提供波形调试和常见问题排查方法,帮助工程师提升开关电源和电机驱动等应用的效率与可靠性。

weixin_30555125的博客 153

Linux内核阶段详解

真正的内核在/usr/lib/modules/4.18.0-80.el8.x86_64/kernel中,内核中封装了很多模块,系统启动后,需要加载这些设备(网卡,usb..),这些设备都在内核文件下,内核又在/下面,/又在nvme的驱动上,需要加载引导程序,系统启动会首先加载/boot/grub2/grub.cfg,正常启动之后才会加载/usr/lib/modules/4.18.0-80.el8.x86_64/kernel。1)/boot单独分出来,就是/boot所在的分区。

weixin_46113061的博客 451

基于云平台的ATS系统微服务架构方案研究

在当前智慧地铁的升级转型过程中,城市轨道交通ATS系统面临着稳定性差、运维方 式繁琐和故障应急处理效率低等问题。为此,提出一种基于云平台的ATS系统微服务架构方案; 研究了ATS系统在云平台上的微服务总体架构、ATS应用的微服务划分和设计、容器部署方式 及通信交互模式,可实现系统松耦合和易扩展,达到节约计算资源、提高系统稳定性和运营效 率的目的

mi_lan1的博客 966

无线通信基础:调制与解调技术_(42).7.3.2多进制频移键控解调(MFSK解调)

MFSK解调是一种通过频谱分析和频率检测来恢复数字信号的技术。本文介绍了MFSK解调的基本原理,包括信号接收、频谱分析、频率检测和符号判决。在实际应用中,噪声会对解调性能产生影响,因此引入了信噪比优化和多步判决方法来提高解调的准确性。通过性能评估,可以更好地理解MFSK解调在不同噪声环境下的表现。这些方法和技术为MFSK在实际通信系统中的应用提供了理论和实践基础。

2401_87715305的博客 1318

Openwrt学习笔记(三)——内核启动

本来想整理一下linux内核启动的大致过程,后来网上找到了朱老师的关于这方面的付费视频课程,讲的挺好,所以这里就自己偷偷懒,直接将笔记贴上来了,希望没影响到人家的知识产权 http://edu.51cto.com/lesson/id-87648.html 第一部分、章节目录 2.16.1.做好内核分析的准备工作 2.16.2.head.S文件分析1 2.16.3.内核启动的汇

奔跑的路 5353

28-手把手教你手写CPU-Verilog - 乘法器设计:Booth算法与Wallace树乘法器

文章摘要: 本文详细介绍了两种高效乘法器设计方法:Booth算法和Wallace树乘法器。Booth算法通过检测乘数连续1/0减少部分积,适合有符号数运算;Wallace树采用树形结构压缩部分积,显著降低延迟。文章包含算法原理、具体示例、Verilog实现代码(4位乘法器)及性能对比表,指出Booth适用于通用处理器,Wallace树更适合高性能DSP/GPU。最后强调实际设计中需根据速度、面积和功耗需求选择合适方案。

2301_79143213的博客 206

linux 2.6 启动流程分析

内核在启动时可以传递一个字符串命令行,来控制内核启动的过程,例如:"console=ttyS2,115200 mem=64M@0xA0000000"这里指定了控制台是串口2,波特率是115200,内存大小是64M,物理基地址是0xA0000000。另外我们可以在内核中定义一些全局变量,使用这些全局变量控制内核的配置,例如usb驱动中定义了static int nousb; /*

menuconfig的专栏 2754

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Linux-arm(1)ATF启动流程

ARM ATF-A (ARM Trusted Firmware-A)是ARM官方为ARMv8-A架构提供的一套开源、安全、可靠的参考firmware实现。它主要面向ARM64(AArch64)和ARM32(AArch32)架构,提供了全面的安全世界(Secure World)支持和丰富的功能。ATF-A支持ARMv7-A和ARMv8-A架构系列处理器,包括Cortex-A53/57/72/73/75/76/77等。

梅花香自苦寒来,宝剑锋从磨砺出。 3822

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

编译内核之启动流程分析

源码配置编译: 本文主要是针对linux-2.6.22.6来进行配置编译和源码的分析,这里韦老师已经做好补丁文件和配置文件,直接在此基础上进行配置编译 解压缩 tar xjf 压缩文件 打补丁 patch -p1 <补丁文件 (这里韦老师已经为我们做好了补丁文件) 配置 linux有两...

qq_35547417的博客 759

ARM-Linux移植之(一)——内核启动流程分析

ARM-Linux内核移植之(一)——内核启动流程分析 K-Style   转载请注明来自于衡阳师范学院08电2  K-Style  http://blog.csdn.net/ayangke,QQ:843308498 邮箱:yangkeemail@qq.com          内核版本:2.6.22  为什么要采用这样一个较低的版本进行移植了,因为韦东山大牛说了,低版本的才能学到东西,

屌丝终有逆袭日。 8506

Linux启动流程和内核管理

POST #加电自检boot loader #引导启动内核vmlinux(initrd /initramfs-2.6.32-71.el6.x86_64.img) #临时系统rootfs #根文件系统/sbin/init #执行init程序/etc/inittab #设置默认运行级别/etc/rc.d/rc.sysinit #运行系统初始脚本完成系统初始化/etc/rcN.d/KNN #当前级别下需要停止的服务。

qq_59349464的博客 1760

Linux系统移植之Uboot启动流程

第一阶段初始化硬件,采用的汇编语言。 第二阶段更为复杂的初始化和内核加载,采用C语言。uboot启动,先找到入口(第一行程序),通过链接脚本u-boot.lds找到程序的入口地址,即文件中的_start,如下: 由于 Flash 等存储设备的读写速度较慢,为了提高程序的执行效率,通常会将 U-Boot 的第二阶段代码从 Flash 复制到 RAM 中执行。复制的起始地址和长度需要根据具体的硬件和 U-Boot 配置来确定。在完成硬件初始化和代码复制后,程序会跳转到 U-Boot 第二阶段的入口点,开始执行

xxxx123445的博客 1241

【嵌入式Linux学习七步曲之第四篇 Linux内核移植】PPC Linux启动流程分析

 PPC Linux启动流程分析Sailor_forever  sailing_9806#163.com 转载请注明http://blog.csdn.net/sailor_8318/archive/2009/11/22/4853319.aspx【摘要】本文分析了MPC8270在Linux2.6.19下的启动流程。介绍了压缩内核的链接脚本、映像生成的过程、压缩内核如何重定位解

Sailor_forever 7681

Linux_22_系统初始化流程

Linux系统启动流程和Grub2

爱喝可乐的w 4787

linux+2.6系统下载,linux-2.6.22.6

linux-2.6.22.6/.gitignorelinux-2.6.22.6/.mailmaplinux-2.6.22.6/arch/alpha/boot/bootloader.ldslinux-2.6.22.6/arch/alpha/boot/bootp.clinux-2.6.22.6/arch/alpha/boot/bootpz.clinux-2.6.22.6/arch/alpha/boot...

weixin_29016865的博客 945

linux内核启动流程

空

u010743406的博客 527

Linux系统启动流程深度解析:从BIOS到用户空间的全链路指南

Linux系统启动流程深度解析与故障排查指南 本文详细剖析了现代Linux(UEFI+GRUB2+systemd)启动流程的6个核心阶段: UEFI:硬件初始化并加载GRUB引导程序 GRUB2:提供启动菜单并加载内核/initramfs 内核:解压内核、加载驱动并挂载initramfs临时根文件系统 Initramfs:执行关键初始化脚本,挂载真实根分区 systemd:并行启动服务(取代传统SysVinit) 用户空间:完成系统就绪 关键价值:掌握启动流程可快速定位故障(如GRUB损坏、内核恐慌、驱动缺

xxylllw 943

linux2.6.29 启动过程详细分析

jun2ran的专栏 867
上一篇: linux-2.6.22.6分析(一)配置编译链接过程
下一篇: linux-2.6.22.6分析(三)启动流程之第二阶段
floatinglong
博客等级 码龄9年 90粉丝 143原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值