zoukankan      html  css  js  c++  java
  • 一、Linux 设备驱动介绍及开发环境搭建(续)

    1.2.6 uboot 编译安装

    • 嵌入式 bootloader 的功能:
      • 功能类似于 PC 的 BIOS、硬件检测是否正常
      • 加载操作系统镜像到 RAM
      • 设置不同的启动方式
    • 常见的启动方式:
      • NOR/NAND Flash 启动
      • 从 SD 卡启动
      • Bootloader 从网络加载 Linux 内核启动
    • uboot 编译
      • 下载地址:ftp://ftp.denx.de/pub/u-boot/
        • 获取得版本为 u-boot-2017.01.tar.bz2,发布时间为 2017-1-15
      • 主 Makefile 中修改 CROSS_COMPILE,config.mk 中修改 ARCH
      • 配置 make vexpress_ca9x4_defconfig
      • 编译 make -j8
      • 测试 uboot 可用:qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M
    • 启动成功后,需要对 uboot 配置网络功能,即 QEMU 网络功能设置
      • 采用桥接(bridge)的网络连接与 Host 通信
      • 需要主机内核 tun/tap 模块支持
      • 配置:
        • 主机安装工具包
          • sudo apt-get install uml-utilities
          • sudo apt-get install bridge-utils
        • 创建 tun 设备文件:/dev/net/tun,工具安装成功后,会生成此设备节点
        • 开启 tun 网络功能,使其声线:
          • 修改 /etc/network/interfaces 文件,重启生效
        • 配置 /etc/qemu-ifup、/etc/qemu-ifdown 脚本,这些可能自动生成了,那就不需要配置
        • 重启,使 br0 生效:
        •  虚拟网口 br0 是 QEMU 虚拟机与Linux主机通讯的网口

    • 内核配置编译:
      • 使用 u-boot 引导内核镜像
        • 需要将内核编译为 uImage 格式
        • 需要指定 uImage 的加载地址
        • 编译时指定:make LOADADDR=0x60003000 uImage -j8
    • 主机 TFTP 工具安装
      • 工具安装:sudo apt-get install tftp-hpa tftpd-hpa xinetd
      • 修改配置文件:/etc/default/tftpd-hpa
        • TFTP_DIRECTORY 是我们的工作目录,开发板从此目录下载镜像和配置文件,我们的镜像和配置文件也存放此目录中
      • 创建 tftpboot 目录,mkdir tftpboot, chmod 777 tftpboot
      • 配置 /etc/xinetd.conf,如果没有此文件,则创建此文件:


      • 配置 /etc/xinetd.d/tftp 文件,如果没有此文件,则创建此文件


      • 重启 tftp:
        • sudo /etc/init.d/tftpd-hpa restart
        • sudo /etc/init.d/xinetd reload
        • sudo /etc/init.d/xinetd restart
      • 测试 tftp
        • cd ..
        • tftp localhost
        • tftp> get test.c
        • 获取文件成功,则OK
    • 启动测试:
      • qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -sd rootfs.ext3
      • 注意:若是高版本得QEMU,则去掉 vlan 参数
      • 脚本在最后

    1.3 挂载 NFS 文件系统

    1.3.1 介绍

    • 主机 HOST 支持 NFS 服务
      • 安装:sudo apt-get install nfs-kernel-server
      • 配置NFS
        • 在 /etc/exports 文件中添加:
        • /home/rootfs *(rw,sync,no_root_squash,no_subtree_check)
          • /home/rootfs:是根文件系统的主目录
          • rw:可读可写
          • sync:磁盘和内存进行同步
          • no_root_squash:不执行开发板 root 用户映射为主机的匿名用户,保证权限重组
          • no_subtree_check:不检查根文件系统的子目录
      • 开启 NFS 服务
        • /etc/init.d/rpcbind restart
        • /etc/init.d/nfs-kernel-server restart
    • 修改 bootargs 启动参数
      • 设置为 NFS 为根文件系统
      • 设置主机 NFS 文件系统的地址
      • nfsroot 是主机的 IP 地址
      • ip 是开发板的 IP 地址
      • 注意:若是 QEMU 得版本较高,则参数配置如下:
      • 即相比于低版本 QEMU,在nfsroot 后添加了 proto=tcp,nfsvers=3,nolock 三个参数 

    • 内核支持挂载 NFS 文件系统
      • make menuconfig 配置
      • 修改完后:make uImage -j8
      • 由于暂时 uboot 没办法启动内核,则单独启动内核
      • VFS 已经 mount 成功
      • 在根文件系统(/home/coco/work/rootfs)下创建一个文件:test.c,然后在 linux 控制台查看是否存在此文件

    1.3.2 完善跟文件系统

    • 启动流程:
      • Linux 内核启动之后,挂载 NFS或其他根文件系统
      • 然后开启 init 进程(前面设置的 bootargs 中,init=/linuxrc),这个init 进程会执行 inittab 脚本
    • 增加内核的各种用户接口,用户接口存在 /proc 和 /sys 下
      • /etc 内核配置和启动文件,需要在下面添加以下文件
        • inittab:脚本文件,运行命令
    1 ::sysinit:/etc/init.d/rcS            ///< 启动 rcS 脚本
    2 #::respawn:-/bin/sh
    3 #tty2::askfirst:-/bin/sh
    4 #::ctrlaltdel:/bin/umount -a -r
    5 
    6 console::askfirst:-/bin/sh            ///< 启动控制台,控制台与 shell 绑定一起,"-" 表示启动 shell 之前,要启动 profile
    7 ::ctrlaltdel:/sbin/reboot
    8 ::shutdown:/bin/umount -a -r
        • fstab:文件init.d:目录
    1 挂载的文件系统    挂载的目录        
    2 proc            /proc           proc            defaults            0       0
    3 tmpfs           /tmp            tmpfs           defaults            0       0
    4 sysfs           /sys            sysfs           defaults            0       0
    5 tmpfs           /dev            tmpfs           defaults            0       0
    6 var             /dev            tmpfs           defaults            0       0
    7 ramfs           /dev            ramfs           defaults            0       0
    8 
    9 注意:挂载的目录必须在根文件系统下存在,不存在则创建,这个文件的作用就是将文件系统挂载到目录的节点上
        • rcS:文件
     1 #!bin/sh
     2 # 设置环境变量
     3 PATH=/sbin:/bin:/usr/sbin:/usr/bin
     4 LD_LIBRARY_PATH=/lib
     5 export PATH LD_LIBRARY_PATH
     6 
     7 # 挂载各种文件系统,挂载的文件系统与 fstab 有关
     8 mount -a
     9 mkdir -p /dev/pts
    10 mount -t devpts devpts /dev/pts
    11 mdev -s
    12 mkdir -p /var/lock
    13 
    14 echo "--------------------------------------------------------------------------------"
    15 
    16 echo "Welcome to my cortex-a9 board"
    17 
    18 echo "--------------------------------------------------------------------------------"
        • profile:文件
    1 PS1='cortex_a9@arm:w # '        ///< 显示控制台的格式,就相当于终端中的 coco@ubuntu:~/work/rootfs/etc$
    2 export PS1
    3 
    4 注意:此文件也可以做其他操作
    • 重启 reboot 功能,已经在 inittab 中操作
    • 最终结果

     1.4 在开发板上运行应用和内核驱动程序

    1.4.1 运行应用程序

      main.c

      

       执行交叉编译:arm-linux-gnueabi-gcc main.c

      将生成 a.out 拷贝进开发板中(NFS 文件系统),并执行:

      

     1.4.2 运行内核驱动程序

      

       Makefile:

     1 .PHONY:all clean
     2 ifneq ($(KERNELRELEASE),)
     3 
     4 obj-m := hello.o
     5 
     6 else
     7 
     8 EXTRA_CFLAGS += -DDEBUG 
     9 KDIR := /home/coco/work/kernel/linux-4.4.194
    10 all:
    11             make  CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm -C $(KDIR) M=$(PWD) modules
    12 clean:
    13             rm -fr *.ko *.o *.mod.o *.mod.c *.symvers *.order .*.ko .tmp_versions
    14 
    15 endif

      拷贝 hello.ko 进NFS文件系统:cp /home/coco/work/code/test_driver/hello.ko ./work

      加载模块:insmod hello.ko

      

       查看模块:lsmod

      

       卸载模块:rmmod hello.ko

      查看模块:lsmod

      

     1.5 启动脚本

      boot.sh

      1 #!/bin/bash
      2 
      3 BOARD=vexpress-a9
      4 
      5 KERNEL_DIR=/home/ubuntu/work/arm/kernel/linux-4.4.194
      6 KERNEL_BIN_DIR=${KERNEL_DIR}/arch/arm/boot
      7 DTB_DIR=${KERNEL_BIN_DIR}/dts
      8 DTB_BIN=vexpress-v2p-ca9.dtb
      9 UIMAGE=uImage
     10 ZIMAGE=zImage
     11 
     12 UBOOT_DIR=/home/ubuntu/work/arm/uboot/u-boot-2017.01
     13 UBOOT_BIN_DIR=${UBOOT_DIR}
     14 UBOOT_BIN=u-boot
     15 
     16 ROOTFS_DIR=/home/ubuntu/work/arm
     17 ROOTFS_BIN=rootfs.ext3
     18 
     19 TFTPBOOT_DIR=/home/ubuntu/work/arm/tftpboot
     20 
     21 help()
     22 {
     23   echo "-t start qemu"
     24   echo "    s;    start with graphic......"
     25   echo "    s-no; start with no graphic......"
     26   echo "-h print help"
     27 }
     28 
     29 tftp_init()
     30 {
     31   echo "init...."
     32   if [ "${TFTPBOOT_DIR}/${UIMAGE}" -ot "${KERNEL_BIN_DIR}/${UIMAGE}" -o  ! -f "${TFTPBOOT_DIR}/${UIMAGE}" ]; then
     33     echo "cp ${KERNEL_BIN_DIR}/${UIMAGE} ${TFTPBOOT_DIR}"
     34     cp ${KERNEL_BIN_DIR}/${UIMAGE} ${TFTPBOOT_DIR}
     35   fi
     36 
     37   if [ "${TFTPBOOT_DIR}/${DTB_BIN}" -ot "${DTB_DIR}/${DTB_BIN}" -o ! -f "${DTB_DIR}/${DTB_BIN}" ]; then
     38     echo "cp ${DTB_DIR}/${DTB_BIN} ${TFTPBOOT_DIR}"
     39     cp ${DTB_DIR}/${DTB_BIN} ${TFTPBOOT_DIR}
     40   fi
     41 
     42   if [ "${TFTPBOOT_DIR}/${UBOOT_BIN}" -ot "${UBOOT_BIN_DIR}/${UBOOT_BIN}" -o ! -f "${UBOOT_BIN_DIR}/${UBOOT_BIN}" ]; then
     43     echo "cp ${UBOOT_BIN_DIR}/${UBOOT_BIN} ${TFTPBOOT_DIR}"
     44     cp ${UBOOT_BIN_DIR}/${UBOOT_BIN} ${TFTPBOOT_DIR}
     45   fi
     46 
     47   if [ "${TFTPBOOT_DIR}/${ROOTFS_BIN}" -ot "${ROOTFS_DIR}/${ROOTFS_BIN}" -o ! -f "${ROOTFS_DIR}/${ROOTFS_BIN}" ]; then
     48     echo "cp ${ROOTFS_DIR}/${ROOTFS_BIN} ${TFTPBOOT_DIR}"
     49     cp ${ROOTFS_DIR}/${ROOTFS_BIN} ${TFTPBOOT_DIR}
     50   fi
     51 }
     52 
     53 tftp_start_no_graphic()
     54 {
     55   qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M -net nic, -net tap,ifname=tap0 -sd rootfs.ext3
     56 }
     57 
     58 nfs_start_no_graphic()
     59 {
     60   qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M -net nic -net tap,ifname=tap0
     61 }
     62 
     63 kernel_start_no_graphic()
     64 {
     65   qemu-system-arm 
     66     -M ${BOARD} 
     67     -kernel ${KERNEL_BIN_DIR}/${ZIMAGE} 
     68     -nographic 
     69     -m 512M 
     70     -dtb ${DTB_DIR}/${DTB_BIN} 
     71     -append "root=/dev/mmcblk0 rw console=ttyAMA0" 
     72     -sd ${ROOTFS_DIR}/${ROOTFS_BIN}
     73 }
     74 
     75 kernel_start_with_graphic()
     76 {
     77   qemu-system-arm 
     78     -M ${BOARD} 
     79     -kernel ${KERNEL_BIN_DIR}/${ZIMAGE} 
     80     -m 512M
     81 }
     82 
     83 uboot_start_no_graphic()
     84 {
     85   qemu-system-arm 
     86     -M ${BOARD} 
     87     -kernel ${UBOOT_BIN_DIR}/${UBOOT_BIN} 
     88     -nographic 
     89     -m 512M
     90 }
     91 
     92 uboot_start_with_graphic()
     93 {
     94   qemu-system-arm 
     95     -M ${BOARD} 
     96     -kernel ${UBOOT_BIN_DIR}/${UBOOT_BIN} 
     97     -m 512M
     98 }
     99 
    100 while getopts "t:h" opt
    101 do
    102   case $opt in
    103     t)
    104       OPTARG_TYPE=$OPTARG
    105       ;;
    106     h)
    107       help
    108       exit 1
    109       ;;
    110   esac
    111 done
    112 
    113 case "$OPTARG_TYPE" in
    114   n-no)
    115     tftp_init
    116     echo "nfs start with no graphic......"
    117     nfs_start_no_graphic $@
    118     ;;
    119   s)
    120     echo "tftp start with graphic......"
    121     tftp_init
    122     start_graphic $@
    123     ;;
    124   s-no)
    125     tftp_init
    126     echo "tftp start with no graphic......"
    127     tftp_start_no_graphic $@
    128     ;;
    129   k)
    130     kernel_start_with_graphic $@
    131     ;;
    132   k-no)
    133     kernel_start_no_graphic $@
    134     ;;
    135   u)
    136     uboot_start_with_graphic $@
    137     ;;
    138   u-no)
    139     uboot_start_no_graphic $@
    140     ;;
    141   *)
    142     echo "Unknow option $OPTARG_TYPE..."
    143     exit 1
    144     ;;
    145 esac
  • 相关阅读:
    HDU 4221 Greedy?(贪心)
    HDU 3400 Line belt (三分法)
    POJ 1026 Cipher(置换)
    POJ 1166 The Clocks(暴搜)
    HDU 4122 Alice's mooncake shop(RMQ,或者单调队列)
    POJ 1721 CARDS(置换)
    POJ 3270 Cow Sorting(置换)
    高斯消元法(模板)
    http://blog.seirsoft.com
    转载 STL容器的erase用法
  • 原文地址:https://www.cnblogs.com/kele-dad/p/11560407.html
Copyright © 2011-2022 走看看