1.1 Linux 設備驅動介紹
1.1.1 分類及特色
- 計算機系統的硬件主要由 CPU、存儲器和外設組成。
- 當前 CPU 內部都集成有存儲器和外設適配器。
- 外設適配器有入 UART、IIC 控制器、SPI 控制器、USB 控制器、SDRAM 控制器等,有的 CPU 還集成有 GPU(圖形處理器)、視頻編輯器等。
- 驅動針對的對象是存儲器和外設(包含 CPU 內部集成的存儲器和外設),而不是針對 CPU 內核。Linux 將存儲器和外設分爲 3 個基礎大類:
- 字符設備:必須以串行順序依次進行訪問的設備,如觸摸屏、磁帶驅動器、鼠標等。
- 塊設備:能夠按任意順序進行訪問,以塊爲單位進行操做,如硬盤、eMMC等
- 網絡設備:面向數據包的接收和發送而設計,並不傾向於對應於文件系統的節點。
1.1.2 設備驅動與整個軟硬件的系統的關係
- 除網絡設備外,字符設備與塊設備都被映射到 Linux 文件系統的文件和目錄,經過文件系統的系統調用接口 open()、write() 等便可訪問字符設備和塊設備。全部字符設備和塊設備都統一呈現給用戶。
- Linux 的塊設備有兩種訪問方法:
- 一種是相似於 dd 命令對應的原始塊設備,如 」/dev/sdb1「 等
- 另外一種方式是在塊設備上創建 FAT、EXT四、BTRFS 等文件系統,而後以文件路徑如 "/home/barry/hello.txt" 的形式進行訪問
- 在 Linux 中,針對 NOR、NAND 等提供了獨立的內存技術設備( Memory Technology Device,MTD) 子系統,其上裕興 YAFFS二、JFFS二、UBIFS 等具有擦除和負載均衡能力的文件系統
- 針對磁盤或者 Flash 設備的 FAT、EXT四、YAFFS二、JFFS二、UBIFS 等文件系統定義了文件和目錄在存儲介質上的組織。
- Linux 的虛擬文件系統對上述進行了統一的抽象
- 應用程序可使用 Linux 的系統調用接口編程,也可使用 C 庫函數。
1.2 QEMU 環境創建
1.2.1 虛擬機環境搭建
略過linux
1.2.2 安裝 uboot-tools
- 用來生成 u-boot 引導的鏡像文件
- sudo apt-get install u-boot-tools
1.2.3 安裝交叉編譯工具鏈
- 交叉編譯是一種計算機環境中編譯程序,在另外一種環境下運行。或者說在一個平臺上編譯生成在另外一個平臺上運行的可執行代碼
- ABI 和 EABI
- ABI:二進制應用程序接口(Application Binary Interface(ABI) for the ARM Architecture),在計算機中,應用二進制接口描述了應用程序(或者其餘類型)和操做系統之間或其餘應用程序的低級接口,涵蓋了數據類型的大小,佈局和對齊,調用約定
- EABI:嵌入式 ABI,嵌入式應用二進制接口指定了文件格式,數據類型,寄存器使用,堆積組織優化和在一個嵌入式軟件中的參數的標準約定
- arm-none-gnueabi-linux 比 arm-linux-gcc 要好,在可移植性、兼容性上面
- 早期的 u-boot 和 linux 編譯可能使用的都不是一個 arm-linux-gcc 版本
- 安裝
- sudo apt-get install gcc-arm-linux-gnueabi
- sudo apt-get install gcc-arm-linux-gnueabihf
- sudo apt-get install g++-arm-linux-gnueabi
- sudo apt-get install g++-arm-linux-gnueabihf
1.2.4 QEMU 安裝
- QEMU 是一個模擬器,能夠模擬CPU,ARM、X8六、MIPS 等架構
- 能夠仿真 ARM 處理器:ARM926E、ARM1136,cortex-A8/A9 等
- 模擬真實的開發板、外設:串口、LCD、網卡、USB、SD 卡...
- 使用 QEMU 能夠作的事情:
- 研究內核虛擬化
- 模擬 CPU, 對於芯片公司,流片以前在 QEMU 上作驗證、仿真、軟硬件協同設計,開發 BSP 和驅動
- 模擬開發板,在模擬平臺上進行系統軟件開發、驅動開發
- 學生、工程師能夠利用 qemu-system-arm 學習嵌入式開發、研究 bootloader、Linux 內核\驅動開發、應用開發等。
- 聯網安裝:sudo apt-get install qemu qemu-system-common qemu-system qemu-system-arm
- 輸入命令顯示支持的設備:qemu-system-arm -machine help
- 啓動設備:qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-cap.dtb -nographic -append "console=ttyAMA0"
- -M 指定開發板
- -m 指定內存大小
- -kernel 指定 kernel 鏡像
- -dtb 指定設備樹
- -nographic 不使用圖形界面,使用串口控制檯
- -append 指定串口控制檯參數
- 實驗用得是 vexpress-a9 得四核處理器開發板,板上集成了 Flash、SD、IIC、LCD 等設備。
- 查看 QEMU 版本:qemu-system-arm --version
1.2.5 開發板選擇
- 選用的是 vexpress-a9 開發板,這是ARM 公司推出的一款開發板,全稱爲 versatile express family
- 主要用於 SOC 廠商設計、驗證和測試本身的 SOC 芯片
- 採用主板 + 子板的設計,主板提供各類外圍接口,子板提供 CPU 運算
- Vexpress 系列支持的 CPU
- cortex-a9:處理器子板 Express A9 x 4(v2p-ca9 x 4)
- cortex-a5:處理器子板 Express A5 x 4(v2p-ca5 x 2s)
- cortex-r5:
- cortex-a15:處理器子板 Express A15 x 4(v2p-ca15 x 2)
- 開發板:
1.2.5 編譯內核和 dtb 文件
下載地址:https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/shell
也能夠下載其餘版本得內核,這裏選擇得是 Linux-4.20.0 版本,發佈日期是2018-12-24express
下載下來後,解壓,修改主目錄下的 Makefile:編程
原始的:ubuntu
修改後:網絡
配置開發板,主要是生成 .config 文件,能夠在 arch/arm/configs 中查看默認配置,執行 make vexpress_defconfig。多線程
執行 make zImage -j8 進行編譯,-j8 是使用多線程編譯。架構
編譯內核模塊:make modules -j8app
編譯 dts 文件:make dtbs負載均衡
運行開發板:
qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0」
能夠看到內核已經起來,可是無文件系統。
1.2.6 使用 busybox 製做根文件系統
- 文件系統
- 爲何要使用文件系統
- Linux的哲學:一切皆文件
- 用戶與操做系統進行交互的主要工具:文件系統調用
- 用戶和底層存儲的接口
- 根文件系統
- Linux內核啓動後第一個掛載的文件系統
- 主要由基本的shell命令、各類庫、字符設備、配置腳本組成
- 提供了根目錄 /
- RFS能夠放在: nor/nand flash、 SD卡、磁盤、網絡空間上
- 什麼是busybox?
- 一個集成100多個Linux經常使用命令和工具的軟件
- 一個適合製做嵌入式文件系統的軟件工具
- 編譯安裝
- 下載源代碼: http://www.busybox.net/downloads/
- 修改Makefile: ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
- 配置: make defconfig ; make menuconfig
- 注意要將跟文件系統做爲靜態庫生成:
- 編譯: make
- 安裝: make install
- 全部生成的二進制文件都在 _install 目錄下
- 製做根文件系統
- $ mkdir rootfs
- $ mkdir rootfs/lib
- $ cp –r _install/* rootfs
- 跟文件系統的庫存放在編譯工具鏈中的:$ cp -p /usr/arm-linux-gnueabi/lib/* rootfs/lib
- 建立設備:$ mkdir -p rootfs/dev/
- 建立串口節點,串口節點用的比較頻繁,因此建立的比較多
- $ mknod –m 666 tty1 c 4 1
- $ mknod –m 666 tty2 c 4 2
- $ mknod –m 666 tty3 c 4 3
- $ mknod –m 666 tty4 c 4 4
- $ mknod –m 666 console c 5 1
- $ mknod –m 666 null c 1 3
- 製做SD卡文件系統鏡像
- 生成虛擬文件鏡像: dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
- if 輸入
- of 輸出
- bs 塊大小
- count 多少個塊
- 格式化爲exts文件系統: mkfs.ext3 rootfs.ext3
- 往SD卡拷貝東西,將各類文件拷貝到文件系統鏡像中:
- 執行掛載:$ mount -t ext3 rootfs.ext3 /mnt/ -o loop
- $ cp -r rootfs/* /mnt
- 卸載:$ umount /mnt/
- 啓動內核,掛載rootfs
- $ qemu-system-arm -M vexpress-a9 -m 512M -dtb ./vexpressv2p-ca9.dtb -kernel ./zImage -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd rootfs.ext3
- -append 參數作了修改,root是在 /dev/mmcblk0 上啓動的,可讀寫權限,mmcblk0 是 SD 卡的設備節點
- -sd 掛載SD卡
- 完善文件系統:
- rcS 文件完善
- 修改完成後,再從新走《製做 SD 卡文件系統映像步驟》,mount 步驟,結果以下
- 圖形化啓動內核
- $ qemu-system-arm -M vexpress-a9 -m 512M -dtb ./vexpressv2p-ca9.dtb -kernel ./zImage -append "root=/dev/mmcblk0 rw
console=tty0" -sd rootfs.ext3
啓動命令腳本(無LCD)
1 qemu-system-arm \
2 -M vexpress-a9 \
3 -m 512M \
4 -kernel /home/ubuntu/work/kernel/linux-4.20/arch/arm/boot/zImage \
5 -dtb /home/ubuntu/work/kernel/linux-4.20/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
6 -nographic \
7 -append "root=/dev/mmcblk0 rw console=ttyAMA0" \
8 -sd /home/ubuntu/work/rootfs.ext3
啓動命令腳本(LCD)
1 qemu-system-arm \
2 -M vexpress-a9 \
3 -m 512M \
4 -kernel /home/ubuntu/work/kernel/linux-4.20/arch/arm/boot/zImage \
5 -dtb /home/ubuntu/work/kernel/linux-4.20/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
6 -append "root=/dev/mmcblk0 rw console=tty0" \
7 -sd /home/ubuntu/work/rootfs.ext3