物聯網之內核及驅動開發初級一(linux驅動之環境搭建)

Linux驅動開發環境搭建--exynos4412

Linux驅動開發環境搭建
    1,ubuntu中配置編譯環境
        設置交叉工具鏈:
            tar -xvf gcc-4.6.4.tar.xz -C  ~/Linux_4412/toolchain
        設置環境變量:
            vim  ~/.bashrc  最後面添加
                export PATH=$PATH:/home/george/Linux_4412/toolchain/gcc-4.6.4/bin
        更新腳本:
            source ~/.bashrc

            arm-none-linux-gnueabi-gcc -v
                Using built-in specs.
                COLLECT_GCC=arm-none-linux-gnueabi-gcc
                COLLECT_LTO_WRAPPER=/home/george/Linux_4412/toolchain/gcc-4.6.4/bin/
                ../libexec/gcc/arm-arm1176jzfssf-linux-gnueabi/4.6.4/lto-wrapper

    2,運行開發
        a,通過tftp去啓動內核
            1,將uImage和dtb文件放入到ubuntu中/tftpboot
            2,在開發板中設置uboot參數,使其能夠去加載內核
                set ipaddr 192.168.7.22
                set serverip 192.168.7.21
                set bootcmd tftp 0x41000000 uImage \; tftp 0x42000000 exynos4412-fs4412.dtb \; bootm 0x41000000 - 0x42000000
                save
        
        b,通過nfs去掛載rootfs
            1,需要一個跟文件系統目錄--rootfs.tar.xz,需要解壓到ubuntu
                sudo tar -xvf rootfs.tar.xz  -C /opt/4412/
            
            2, 配置nfs服務器(需要安裝),讓/opt/4412/rootfs可以被掛載
                sudo vim /etc/exports
                     /opt/4412/rootfs                *(subtree_check,rw,no_root_squash,async)
                
                sudo service nfs-kernel-server restart  //重啓nfs服務器
            
                測試:
                    sudo mount -t nfs localhost:/opt/4412/rootfs   /mnt
            3,在開發中去指定內核要掛載/opt/4412/rootfs--切換到開發操作
                set bootargs console=ttySAC2,115200 init=/linuxrc root=/dev/nfs rw nfsroot=192.168.7.21:/opt/4412/rootfs ip=192.168.7.22
                save

                解釋:
                    bootargs 是uboot傳遞給內核到啓動參數,是一個字符串

                        console=xxx: 告訴內核啓動時候到調試信息是從哪個設備輸出
                        init=xxx:  告訴內核linux到第一個用戶進程是什麼
                        root=xxx : 告訴內核根文件系統在哪裏
                            root=/dev/nfs 表示根文件系統在網路遠端
                            nfsroot=ip:path
                        ip=xxx :告訴內核開機的時候內核的ip地址是多少(靜態分配ip)
    
    3,可以開始去編寫代碼--開發驅動
        a, 編譯內核
             tar -xvf linux-3.14.tar.xz

             步驟:
                1,設置交叉工具鏈--uImage也運行arm開發板
                    vim  Makefile
                        ARCH = arm
                        CROSS_COMPILE = arm-none-linux-gnueabi-
                2, 選擇一個soc    ,可以支持很多到soc,所以必須挑出針對我們到平臺到代碼
                    make exynos_defconfig
                        //  cp -raf  arch/arm/configs/exynos_defconfig   .config
                
                3,make menuconfig 內核裁剪,產生一個圖像界面
                        System Type  ---> 
                            (2) S3C UART to use for low-level messages
                4,make uImage  : 編譯內核

                    //如果編譯報錯:缺mkimage
                        sudo cp -raf mkimage  /usr/bin/
                        sudo chmod 777 /usr/bin/
                        重新在make uImage

                5,編譯設備樹文件--描述設備信息--最終要編譯成dtb
                    以一個默認到dts爲參考,變成我們自己想要的dts

                    arch/arm/boot/dts$ cp exynos4412-origen.dts exynos4412-fs4412.dts


                    arch/arm/boot/dts$ vim Makefile
                        70行        exynos4412-fs4412.dtb \

                    回到內核源碼頂層目錄:
                    george@ubuntu:~/Linux_4412/kernel/linux-3.14$ make dtbs
                          DTC     arch/arm/boot/dts/exynos4210-origen.dtb
                          DTC     arch/arm/boot/dts/exynos4210-smdkv310.dtb
                          DTC     arch/arm/boot/dts/exynos4210-trats.dtb
                          DTC     arch/arm/boot/dts/exynos4210-universal_c210.dtb
                          DTC     arch/arm/boot/dts/exynos4412-odroidx.dtb
                          DTC     arch/arm/boot/dts/exynos4412-origen.dtb
                          DTC     arch/arm/boot/dts/exynos4412-fs4412.dtb
                          DTC     arch/arm/boot/dts/exynos4412-smdk4412.dtb
                          DTC     arch/arm/boot/dts/exynos4412-tiny4412.dtb
                          DTC     arch/arm/boot/dts/exynos4412-trats2.dtb
                          DTC     arch/arm/boot/dts/exynos5250-arndale.dtb
                          DTC     arch/arm/boot/dts/exynos5250-smdk5250.dtb
                          DTC     arch/arm/boot/dts/exynos5250-snow.dtb
                          DTC     arch/arm/boot/dts/exynos5420-arndale-octa.dtb
                          DTC     arch/arm/boot/dts/exynos5420-smdk5420.dtb
                          DTC     arch/arm/boot/dts/exynos5440-sd5v1.dtb
                          DTC     arch/arm/boot/dts/exynos5440-ssdk5440.dtb

            使用uImag和dtb文件
                cp -raf arch/arm/boot/uImage  /tftpboot
                cp -raf arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot


        ==============================================
        移植dm9000
            實際是設備樹文件修改
                vim   arch/arm/boot/dts/exynos4412-fs4412.dts
            添加如下內容:
                srom-cs1@5000000 { 
                     compatible = "simple-bus"; 
                     #address-cells = <1>; 
                     #size-cells = <1>; 
                     reg = <0x5000000 0x1000000>; 
                     ranges; 

                     ethernet@5000000 { 
                          compatible = "davicom,dm9000"; 
                          reg = <0x5000000 0x2 0x5000004 0x2>; 
                          interrupt-parent = <&gpx0>; 
                          interrupts = <6 4>; 
                          davicom,no-eeprom; 
                          mac-address = [00 0a 2d a6 55 a2]; 
                     }; 
                }; 

                保存退出後,需要再次編譯dts文件
                    make dtbs

            配置內核:
                make menuconfig
                [*] Networking support   --->
                            Networking options   --->
                                <*> Packet socket
                                <*> Unix domain sockets 
                                [*] TCP/IP networking
                                [*]    IP: kernel level autoconfiguration
                                    [*]     IP: BOOTP support

                Device Drivers   --->
                    [*] Network device support   --->
                        [*]    Ethernet driver support (NEW)   --->
                            <*>    DM9000 support
                File systems   --->
                        [*] Network File Systems (NEW)   --->
                                <*>    NFS client support
                                [*]  NFS client support for NFS version 2 
                                [*]      NFS client support for NFS version 3
                                [*]        NFS client support for the NFSv3 ACL protocol extension
                                [*]    Root file system on NFS
                退出到時候要保存:
                    再次編譯內核:
                        make  uImage -j2

                cp -raf arch/arm/boot/uImage  /tftpboot
                cp -raf arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot

                在開發板中到uboot設置中,添加一個參數    clk_ignore_unused        
                set bootargs  clk_ignore_unused console=ttySAC2,115200 init=/linuxrc root=/dev/nfs rw nfsroot=192.168.7.21:/opt/4412/rootfs ip=192.168.7.22 

                重新啓動開發板

        b, 編寫驅動代碼
            1,用什麼工具去寫---source insight(看代碼的工具)
                    環境搭建\燒錄鏡像和工具\si_linux3.14-ori.tgz
                    解壓到內核源碼的頂層目錄:

                    tar  -xvf   si_linux3.14-ori.tgz


            2,怎麼寫
                在souceinsght去寫
                
                驅動代碼需要有四個部分
                    1,頭文件
                        #include <linux/init.h>
                        #include <linux/module.h>
                    2,驅動模塊裝載和卸載函數入口到聲明
                        module_init(hello_drv_init);
                        module_exit(hello_drv_exit);
                    3,實現模塊裝載和卸載函數入口
                        static int __init hello_drv_init(void)
                        {

                            return 0;
                        }

                        static void __exit hello_drv_exit(void)
                        {


                        }
                    4,GPL聲明
                        MODULE_LICENSE("GPL");


        c,編譯驅動代碼--Makefile(被讀取兩次: make  2,內核源碼中Makefile)
            ROOTFS_DIR = /opt/4412/rootfs

            ifeq ($(KERNELRELEASE), )
            #內核源碼到路徑,不同環境會不一樣,內核源碼一定要先編譯
            KERNEL_DIR = /home/george/Linux_4412/kernel/linux-3.14
            CUR_DIR = $(shell pwd)

            all :
                    make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules

            clean :
                    make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean

            install:
                    cp -raf *.ko   $(ROOTFS_DIR)/drv_module


            else
            #用於指定到底編譯哪個代碼--hello.c
            obj-m += hello.o


            endif


        d,加載ko
            [root@farsight drv_module]# insmod hello.ko
                [ 2789.700000] -------hello_drv_init-------------

            [root@farsight drv_module]# lsmod
                hello 805 0 - Live 0xbf000000 (O)
            [root@farsight drv_module]# rmmod hello
                rmmod: can't change directory to '/lib/modules': No such file or directory
            [root@farsight drv_module]# mkdir /lib/modules

            [root@farsight drv_module]# rmmod hello
                rmmod: can't change directory to '3.14.0': No such file or directory
            [root@farsight drv_module]# mkidr /lib/modules/3.14.0

            [root@farsight drv_module]# rmmod hello
                [ 2903.230000] -------hello_drv_exit-------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章