成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux模塊文件如何編譯到內核和獨立編譯成模塊?

系統 Linux
初次接觸Linux內核,好仔細閱讀頂層目錄的readme文件,它是Linux內核的概述和編譯命令說明。readme的說明側重于X86等通用的平臺,對于某些特殊的體系結構,可能有些特殊的說明。

[[400161]]

很多粉絲在群里提問,如何把一個模塊文件編譯到內核中或者獨立變異成ko文件。本文給大家詳解講解。

1. 內核目錄

Linux內核源代碼非常龐大,隨著版本的發展不斷增加。它使用目錄樹結構,并且使用Makefile組織配置、編譯。

初次接觸Linux內核,好仔細閱讀頂層目錄的readme文件,它是Linux內核的概述和編譯命令說明。readme的說明側重于X86等通用的平臺,對于某些特殊的體系結構,可能有些特殊的說明。

頂層目錄的Makefile是整個內核配置編譯的核心文件,負責組織目錄樹中子目錄的編譯管理,還可以設置體系結構和版本號等。

內核源碼的頂層有許多子目錄,分別組織存放各種內核子系統或者文件。具體的目錄說明如下表所示。

2. 編譯工具

1.make mrproper: 清除內核生成的配置文件與目標文件等,一般在第一次編譯時使用

2.導入默認配置信息(在內核根目錄中)

  1. a) make xxx_deconfig 
  2. b) cp arch/arm/configs/xx_deconfig  .config 
  3. 生成默認配置文件 

3.配置命令

  1. make xxxxconfig  修改配置文件 
  2. make xconfig (圖形界面 qt庫) 
  3. make menuconfig (常用 libncurses庫) 
  4. sudo apt-get install libncurses5-dev 
  5. make config (精簡) 

4.編譯內核

  1. make uImage ---生成內核鏡像  /arch/arm/boot/uImage 

5.編譯設備樹

  1. make dtbs ---生成設備樹文件  /arch/arm/boot/dtb/xxxxxx.dtb 

6.編譯生成模塊文件

  1. make modules ---把配置值選成M的代碼編譯生成模塊文件。(.ko)  放在對應的源碼目錄下。 

3. 內核編譯

現在很多基于Linux的產品開發,通常廠家都會提供集成開發環境SDK。builroot使我們搭建環境變得更加方便,但是作為初學者我們還是要掌握如何獨立編譯內核源碼。

0) 前提條件

必須先安裝交叉編譯工具鏈,關于交叉編譯工具鏈的安裝可以參考 《linux環境搭建-ubuntu16.04安裝》

在這里我們使用的是arm-none-linux-gnueabi-gcc。

1)下載內核源碼

下載地址:https://mirrors.edge.kernel.org/pub/linux/kernel/

我們下載Linux-3.14內核(可以是更高的版本)至/home/peng目錄。

或者直接點擊下面鏈接 https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/linux-3.14.10.tar.xz

解開壓縮包,并進入內核源碼目錄,具體過程如下:

  1. $ tar  xvf  linux-3.14.tar.xz 
  2. $ cd  linux-3.14 

2)修改內核目錄樹根下的Makefile,指明交叉編譯器:

  1. $ vim Makefile 

找到ARCH和CROSS_COMPILE, 修改:

  1. ARCH  ?= $(SUBARCH) 
  2. CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) 

  1. ARCH  ?= arm 
  2. CROSS_COMPILE ?= arm-none-linux-gnueabi- 

  

3)配置內核產生.config文件:

導入默認配置

  1. $ make  exynos_defconfig 

這里我們假定要編譯的內核最終在三星的板子上運行,soc名字是exynos,三星公司其實已經將自己的配置文件放置在 ./arch/arm/configs/exynos_defconfig

執行這個命令,最終會在內核根目錄下生成.config文件,

我們編譯內核就完全依賴這個文件。該文件是exynos開發板所需要的一些內核模塊宏定義和參數設置,這些值是廠商給的一個初始配置。實際項目開發中,需要在這個配置文件基礎之上再重新移植自己需要的對應的驅動模塊。

4)配置內核模塊

輸入內核配置命令,進行內核選項的選擇,命令如下:

  1. $ make menuconfig 

命令執行成功以后,會看到如下圖所示的界面。其實我們在圖1.5中看到過同樣功能的界面,那個圖也是內核選項配置界面,只不過那個界面在X-window下才能執行。

其中:

1.子菜單--->

表示有子菜單,按下回車可以進入子菜單。

2.中括號[] 在每一個選項前都有個括號,有的是中括號,有的是尖括號,還有的是圓括號。

[] 表示該選項只有兩種選項,中括號中要么是空,要么是“*”;

用空格鍵可以做出選擇。

3.尖括號<>

<>選擇相應的配置時,有3種選擇,它們代表的含義分別如下。

  1. ● *:將該功能編譯進內核。 
  2. ● 空:不將該功能編譯進內核。 
  3. ● M:將該功能編譯成可以在需要時動態插入到內核中的模塊。 

 4.模塊配置圓括號() 而圓括號的內容是要你在所提供的幾個選項中選擇一項。

如果使用的是make xconfig,使用鼠標就可以選擇對應的選項。如果使用的是make menuconfig,則需要使用回車鍵進行選取。

在編譯內核的過程中,麻煩的事情就是配置這步工作了。初次接觸Linux內核的開發者往往弄不清楚該如何選取這些選項。

實際上,在配置時,大部分選項可以使用其默認值,只有小部分需要根據用戶不同的需要選擇。

選擇的原則是將與內核其他部分關系較遠且不經常使用的部分功能代碼編譯成為可加載模塊,這有利于減小內核的長度,減少內核消耗的內存,簡化該功能相應的環境改變時對內核的影響;不需要的功能就不要選;與內核關系緊密而且經常使用的部分功能代碼直接編譯到內核中。

5)編譯內核:

  1. root@ubuntu:/home/peng/linux-3.14# make uImage 

 

uImage

如果按照默認的配置,沒有改動的話,編譯后系統會在arch/arm/boot目錄下生成一個uImage文件,這個文件就是剛剛生成的。

6)下載Linux內核

因為不同的板子對應的uboot版本都不一樣,所以下載程序的uboot命令也會有所差異,關于驗證,本文暫不討論。

4. 獨立驅動程序的編譯

1. 編譯成獨立模塊

假定我們有以下驅動程序,要編譯成可以加載到開發板的獨立ko文件

hello.c

  1. #include <linux/init.h> 
  2. #include <linux/module.h> 
  3. #include <linux/kdev_t.h> 
  4. #include <linux/fs.h> 
  5. #include <linux/cdev.h> 
  6. //#include <io/uaccess.h> 
  7. #include <linux/device.h> 
  8. #include <asm/io.h> 
  9. #include <asm/uaccess.h> 
  10.  
  11. static int major = 237; 
  12. static int minor = 0; 
  13. static dev_t devno; 
  14. struct device *class_dev = NULL
  15. struct class *cls; 
  16.  
  17.  
  18. static int hello_open (struct inode *inode, struct file *filep) 
  19.  printk("hello_open()\n"); 
  20.  return 0; 
  21. static int hello_release (struct inode *inode, struct file *filep) 
  22.  printk("hello_release()\n"); 
  23.  
  24.  return 0; 
  25.  
  26. #define KMAX_LEN 32 
  27. char kbuf[KMAX_LEN+1] = "kernel"
  28.  
  29.  
  30. //read(fd,buff,40); 
  31.  
  32. static ssize_t hello_read (struct file *filep, char __user *buf, size_t size, loff_t *pos) 
  33.  int error; 
  34.  
  35.   
  36.  if(size > strlen(kbuf)) 
  37.  { 
  38.   size = strlen(kbuf); 
  39.  } 
  40.  
  41.  if(copy_to_user(buf,kbuf, size)) 
  42.  { 
  43.   error = -EFAULT; 
  44.   return error; 
  45.  } 
  46.  
  47.  return size
  48. //write(fd,buff,40); 
  49. static ssize_t hello_write (struct file *filep, const char __user *buf, size_t size, loff_t *pos) 
  50.  int error; 
  51.  
  52.  if(size > KMAX_LEN) 
  53.  { 
  54.   size = KMAX_LEN; 
  55.  } 
  56.  memset(kbuf,0,sizeof(kbuf)); 
  57.  if(copy_from_user(kbuf, buf, size)) 
  58.  { 
  59.   error = -EFAULT; 
  60.   return error; 
  61.  } 
  62.  printk("%s\n",kbuf); 
  63.  return size
  64.  
  65.  
  66. static struct file_operations hello_ops =  
  67.  .open = hello_open, 
  68.  .release = hello_release, 
  69.  .read = hello_read, 
  70.  .write = hello_write, 
  71. }; 
  72. static int hello_init(void) 
  73.  int result; 
  74.   
  75.  printk("hello_init \n"); 
  76.  result = register_chrdev( major, "hello", &hello_ops); 
  77.  if(result < 0) 
  78.  { 
  79.   printk("register_chrdev fail \n"); 
  80.   return result; 
  81.  } 
  82.  cls = class_create(THIS_MODULE, "hellocls"); 
  83.  if (IS_ERR(cls)) { 
  84.   printk(KERN_ERR "class_create() failed for cls\n"); 
  85.   result = PTR_ERR(cls); 
  86.   goto out_err_1; 
  87.  } 
  88.  devno = MKDEV(major, minor); 
  89.   
  90.  class_dev = device_create(cls, NULL, devno, NULL"hellodev"); 
  91.  if (IS_ERR(class_dev)) { 
  92.   result = PTR_ERR(class_dev); 
  93.   goto out_err_2; 
  94.  } 
  95.   
  96.  return 0; 
  97.  
  98. out_err_2: 
  99.  class_destroy(cls); 
  100. out_err_1: 
  101.  unregister_chrdev(major,"hello"); 
  102.  return  result; 
  103. static void hello_exit(void) 
  104.  printk("hello_exit \n"); 
  105.  device_destroy(cls, devno); 
  106.  class_destroy(cls); 
  107.  unregister_chrdev(major,"hello"); 
  108.  return
  109. module_init(hello_init); 
  110. module_exit(hello_exit); 
  111. MODULE_LICENSE("GPL"); 
  112. //proc/devices 

注意我們需要編寫Makefile如下:

  1. ifneq ($(KERNELRELEASE),) 
  2. obj-m:=hello.o 
  3. else 
  4. KDIR :=/home/peng/linux-3.14 
  5. PWD  :=$(shell pwd) 
  6. all
  7.  make -C $(KDIR) M=$(PWD) modules 
  8. clean: 
  9.  rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order 
  10. endif 

關于Makefile的詳解,大家可以參考我們之前的文章 《手把手教Linux驅動1-模塊化編程》 其中內核路徑:

  1. KDIR :=/home/peng/linux-3.14 

必須是我們剛才編譯過的內核源碼根目錄。

編譯時,程序可以放到其他目錄下:

用file命令查看文件屬性,是基于ARM的。該模塊文件就是與前面編譯的內核配套的驅動模塊,如果開發板的內核版本與上面編譯的版本號一致,那么該模塊文件就可以在開發板上insmod。

2. 編譯到內核

步驟:

1)拷貝文件 如果要將剛才的驅動程序直接編譯到內核,那么我們必須把hello.c拷貝到內核的某個目錄下。

字符設備可以考慮放到以下目錄:

  1. linux-3.14/drivers/char 

 

2)修改Makefile

  1. root@ubuntu:/home/peng/linux-3.14/drivers/char# vim Makefile  

修改如下:

該行內容是根據宏CONFIG_HELLO來決定是否編譯hello.c這個文件。

3)修改Kconfig

7 HELLO 取前面步驟CONFIG_HELLO下劃線后面的字符串 8 tristate 表示該模塊最終有3個選項 空 * M 9 表示該模塊依賴的模塊,如果ARCH_EXYNOS4模塊沒有被選中,那么HELLO模塊也不會被編譯到內核 10 幫助信息

4) 重新配置 執行

  1. make menuconfig 

進入配置頁面,

輸入 / 可以根據關鍵字查找模塊所在位置。

我們添加的模塊文件的位置:

根據路徑

  1. -> Device Drivers  
  2.    -> Character devices 

找到我們剛才的模塊配置路徑

此處是尖括號,因為我們設置的屬性是tristate

移動到Help處,可以看到前面我們填充的幫助信息

我們可以按下空格鍵設置為*,編譯到內核中。

選擇Save,

然后再點擊2次Exit,就可以退出。

5)重新編譯內核

  1. root@ubuntu:/home/peng/linux-3.14# make uImage 

這樣,我們的模塊編譯到了新生成的內核模塊文件中。

3. 補充

前面一節其實最終目的是生成CONFIG_HELLO=y 這個定義信息,并把該信息保存到內核根目錄的.config文件中。

其實我們如果不修改Kconfig,直接在.config中增加這個宏定義也是可以的。

今天內容就到這里,還等什么?抓緊操練起來吧。

文中用到的虛擬機,叫交叉編譯工具,還有源代碼,

本文轉載自微信公眾號「一口Linux」,可以通過以下二維碼關注。轉載本文請聯系一口Linux公眾號。

 

責任編輯:姜華 來源: 一口Linux
相關推薦

2019-05-24 16:20:11

Python 開發編程語言

2023-05-08 08:05:42

內核模塊Linux

2010-04-12 11:19:47

編譯內核模塊

2009-12-17 15:28:32

內核模塊編譯

2021-08-18 08:00:00

Emscripten開發技術

2015-04-15 09:28:45

JavaScript熱門工具

2009-12-16 10:15:58

VS2003編譯

2011-08-29 15:12:24

UbuntuLinux模塊

2011-03-14 13:51:00

iptables編譯

2018-06-19 09:07:57

Linux內核模塊

2017-03-27 18:05:49

Linux內核編譯與開發

2010-01-22 11:01:04

linux內核模塊

2010-03-23 10:47:46

python代碼

2009-10-16 09:42:06

2018-10-31 14:00:05

LispJavaScript編程語言

2009-09-10 13:17:50

matlab函數

2011-01-04 17:00:32

Linux內核編譯

2010-03-02 16:13:56

Linux升級

2009-10-16 09:45:41

Linux內核操作系統

2009-12-17 15:18:47

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区在线视频 | 婷婷久久综合 | 欧美另类日韩 | 亚洲一区不卡在线 | 午夜影院网站 | 香蕉一区| 亚洲精品美女视频 | 久色| 天天人人精品 | a级大片免费观看 | 国产精品久久久久久一区二区三区 | 黄色网毛片| 国产不卡一 | 国产精品久久久久久一级毛片 | 国产福利在线视频 | 久久久夜夜夜 | 午夜精品一区二区三区在线视频 | 久久久久网站 | 日日做夜夜爽毛片麻豆 | 99精品一区二区三区 | 亚洲精品久久久久久久久久久 | 国产精品揄拍一区二区 | 国产精品a久久久久 | 久优草| 91亚洲一区| 97国产一区二区 | 成人字幕网zmw | 中文字幕一区二区三区在线视频 | 亚洲电影在线播放 | 在线免费观看欧美 | 日韩在线观看中文字幕 | 成人二区三区 | 国产日韩精品久久 | 男人天堂免费在线 | 天堂在线1 | 亚洲国产成人av好男人在线观看 | 国产精品69久久久久水密桃 | 超碰在线国产 | 亚洲欧美一区二区三区国产精品 | 亚洲一区二区在线电影 | 国产福利资源 |