今天是腊八节,说好的女票要给我做的腊八粥就这样泡汤了,好伤心,好心酸呀,看来代码写久了真的是惹人烦滴,所以告诫各位技术男敲醒警钟,不要想我看齐,不然就只能和代码为伴了的~~话说没了腊八粥但还是有代码,还有各位读者的支持呀,所以得继续写下去,静下心来,完成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内核相关推荐

  1. 24小时学通linux视频教程下载

    24小时学通linux视频教程下载 <楚广明24小时学通linux>引用:伏了好长时间,今天总算又一次的为大家带来一点点儿新东西,准备了一段时间后我为大家推了这一套24小时学通linux系 ...

  2. 24小时学通LINUX内核系列

    http://www.cnblogs.com/lihuidashen/category/667475.html 转载于:https://www.cnblogs.com/zengkefu/p/55583 ...

  3. 通过chroot运行linux,通过chroot构建Linux操作系统

    通过chroot构建Linux操作系统 发布时间:2006-04-14 12:41:48来源:红联作者:翔翔 转贴:出处:天极网 在已有的Linux操作系统中,安装另一个开源操作系统,我们一般是先构建 ...

  4. u盘linux 路由器,如何构建Linux系统下U盘路由器防火墙

    如何构建Linux系统下U盘路由器防火墙 步骤十二:高级应用,以其他存储介质使用coyote Linux coyote Linux 官方网址的链接说明其不支持USB启动(http://www.vort ...

  5. kmem 反编译linux内核_24小时学通Linux内核之如何处理输入输出操作

    Linux内核是如何将软硬件结合起来的呢?这里我们将一起探究内核与周围硬件主要是文件IO和硬件设备之间的关系,来解释这个问题.处理器与周围设备的通信依赖于一系列的电路电线,总线就是具有类似功能的电线, ...

  6. linux 内存大页,Linux大页内存管理等---菜鸟初学

    1. 查看linux的内存情况: free -m 2. 查看是否开启大页的方法: cat /proc/meminfo |grep -i HugePage AnonHugePages: 276480 k ...

  7. Linux 之八 完整嵌入式 Linux 环境、(交叉)编译工具链、CPU 体系架构、嵌入式系统构建工具

      最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,由于之前对嵌入式 Linux 环境并不是很了解,因此,第一步就是需要了解如何搭建一个完整的嵌入式 Linux 环境.现在将学习心得记录 ...

  8. Linux 之八 完整嵌入式 Linux 环境及构建工具、(交叉)编译工具链、CPU 体系架构

      最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,由于之前对嵌入式 Linux 环境并不是很了解,因此,第一步就是需要了解如何搭建一个完整的嵌入式 Linux 环境.现在将学习心得记录 ...

  9. 深度linux_工程师深度:学通Linux内核(含详细代码)

    内核探索工具类 Linux的具体概述这里就不多说了,今天主要讲的是Linux内核中常用的数据结构和语法的使用,并简述一些工具和实用程序,从而获取理解内核内幕所需要的信息,还会介绍一下在每个内核子系统所 ...

最新文章

  1. Java基础day21
  2. MySQL变量,存储过程,函数,流程控制详解(小白都能懂哦)
  3. 洛谷P3327:[SDOI2015]约数个数和(莫比乌斯反演)
  4. java 屏蔽邮箱_使用javamail发送邮件的时候如何阻止附件内容输出到控制台
  5. Firefox、Chrome 盘助手
  6. 现代软件工程 团队作业 - 软件分析和用户需求调查 (2013)
  7. jquery获得指定元素坐标的方法
  8. 【script】python3使用http.server搭建简易web服务
  9. [转]JS部分通用函数
  10. pelco协议及其实现的简单认识
  11. windows脚本编制引擎_从零开始的场景编辑器(二):脚本系统
  12. 在Windows Server 2008 R2上安装Ftp服务
  13. ojdbc6手动装载
  14. 计算机应用程序错误怎么办 6,WinXP电脑应用程序错误怎么办?
  15. unipush配置华为通道
  16. html九宫格拼图怎么做,朋友圈九宫格拼图照片制作方法
  17. 2017ICPCECIC MJF wants to work
  18. 把SD卡制作为启动卡的操作步骤
  19. Anybackup-7.0.8.0系统配置-授权管理
  20. 利用腾讯漏洞,QQ群日拉万人精准流量的方法

热门文章

  1. 真实集群中Flink命令行各种模式提交wordcount
  2. TypeError: the JSON object must be str, bytes or bytearray, not NoneType
  3. 批量kill掉包含某个nginx的进程
  4. gensim在“中文查找(关键词)“与“txt文本“之间做相似度计算(返回最相似的文本)
  5. Unknown column 'XXX' in 'where clause'一例排查
  6. CentOS下面service mysqld start出现[failed]情况
  7. 数据结构与算法 总结
  8. 机器学习(二十)——EMD, LSA, HMM
  9. 针对eclipse调式代码时打断点出现斜杠的解决方法
  10. 大话javascript 2期:执行上下文与执行上下文栈