這篇文章只是拿來記錄compile Kernel for Cortex-A57, 用於研究PCIe Driver, 其餘的rootfs與busybox請參考附錄
[brook@:~/Projects/qemu/linux-virt]$ sudo apt-get install gcc-aarch64-linux-gnu #for ARM64 [brook@:~/Projects/qemu/linux-virt]$ export ARCH=arm64 [brook@:~/Projects/qemu/linux-virt]$ export CROSS_COMPILE=aarch64-linux-gnu- [brook@:~/Projects/qemu/linux-virt]$ cp arch/arm64/configs/defconfig .config [brook@:~/Projects/qemu/linux-virt]$ make olddefconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o HOSTCC scripts/kconfig/confdata.o HOSTCC scripts/kconfig/expr.o LEX scripts/kconfig/lexer.lex.c YACC scripts/kconfig/parser.tab.[ch] HOSTCC scripts/kconfig/lexer.lex.o HOSTCC scripts/kconfig/parser.tab.o HOSTCC scripts/kconfig/preprocess.o HOSTCC scripts/kconfig/symbol.o HOSTLD scripts/kconfig/conf scripts/kconfig/conf --olddefconfig Kconfig # # configuration written to .config # [brook@:~/Projects/qemu/linux-virt]$ make -j16 [brook@:~/Projects/qemu/linux-virt]$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -smp 8 -m 4096 -kernel ./arch/arm64/boot/Image -append "console=ttyAMA0 root=/dev/vda" -nographic -initrd ../initrd-arm.img [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x411fd070] ... Please press Enter to activate this console. / # / # lspci -k 00:01.0 Class 0200: 1af4:1000 virtio-pci 00:00.0 Class 0600: 1b36:0008 / # uname -r 5.4.01af4:1000是Virtio network device, 而1b36:0008是QEMU PCIe Host bridge
ETH PCIe driver在"drivers/virtio/virtio_pci_common.c", 其vendor ID是0x1af4, 當device插入時, 就會去比對ID, match後就會載入該module並probe
/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ static const struct pci_device_id virtio_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_ANY_ID) }, { 0 } }; MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); ... static struct pci_driver virtio_pci_driver = { .name = "virtio-pci", .id_table = virtio_pci_id_table, .probe = virtio_pci_probe, .remove = virtio_pci_remove, #ifdef CONFIG_PM_SLEEP .driver.pm = &virtio_pci_pm_ops, #endif .sriov_configure = virtio_pci_sriov_configure, }; module_pci_driver(virtio_pci_driver);
這裡我把PCI ID移成PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET + 1, 再透過echo <vendor_code> <device_code> > /sys/bus/pci/drivers/<pci_device_driver>/new_id動態對PCIe driver新增ID, 讓系統認到網卡
[brook@:~/Projects/qemu/linux-virt]$ git diff . diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index f2862f66c2ac..60aef3fea650 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -492,7 +492,7 @@ static const struct dev_pm_ops virtio_pci_pm_ops = { /* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ static const struct pci_device_id virtio_pci_id_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_ANY_ID) }, + { PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET + 1, PCI_ANY_ID) }, { 0 } }; @@ -514,6 +514,7 @@ static int virtio_pci_probe(struct pci_dev *pci_dev, { struct virtio_pci_device *vp_dev, *reg_dev = NULL; int rc; + printk("%s(#%d): Brook\n", __FUNCTION__, __LINE__); /* allocate our structure and fill it out */ vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL);lspci會認到1af4:1000, 但是eth driver因為被我跳號, 所以認不到, 再透過/sys/bus/pci/drivers/<pci_device_driver>/new_id將往卡帶起來
/ # lspci 00:01.0 Class 0200: 1af4:1000 00:00.0 Class 0600: 1b36:0008 / # ifconfig -a lo Link encap:Local Loopback LOOPBACK MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / # echo 1af4 1000 > /sys/bus/pci/drivers/virtio-pci/new_id [ 130.728345] virtio_pci_probe(#517): Brook [ 130.729216] virtio-pci 0000:00:01.0: enabling device (0000 -> 0003) / # ifconfig -a eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback LOOPBACK MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
透過echo <Domain:Bus:Device.Function> > /sys/bus/pci/drivers/<pci_device_driver>/unbind將driver移除, 也可以透過echo <Domain:Bus:Device.Function> > /sys/bus/pci/drivers/<pci_device_driver>/bind重新將driver帶上
/ # lspci 00:01.0 Class 0200: 1af4:1000 00:00.0 Class 0600: 1b36:0008 / # echo 0000:00:01.0 > /sys/bus/pci/drivers/virtio-pci/unbind [ 5163.097254] hrtimer: interrupt took 87350512 ns / # ifconfig -a lo Link encap:Local Loopback LOOPBACK MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / # echo 0000:00:01.0 > /sys/bus/pci/drivers/virtio-pci/bind [ 5183.251580] virtio_pci_probe(#517): Brook / # ifconfig -a eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback LOOPBACK MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
-
參考資料:
- https://blog.csdn.net/zhqh100/article/details/51173275, qemu模拟Cortex-A57运行Linux4.5.1
- Build the Linux Kernel and Busybox for ARM and run them on QEMU
- https://zhuanlan.zhihu.com/p/113467453, qemu PCIe总线结构
- https://pci-ids.ucw.cz/read/PC/1af4, The PCI ID Repository
- https://stackoverflow.com/questions/22901282/hard-time-in-understanding-module-device-tableusb-id-table-usage, Hard time in understanding MODULE_DEVICE_TABLE(usb, id_table) usage