日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

24小时学通Linux内核之构建Linux内核

發(fā)布時(shí)間:2023/12/19 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 24小时学通Linux内核之构建Linux内核 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  今天是臘八節(jié),說(shuō)好的女票要給我做的臘八粥就這樣泡湯了,好傷心,好心酸呀,看來(lái)代碼寫久了真的是惹人煩滴,所以告誡各位技術(shù)男敲醒警鐘,不要想我看齊,不然就只能和代碼為伴了的~~話說(shuō)沒了臘八粥但還是有代碼,還有各位讀者的支持呀,所以得繼續(xù)寫下去,靜下心來(lái),完成Linux內(nèi)核的學(xué)習(xí),堅(jiān)持,加油~

  到目前為止,我們已經(jīng)認(rèn)識(shí)了Linux內(nèi)核子系統(tǒng),也探究了系統(tǒng)的初始化過(guò)程,并且深入探索了start_kernel()函數(shù),同樣,了解內(nèi)核映像的創(chuàng)建也是非常重要的,接下來(lái)將討論一下內(nèi)核映像的編譯和鏈接過(guò)程,那么這些當(dāng)然需要工具鏈了,工具鏈包含編譯程序、匯編程序、鏈接程序,是創(chuàng)建Linux內(nèi)核映像的一組程序集合,下圖說(shuō)明了工具鏈的鏈?zhǔn)疥P(guān)系:

ELF二進(jìn)制目標(biāo)文件

可執(zhí)行ELF目標(biāo)文件包括:ELF頭,程序頭表(用于加載的節(jié)),第1節(jié),第2節(jié)。。。。節(jié)頭表(可選)

ELF頭文件

typedef struct elf32_hdr{unsigned char e_ident[EI_NIDENT]; //標(biāo)識(shí)該文件是否為ELF文件Elf32_Half e_type; //指定目標(biāo)文件類型,例如可執(zhí)行文件,重定位文件,共享的目標(biāo)文件Elf32_Half e_machine; //被編譯文件所在系統(tǒng)的體系結(jié)構(gòu)Elf32_Word e_version; //目標(biāo)文件的版本Elf32_Addr e_entry; /* Entry point */ //程序的起始地址Elf32_Off e_phoff; //保存程序頭表在文件中的偏移量Elf32_Off e_shoff; //保存節(jié)頭表在文件中的偏移量Elf32_Word e_flags; //保存于特定與處理器的標(biāo)志Elf32_Half e_ehsize; //字段保存ELF頭的大小Elf32_Half e_phentsize; //保存程序頭表中的每一項(xiàng)的大小Elf32_Half e_phnum; //程序頭中表項(xiàng)的個(gè)數(shù)Elf32_Half e_shentsize; //節(jié)頭表中每一項(xiàng)的大小Elf32_Half e_shnum; //保存節(jié)頭中項(xiàng)的數(shù)量,表明該文件中有多少節(jié)Elf32_Half e_shstrndx; //保存節(jié)頭中節(jié)字符串的索引 } Elf32_Ehdr;

節(jié)頭表

typedef struct elf32_shdr {Elf32_Word sh_name; //包含節(jié)名Elf32_Word sh_type; //包含節(jié)的內(nèi)容Elf32_Word sh_flags; //各種屬性的內(nèi)容Elf32_Addr sh_addr; //節(jié)在內(nèi)存映像中的地址 Elf32_Off sh_offset; //保存ELF文件中這一節(jié)中初始字節(jié)的偏移量Elf32_Word sh_size; //包含節(jié)的大小Elf32_Word sh_link; //表鏈接的索引Elf32_Word sh_info; //包含附加信息Elf32_Word sh_addralign; //包含地址對(duì)其的約束Elf32_Word sh_entsize; //節(jié)中每項(xiàng)的大小 } Elf32_Shdr;

非可執(zhí)行ELF文件節(jié)

節(jié)點(diǎn)說(shuō)明
.data已初始化的數(shù)據(jù)
bss為初始化的數(shù)據(jù)
.hash符號(hào)散列表
.init初始化代碼
.symtab?符號(hào)表
.text ?可執(zhí)行的指令
.plt ?過(guò)程鏈接表
.rodata?只讀數(shù)據(jù)
dynamic動(dòng)態(tài)鏈接信息

?

?

?

?

?

?

?

?

?

?

程序頭表

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;">該段的開始相對(duì)于文件開始的偏移量</span>Elf64_Addr p_vaddr; //段虛擬地址Elf64_Addr p_paddr; //段的虛擬地址 Elf64_Xword p_filesz; //文件映像中該段的字節(jié)數(shù)Elf64_Xword p_memsz; //內(nèi)存映像中該段的字節(jié)數(shù)Elf64_Xword p_align; //描述要對(duì)齊的段在內(nèi)存中如何對(duì)齊,該值是2的整數(shù)次冪
}?Elf64_Phdr;?

通過(guò)這些信息,系統(tǒng)函數(shù)exec()和鏈接程序合作,為可執(zhí)行程序在內(nèi)存中創(chuàng)建進(jìn)程映像,該過(guò)程如下:

  • 將可執(zhí)行文件的段加入內(nèi)存
  • 加載所有需要的共享庫(kù)
  • 需要時(shí)重定向可執(zhí)行文件及其共享對(duì)象
  • 將控制權(quán)交給程序

  

  那么內(nèi)核是如何被編譯成二進(jìn)制文件的呢,又是如何在執(zhí)行前裝入內(nèi)存。下面將開始介紹編譯內(nèi)核源代碼。內(nèi)存啟動(dòng)始于執(zhí)行arch/x86/boot/目錄中的實(shí)模式匯編代碼。查看arch/x86/kernel/setup_32.c文件可以看出保護(hù)模式的內(nèi)核怎樣獲取實(shí)模式內(nèi)核收集的信息。第一條信息來(lái)自于init/main.c中的代碼,深入挖掘init/calibrate.c可以對(duì)BogoMIPS校準(zhǔn)理解得更清楚,而include/asm-your-arch/bugs.h則包含體系架構(gòu)相關(guān)的檢查。

  內(nèi)核中的時(shí)間服務(wù)由駐留于arch/your-arch/kernel/中的體系架構(gòu)相關(guān)的部分和實(shí)現(xiàn)于kernel/timer.c中的通用部分組成。從include/linux/time*.h頭文件中可以獲取相關(guān)的定義。

  jiffies定義于linux/jiffies.h文件中。HZ的值與處理器相關(guān),可以從include/asm-your-arch/ param.h找到,內(nèi)存管理源代碼存放在頂層mm/目錄中。

Linux的官方源代碼發(fā)布網(wǎng)址是www.kernel.org。其源代碼目錄結(jié)構(gòu)示意圖如下:

  利用內(nèi)核配置工具自動(dòng)生成.config的內(nèi)核配置文件,這是編譯的第一步,.config文件位于源代碼目錄下,其選項(xiàng)的位置根據(jù)它們?cè)趦?nèi)核配置工具中的位置進(jìn)行排序,我們來(lái)看看一個(gè).config文件的節(jié)選:

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行位于代碼成熟度選項(xiàng)菜單中 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行位于通用設(shè)置選項(xiàng)菜單中

  

  最后來(lái)粗略的介紹一下Linux內(nèi)核的Makefile文件,也只能簡(jiǎn)單的介紹一下啦,這個(gè)可是重難點(diǎn),這里我稍微說(shuō)一下,以后會(huì)具體去學(xué)習(xí)。Linux內(nèi)核是一種單體內(nèi)核,但是通過(guò)動(dòng)態(tài)加載模塊的方式,使它的開發(fā)非常靈活 方便。那么,它是如何編譯內(nèi)核的呢?我們可以通過(guò)分析它的Makefile入手。以下是 一個(gè)簡(jiǎn)單的hello內(nèi)核模塊的Makefile.?

ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
KERNELDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
??????? $(MAKE) -C $(KERNELDIR)? M=$(PWD) modules
clean:
??????? rm -rf *.o *.mod.c *.mod.o *.ko
endif

  首先,由于make 后面沒有目標(biāo),所以make會(huì)在Makefile中的第一個(gè)不是以.開頭的目標(biāo)作為默認(rèn)的目標(biāo)執(zhí)行。于是default成為make的目標(biāo)。make會(huì)執(zhí)行 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules shell是make內(nèi)部的函數(shù),make執(zhí)行了兩次。

第一次執(zhí)行時(shí)是讀hello模塊的源代碼所在目錄/home/s tudy/prog/mod/hello/下的Makefile。

第二次執(zhí)行時(shí)是執(zhí)行/usr/src/linux/下的Makefile時(shí).?

這其中很復(fù)雜,我也不知道怎么講了。關(guān)于make modules的更詳細(xì)的過(guò)程可以在scripts/Makefile.modpost文件的注釋 中找到。不過(guò)我找到了一個(gè)大牛寫的跟我一下學(xué)Makefile的博客,我把博客地址附在下面,供大家參考一下:http://blog.csdn.net/haoel/article/details/2886/

?

  小結(jié)

  本章探究了目標(biāo)文件的編譯,鏈接過(guò)程,以及目標(biāo)文件的結(jié)構(gòu),以便理解可執(zhí)行代碼的最終形式,構(gòu)建Linux內(nèi)核涵蓋了內(nèi)核編譯所需要的工具,最后還簡(jiǎn)單的描述了Makefile,,這些都是難點(diǎn),,得多加縮習(xí)啦,,盡管今天沒吃到臘八粥,但是轉(zhuǎn)轉(zhuǎn)鍋還是很給力的,吃到現(xiàn)在還不餓,是一個(gè)難忘的一天  ~~

?

  版權(quán)所有,轉(zhuǎn)載請(qǐng)注明轉(zhuǎn)載地址:http://www.cnblogs.com/lihuidashen/p/4253752.html

轉(zhuǎn)載于:https://www.cnblogs.com/lihuidashen/p/4253752.html

總結(jié)

以上是生活随笔為你收集整理的24小时学通Linux内核之构建Linux内核的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。