原文地址:Linux設備驅動開發0-環境搭建
1 環境介紹
主機環境:
Win10 64 + VirtualBox 6.0 + ubuntu16.04(32位)-4.10.0-28-generic
u-boot 版本:
u-boot-2015-04
Linux kernel版本:
linux-4.4.203
busybox版本:
busybox-1.31.1.tar.bz2
交叉編譯工具鏈:
arm-linux-gnueabi-
qemu版本:
QEMU emulator version 4.1.93 (v4.2.0-rc3-dirty)
2 下載Linux內核
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
方法1: 直接下載某一個版本的內核
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.203.tar.xz
方法2: 獲取最新的內核版本
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
3 安裝交叉編譯工具
ubuntu安裝方法:
sudo apt-get install gcc-arm-linux-gnueabi
4 編譯Linux內核
解壓下載的內核tarball:
tar -xvf linux-4.4.203.tar.xz
清理編譯環境的命令:
make mrproper
生成vexpress
開發板的.config
文件:
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig
個性化配置
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm menuconfig
編譯內核:
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm
5 編譯安裝QEMU
具體的QEMU安裝方法可以參考另一篇文章-Ubuntu-16.04編譯Qemu
ERROR: glib-2.48 gthread-2.0 is required to compile QEMU
-
執行
sudo apt-get install libglib2.0-dev
-
如果報下面的錯
The following packages have unmet dependencies: libglib2.0-dev : Depends: libglib2.0-0 (= 2.48.0-1ubuntu4) but 2.48.2-0ubuntu4.1 is to be installed Depends: libglib2.0-bin (= 2.48.0-1ubuntu4) but 2.48.2-0ubuntu4.1 is to be installed Depends: zlib1g-dev but it is not going to be installed E: Unable to correct problems, you have held broken packages.
-
逐個執行下面的代碼
sudo apt-get install libglib2.0-0=2.48.0-1ubuntu4 sudo apt-get install libglib2.0-bin=2.48.0-1ubuntu4 sudo apt-get install zlib1g= 1:1.2.8.dfsg-2ubuntu4
-
然後再執行1
6 測試QEMU和內核
運行下面的命令:
qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/qemu4/qemu/linux/linux-4.4.203/arch/arm/boot/zImage -dtb /home/qemu4/qemu/linux/linux-4.4.203/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0"
# 請將/home/qemu4/qemu/linux/linux-4.4.203/修改爲自己的目錄
運行結果:
#0: ARM AC'97 Interface PL041 rev0 at 0x10004000, irq 33
input: ImExPS/2 Generic Explorer Mouse as /devices/platform/smb/smb:motherboard/smb:motherboard:iofpga@7,00000000/10007000.kmi/serio1/input/input2
VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
1f00 131072 mtdblock0 (driver?)
1f01 32768 mtdblock1 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.4.203 #1
Hardware name: ARM-Versatile Express
[<80015d70>] (unwind_backtrace) from [<800127a8>] (show_stack+0x10/0x14)
[<800127a8>] (show_stack) from [<80248be4>] (dump_stack+0x90/0xa4)
[<80248be4>] (dump_stack) from [<800a834c>] (panic+0x9c/0x1f4)
[<800a834c>] (panic) from [<806362c8>] (mount_block_root+0x1c8/0x268)
[<806362c8>] (mount_block_root) from [<8063648c>] (mount_root+0x124/0x12c)
[<8063648c>] (mount_root) from [<806365e4>] (prepare_namespace+0x150/0x198)
[<806365e4>] (prepare_namespace) from [<80635ed0>] (kernel_init_freeable+0x250/0x260)
[<80635ed0>] (kernel_init_freeable) from [<804afafc>] (kernel_init+0x8/0xe8)
[<804afafc>] (kernel_init) from [<8000f2d0>] (ret_from_fork+0x14/0x24)
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
在這兒之所以報Kernel panic
,是因爲我們現在還沒有安裝根文件系統,無法啓動init進程所致。那麼接下來我們就來研究根文件系統。
7 製作根文件系統
本文要製作的根文件系統rootfs=busybox(包含基本的linux命令)+運行庫+幾個字符設備。
7.1 根文件系統存放位置
其實依賴於每個開發板支持的存儲設備,可以放到Nor Flash上,也可以放到SD卡,甚至外部磁盤上。最關鍵的一點是你要清楚知道開發板有什麼存儲設備。
本文直接使用SD卡做爲存儲空間,文件格式爲ext3格式
7.2 下載、編譯和安裝busybox
下載:
wget https://busybox.net/downloads/busybox-1.31.1.tar.bz2
編譯安裝:
make defconfig
make CROSS_COMPILE=arm-linux-gnueabi-
make install CROSS_COMPILE=arm-linux-gnueabi-
安裝完成後,會在busybox目錄下生成_install目錄,該目錄下的程序就是單板運行所需要的命令。
7.3 rootfs目錄結構
-
創建rootfs目錄,根文件系統內的文件全部放到其中。
mkdir -p rootfs/{bin,dev,etc/init.d,lib,proc,sbin,sys,usr,mnt,tmp,var}
-
拷貝busybox到根目錄下
sudo cp busybox-1.20.2/_install/* -r rootfs/
-
從工具鏈中拷貝運行庫到lib目錄下
sudo cp -P /usr/arm-linux-gnueabi/lib/* rootfs/lib/
-
創建4個tty端終設備
sudo mknod rootfs/dev/tty1 c 4 1 sudo mknod rootfs/dev/tty2 c 4 2 sudo mknod rootfs/dev/tty3 c 4 3 sudo mknod rootfs/dev/tty4 c 4 4 sudo mknod rootfs/dev/console c 5 1 sudo mknod rootfs/dev/null c 1 3
-
安裝內核模塊
make modules_install ARCH=arm INSTALL_MOD_PATH=../../rootfs //把.ko文件copy到lib/modules中
7.4 製作rootfs文件系統鏡像
-
生成32M大小的鏡像
dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
-
格式化成ext3文件系統
mkfs.ext3 a9rootfs.ext3
-
將文件拷貝到鏡像中
sudo mkdir tmpfs sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop sudo cp -r rootfs/* tmpfs/ sudo umount tmpfs
8 系統啓動運行
現在是時候運行QEMU,模擬vexpress-A9開發板了,啓動命令如下:
qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/qemu4/qemu/linux/linux-4.4.203/arch/arm/boot/zImage -dtb /home/qemu4/qemu/linux/linux-4.4.203/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 console=ttyAMA0" -sd a9rootfs.ext3
激動人心的時刻來了:
aaci-pl041 10004000.aaci: ARM AC'97 Interface PL041 rev0 at 0x10004000, irq 33
aaci-pl041 10004000.aaci: FIFO 512 entries
oprofile: using arm/armv7-ca9
NET: Registered protocol family 17
9pnet: Installing 9P2000 support
Registering SWP/SWPB emulation handler
rtc-pl031 10017000.rtc: setting system clock to 2019-11-29 05:53:09 UTC (1575006789)
ALSA device list:
#0: ARM AC'97 Interface PL041 rev0 at 0x10004000, irq 33
input: ImExPS/2 Generic Explorer Mouse as /devices/platform/smb/smb:motherboard/smb:motherboard:iofpga@7,00000000/10007000.kmi/serio1/input/input2
EXT4-fs (mmcblk0): mounting ext3 file system using the ext4 subsystem
EXT4-fs (mmcblk0): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext3 filesystem) readonly on device 179:0.
Freeing unused kernel memory: 276K
random: nonblocking pool is initialized
can't run '/etc/init.d/rcS': No such file or directory
Please press Enter to activate this console.
/ # ls
bin etc linuxrc sbin
dev lib lost+found usr
/ #