Linux内核启动的详细过程

在板子上电的uboot之后,便是linux内核的启动过程

        在 Linux 内核启动过程中,最初的部分是由汇编代码完成的,主要负责进行最基础的硬件初始化、内存布局设置以及从低级模式(比如实模式或保护模式)切换到内核所需的更高级模式。例如,在 x86_64 架构下,这部分代码主要集中在 arch/x86/kernel/head_64.S (或 32 位系统下的 head.S)中。

        在完成这些低级的初始化工作后,汇编代码会调用 C 语言编写的内核初始化入口函数——start_kernel()。这个函数定义在 init/main.c 中,标志着内核从汇编环境切换到 C 语言环境,接下来由 C 语言代码负责进一步的系统初始化工作和设备驱动加载等任务。

        在基本的初始化后,系统会跳到 init/main.c 中的rest_init  内,创建1号进程和2号进程,并通过遍历的方式进行驱动模块的初始化。并开始运行命令行指定的第一个进程init=/linuxrc。


        根据上文将此过程大概分为三个部分:引导、内核初始化、过渡倒rootfs三个阶段

一、引导:

uboot的初始文件为start.s,而内核初始化的初始文件为head.s

head.s 文件通常是用 汇编语言 编写的,特别是在 Linux 启动阶段(Booting Stage)中。这个文件的主要作用是完成早期的硬件初始化,并为后续的 C 语言代码(如 start_kernel)准备运行环境

二、内核初始化:

        start_kernel 是内核启动的重要函数,在这过程种要进行从设备树到中断、定时器等等一系列的初始化,此过程已经由汇编语言转为C语言

三、过渡倒rootfs:

        start_kernel函数结束后会跳转到rest_init函数,这过程会进行创建1号进程和2号进程,并通过遍历的方式进行驱动模块的初始化。并开始运行命令行指定的第一个进程init=/linuxrc。

        0号进程:内核启动时由汇编及早期 C 代码创建的 idle 进程,它负责在系统空闲时运行,同时作为所有进程的根基。

        1号进程:由 0号进程在 rest_init() 中 fork 出来的第一个用户空间进程(init),它承担了用户空间初始化和启动所有后续进程的任务。

        2号进程(守护进程):即 kthreadd,它作为内核线程的管理者,负责后续内核线程的创建和管理。


跟踪方法:

        正常我们开启Ctags后可以选定函数后敲击Ctrl  +  ] 键进行跟踪,当没法跳转时可以打开system.map 这个文件,先用Vim检索的方法找到对应的函数,获得对应的地址

        获得地址之后使用交叉编译工具链进行定位目录路劲,例如用aarch64-linux-gnu-addr2line ffffff8008080000 -e vmlinux -f /*查找地址对应的文件位置

        1、原理:aarch64-linux-gnu-addr2line 是专门为 AArch64 架构编译的版本,能够正确解析 ARMv8 架构的地址映射和指令集相关的符号信息,用于将二进制文件中的地址转换为对应的源代码文件和行号。之所以可以用该命令查找地址对应的文件位置。

        2、使用方法:

        命令格式 aarch64-linux-gnu-addr2line ffffff8008080000 -e vmlinux -f 中:

        ffffff8008080000 是要查询的地址。

        -e vmlinux 指定了包含符号信息的二进制文件。

        -f 表示同时显示函数名。

        工具通过查找 vmlinux 内部的调试信息,将该地址映射回源代码中的文件和行号。

    

  system.map界面:      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值