基础知识(复习)

如何查看当前系统配置CONFIG

  1. # 方法1:需要内核使能 CONFIG_IKCONFIG_PROC
  2. sudo modprobe configs
  3. zcat /proc/config.gz
  4. # 方法2:直接看
  5. cat /boot/config-$(uname -r)

如何查看当前系统System.map

Ubuntu会把System.map文件放到/boot目录下,有的可能在源码目录:

  1. inno@DEV-005:~$ ls /usr/src/linux-headers-$(uname -r)
  2. arch block .....
  3. inno@DEV-005:~$ ls /boot/System.map-$(uname -r)
  4. /boot/System.map-5.4.0-47-generic

模块加载过程

复习-initcall全过程

  1. 调用过程
  2. rest_init
  3. kernel_init # 进程1加载的驱动模块
  4. kernel_init_freeable
  5. do_basic_setup
  6. driver_init(); // 驱动架构初始化
  7. do_initcalls(); // initcalls初始化
  8. 调用级别
  9. #define pure_initcall(fn) __define_initcall("0",fn,0)
  10. #define core_initcall(fn) __define_initcall("1",fn,1)
  11. #define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
  12. #define postcore_initcall(fn) __define_initcall("2",fn,2)
  13. #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
  14. #define arch_initcall(fn) __define_initcall("3",fn,3)
  15. #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
  16. #define subsys_initcall(fn) __define_initcall("4",fn,4)
  17. #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
  18. #define fs_initcall(fn) __define_initcall("5",fn,5)
  19. #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
  20. #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
  21. #define device_initcall(fn) __define_initcall("6",fn,6)
  22. #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
  23. #define late_initcall(fn) __define_initcall("7",fn,7)
  24. #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)

初始化代码流程

参考好文:

注:这部分代码暂时绕过ACPI的枚举过程,下一章节详解

代码初始化总览

  1. [baiy@test pci]$ pwd
  2. /home/public/baiy/linux/x86/linux-5.7.14/drivers/pci
  3. [baiy@test pci]$ grep -nr "_initcall"
  4. pci-acpi.c:1360:arch_initcall(acpi_pci_init);
  5. pci-driver.c:1681:postcore_initcall(pci_driver_init);
  6. pci-mid.c:77:arch_initcall(mid_pci_init);
  7. pci-sysfs.c:1453:late_initcall(pci_sysfs_init);
  8. pci.c:6389:late_initcall(pci_resource_alignment_sysfs_init);
  9. pci.c:6564:pure_initcall(pci_realloc_setup_params);
  10. pcie/portdrv_pci.c:264:device_initcall(pcie_portdrv_init);
  11. probe.c:108:postcore_initcall(pcibus_class_init);
  12. proc.c:462:device_initcall(pci_proc_init);
  13. quirks.c:193:fs_initcall_sync(pci_apply_final_quirks);
  14. slot.c:377:subsys_initcall(pci_slot_init);
  15. [baiy@test pci]$ pwd
  16. /home/public/baiy/linux/x86/linux-5.7.14/arch/x86/pci
  17. [baiy@test pci]$ grep -nr "_initcall"
  18. i386.c:373:fs_initcall(pcibios_assign_resources);
  19. init.c:45:arch_initcall(pci_arch_init);
  20. legacy.c:77:subsys_initcall(pci_subsys_init);
  21. mmconfig-shared.c:718:late_initcall(pci_mmcfg_late_insert_resources);
  22. # 或者执行 cat /proc/kallsyms | grep pci | grep initcall
  23. # 或者执行 cat /proc/System.map | grep pci | grep initcall
  24. [baiy@test pci]$ cat /proc/kallsyms | grep pci | grep initcall # 忘了加sudo,所以地址都是0
  25. 0000000000000000 t __initcall_pci_realloc_setup_params0
  26. 0000000000000000 t __initcall_pcibus_class_init2
  27. 0000000000000000 t __initcall_pci_driver_init2
  28. 0000000000000000 t __initcall_acpi_pci_init3
  29. 0000000000000000 t __initcall_register_xen_pci_notifier3
  30. 0000000000000000 t __initcall_pci_arch_init3
  31. 0000000000000000 t __initcall_pci_slot_init4
  32. 0000000000000000 t __initcall_pci_subsys_init4
  33. 0000000000000000 t __initcall_pci_eisa_init_early4s
  34. 0000000000000000 t __initcall_pcibios_assign_resources5
  35. 0000000000000000 t __initcall_pci_apply_final_quirks5s
  36. 0000000000000000 t __initcall_pci_iommu_initrootfs
  37. 0000000000000000 t __initcall_pwm_lpss_driver_pci_init6
  38. 0000000000000000 t __initcall_pci_proc_init6
  39. 0000000000000000 t __initcall_pcie_portdrv_init6
  40. 0000000000000000 t __initcall_pci_hotplug_init6
  41. 0000000000000000 t __initcall_pci_ep_cfs_init6
  42. 0000000000000000 t __initcall_pci_epc_init6
  43. 0000000000000000 t __initcall_pci_epf_init6
  44. 0000000000000000 t __initcall_dw_plat_pcie_driver_init6
  45. 0000000000000000 t __initcall_virtio_pci_driver_init6
  46. 0000000000000000 t __initcall_serial_pci_driver_init6
  47. 0000000000000000 t __initcall_sis_pci_driver_init6
  48. 0000000000000000 t __initcall_ata_generic_pci_driver_init6
  49. 0000000000000000 t __initcall_vfio_pci_init6
  50. 0000000000000000 t __initcall_ehci_pci_init6
  51. 0000000000000000 t __initcall_ohci_pci_init6
  52. 0000000000000000 t __initcall_xhci_pci_init6
  53. 0000000000000000 t __initcall_pci_resource_alignment_sysfs_init7
  54. 0000000000000000 t __initcall_pci_sysfs_init7
  55. 0000000000000000 t __initcall_pci_mmcfg_late_insert_resources7

然后我们根据加载顺序配合System.map开始看就好,ACPI牵扯到上电过程,后边详解。

代码目录

x86的PCI代码集中在两个目录

arch/x86/pci driver/x86/pci

流程总览

这里为了以后复习,总览下代码

2.驱动初始化流程-流程总览 - 图12.驱动初始化流程-流程总览 - 图2

初始化的两个阶段

第一阶段(PCI基础环境搭建):

  • MMC config基础地址初始化 pci_mmconfig_add
  • 获取系统启动的pci命令行参数 pci_setup
  • 注册/sys/class/pci_bus接口 pcibus_class_init
  • 注册/sys/bus/pci和/sys/bus/pci_express设备总线 pci_driver_init (重点,sysfs下的信息)
  • 检测PCI 总线0,校验主桥,并占用X86对PCI访问IO端口,设置访问函数 pci_arch_init (重点)

第二阶段(ACPI初始化,重点):

  • 初始化PCI的入口地址,初始化acpi_pci_root 结构 acpi_pci_root_add
  • 初始化主桥设备 pci_create_root_bus
  • 扫描并添加主桥下所有pci设备 pci_scan_child_bus
  • 给每个pci设备分配资源,并初始化所有cap
  • 如何是桥设备,递归初始化

Ubuntu 18.04下的一些配置

config.txt
screen.log