Linux启动过程代码分析

这篇博客深入解析了Linux内核启动过程,包括入口函数stext在链接脚本中的定义,内核的链接地址0xc0008000,以及head.S文件中的关键代码分析。启动条件涉及MMU关闭、特定寄存器的值。通过汇编代码,内核初始化MMU,设置栈指针和页表,最终调用start_kernel函数进入C代码执行。此外,文中还提及了uboot传递的参数对内核启动的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,入口函数和链接地址

从链接脚本中可以找到入口函数,Linux内核的链接脚本arch/arm/kernel/vmlinux.lds是由arch/arm/kernel/vmlinux.lds.S这个汇编文件生成的。

从链接脚本可以得出内核的入口函数为stext函数,在arch/arm/kernel/head.S中。

从链接脚本还可以的出,内核的链接地址为0xc0008000。
在这里插入图片描述
在这里插入图片描述

2,head.S文件分析

首先定义两个宏,这两个宏分别是内核起始地址的虚拟地址和物理地址,分别为0xC0008000和0x30008000。
在这里插入图片描述
地址检测,内核地址必须从0xXXXX8000开始
在这里插入图片描述
重要的注释:

/*
 * Kernel startup entry point.
 * ---------------------------
 *
 * This is normally called from the decompressor code.  The requirements
 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
 * r1 = machine nr, r2 = atags pointer.	内核启动条件 :1,MMU=off,D-cache=off;2,r0=0,r1=硬件号,r2=内核传参的地址
 *
 * This code is mostly position independent, so if you link the kernel at
 * 0xc0008000, you call this at __pa(0xc0008000).	内核的链接地址是虚拟地址0xc0008000,但是mmu 关闭了,所以没开启mmu 之前要用地址无关码可以通过__pa()函数得到虚拟地址对于的物理地址
 *
 * See linux/arch/arm/tools/mach-types for the complete list of machine
 * numbers for r1.	uboot通过r1 传递的机械码可以在linux/arch/arm/tools/mach-types目录查找
 *
 * We're trying to keep crap to a minimum; DO NOT add any machine specific
 * crap here - that's what the boot loader (or in extreme, well justified
 * circumstances, zImage) is for.	zImage是压缩后的内核,uboot跳转到的地址其实是一段解压缩的代码,然后才运行内核
 */

汇编阶段

__HEAD,表示下面的代码在一个自定义断。
在这里插入图片描述
在这里插入图片描述
注释:如果uboot的memtags或bootargs传参错误,内核将无法启动;
这里建立的映射页表是一个段式页表(16K),后面会再次建立细页表并舍弃这个段式页表。

将栈指针指向__mmap_switched,__mmap_switched是一个函数指针。
并将lr返回寄存器设置成__enable_mmu函数的地址。
在这里插入图片描述
在这里插入图片描述
执行__enable_mmu函数,使能mmu
在这里插入图片描述
继续指向__turn_mmu_on函数,操作cp15的control寄存器
同时将pc指针指向r13栈指针寄存器,这个寄存器之前存放了__mmap_switched函数的地址,所以这里远跳转到 __mmap_switched函数
在这里插入图片描述
** __mmap_switched函数:复制数据段、清bss段、保存处理器ID、机器码、uboot传参指针。最后执行start_kernel函数,执行C代码。**
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

setenv bootargs 'console=ttySAC2,115200 root=/dev/mmcblk0p3 rw init=/linuxrc rootfstype=ext3'
setenv bootargs 'root=/dev/nfs nfsroot=192.168.6.99:/root/rootfs ip=192.168.6.66:192.168.6.99:192.168.1.1:255.255.255.0::eth0:off  init=/linuxrc console=ttySAC2,115200 '

阅读原子linux开发pdf笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值