您的位置:首页 > 编程语言 > PHP开发

嵌入式内核及驱动开发-01设备驱动环境搭建(交叉开发, tftp,nfs,内核启动,根文件系统制作)

2019-06-14 09:15 375 查看
版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

文章目录

  • 运行开发
  • 可以开始去编写代码--开发驱动
  • b, 编写驱动代码
  • c,编译驱动代码--Makefile(被读取两次: make 2,内核源码中Makefile)
  • d,加载ko
  • Linux驱动开发环境搭建

    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

    运行开发

    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)

    可以开始去编写代码–开发驱动

    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_
    4000
    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-------------
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: 
    相关文章推荐