物联网之内核及驱动开发初级一(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-------------

猜你喜欢

转载自blog.csdn.net/weixin_39148042/article/details/82495159