1. 程式人生 > >18 增加驅動原始碼到核心

18 增加驅動原始碼到核心

增加驅動原始碼到核心


linux核心原始碼目錄下,進行配置時:

make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

    上面命令執行,它又會呼叫:
        scripts/kconfig/mconf Kconfig  
            //其中"scripts/kconfig/mconf"是一個專門在終端上顯示介面的程式
            //"Kconfig"是在原始碼目錄下的檔案,傳遞給mconf程式,讓mconf根據"Kconfig"裡面的內容產生相應的配置項
            //也就是說如要在linux核心裡增加自己驅動的配置項時,只需要修改Kconfig檔案裡的內容即可
//配置完成後,最終的核心配置結果存放在linux核心原始碼目錄下的".config"裡

Kconfig語法:

型別有:
    bool:布林(選或不選)  
    tristate:三態(編進核心或編成模組或不編)  
    hex:十六進位制數  
    string:字串
    int:整型


基礎語法1:
    config  關鍵字A
        型別  "提示字元" if 關鍵字B  //if表示依賴關鍵字B項,如果B項不選中,則A項不會顯示出來(可不寫依賴)
        default y/m/n   //設定預設值(y編進核心,m編為模組,n不編譯)(可不寫)
        help
            幫助資訊


基礎語法2
: config 關鍵字C depends on 關鍵字D && 關鍵字E && 關鍵字F //depends on表示依賴關鍵字D, E, F項,如果這些項有其中一項不選中,則C項不會顯示出來(可不寫依賴) 型別 "提示字元" 增加選單項: menu "選單名" //增加一個選單 config ... config ... ... endmenu 必須選擇一項的配置項: choice prompt "選項名" default 關鍵字 //預設選中的項 config 關鍵字 bool/tristate "提示"
config ... config ... .... endchoice

menuconfig與config用法一樣,區別在:menuconfig如有子項依賴的話,則子項在下級選單裡,config不管依賴關係怎樣,都是在並列的選單項裡


在linux核心裡應用兩個配置項來表示這兩個驅動模組,而且它們有依賴關係。

在linux核心裡幾乎每個目錄裡都有Kconfig,Kconfig檔案由它的上一級目錄的Kconfig裡”source”呼叫。


增加我們自己的驅動配置項(Kconfig裡面可通過“source xxx/xxx/Kconfig”呼叫其它目錄的Kconfig):

1.在核心原始碼的drivers/目錄下建立一個"mydrives"子目錄(裡面存放我們自己的驅動原始碼)

2.在mydrivers目錄下增加我們的驅動原始碼:
    (1)建立myfunc子目錄寫myfunc.c(用於提供全域性函式"myfunc"):
            myfunc.c的內容:
                #include <linux/init.h>
                #include <linux/module.h>

                void myfunc(char *str)
                {
                    printk("in my func\n");
                    printk("%s\n", str);
                }

                MODULE_LICENSE("GPL");

                EXPORT_SYMBOL(myfunc);

    (2)建立mytest子目錄寫mytest.c(呼叫"myfunc"函式的測試程式碼):
            mytest.c的內容:
                #include <linux/init.h>
                #include <linux/module.h>

                extern void myfunc(char *str);

                int num = 1000;

                static int __init test_init(void)
                {
                    myfunc("in test to call the extern func of myfunc");
                    printk("in test : num is %d\n", num);
                    printk("test init success\n");

                    return 0;
                }

                static void __exit test_exit(void)
                {
                    printk("test exited\n");
                }

                module_init(test_init);
                module_exit(test_exit);

                MODULE_LICENSE("GPL");

    (3)分別在myfunc子目錄和mytest子目錄寫Kconfig檔案:
            myfunc子目錄裡的Kconfig內容:
                config  MYFUNC
                    tristate  "configuration of myfunc"
                    default  y
                    help
                        help of myfunc

            mytest子目錄裡的Kconfig內容:   
                config  MYTEST
                    tristate  "test of myfunc"
                    depends on  MYFUNC
                    help
                        this is a test of myfunc

    (4)寫mydrivers目錄Kconfig檔案:
            mydrivers目錄裡的Kconfig內容:
                source "drivers/mydrivers/myfunc/Kconfig"
                source "drivers/mydrivers/mytest/Kconfig"5)最後,不要忘了在核心原始碼drivers目錄裡的Kconfig增加呼叫mydrivers裡的Kconfig
            在drivers目錄裡的Kconfig增加語句:
                source "drivers/mydrivers/Kconfig"

注意:通過"make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-"選上這兩個配置項後,在.config檔案裡可檢視到:
    CONFIG_MYFUNC=y/m/n
    CONFIG_MYTEST=y/m/n

編譯還是需要用Makefile來指定編譯的,但是Makefile裡應當由.config裡的相應的關鍵字內容來決定是否編譯(即編進核心或編成模組或不編譯)

在linux核心裡又是每個目錄裡都有Makefile檔案,由它的上一級目錄裡的Makefile檔案裡呼叫

3.寫Makefile檔案:
    (1)在mydrivers目錄裡的Makefile內容:
            obj-y += myfunc/
            obj-y += mytest/

    (2)在mydrivers目錄裡的myfunc子目錄的Makefile內容:
            obj-$(CONFIG_MYFUNC) += myfunc.o

    (3)在mydrivers目錄裡的mytest子目錄的Makefile內容:    
            obj-$(CONFIG_MYTEST) += mytest.o

    (4)最後在核心原始碼的drivers目錄的Makefile增加呼叫mydrivers裡的Makefile:
            在drivers目錄裡的Makefile增加語句:
                obj-y += mydrivers/

4.寫好xxx.c、Kconfig、Makefile後,編譯:
    (1)如果配置項是編進核心映象:
            make uImage ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
            //編譯好後,更換uImage,重啟系統時,就會看到相應的內容輸出2)如果配置項是編成模組:
            make uImage ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
            make modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
            如果編譯出的模組很多的話,可以通過以下命令寫進檔案系統:
                make modules_install INSTALL_MOD_PATH=sd卡掛載目錄(板檔案系統根目錄)/ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
            //更換uImage,將模組拷貝到板檔案系統,通過載入或解除安裝驅動,即可看到相應的內容輸出

注意:用modprobe載入驅動模組必須是用”make modules_install INSTALL_MOD_PATH=sd卡掛載目錄(板檔案系統根目錄)/ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-“生成的