基础知识(复习)
如何查看当前系统配置CONFIG
# 方法1:需要内核使能 CONFIG_IKCONFIG_PROC
sudo modprobe configs
zcat /proc/config.gz
# 方法2:直接看
cat /boot/config-$(uname -r)
如何查看当前系统System.map
Ubuntu会把System.map文件放到/boot目录下,有的可能在源码目录:
inno@DEV-005:~$ ls /usr/src/linux-headers-$(uname -r)
arch block .....
inno@DEV-005:~$ ls /boot/System.map-$(uname -r)
/boot/System.map-5.4.0-47-generic
模块加载过程
调用过程
rest_init
kernel_init # 进程1加载的驱动模块
kernel_init_freeable
do_basic_setup
driver_init(); // 驱动架构初始化
do_initcalls(); // initcalls初始化
调用级别
#define pure_initcall(fn) __define_initcall("0",fn,0)
#define core_initcall(fn) __define_initcall("1",fn,1)
#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
#define postcore_initcall(fn) __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
#define arch_initcall(fn) __define_initcall("3",fn,3)
#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
#define subsys_initcall(fn) __define_initcall("4",fn,4)
#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
#define fs_initcall(fn) __define_initcall("5",fn,5)
#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
#define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
#define late_initcall(fn) __define_initcall("7",fn,7)
#define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
初始化代码流程
参考好文:
注:这部分代码暂时绕过ACPI的枚举过程,下一章节详解
代码初始化总览
[baiy@test pci]$ pwd
/home/public/baiy/linux/x86/linux-5.7.14/drivers/pci
[baiy@test pci]$ grep -nr "_initcall"
pci-acpi.c:1360:arch_initcall(acpi_pci_init);
pci-driver.c:1681:postcore_initcall(pci_driver_init);
pci-mid.c:77:arch_initcall(mid_pci_init);
pci-sysfs.c:1453:late_initcall(pci_sysfs_init);
pci.c:6389:late_initcall(pci_resource_alignment_sysfs_init);
pci.c:6564:pure_initcall(pci_realloc_setup_params);
pcie/portdrv_pci.c:264:device_initcall(pcie_portdrv_init);
probe.c:108:postcore_initcall(pcibus_class_init);
proc.c:462:device_initcall(pci_proc_init);
quirks.c:193:fs_initcall_sync(pci_apply_final_quirks);
slot.c:377:subsys_initcall(pci_slot_init);
[baiy@test pci]$ pwd
/home/public/baiy/linux/x86/linux-5.7.14/arch/x86/pci
[baiy@test pci]$ grep -nr "_initcall"
i386.c:373:fs_initcall(pcibios_assign_resources);
init.c:45:arch_initcall(pci_arch_init);
legacy.c:77:subsys_initcall(pci_subsys_init);
mmconfig-shared.c:718:late_initcall(pci_mmcfg_late_insert_resources);
# 或者执行 cat /proc/kallsyms | grep pci | grep initcall
# 或者执行 cat /proc/System.map | grep pci | grep initcall
[baiy@test pci]$ cat /proc/kallsyms | grep pci | grep initcall # 忘了加sudo,所以地址都是0
0000000000000000 t __initcall_pci_realloc_setup_params0
0000000000000000 t __initcall_pcibus_class_init2
0000000000000000 t __initcall_pci_driver_init2
0000000000000000 t __initcall_acpi_pci_init3
0000000000000000 t __initcall_register_xen_pci_notifier3
0000000000000000 t __initcall_pci_arch_init3
0000000000000000 t __initcall_pci_slot_init4
0000000000000000 t __initcall_pci_subsys_init4
0000000000000000 t __initcall_pci_eisa_init_early4s
0000000000000000 t __initcall_pcibios_assign_resources5
0000000000000000 t __initcall_pci_apply_final_quirks5s
0000000000000000 t __initcall_pci_iommu_initrootfs
0000000000000000 t __initcall_pwm_lpss_driver_pci_init6
0000000000000000 t __initcall_pci_proc_init6
0000000000000000 t __initcall_pcie_portdrv_init6
0000000000000000 t __initcall_pci_hotplug_init6
0000000000000000 t __initcall_pci_ep_cfs_init6
0000000000000000 t __initcall_pci_epc_init6
0000000000000000 t __initcall_pci_epf_init6
0000000000000000 t __initcall_dw_plat_pcie_driver_init6
0000000000000000 t __initcall_virtio_pci_driver_init6
0000000000000000 t __initcall_serial_pci_driver_init6
0000000000000000 t __initcall_sis_pci_driver_init6
0000000000000000 t __initcall_ata_generic_pci_driver_init6
0000000000000000 t __initcall_vfio_pci_init6
0000000000000000 t __initcall_ehci_pci_init6
0000000000000000 t __initcall_ohci_pci_init6
0000000000000000 t __initcall_xhci_pci_init6
0000000000000000 t __initcall_pci_resource_alignment_sysfs_init7
0000000000000000 t __initcall_pci_sysfs_init7
0000000000000000 t __initcall_pci_mmcfg_late_insert_resources7
然后我们根据加载顺序配合System.map开始看就好,ACPI牵扯到上电过程,后边详解。
代码目录
x86的PCI代码集中在两个目录
arch/x86/pci driver/x86/pci
流程总览
这里为了以后复习,总览下代码
初始化的两个阶段
第一阶段(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
- 如何是桥设备,递归初始化