读Kernel感悟-Linux内核启动-内核的生成

从start_kernel到init进程启动Linux内核分析》笔记 从start_kernel到init进程启动Linux内核分析》笔记GDB的使用在进入GDB调试前,首先掌握GDB最常用的命令,以方便完成跟踪。 b[reak] linenumber:加断点 s[tep]:单步进入 n[ext]:单步跳过 c[ontinue]:继续执行 r[un]:运行至结束或者崩溃 q[uit]:退出 info:查看已设置的断点和观察点 watch:设置观察点 其他有用的命令 阅读详情

这段时间在看《Linux内核源代码情景分析》,顺便写了一些感悟。读内核源代码是一件很有意思的事。它像一条线,把操作系统,编译原理,C语言,数据结构与算法,计算机体系结构等等计算机的基础课程串起来。

        我看内核源代码是用lxr+glimpse(不一定要自己架,可以直接访问校内外的lxr网站)的。如果在windows下也可以用source insight。以下的当前路径为内核源代码路径,通常为/usr/src/linux。内核版本为2.6.13,平台为x86

好,让我们开始Linux内核之旅。

      我们的出发点是在CPU加电的一刹那,系统处于16位实地址模式下,终点是内核开始运行start_kernel(),系统处于32位页式寻址的保护模式下。那时内核映象bzImage已经解压完毕,运行于内核态。系统中已经有了一个叫swapper的0号进程,有自己的内核堆栈,情况就相对好理解得多。(尽管与用户态程序相比,还要多操心不少事,包括对硬件的直接操作,内核态各种数据结构的初始化,对页表的操作等等)。不过,不妨先做些准备动作。

      首先,什么是内核?目前,只知道编译内核后,产生一个叫bzImage的压缩内核映象。它不同于任何普通的可执行程序。我们甚至不知道它从哪里开始执行。只知道把它往/boot/下一放,往boot loader的配置文件(例如grub的menu.lst)中写上相关信息,机子就顺利启动了。因此,我对它的生成过程产生了浓厚兴趣。于是,我查看了相关资料,最直接的资料来自于arch/i386/boot/下的Makefile。从Makefile中可以知道。bzImage的产生过程是这样的:不过我不满足于此。于是,我想到了去看arch/i386/boot/下的Makefile。从arch/i386/boot/Makefile和arch/i386/boot/compressed/Makefile中可以看出(具体过程省略,)

1.先生成vmlinux.这是一个elf可执行文件

2.然后objcopy成arch/i386/boot/compressed/vmlinux.bin,去掉了原elf文件中的一些无用的section等信息。

3.gzip后压缩为arch/i386/boot/compressed/vmlinux.bin.gz

4.把压缩文件作为数据段链接成arch/i386/boot/compressed/piggy.o

5.链接:arch/i386/boot/compressed/vmlinux = head.o+misc.o+piggy.o

其中head.o和misc.o是用来解压缩的。

6.objcopy成arch/i386/boot/vmlinux.bin,去掉了原elf文件中的一些无用的section等信息。

7.用arch/i386/boot/tools/build.c工具拼接bzImage = bootsect+setup+vmlinux.bin

过程好复杂。

      这里要介绍一下objcopy命令,它的作用是把一个object文件转化为另一种格式的文件。在这里,objcopy的作用就是去掉原来elf文件中的elf header和一些无用的section信息。为什么要这么做呢?因为elf文件中的elf header和一些section的作用是告诉elf loader如何载入elf可执行文件。但是,linux内核作为一种特殊的elf文件,需要特殊折辅助程序去装载它。往往它的装载地址是固定的。这时,为了保证通用性而存在的elf header和一些section对内核的装载就没有意义了。加上为了使内核尽可能小,所以干脆把这些信息去掉。

       我们可以看一下vmlinux和arch/i386/boot/compressed/vmlinux。用file命令查看,它们也是elf可执行文件。只是没有main函数而已

 

参考:

Documentation/kbuild/makefiles.txt

Documentation/kbuild/modules.txt

详情参考:http://www.top-e.org/jiaoshi/html/?192.html

 

MAX3232芯片引脚功能详解与外围电路设计避坑指南(从电荷泵到静电防护) 本文详细解析了MAX3232芯片的引脚功能与外围电路设计,重点介绍了其电荷泵架构和RS232通信接口的应用。通过实际案例和参数对比,提供了电路设计中的常见问题解决方案和静电防护建议,帮助工程师优化工业控制与嵌入式系统中的通信可靠性。 阅读详情

相关推荐

Vue3 - Element Plus 日期选择器 el-date-picker,设置 type=week 变成周选择器后,将选择周时修改为 “周一至周日“ 为一组范围(详细示例代码,新手小白秒会)

vue3,element-plus,DatePicker日期选择器,el-date-picker,周,type=week,周选择器,日期选择器week怎么拿到具体的时间范围,如何取week周选择器的value值,format如何设置,时间选择器按周选择时展示具体日期范围,vue3elementPlus日期选择器选择一周7天的数据格式怎么拿到,el-date-picker设置type等于week后怎么设置format属性,format和value-format怎么设置,范围选择器周,一周,选择一周7天时间

🏆 前端领域优质创作者 1万+

感悟-kbuild系统-make bzImage的过程

文章来源:http://www.top-e.org/jiaoshi/class/ 从以上例子中可以看到,内核的编译系统kbuild是个很庞大的系统。但是,它所使用的make和我们平时用的make是一模一样的。kbuild只是通过预定义一些变量(obj-m,obj-y等等)和目标(bzImage ,menuconfig等等),使内核的编译和扩展变得十分方便。我们不妨yy一下kbuild的一些

李亚锋老师 4047

HCIA-AI V4.0 培训文档及实验手册.zip

HCIA-AI V4.0 培训文档HCIA-AI V4.0 实验手册

[Funkunux] Linux_2.6.22.6 内核start_kernel函数分析之parse_args

在我的上一篇文章 [Funkunux] Linux_2.6.22.6的Makefile分析 中,已经找到linux内核的第一条代码的位置是head.s,在head.s中,内核将bootloader中传给内核的参数进行解析,比对机器ID等参数,设置页表,开启MMU,然后跳转到/init/Main.c中的start_kernel()中进行一系列初始化。以下是start_kernel函数的分析,重点

FUNKUNUX 2561

分析Linux内核启动过程:从start_kernel到init

郑德伦 原创作品转载请注明出处《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 STEP1:在自己的linux系统中搭建实验环境。 1.下载linux-3.18.6的内核源码,并且编译 cd ~/LinuxKernel/ wget https://www.kernel.org/pub/linux/kerne

a363344923的专栏 1万+

Linux内核线程kernel thread详解--Linux进程的管理与调度(十)

Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求)。 内核需要多个执行流并行,为了防止可能的阻塞,支持多线程是必要的。 内核线程就是内核的分身,一个分身可以处理一件特定事情。内核线程的调度由内核负责,一个内核线程处于阻塞状态时不影响其他的内核线程,因为其是调度的基本单位。 这与用户线程是不一样的。因为内核线程只运行在内核

OSKernelLAB(gatieme) 4万+

linux工作原理fiq,Kernel感悟-Linux内核启动-内核生成 - kernel hacker 修炼之道——李万鹏 - 博客频道 - CSDN...

这段时间在看《源代码情景分析》,顺便写了一些感悟,去看小游戏http://www.qukan.net/。内核源代码是一件很有意思的事。它像一条线,把操作系统,编译原理,C语言,数据结构算法,计算机体系结构等等计算机的基础课程串起来。我看内核源代码是用lxr+glimpse(不一定要自己架,可以直接访问校内外的lxr网站)的。如果在windows下也可以用sourceinsight。以下的当前路...

weixin_30394019的博客 272

Kernel感悟-Linux内核启动-BIOS

文章来源:http://www.top-e.org/jiaoshi/html/?196.html “真罗嗦,直接告诉我Linux下用glibc库编译出来的C程序真正的入口地址是_start()不就行了么?”臭鸡蛋扑面而来。嗯,我说了我只是想用一种特别的方式来叙述问题。我更看重探索的过程中体现的思考方式以及其中的乐趣。回到我们的主题。Linux内核为什么不是从main函数开始执行?事

李亚锋老师 1302

Kernel感悟-Linux内核启动-链接脚本

文章来源:http://www.top-e.org/jiaoshi/class/一般来说,用户是不需要关心section的具体位置的。在用户态,内核会解析elf可执行文件的各个section,然后把它映射到虚拟地址空间。然而,在内核启动时,一切得从零开始。很多在用户态下应用程序不需要操心的东西,例如映射section的任务不得不由内核自己来完成。上一篇感悟揭示了内核如何建立页表,并且把自身

李亚锋老师 1590

Kernel感悟-Linux内核启动-开启页面映射

文章来源:http://www.top-e.org/jiaoshi/class/ 在setup的帮助下,我们顺利地从16位实地址模式过渡到32位段式寻址的保护模式。又在arch/i386/boot/compressed/head.S的帮助下实现了内核的自解压,并且从arch/i386/kernel/head.S中的startup_32开始。现在在线性地址0x100000(1M)处开始就是我

李亚锋老师 2115

Kernel感悟-Linux内核启动-内核解压缩

 文章来源:http://www.top-e.org/jiaoshi/class/ 这得从vmliux.bin的产生过程说起。从内核生成过程来看内核的链接主要有三步:第一步是把内核的源代码编译成.o文件,然后链接,这一步,链接的是arch/i386/kernel/head.S,生成的是vmlinux。注意的是这里的所有变量地址都是32位页寻址方式的保护模式下的虚拟地址。通常在

李亚锋老师 1270

Kernel感悟-Linux内核启动-setup辅助程序

文章来源:http://www.top-e.org/jiaoshi/class/ 我们发现,在起点与终点之间,还有几个中转站。最近的一站叫作MBR。BIOS,带你到MBR后,说:“对不起,只能送你到这里了。”那其它几个中转站是什么呢?我们知道,在x86上,保护模式有两种,32位页式寻址的保护模式和32位段式寻址的保护模式。显然,32位页式寻址的保护模式要求系统中已经构造好页表。从16位

李亚锋老师 1024

linux内核感悟,Kernel感悟-Linux内核启动-从hello world说起

内核是从哪里开始执行的呢?几乎任何一本源代码分析的书都会给出详细的答案。不过,我试图从一个不同的角度(一个初学者的角度)来叙述,而不是一上来就给出答案。从熟悉的事物入手,慢慢接近陌生的事物,这是比较常见的思路。既然都是二进制代码,那么不妨从最简单的用户态C程序,helloworld开始。说不定能找到共同点。恰好我是一个喜欢寻根究底的人。也许,理解了helloworld程序的启动过程,有助于更好...

weixin_39877898的博客 117

安卓linux内核解包,Kernel感悟-Linux内核启动-内核解压缩

这得从vmliux.bin的产生过程说起。从Linux内核生成过程来看内核的链接主要有三步:第一步是把内核的源代码编译成.o文件,然后链接,这一步,链接的是arch/i386/kernel/head.S,生成的是vmlinux。注意的是这里的所有变量地址都是32位页寻址方式的保护模式下的虚拟地址。通常在3G以上。第二步,将vmlinux objcopy 成arch/i386/boot/compr...

weixin_42300400的博客 466

Kernel感悟-Linux内核启动-从hello world说起

顶嵌专栏 869
上一篇: Android JNI实例
下一篇: 读Kernel感悟-Linux内核启动-从hello world说起
TopEmbedded
博客等级 码龄18年 58粉丝 61原创
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值