x86 pci初始化过程
来源:互联网 发布:java有decimal 编辑:程序博客网 时间:2024/04/29 13:24
在《PCI-E体系结构导读》+linux3.15的基础,大致过了下x86 linux pci的初始化过程
=========do_initcalls完成一系列驱动初始化,包括PCI的初始化也在这个过程中=================
kernel_init->kernel_init_freeable->do_basic_setup->do_initcalls
===============================================linux PCI初始化==========================================
Sysmap信息
........
==============
1、drivers/pci/probe.c ---->postcore_initcall(pcibus_class_init); --->.initcall2.init
class_register(&pcibus_class); //在sys/class/下创建一个pci_bus目录
===============
2、drivers/pci/pci-driver.c ---->postcore_initcall(pci_driver_init); --->.initcall2.init
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,/*pci match函数*/
.uevent = pci_uevent,
.probe = pci_device_probe,
.remove = pci_device_remove,
.shutdown = pci_device_shutdown,
.dev_groups = pci_dev_groups,
.bus_groups = pci_bus_groups,
.drv_groups = pci_drv_groups,
.pm = PCI_PM_OPS_PTR,
};
static int __init pci_driver_init(void)
{
return bus_register(&pci_bus_type);/*注册pci总线,并在/sys/bus/下创建了一个pci目录*/
}
===================
3、drivers/pci/pci-acpi.c ---->arch_initcall(acpi_pci_init); --->.initcall3.init
===================
4、arch/x86/pci/init.c ---->arch_initcall(pci_arch_init); --->.initcall3.init
//体系架构相关,对于64 bit x86来说使用CONFIG_PCI_DIRECT的方式进行访问PCI配置空间
pci_direct_probe();
pci_direct_init()
//PCI_DIRECT PCI配置空间的读写方式 (PORT IO的读写方式)
struct pci_raw_ops pci_direct_conf1 = {
.read = pci_conf1_read,
.write = pci_conf1_write,
};
/*arch/x86/pci/direct.c*/
pci_conf1_read
pci_conf1_write
//MMIO的PCI配置空间读写方式
arch/x86/pci/mmconfig_32/64.c
=======================
5、driver\pci\slot.cf ---->subsys_initcall(pci_slot_init); 在/sys/bus/pci/下建立一个slots目录
======================
6、drivers/pci/pci-acpi.c subsys_initcall(acpi_init); --->.initcall4.init
=======================
7、arch/x86/pci/legacy.c ---->subsys_initcall(pci_subsys_init) --->.initcall4.init
=======================
8、arch/x86/pci/i386.c ---->fs_initcall(pcibios_assign_resources); --->.initcall5.init
=========================================基于ACPI机制的linux PCI初始化============================================
===========
1、acpi的解析与初始化
start_kernel
-->setup_arch
{
acpi_boot_table_init();-->acpi_table_init/*在内存中找到RSDP、RSDT、XSDT,从而定位ACPI表*/
early_acpi_boot_init();
acpi_boot_init();
}
===========
2、drivers/pci/pci-acpi.c ---->arch_initcall(acpi_pci_init); --->.initcall3.init
===========
3、drivers/pci/pci-acpi.c subsys_initcall(acpi_init); --->.initcall4.init
/*ACPI的方式扫描枚举PCI*/
acpi_init
------>acpi_pci_root_init
--->acpi_pci_root_init();
--->一系列调用,能最调用到acpi_pci_root_add
--->pci_acpi_scan_root/*遍历pci总线树*/
--->pci_create_root_bus/*创建root总线*/
--->pci_scan_child_bus/*枚举pci树上的设备*/
-->pci_scan_slot
-->pci_scan_single_device
pci_scan_device
pci_device_add
-->pci_scan_bridge
------->acpi_pci_link_init();
===========
4、arch/x86/pci/legacy.c ---->subsys_initcall(pci_subsys_init) --->.initcall4.init
pci_subsys_init
->x86_init.pci.init /*pci_acpi_init*/
/*
//由于使用acpi pci的方式枚举PCI树上的设备, pci_legacy_init函数将不会被执行了
pci_legacy_init() /*完成对PCI的枚举过程*/
{
pcibios_scan_root(0);/*从PCI 0号总线开始扫描枚举*/
}
*/
->x86_init.pci.init_irq (x86_init_noop)
->pcibios_init();
-->pcibios_resource_survey();/*检查pci设备的bar空间*/
===========
5、arch/x86/pci/i386.c ---->fs_initcall(pcibios_assign_resources); --->.initcall5.init
pcibios_assign_resources /*设备pci设备的BAR空间*/
{
list_for_each_entry(root_bus, &pci_root_buses, node)
pci_assign_unassigned_root_bus_resources(root_bus);
----〉__pci_bus_size_bridges/*修复当前PCI总线树下所有PCI设备的IO空间和存储空间*/
----〉__pci_bus_assign_resources/*配置PCI设备/PCI桥的 PCI配置空间,主要为BAR等关键配置*/
----〉pci_bus_dump_resources/*打印pci设备的系统资源*/
linux3.15源码
=========do_initcalls完成一系列驱动初始化,包括PCI的初始化也在这个过程中=================
kernel_init->kernel_init_freeable->do_basic_setup->do_initcalls
===============================================linux PCI初始化==========================================
Sysmap信息
........
==============
1、drivers/pci/probe.c ---->postcore_initcall(pcibus_class_init); --->.initcall2.init
class_register(&pcibus_class); //在sys/class/下创建一个pci_bus目录
===============
2、drivers/pci/pci-driver.c ---->postcore_initcall(pci_driver_init); --->.initcall2.init
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,/*pci match函数*/
.uevent = pci_uevent,
.probe = pci_device_probe,
.remove = pci_device_remove,
.shutdown = pci_device_shutdown,
.dev_groups = pci_dev_groups,
.bus_groups = pci_bus_groups,
.drv_groups = pci_drv_groups,
.pm = PCI_PM_OPS_PTR,
};
static int __init pci_driver_init(void)
{
return bus_register(&pci_bus_type);/*注册pci总线,并在/sys/bus/下创建了一个pci目录*/
}
===================
3、drivers/pci/pci-acpi.c ---->arch_initcall(acpi_pci_init); --->.initcall3.init
===================
4、arch/x86/pci/init.c ---->arch_initcall(pci_arch_init); --->.initcall3.init
//体系架构相关,对于64 bit x86来说使用CONFIG_PCI_DIRECT的方式进行访问PCI配置空间
pci_direct_probe();
pci_direct_init()
//PCI_DIRECT PCI配置空间的读写方式 (PORT IO的读写方式)
struct pci_raw_ops pci_direct_conf1 = {
.read = pci_conf1_read,
.write = pci_conf1_write,
};
/*arch/x86/pci/direct.c*/
pci_conf1_read
pci_conf1_write
//MMIO的PCI配置空间读写方式
arch/x86/pci/mmconfig_32/64.c
=======================
5、driver\pci\slot.cf ---->subsys_initcall(pci_slot_init); 在/sys/bus/pci/下建立一个slots目录
======================
6、drivers/pci/pci-acpi.c subsys_initcall(acpi_init); --->.initcall4.init
=======================
7、arch/x86/pci/legacy.c ---->subsys_initcall(pci_subsys_init) --->.initcall4.init
=======================
8、arch/x86/pci/i386.c ---->fs_initcall(pcibios_assign_resources); --->.initcall5.init
=========================================基于ACPI机制的linux PCI初始化============================================
===========
1、acpi的解析与初始化
start_kernel
-->setup_arch
{
acpi_boot_table_init();-->acpi_table_init/*在内存中找到RSDP、RSDT、XSDT,从而定位ACPI表*/
early_acpi_boot_init();
acpi_boot_init();
}
===========
2、drivers/pci/pci-acpi.c ---->arch_initcall(acpi_pci_init); --->.initcall3.init
===========
3、drivers/pci/pci-acpi.c subsys_initcall(acpi_init); --->.initcall4.init
/*ACPI的方式扫描枚举PCI*/
acpi_init
------>acpi_pci_root_init
--->acpi_pci_root_init();
--->一系列调用,能最调用到acpi_pci_root_add
--->pci_acpi_scan_root/*遍历pci总线树*/
--->pci_create_root_bus/*创建root总线*/
--->pci_scan_child_bus/*枚举pci树上的设备*/
-->pci_scan_slot
-->pci_scan_single_device
pci_scan_device
pci_device_add
-->pci_scan_bridge
------->acpi_pci_link_init();
===========
4、arch/x86/pci/legacy.c ---->subsys_initcall(pci_subsys_init) --->.initcall4.init
pci_subsys_init
->x86_init.pci.init /*pci_acpi_init*/
/*
//由于使用acpi pci的方式枚举PCI树上的设备, pci_legacy_init函数将不会被执行了
pci_legacy_init() /*完成对PCI的枚举过程*/
{
pcibios_scan_root(0);/*从PCI 0号总线开始扫描枚举*/
}
*/
->x86_init.pci.init_irq (x86_init_noop)
->pcibios_init();
-->pcibios_resource_survey();/*检查pci设备的bar空间*/
===========
5、arch/x86/pci/i386.c ---->fs_initcall(pcibios_assign_resources); --->.initcall5.init
pcibios_assign_resources /*设备pci设备的BAR空间*/
{
list_for_each_entry(root_bus, &pci_root_buses, node)
pci_assign_unassigned_root_bus_resources(root_bus);
----〉__pci_bus_size_bridges/*修复当前PCI总线树下所有PCI设备的IO空间和存储空间*/
----〉__pci_bus_assign_resources/*配置PCI设备/PCI桥的 PCI配置空间,主要为BAR等关键配置*/
----〉pci_bus_dump_resources/*打印pci设备的系统资源*/
}
参考资料:
《PCIE 体系结构导读》linux3.15源码
0 0
- x86 pci初始化过程
- pci 初始化
- PCI 初始化过程一 :总线拓扑结构的建立
- intel dpdk api pci设备驱动注册和初始化过程
- intel dpdk api pci设备驱动注册和初始化过程
- Linux 2.6.36 x86 内核中断初始化过程详解
- PCI设备的初始化
- PCI 总线初始化
- linux pci 初始化
- PMON PCI设备初始化
- WDF----PCI设备初始化
- PCI 总线初始化
- pci设备的初始化
- pci设备的初始化
- pci设备的初始化
- PCI 总线初始化
- PCI的中断过程
- 获取PCI设备并初始化
- python3.3三种简单获取网页信息的方法
- 一篇谈论Scrum的好文章
- 五步看盘法》---韩东良(完整版)
- 喝酒不骑马的Android自学日记(10)-ProgressBar&&WebView
- poj 1979 &&hdu 1312Red and Black (bfs)
- x86 pci初始化过程
- RNN学习笔记(一)-简介及BPTT RTRL及Hybrid(FP/BPTT)算法
- 实用ps教程-第一节:使用ps制作GIF动图
- java学习笔记-自动装箱,自动拆箱
- 2.Storyboard传参小技巧
- 78. Cookie
- One Month~
- 添加环境变量
- MFC中CEdit判断空行