|
qemu 虚拟 gadget 驱动开发环境搭建
因为我的项目主要是围绕 usb gadget 驱动进行开发的,加上最近一段时间出差手边没有板子,所以本
篇就记录下在没有板子的情况下如何进行程序开发调试。
本次,我实现的效果是使用最新版的 qemu-system-arm 模拟 orangepi PC 这个虚拟板卡,并手动编译
内核和根文件系统。同时引导启动。
环境
本次,我使用的环境:
PC 环境是 Linux fedora 6.1.14-100.fc36.x86_64
qemu 版本(手动编译的最新版本) QEMU emulator version 8.1.50 (v8.1.0-549-
gc5ea91da44)
orangepi-PC 对应的内核版本是 5.4.65
orangepi-PC 使用的根文件系统,使用最新版本的 buildroot 进行构建
过程
1. qemu 的编译过程,这里需要注意,我开始编译的时候没有生成 qemu-system-arm 工具,后来发现
是没有使能 -enable-system,同时因为后续会使用到 -nic 的 user 模式,所以这里还要在 PC 端
安装相关的软件包 libslirp-devel 。最后,完整的配置命令是 ./configure --target-
list='aarch64-linux-user arm-linux-user arm-softmmu aarch64-softmmu' --enable-
tools --enable-linux-user --enable-system --enable-slirp --enable-kvm
2. orangepi-PC 内核的编译过程相对就简单了,参数 orangepi-PC 根据OrangePi_PC_H3
用户手册
v3.2.pdf 这份文档,可以找对对应内核的仓库和对应的交叉编译器, 配置就选择仓库的
orangepi_defconfig 进行编译就行,中间出现部分错误提示有些文件(regulatory.db
regulatory.db.p7s)找不到,从 github 找到对应的文件,另外的文件(edid/asus.bin)我在配置
过程中给删除了(因为我没有从网上找到)。然后就可以顺利编译通过了。
- ...
- MODPOST 3 modules
- CC [M] drivers/usb/gadget/legacy/g_serial.mod.o
- CC [M] drivers/usb/gadget/legacy/g_zero.mod.o
- Kernel: arch/arm/boot/Image is ready
- CC [M] drivers/usb/gadget/udc/dummy_hcd.mod.o
- LD [M] drivers/usb/gadget/legacy/g_serial.ko
- LD [M] drivers/usb/gadget/legacy/g_zero.ko
- LZ4 arch/arm/boot/compressed/piggy_data
- LD [M] drivers/usb/gadget/udc/dummy_hcd.ko
- CC arch/arm/boot/compressed/decompress.o
- AS arch/arm/boot/compressed/piggy.o
- LD arch/arm/boot/compressed/vmlinux
- OBJCOPY arch/arm/boot/zImage
- Kernel: arch/arm/boot/zImage is ready
复制代码
3. 构建根文件系统的时候,为了加快构建,选择使用先安装好的工具链,不编译内核和bootloader,
如果本地有 buildroot 的相关下载源,那么可以加快下载构建的过程。构建成功后会生成
rootfs.ext2 文件。接着使用下面的脚本将文件转换为 ramdisk 模式(记得在内核配置过程中
也要放开选项 CONFIG_BLK_DEV_RAM , 以及 CONFIG_BLK_DEV_RAM_SIZE )
- ...
- Creating regular file
- /home/red/Downloads/qemu_gadget/orangpi_pc_software/buildroot/output/images/rootf
- s.ext2
- 64-bit filesystem support is not enabled. The larger fields afforded by this
- feature enable full-strength checksumming. Pass -O 64bit to rectify.
- Creating filesystem with 61440 1k blocks and 15360 inodes
- Filesystem UUID: 709417d3-e230-4a1e-888c-8ef34bf4f014
- Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345
- Allocating group tables: done
- Writing inode tables: done
- Creating journal (4096 blocks): done
- Copying files into the device: done
- Writing superblocks and filesystem accounting information: done
- ln -sf rootfs.ext2
- /home/red/Downloads/qemu_gadget/orangpi_pc_software/buildroot/output/images/rootf
- s.ext4
复制代码
测试
接着就是完事具备,测试引导启动了,启动命令为: qemu-system-arm -M orangepi-pc -nic user -
nographic -kernel arch/arm/boot/zImage -append 'console=ttyS0,115200 nosmp
root=/dev/ram' -dtb arch/arm/boot/dts/sun8i-h3-orangepi-pc.dtb -initrd rootfs.ext2(根
文件系统的完整路径) 正常的启动打印信息如下:
- Booting Linux on physical CPU 0x0
- Linux version 5.4.65-g018b9c0bc2d5-dirty (red@fedora) (gcc version 9.2.1 20191025
- (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10))) #6 SMP Sun
- Sep 10 20:28:01 CST 2023
- CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=30c5387d
- CPU: div instructions available: patching division code
- CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
- OF: fdt: Machine model: Xunlong Orange Pi PC
- Memory policy: Data cache writealloc
- cma: Reserved 128 MiB at 0x0000000078000000
- On node 0 totalpages: 262144
- Normal zone: 2304 pages used for memmap
- Normal zone: 0 pages reserved
- Normal zone: 196608 pages, LIFO batch:63
- HighMem zone: 65536 pages, LIFO batch:15
- ...
- sun8i-h3-pinctrl 1c20800.pinctrl: 1c20800.pinctrl supply vcc-pg not found, using
- dummy regulator
- ehci-platform 1c1b000.usb: EHCI Host Controller
- ehci-platform 1c1b000.usb: new USB bus registered, assigned bus number 5
- ehci-platform 1c1b000.usb: irq 28, io mem 0x01c1b000
- ehci-platform 1c1b000.usb: USB 2.0 started, EHCI 1.00
- usb usb5: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04
- usb usb5: New USB device strings: Mfr=3, Product=2, SerialNumber=1
- usb usb5: Product: EHCI Host Controller
- usb usb5: Manufacturer: Linux 5.4.65-g018b9c0bc2d5-dirty ehci_hcd
- usb usb5: SerialNumber: 1c1b000.usb
- hub 5-0:1.0: USB hub found
- hub 5-0:1.0: 6 ports detected
- ehci-platform 1c1c000.usb: EHCI Host Controller
- ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 6
- ehci-platform 1c1c000.usb: irq 30, io mem 0x01c1c000
- ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
- usb usb6: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04
- usb usb6: New USB device strings: Mfr=3, Product=2, SerialNumber=1
- usb usb6: Product: EHCI Host Controller
- usb usb6: Manufacturer: Linux 5.4.65-g018b9c0bc2d5-dirty ehci_hcd
- usb usb6: SerialNumber: 1c1c000.usb
- hub 6-0:1.0: USB hub found
- hub 6-0:1.0: 6 ports detected
- ehci-platform 1c1d000.usb: EHCI Host Controller
- ehci-platform 1c1d000.usb: new USB bus registered, assigned bus number 7
- ehci-platform 1c1d000.usb: irq 32, io mem 0x01c1d000
- ehci-platform 1c1d000.usb: USB 2.0 started, EHCI 1.00
- usb usb7: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04
- usb usb7: New USB device strings: Mfr=3, Product=2, SerialNumber=1
- usb usb7: Product: EHCI Host Controller
- usb usb7: Manufacturer: Linux 5.4.65-g018b9c0bc2d5-dirty ehci_hcd
- usb usb7: SerialNumber: 1c1d000.usb
- hub 7-0:1.0: USB hub found
- hub 7-0:1.0: 6 ports detected
- ohci-platform 1c1b400.usb: Generic Platform OHCI controller
- ohci-platform 1c1b400.usb: new USB bus registered, assigned bus number 8
- ohci-platform 1c1b400.usb: irq 29, io mem 0x01c1b400
- usb usb8: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 5.04
- usb usb8: New USB device strings: Mfr=3, Product=2, SerialNumber=1
- usb usb8: Product: Generic Platform OHCI controller
- usb usb8: Manufacturer: Linux 5.4.65-g018b9c0bc2d5-dirty ohci_hcd
- usb usb8: SerialNumber: 1c1b400.usb
- hub 8-0:1.0: USB hub found
- hub 8-0:1.0: 3 ports detected
- ohci-platform 1c1c400.usb: Generic Platform OHCI controller
- ohci-platform 1c1c400.usb: new USB bus registered, assigned bus number 9
- ohci-platform 1c1c400.usb: irq 31, io mem 0x01c1c400
- usb usb9: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 5.04
- usb usb9: New USB device strings: Mfr=3, Product=2, SerialNumber=1
- usb usb9: Product: Generic Platform OHCI controller
- usb usb9: Manufacturer: Linux 5.4.65-g018b9c0bc2d5-dirty ohci_hcd
- usb usb9: SerialNumber: 1c1c400.usb
- hub 9-0:1.0: USB hub found
- hub 9-0:1.0: 3 ports detected
- ohci-platform 1c1d400.usb: Generic Platform OHCI controller
- ohci-platform 1c1d400.usb: new USB bus registered, assigned bus number 10
- ohci-platform 1c1d400.usb: irq 33, io mem 0x01c1d400
- usb usb10: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 5.04
- usb usb10: New USB device strings: Mfr=3, Product=2, SerialNumber=1
- usb usb10: Product: Generic Platform OHCI controller
- usb usb10: Manufacturer: Linux 5.4.65-g018b9c0bc2d5-dirty ohci_hcd
- usb usb10: SerialNumber: 1c1d400.usb
- hub 10-0:1.0: USB hub found
- hub 10-0:1.0: 3 ports detected
- usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not
- found, using dummy regulator
- musb-hdrc musb-hdrc.1.auto: MUSB HDRC host driver
- musb-hdrc musb-hdrc.1.auto: new USB bus registered, assigned bus number 11
- usb usb11: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04
- usb usb11: New USB device strings: Mfr=3, Product=2, SerialNumber=1
- usb usb11: Product: MUSB HDRC host driver
- usb usb11: Manufacturer: Linux 5.4.65-g018b9c0bc2d5-dirty musb-hcd
- usb usb11: SerialNumber: musb-hdrc.1.auto
- hub 11-0:1.0: USB hub found
- hub 11-0:1.0: 1 port detected
- ...
- EXT4-fs (ram0): mounted filesystem with ordered data mode. Opts: (null)
- VFS: Mounted root (ext4 filesystem) readonly on device 1:0.
- devtmpfs: mounted
- Freeing unused kernel memory: 2048K
- Run /sbin/init as init process
- EXT4-fs (ram0): re-mounted. Opts: (null)
- Starting syslogd: OK
- Starting klogd: OK
- Running sysctl: OK
- random: seedrng: uninitialized urandom read (256 bytes read)
- Saving 2048 bits of non-creditable seed for next boot
- Starting rpcbind: OK
- Starting network: dwmac-sun8i 1c30000.ethernet eth0: PHY [0.1:01] driver [Generic
- PHY]
- dwmac-sun8i 1c30000.ethernet eth0: No Safety Features support found
- dwmac-sun8i 1c30000.ethernet eth0: No MAC Management Counters available
- dwmac-sun8i 1c30000.ethernet eth0: PTP not supported by HW
- dwmac-sun8i 1c30000.ethernet eth0: configuring for phy/mii link mode
- dwmac-sun8i 1c30000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
- udhcpc: started, v1.36.1
- udhcpc: broadcasting discover
- udhcpc: broadcasting select for 10.0.2.15, server 10.0.2.2
- udhcpc: lease of 10.0.2.15 obtained from 10.0.2.2, lease time 86400
- deleting routers
- adding dns 10.0.2.3
- OK
- Starting NFS statd: OK
- Starting NFS services: OK
- Starting NFS daemon: NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state
- recovery directory
- NFSD: unable to find recovery directory /var/lib/nfs/v4recovery
- NFSD: Unable to initialize client recovery tracking! (-2)
- NFSD: starting 90-second grace period (net f0000049)
- OK
- Starting NFS mountd: OK
- Welcome to Buildroot for the Orange Pi PC By Red
- OrangePi_PC login: random: fast init done
- # uname -a
- Linux OrangePi_PC 5.4.65-g018b9c0bc2d5-dirty #6 SMP Sun Sep 10 20:28:01 CST 2023
- armv7l GNU/Linux
复制代码
手动修改 serial.c 文件如下:
- diff --git a/drivers/usb/gadget/legacy/serial.c
- b/drivers/usb/gadget/legacy/serial.c
- index de30d7628eef..bf7a75670c42 100644
- --- a/drivers/usb/gadget/legacy/serial.c
- +++ b/drivers/usb/gadget/legacy/serial.c
- @@ -21,7 +21,7 @@
- #define GS_VERSION_STR "v2.4"
- #define GS_VERSION_NUM 0x2400
- -#define GS_LONG_NAME "Gadget Serial"
- +#define GS_LONG_NAME "Gadget Serial Wow"
- #define GS_VERSION_NAME GS_LONG_NAME " " GS_VERSION_STR
- /*-------------------------------------------------------------------------*/
- @@ -42,7 +42,7 @@ USB_GADGET_COMPOSITE_OPTIONS();
- #define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX
- static struct usb_string strings_dev[] = {
- - [USB_GADGET_MANUFACTURER_IDX].s = "",
- + [USB_GADGET_MANUFACTURER_IDX].s = "Red Inc",
- [USB_GADGET_PRODUCT_IDX].s = GS_VERSION_NAME,
- [USB_GADGET_SERIAL_IDX].s = "",
- [STRING_DESCRIPTION_IDX].s = NULL /* updated; f(use_acm) */,
复制代码
进一步测试加载驱动的打印如下:
- [root@OrangePi_PC ~]# insmod g_serial.ko
- udc usbip-vudc.0: registering UDC driver [g_serial]
- g_serial gadget: adding 'acm'/776f8dd4 to config 'CDC ACM config'/a5c02f92
- g_serial gadget: acm ttyGS0: dual speed IN/ep1in OUT/ep1out NOTIFY/ep2in
- g_serial gadget: Gadget Serial Wow v2.4
- g_serial gadget: g_serial ready
复制代码
至此可以看出使用 qemu 调试 usb gadget 驱动成为可能(备注:qemu 模拟的 origanpi-PC 和 PC 机测试使用
的 tftp 服务传输文件)。 |
|