24小时学通Linux内核之构建Linux内核
今天是腊八节,说好的女票要给我做的腊八粥就这样泡汤了,好伤心,好心酸呀,看来代码写久了真的是惹人烦滴,所以告诫各位技术男敲醒警钟,不要想我看齐,不然就只能和代码为伴了的~~话说没了腊八粥但还是有代码,还有各位读者的支持呀,所以得继续写下去,静下心来,完成Linux内核的学习,坚持,加油~
到目前为止,我们已经认识了Linux内核子系统,也探究了系统的初始化过程,并且深入探索了start_kernel()函数,同样,了解内核映像的创建也是非常重要的,接下来将讨论一下内核映像的编译和链接过程,那么这些当然需要工具链了,工具链包含编译程序、汇编程序、链接程序,是创建Linux内核映像的一组程序集合,下图说明了工具链的链式关系:
ELF二进制目标文件
可执行ELF目标文件包括:ELF头,程序头表(用于加载的节),第1节,第2节。。。。节头表(可选)
ELF头文件
typedef struct elf32_hdr{unsigned char e_ident[EI_NIDENT]; //标识该文件是否为ELF文件Elf32_Half e_type; //指定目标文件类型,例如可执行文件,重定位文件,共享的目标文件Elf32_Half e_machine; //被编译文件所在系统的体系结构Elf32_Word e_version; //目标文件的版本Elf32_Addr e_entry; /* Entry point */ //程序的起始地址Elf32_Off e_phoff; //保存程序头表在文件中的偏移量Elf32_Off e_shoff; //保存节头表在文件中的偏移量Elf32_Word e_flags; //保存于特定与处理器的标志Elf32_Half e_ehsize; //字段保存ELF头的大小Elf32_Half e_phentsize; //保存程序头表中的每一项的大小Elf32_Half e_phnum; //程序头中表项的个数Elf32_Half e_shentsize; //节头表中每一项的大小Elf32_Half e_shnum; //保存节头中项的数量,表明该文件中有多少节Elf32_Half e_shstrndx; //保存节头中节字符串的索引 } Elf32_Ehdr;
节头表
typedef struct elf32_shdr {Elf32_Word sh_name; //包含节名Elf32_Word sh_type; //包含节的内容Elf32_Word sh_flags; //各种属性的内容Elf32_Addr sh_addr; //节在内存映像中的地址 Elf32_Off sh_offset; //保存ELF文件中这一节中初始字节的偏移量Elf32_Word sh_size; //包含节的大小Elf32_Word sh_link; //表链接的索引Elf32_Word sh_info; //包含附加信息Elf32_Word sh_addralign; //包含地址对其的约束Elf32_Word sh_entsize; //节中每项的大小 } Elf32_Shdr;
非可执行ELF文件节
节点 | 说明 |
.data | 已初始化的数据 |
bss | 为初始化的数据 |
.hash | 符号散列表 |
.init | 初始化代码 |
.symtab | 符号表 |
.text | 可执行的指令 |
.plt | 过程链接表 |
.rodata | 只读数据 |
dynamic | 动态链接信息 |
程序头表
typedef struct elf64_phdr {Elf64_Word p_type; //描述该段的类型Elf64_Word p_flags; //以p_type而定Elf64_Off p_offset; //<span style="font-family: Arial, Helvetica, sans-serif;">该段的开始相对于文件开始的偏移量</span>Elf64_Addr p_vaddr; //段虚拟地址Elf64_Addr p_paddr; //段的虚拟地址 Elf64_Xword p_filesz; //文件映像中该段的字节数Elf64_Xword p_memsz; //内存映像中该段的字节数Elf64_Xword p_align; //描述要对齐的段在内存中如何对齐,该值是2的整数次幂 } Elf64_Phdr;
通过这些信息,系统函数exec()和链接程序合作,为可执行程序在内存中创建进程映像,该过程如下:
- 将可执行文件的段加入内存
- 加载所有需要的共享库
- 需要时重定向可执行文件及其共享对象
- 将控制权交给程序
那么内核是如何被编译成二进制文件的呢,又是如何在执行前装入内存。下面将开始介绍编译内核源代码。内存启动始于执行arch/x86/boot/目录中的实模式汇编代码。查看arch/x86/kernel/setup_32.c文件可以看出保护模式的内核怎样获取实模式内核收集的信息。第一条信息来自于init/main.c中的代码,深入挖掘init/calibrate.c可以对BogoMIPS校准理解得更清楚,而include/asm-your-arch/bugs.h则包含体系架构相关的检查。
内核中的时间服务由驻留于arch/your-arch/kernel/中的体系架构相关的部分和实现于kernel/timer.c中的通用部分组成。从include/linux/time*.h头文件中可以获取相关的定义。
jiffies定义于linux/jiffies.h文件中。HZ的值与处理器相关,可以从include/asm-your-arch/ param.h找到,内存管理源代码存放在顶层mm/目录中。
Linux的官方源代码发布网址是www.kernel.org。其源代码目录结构示意图如下:
利用内核配置工具自动生成.config的内核配置文件,这是编译的第一步,.config文件位于源代码目录下,其选项的位置根据它们在内核配置工具中的位置进行排序,我们来看看一个.config文件的节选:
1 #2 # Automatically generated make config: don't edit3 #4 CONFIG_X86=y5 CONFIG_MMU=y6 CONFIG_UID16=y7 CONFIG_GENERIC_ISA_DMA=y //这4行位于顶层菜单中 8 9 # 10 # Code maturity level options 11 # 12 CONFIG_EXPERIMENTAL=y 13 CONFIG_CLEAN_COMPILE= 14 CONFIG_STANDALONE=y 15 CONFIG_BROKEN_ON_SMP=y //这4行位于代码成熟度选项菜单中 16 17 # 18 # General setup 19 # 20 CONFIG_SWAP=y 21 CONFIG_SYSVIPC=y 22 #CONFIG_POSIX_MQUEUE is not set 23 CONFIG_BSD_PROCESS_ACCT=y //这4行位于通用设置选项菜单中
最后来粗略的介绍一下Linux内核的Makefile文件,也只能简单的介绍一下啦,这个可是重难点,这里我稍微说一下,以后会具体去学习。Linux内核是一种单体内核,但是通过动态加载模块的方式,使它的开发非常灵活 方便。那么,它是如何编译内核的呢?我们可以通过分析它的Makefile入手。以下是 一个简单的hello内核模块的Makefile.
ifneq ($(KERNELRELEASE),)obj-m:=hello.oelseKERNELDIR:=/lib/modules/$(shell uname -r)/buildPWD:=$(shell pwd)default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean: rm -rf *.o *.mod.c *.mod.o *.koendif
首先,由于make 后面没有目标,所以make会在Makefile中的第一个不是以.开头的目标作为默认的目标执行。于是default成为make的目标。make会执行 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules shell是make内部的函数,make执行了两次。
第一次执行时是读hello模块的源代码所在目录/home/s tudy/prog/mod/hello/下的Makefile。
第二次执行时是执行/usr/src/linux/下的Makefile时.
这其中很复杂,我也不知道怎么讲了。关于make modules的更详细的过程可以在scripts/Makefile.modpost文件的注释 中找到。不过我找到了一个大牛写的跟我一下学Makefile的博客,我把博客地址附在下面,供大家参考一下:http://blog.csdn.net/haoel/article/details/2886/
小结
本章探究了目标文件的编译,链接过程,以及目标文件的结构,以便理解可执行代码的最终形式,构建Linux内核涵盖了内核编译所需要的工具,最后还简单的描述了Makefile,,这些都是难点,,得多加缩习啦,,尽管今天没吃到腊八粥,但是转转锅还是很给力的,吃到现在还不饿,是一个难忘的一天 ~~
版权所有,转载请注明转载地址:http://www.cnblogs.com/lihuidashen/p/4253752.html
转载于:https://www.cnblogs.com/lihuidashen/p/4253752.html
24小时学通Linux内核之构建Linux内核相关推荐
- 24小时学通linux视频教程下载
24小时学通linux视频教程下载 <楚广明24小时学通linux>引用:伏了好长时间,今天总算又一次的为大家带来一点点儿新东西,准备了一段时间后我为大家推了这一套24小时学通linux系 ...
- 24小时学通LINUX内核系列
http://www.cnblogs.com/lihuidashen/category/667475.html 转载于:https://www.cnblogs.com/zengkefu/p/55583 ...
- 通过chroot运行linux,通过chroot构建Linux操作系统
通过chroot构建Linux操作系统 发布时间:2006-04-14 12:41:48来源:红联作者:翔翔 转贴:出处:天极网 在已有的Linux操作系统中,安装另一个开源操作系统,我们一般是先构建 ...
- u盘linux 路由器,如何构建Linux系统下U盘路由器防火墙
如何构建Linux系统下U盘路由器防火墙 步骤十二:高级应用,以其他存储介质使用coyote Linux coyote Linux 官方网址的链接说明其不支持USB启动(http://www.vort ...
- kmem 反编译linux内核_24小时学通Linux内核之如何处理输入输出操作
Linux内核是如何将软硬件结合起来的呢?这里我们将一起探究内核与周围硬件主要是文件IO和硬件设备之间的关系,来解释这个问题.处理器与周围设备的通信依赖于一系列的电路电线,总线就是具有类似功能的电线, ...
- linux 内存大页,Linux大页内存管理等---菜鸟初学
1. 查看linux的内存情况: free -m 2. 查看是否开启大页的方法: cat /proc/meminfo |grep -i HugePage AnonHugePages: 276480 k ...
- Linux 之八 完整嵌入式 Linux 环境、(交叉)编译工具链、CPU 体系架构、嵌入式系统构建工具
最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,由于之前对嵌入式 Linux 环境并不是很了解,因此,第一步就是需要了解如何搭建一个完整的嵌入式 Linux 环境.现在将学习心得记录 ...
- Linux 之八 完整嵌入式 Linux 环境及构建工具、(交叉)编译工具链、CPU 体系架构
最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,由于之前对嵌入式 Linux 环境并不是很了解,因此,第一步就是需要了解如何搭建一个完整的嵌入式 Linux 环境.现在将学习心得记录 ...
- 深度linux_工程师深度:学通Linux内核(含详细代码)
内核探索工具类 Linux的具体概述这里就不多说了,今天主要讲的是Linux内核中常用的数据结构和语法的使用,并简述一些工具和实用程序,从而获取理解内核内幕所需要的信息,还会介绍一下在每个内核子系统所 ...
最新文章
- Java基础day21
- MySQL变量,存储过程,函数,流程控制详解(小白都能懂哦)
- 洛谷P3327:[SDOI2015]约数个数和(莫比乌斯反演)
- java 屏蔽邮箱_使用javamail发送邮件的时候如何阻止附件内容输出到控制台
- Firefox、Chrome 盘助手
- 现代软件工程 团队作业 - 软件分析和用户需求调查 (2013)
- jquery获得指定元素坐标的方法
- 【script】python3使用http.server搭建简易web服务
- [转]JS部分通用函数
- pelco协议及其实现的简单认识
- windows脚本编制引擎_从零开始的场景编辑器(二):脚本系统
- 在Windows Server 2008 R2上安装Ftp服务
- ojdbc6手动装载
- 计算机应用程序错误怎么办 6,WinXP电脑应用程序错误怎么办?
- unipush配置华为通道
- html九宫格拼图怎么做,朋友圈九宫格拼图照片制作方法
- 2017ICPCECIC MJF wants to work
- 把SD卡制作为启动卡的操作步骤
- Anybackup-7.0.8.0系统配置-授权管理
- 利用腾讯漏洞,QQ群日拉万人精准流量的方法
热门文章
- 真实集群中Flink命令行各种模式提交wordcount
- TypeError: the JSON object must be str, bytes or bytearray, not NoneType
- 批量kill掉包含某个nginx的进程
- gensim在“中文查找(关键词)“与“txt文本“之间做相似度计算(返回最相似的文本)
- Unknown column 'XXX' in 'where clause'一例排查
- CentOS下面service mysqld start出现[failed]情况
- 数据结构与算法 总结
- 机器学习(二十)——EMD, LSA, HMM
- 针对eclipse调式代码时打断点出现斜杠的解决方法
- 大话javascript 2期:执行上下文与执行上下文栈