We went over the first pass of pci_enumeration() during boot. Before go ahead with the second pass, we'd like to get the answer of what happen during the two passes of pci_enumeration.
First, let's track where the first pass of pci_enumeration() is called during boot process.
main()
start_up()
startup_modules()
setup_ddi()
create_devinfo_tree()
impl_setup_ddi()
impl_bus_initialprobe()
In imple_bus_initialprobe(), the bus probe modules will be loaded and the first pass of enumeration will be called. For xpv kernel, if it runs on behalf of domain 0, pci_autoconfig, isa, xpv_autoconfig will be loaded and probed; if on behalf of a PV guest, PCI enumeration module will not load since it has no permission to access the real device. Otherwise, if it is bare metal kernel, pci_autoconfig, isa and acpidev will be loaded and probed. Acpidev is a probe for ACPI name space. It enumerate all objects in the ACPI name space and create device nodes for the objects which it is intereted at. The system devices such as processor, memory, and IOMMU are essential for the system, but there is no existing bus mechanism to enumerate. Acpidev was designed to enumerate such devices.
i86pc/os/ddi_impl.c
2642 /*
2643 * impl_bus_initialprobe
2644 *|_____Modload the prom simulator, then let it probe to verify existence
2645 *|_____and type of PCI support.
2646 */
2647 static void
2648 impl_bus_initialprobe(void)
2649 {
2650 |_______struct bus_probe *probe;
2651
2652 |_______/* load modules to install bus probes */
2653 #if defined(__xpv)
2654 |_______if (DOMAIN_IS_INITDOMAIN(xen_info)) {
2655 |_______|_______if (modload("misc", "pci_autoconfig") < 0) {
2656 |_______|_______|_______panic("failed to load misc/pci_autoconfig");
2657 |_______|_______}
2658
2659 |_______|_______if (modload("drv", "isa") < 0)
2660 |_______|_______|_______panic("failed to load drv/isa");
2661 |_______}
2662
2663 |_______(void) modload("misc", "xpv_autoconfig");
2664 #else
2665 |_______(void) modload("misc", "acpidev");
2666
2667 |_______if (modload("misc", "pci_autoconfig") < 0) {
2668 |_______|_______panic("failed to load misc/pci_autoconfig");
2669 |_______}
2670
2671 |_______if (modload("drv", "isa") < 0)
2672 |_______|_______panic("failed to load drv/isa");
2673 #endif
2674
2675 |_______probe = bus_probes;
2676 |_______while (probe) {
2677 |_______|_______/* run the probe functions */
2678 |_______|_______(*probe->probe)(0);
2679 |_______|_______probe = probe->next;
2680 |_______}
2681 }
Second, let's track the second pass of bus probe.
main()
start_up()
startup_end()
configure()
impl_bus_reprobe()
i86pc/os/ddi_impl.c
2683 /*
2684 * impl_bus_reprobe
2685 *|_____Reprogram devices not set up by firmware.
2686 */
2687 static void
2688 impl_bus_reprobe(void)
2689 {
2690 |_______struct bus_probe *probe;
2691
2692 |_______probe = bus_probes;
2693 |_______while (probe) {
2694 |_______|_______/* run the probe function */
2695 |_______|_______(*probe->probe)(1);
2696 |_______|_______probe = probe->next;
2697 |_______}
2698 }
Okay, before go ahead with checking out what happens during these two points. Let me try to answer two questions in my mind.
(i) How are the drivers bound to the specific device node?
For more detailed description, please refer to "Binding a Driver to a Device" in document of "Writing Device Driver".
http://docs.sun.com/app/docs/doc/819-3196/kernelovr-14?a=view
For short, copy and paste some words below.
Each device node has an associated name property. This property can be assigned either from an external agent, such as the PROM, during system boot or from a driver.conf configuration file. In any case, the name property represents the node name assigned to a device in the device tree. The node name is the name visible in /devices and listed in the prtconf(1M) output.
A device node can have an associated compatible property as well. The compatible property contains an ordered list of one or more possible driver names or driver aliases for the device.
The system uses both the compatible and the name properties to select a driver for the device. The system first attempts to match the contents of the compatible property, if the compatible property exists, to a driver on the system. Beginning with the first driver name on the compatible property list, the system attempts to match the driver name to a known driver on the system. Each entry on the list is processed until the system either finds a match or reaches the end of the list.
If the contents of either the name property or the compatible property match a driver on the system, then that driver is bound to the device node. If no match is found, no driver is bound to the device node.
(ii) After ndi_devi_bind_driver() is called, when will the actual driver module loaded, hence attach() method gets called?
It depends. Some device driver modules are loaded during boot via function such as ndi_devi_online(). Some device node remains BOUND status untill the driver is really needed by the any application. Say, the device is about to be open by an application.
Okay, the following things are done between the two passes of pci_enumerate() (actually for two passes of each bus prober, such as PCI and acpidev)
startup_dodules()==>
( 1) DDI instance intialization
( 2) DDI callback intialization
( 3) Allocate and initialize log_event data structures
( 4) FM initialization
( 5) Initialize IRM subsystem before any drivers are attached
( 6) Load driver.conf file for all major's
( 7) LDI initialization
( 8) Initialize the overall cache file management
( 9) Read cache files
(10) Set up the CPU module subsystem for the boot cpu in the native case, and all physical cpu resource in the xpv dom0 case
(11) Fake a prom tree such that /dev/openprom continues to work
(12) Load all platform specific modules. Retrieve the platform specified modules from /etc/mach and load each of them
[allen@blu-wbg:~]cat /etc/mach
... <legal statement> ...
pcplusmp
xpv_psm
startup_end()==>
(13) Perform tasks that get done after most of the VM initialization has been done but before the clock and other devices get started
(14) Perform CPC initialization for this CPU
(15) Initialize cpu event framework
(16) If tod_module_name is set in /etc/system, load TOD module so that ddi_get_time(9F) etc work
(17) Load "xpvtod" module for xpv kernel
(18) Call configure() to configure the system
(19) Check for disabled drivers and initialize root node
(20) Reprogram devices not set up by firmware (BIOS). The second pass of bus enumeration happens here.
As we could see system keep initializing itself during the two passes of bus probe. Actually, the first pass is a PROM emulator. It does what PROM should do on an IEEE Std 1275 compatible platform. The second pass is called in configure() to reprogram/configure the devices in the system. "pci_reprogram()" is called in the second pass of pci_enumerate(). Let dive into pci_reprogram() and see what's been done in that.
pci_reprogram()
===============
(a) Scan ACPI namespace for _BBN objects, make sure that childless root-bridges appear in devinfo tree.
intel/io/pci/pci_boot.c
238 /*
239 * Scan the ACPI namespace for all top-level instances of _BBN
240 * in order to discover childless root-bridges (which enumeration
241 * may not find; root-bridges are inferred by the existence of
242 * children). This scan should find all root-bridges that have
243 * been enumerated, and any childless root-bridges not enumerated.
244 * Root-bridge for bus 0 may not have a _BBN object.
245 */
246 static void
247 pci_scan_bbn()
248 {
249 |_______void *rv;
250
251 |_______(void) AcpiGetDevices(NULL, pci_process_acpi_device, NULL, &rv);
252 }
Walk the objects in ACPI name space and call pci_process_acpi_device() with "NULL" as parameter. The return value of AcpiGetDevices() is returned in "rv" parameter. If a PCI with _BBN found,
225 |_______if (ACPI_SUCCESS(AcpiEvaluateObjectTyped(hdl, "_BBN",
226 |_______ NULL, &rb, ACPI_TYPE_INTEGER))) {
227 |_______|_______/* PCI with _BBN, process it, go no deeper */
228 |_______|_______if (pci_bus_res[ro.Integer.Value].par_bus == (uchar_t)-1 &&
229 |_______|_______ pci_bus_res[ro.Integer.Value].dip == NULL)
230 |_______|_______|_______create_root_bus_dip((uchar_t)ro.Integer.Value);
231 |_______|_______return (AE_CTRL_DEPTH);
232 |_______}
To be continued ...
分享到:
相关推荐
3. 找到Source Insight的配置文件或插件目录,将解压后的文件复制或移动到对应位置。这可能需要查阅Source Insight的官方文档或用户指南来获取准确路径。 4. 重启Source Insight,打开包含中文字符的文件,检查是否...
《Source Insight 4.0.86.0 安装及使用详解》 Source Insight是一款深受程序员喜爱的源代码分析和编辑工具,以其强大的代码浏览、查找和智能提示功能著称。本文将详细介绍如何安装Source Insight 4.0.86.0版本,并...
sourceinsight_4.0.86.0-setup.exe,加破解码
sourceinsight_4.0.86.0-setup安装及破解,不求发家致富,但求有口饭吃
Source Insight 3是一款广受欢迎的源代码阅读器和编辑器,尤其在软件开发领域中,它为程序员提供了强大的代码浏览、分析和编辑功能。对于处理各种编码格式的源代码文件,Source Insight 3表现出了良好的兼容性,其中...
SourceInsight是一款强大的源代码查看和编辑工具,尤其在编程领域深受程序员喜爱。它提供了对多种编程语言的支持,包括C、C++、Java等,并且具有语法高亮、代码跳转、自动完成等功能,极大地提高了代码阅读和编辑的...
SourceInsight是一款强大的源代码分析和浏览工具,尤其在C/C++、Java和C#等编程语言中广泛应用。它提供了一种高效的方式来查看、搜索、理解和编辑源代码,深受程序员喜爱。版本4.0.86.0是SourceInsight的一个特定...
《SourceInsight 4.0.86.0 安装程序详解》 SourceInsight是一款备受程序员喜爱的源代码查看、分析和编辑工具,尤其在C/C++、Java、C#等编程语言中表现出色。本文将详细介绍SourceInsight 4.0.86.0版本的安装过程及...
`cd Source\ Insight\ 3/` 这将显示Source Insight的安装目录。 五、结论 ---------- 在Ubuntu下安装Source Insight可以使用Wine来实现。首先,需要安装Wine,然后使用Wine安装Source Insight。启动Source ...
Source Insight是一款广受欢迎的源代码阅读和分析工具,尤其在软件开发领域中,它以其强大的代码导航、搜索和理解功能而备受赞誉。然而,对于处理包含非英文字符,特别是中文字符的UTF-8编码文件时,原生的Source ...
`GLOBAL_090424.CF3` 文件可能是另一个与Source Insight相关的语言文件,可能包含了全局配置或者与其他编程语言的设置。CF3格式是Source Insight的早期版本中使用的配置文件格式,它也用于定义代码的显示样式和行为...
### Source Insight 编辑器快捷键详解 #### 一、基本操作 - **退出程序**:Alt + F4 - 这个快捷键用于快速关闭 Source Insight 编辑器。 - **重绘屏幕**:Ctrl + Alt + Space - 当编辑器窗口显示异常时,可以...
注意:这是source insight 4.0的主题。解压缩后,在source insight菜单进行导入操作:Source Insight 4->Options->load configurations->选择下载的配置文件
1. 安装原版软件:Source Insight Version 4.0.0087 - October 17, 2017 2. 替换原主程序:sourceinsight4.exe 3. 导入授权文件(Import a new license file):si4.pediy.lic Patched sourceinsight4.exe: Size Date...
在探讨“Source Insight 3.5 序列号”这一主题时,首先需要明确的是,序列号(serial number)通常是指软件开发商为了控制软件的分发与使用而提供的一种授权方式。通过序列号,可以验证用户是否拥有使用该软件的合法...
**源码洞察——Source Insight更快捷使用指南** Source Insight是一款广受程序员喜爱的源代码查看和编辑工具,尤其在C/C++、Java等语言的开发中,它的智能高亮、语法分析、代码跳转等功能极大地提高了开发效率。...
3. **修改Source Insight的配置文件**:通过修改Source Insight的配置文件(如*.prj或*.spp),添加特定的命令行参数来指定UTF-8编码。例如,可以添加`-fcharset=utf8`,但这需要对Source Insight的配置有深入理解。...
3. **导入到Source Insight**: - 回到Source Insight的“Languages”设置界面,找到刚刚添加的语言“at&tasm”,并点击其右侧的“Edit”按钮。 - 在弹出的编辑窗口中选择“Keywords”选项卡,然后点击“Import”...
Source Insight 使用技巧大全 Source Insight 是一款功能强大且灵活的代码编辑器,提供了大量的快捷键和使用技巧。本文将整理和总结 Source Insight 的常用快捷键和使用技巧,帮助开发者提高编码效率和工作质量。 ...