中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux內核編譯與開發的示例分析

發布時間:2021-12-08 11:42:02 來源:億速云 閱讀:155 作者:小新 欄目:系統運維

這篇文章將為大家詳細講解有關Linux內核編譯與開發的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

一.Linux內核簡介

linux kernel map:

Linux內核編譯與開發的示例分析

linux 系統體系結構:

Linux內核編譯與開發的示例分析

linux kernel體系結構:

arm有7種工作模式,x86也實現了4個不同級別RING0-RING3,RING0級別***,

這樣linux用戶代碼運行在RING3下,內核運行在RING0,這樣系統本身就得到了

充分的保護

用戶空間(用戶模式)轉到內核空間(系統模式)方法:

  • 系統調用

  • 硬件中斷

linux kernel 體系結構:

Linux內核編譯與開發的示例分析

虛擬文件系統VFS:

VFS(虛擬文件系統)隱藏各種文件系統的具體細節,為文件操作提供統一的接口

二.Linux內核源代碼

linux內核下載www.kernel.org

目錄結構:

解壓linux kernel tar后目錄

  • arch:根據cpu體系結構不同而分的代碼

  • block:部分塊設備驅動程序

  • crypto:加密,壓縮,CRC校驗算法

  • documentation:內核文檔

  • drivers:設備驅動程序

  • fs(虛擬文件系統vfs):文件系統

  • include:內核所需的頭文件,(與平臺無關的頭文件在include/linux中)

  • lib:庫文件代碼(與平臺相關的)

  • mm:實現內存管理,與硬件體系結構無關的(與硬件體系結構相關的在arch中)

  • net:網絡協議的代碼

  • samples:一些內核編程的范例

  • scripts:配置內核的腳本

  • security:SElinux的模塊

  • sound:音頻設備的驅動程序

  • usr:cpio命令實現,用于制作根文件系統的命令(文件系統與內核放到一塊的命令)

  • virt:內核虛擬機

linux DOC 編譯生成:

linux源根目錄/Documentation/00-INDEX:目錄索引

linux源根目錄/Documentation/HOWTO:指南

生成linux內核幫助文檔:在linux源根目錄(Documentation) 執行make htmldocs

ubuntu16下需要執行sudo apt-get install xmlto安裝插件才可生成doc文檔

后面開發中經常要改的是arch,drivers中的代碼

三.Linux內核配置與編譯

清理文件(在linux源碼根目錄):

  • make clean:只清理所有產生的文件

  • make mrproper:清理所有產生的文件與config配置文件

  • make distclean:清理所有產生的文件與config配置文件,并且編輯過的與補丁文件

配置(收集硬件信息如cpu型號,網卡等...):

  • make config:基于文本模式的交互配置

  • make menuconfig:基于文本模式的菜單模式(推薦使用)

  • make oldconfig:使用已有的.config,但會詢問新增的配置項

  • make xconfig:圖形化的配置(需要安裝圖形化系統)

配置方法:

1)使用make menuconfig操作方法:

1>按y:編譯>連接>鏡像文件

2>按m:編譯

3>按n:什么都不做

4>按"空格鍵":y,n輪換

配置完并保存后會在linux源碼根目錄下生成一個.config文件

注意:在ubuntu11上要執行apt-get install libncurses5-dev來安裝支持包

2)利用已有的配置文件模板(.config)

1>linux源碼根目錄/arch/<cpu架構>/configs/<具體某一的CPU文件>,把里面對應的文件copy并改名為.config至linux源碼根目錄下

2>利用當前運行已有的文件(要用ls /boot/  -a查看)把/boot/config-2.6.18-53.e15拷貝并改名為.config至linux源碼根目錄下執行以上操作就可以用make  menuconfig在拷貝

.config文件上面修改文件了

編譯內核:

1)make zImage

2)make bzImage

區別:在X86平臺上,zimage只能用于小于512k的內核

獲取詳細編譯信息:make zimage V=1 或 make bzimage V=1

編譯好的內核在:arch/<cpu>/boot/目錄下

注意:在把.config配置文件cp到根目錄編譯內核前,必須進入make menuconfig并保存退出(否則生不了效)

編譯并安裝模塊:

1)編譯內核模塊:make modules

2)安裝內核模塊:make modules_install INSTALL_MOD_PATH=/lib/modules

更換本機器內核:將編譯好的內核模塊從內核源碼目錄copy至/lib/modules下

制作init ramdisk():輸入執行命令mkinitrd initrd-2.6.39(任意)  2.6.39(可通過查詢/lib/modules下的目錄得到)

注意:

mkinitrd命令為redhat里面的,ubuntu的命令為:mkinitramfs -k /lib/modules/模塊安裝位置 -o  initrd-2.6.39(任意) 2.6.39(可通過查詢/lib/modules下的目錄得到)

如果ubuntu里面沒有mkinitramfs命令可以用apt-get install initrd-tools進行安裝

安裝內核模塊:

1)手動

1>cp linux根目錄/arch/x86/boot/bzImage /boot/mylinux-2.6.39

2>cp linux根目錄/initrd-2.6.39 /boot/initrd-2.6.39

***修改/etc/grub.conf或/etc/lilo.conf文件

2)自動

1>make install:這個命令會自動完成上面的操作(查看當前內核版本:uname -r)

-----------------------------------------------------------------------------

四.linux內核模塊開發

描述:

linux內核組件非常龐大,內核ximage并不包含某組件,而是在該組件需要被使用的時候,動態的添加到正在運行的內核中(也可以卸載),這種機制叫做“內核模塊”的機制。內核模塊通常通過使用makefile文件對模塊進行編譯

模塊安裝與卸載:

1)加載:insmod hello.ko

2)卸載:rmmod hello

3)查看:lsmod

4)加載(自動尋找模塊依賴):modprobe hello

modprobe會根據文件/lib/modules/version/modules.dep來查看要加載的模塊,看它是否還依賴于其他模塊,如果是,會先找到這些模塊,把它們先加載到內核

實例分析:

1)moduleDep/1(一個模塊的編譯)

 1 #include <linux/module.h> 2 #include <linux/init.h> 3  4 //模塊入口函數 5 //__init:表示代碼段中的子段,里面的內容只運行一次并且回收內存. 6 static int __init hello_init(void) 7 { 8     printk(KERN_EMERG "hello world!\n"); 9     return 0;10 }11 //模塊卸載函數12 //__exit:13 static void __exit hello_exit(void)14 {15     printk(KERN_EMERG "hello exit!\n");16 }17 //內核符號導出 函數18 int add_integar(int a,int b)19 {20     return a+b;  21 }22 int sub_integar(int a,int b)23 {24     return a-b;  25 }26 27 module_init(hello_init);28 module_exit(hello_exit);29 //函數導出30 EXPORT_SYMBOL(add_integar);31 EXPORT_SYMBOL(sub_integar);

makefile:

#***次執行KERNELRELEASE是空的,所以執行else里面的 ifneq ($(KERNELRELEASE),)  obj-m :=hello.o  #else塊  elseKDIR:= /lib/modules/2.6.18-53.el5/build  all: #KDIR    依賴內核模塊源代碼路徑(內核編譯安裝路徑) #PWD     表示內核代碼在哪(當前目錄) #modules 編譯的是模塊     make -C $(KDIR) M=$(PWD) modules   clean:     rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order  endif

2)moduleDep/2(兩個模塊的編譯)

#include <linux/module.h>  #include <linux/init.h>  //模塊可選信息  MODULE_LICENSE("GPL");//許可證聲明  MODULE_AUTHOR("liyuan");//作者聲明  MODULE_DESCRIPTION("This module is a param example.");//模塊描述  MODULE_VERSION("V1.0");//模塊別名  MODULE_ALIAS("a simple module");//模塊別名   //模塊參數 static char *name = "liyuan arg"; static int age = 30; //S_IRUGO是參數權限,也可以用數字 module_param(age,int,S_IRUGO); module_param(name,charp,S_IRUGO);   //使用外部文件函數 extern int add(int a,int b);   //聲明 外部內核符號 函數 extern int add_integar(int a,int b); extern int sub_integar(int a,int b);  static int __init mains_init(void) {      //多文件編譯      printk(KERN_EMERG"param hi");     int vle=add(1,2);     printk(KERN_EMERG"add value:%d\n",vle);     //模塊參數       printk(KERN_EMERG" name : %s\n",name);      printk(KERN_EMERG" age : %d\n",age);      //使用其他模塊的函數(內核符號導出)     int adds=add_integar(3,1);     int subs=sub_integar(3,1);     printk(KERN_EMERG" add_integar : %d\n",adds);     printk(KERN_EMERG" sub_integar : %d\n",subs);     return 0; }  static void __exit mains_exit(void) {     printk("param exit!"); }  module_init(mains_init);52 module_exit(mains_exit);

add.c

int add(int a,int b) {      return a+b; }

makefile

ifneq ($(KERNELRELEASE),) #兩個以上內核源文件 生成單獨的內核模塊名ma  #內核ma obj-m :=ma.o #下面的ma-objs前面必須和上面一樣為ma ma-objs := mains.o add.oelseKDIR:= /lib/modules/2.6.18-53.el5/build  all:         make -C $(KDIR) M=$(PWD) modules  clean:     rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order  endif

運行帶參模塊:insmod hello.ko name=yuan age=12

內核符號導出(/proc/kallsyms記錄了內核中所有導出的符號的名字與地址):

一個內核模塊的運行依賴另一個內核模塊的函數實現,必須先運行***個內核模塊,這樣就需要進行內核符號導出。

注意:

錯誤信息:disagrees about version of symbol struct_module insmod:error inserting  ...

開發內核模塊時會出現,內核模塊不匹配的情況.是你當前運行的linux內核與編譯連接所依賴的

內核版本不匹配,解決方法:

  • 使用modprobe --force-modversion強行插入

  • 可使用uname -r進行查看當前運行的內核版本

printk內核打印:

在<linux/kernel.h>中printk有8個優先級,按優先級遞減的是:

  • KERN_EMERG 0

用于緊急的消息,常常是那些崩潰的消息

  • KERN_ALERT 1

需要立刻行動的消息

  • KERN_CRIT 2

嚴重情況

  • KERN_ERR 3

錯誤情況

  • KERN_WARNING(printk默認級別) 4

有問題的警告

  • KERN_NOTICE 5

正常情況,但是仍然值得注意

  • KERN_INFO 6

信息消息

  • KERN_DEBUG 7

用作調試消息

不管是哪個級別的都會在/var/log/messages里面打印出來(messages可以刪除后,運行內核進行測試內核打印情況)控制臺打印(優先級配置/proc/sys/kernel/printk)

6 4 1 7

  • Console_loglevel

  • Default_message_loglevel

  • Minimum_console_level

  • Default_console_loglevel

在vm+redhat安裝2.6.39內核時出現的錯誤

啟動時報could not find filesystem '/dev/root'

解決方法

a.通過make menuconfig選中以下對應的選項

General setup -->

[*] enable deprecated sysfs features to support old userspace tools

成功時下面那個也*了的

b.修改.config文件

修改.config文件中CONFIG_SYSFS_DEPRECATED_V2,將原本被注釋掉的

CONFIG_SYSFS_DEPRECATED_V2 改成CONFIG_SYSFS_DEPRECATED_V2=y

關于“Linux內核編譯與開發的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

皮山县| 昔阳县| 江西省| 尼勒克县| 汕头市| 和硕县| 平遥县| 彩票| 浪卡子县| 米泉市| 鲜城| 临城县| 曲松县| 六枝特区| 巩义市| 台东市| 旺苍县| 兴和县| 江油市| 固安县| 宜宾县| 攀枝花市| 长白| 苏州市| 钦州市| 阿合奇县| 乌拉特前旗| 海安县| 焦作市| 英山县| 沙雅县| 黎平县| 安阳县| 江永县| 随州市| 浦城县| 信丰县| 诸暨市| 女性| 滨州市| 兴海县|