1、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主機通信的網口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 三個參數 shell

  • 內核支持掛載 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.cexpress

  

 

   執行交叉編譯:arm-linux-gnueabi-gcc main.cubuntu

  將生成 a.out 拷貝進開發板中(NFS 文件系統),並執行:bash

  

 

 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 ./workapp

  加載模塊:insmod hello.kotcp

  

 

   查看模塊: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
相關文章
相關標籤/搜索