The Boot Process at a Glance x86/x64系统启动过程解析
哥又来干体力活了。人肉翻译一下:
The Boot Process at a Glance
This section explains the boot process in sufficient detail to understand the system address map and other bus protocol-related matters that are explained later in this article. You need to have a clear understanding of the boot process before we get into the system address map and bus protocol-related talks.
The boot process in x86/x64 starts with the platform firmware (BIOS/UEFI) execution. The platform firmware execution happens prior to the operating system (OS) boot, specifically before the “boot loader” loads and executes the OS. Platform firmware execution can be summarized as follows:
x86/x64系统的启动过程起始于板子的固件部分(BIOS/UEFI)。固件比OS先执行,再搬移OS到CPU的RAM中,然后运行OS。固件的执行过程大致如下:
- Start of execution in the CPU (processor) reset vector. In all platforms, the bootstrap processor (BSP) starts execution by fetching the instruction located in an address known as the reset vector. In x86/x64 this address is 4GB minus 16-bytes (FFFF_FFF0h). This address is always located in the BIOS/UEFI flash memory on the motherboard. 首先运行CPU复位向量表。
- CPU operating mode initialization. In this stage, the platform firmware switches the CPU to the platform firmware CPU operating mode; it could be real mode, “voodoo” mode, or flat protected mode, depending on the platform firmware. X86/x64 CPU resets in a modified real mode operating mode, i.e., real mode at physical address FFFF_FFF0h. Therefore, if the platform firmware CPU operating mode is flat protected mode, it must switch the CPU into that mode. Present-day platform firmware doesn’t use “voodoo” mode as extensively as in the past. In fact, most present-day platform firmware has abandoned its use altogether. For example, UEFI implementations use flat protected mode. 然后进行CPU(区别于BIOS)运行模式的初始化
- Preparation for memory initialization. In this stage there are usually three steps carried out by the platform firmware code:接着是内存空间初始化,具体分为三个步骤
- CPU microcode update. In this step the platform firmware loads the CPU microcode update to the CPU. CPU microcode更新。
- CPU-specific initialization. 跟CPU相关的一些初始化。In x86/x64 CPUs since (at least) the Pentium III and AMD Athlon era, part of the code in this stage usually sets up a temporary stack known as cache-as-RAM (CAR), i.e., the CPU cache acts as temporary (writeable) RAM because at this point of execution there is no writable memory—the RAM hasn’t been initialized yet. Complex code in the platform firmware requires the use of a stack. In old BIOS, there is some sort of assembler macro trick for return address handling because by default the return address from a function call in x86/x64 is stored in a “read only” stack, but no writeable memory variable can be used. However, this old trick is not needed anymore, because all present-day CPUs support CAR. If you want to know more about CAR, you can consult the BIOS and Kernel Developer Guide (BKDG) for AMD Family 10h over at http://support.amd.com/us/Processor_TechDocs/31116.pdf. Section 2.3.3 of that document explains how to use the CPU L2 cache as general storage on boot. CAR is required because main memory (RAM) initialization is a complex task and requires the use of complex code as well. The presence of CAR is an invaluable help here. Aside from CAR setup, certain CPUs need to initialize some of its machine-specific registers (MSRs); the initialization is usually carried out in this step.
- Chipset initialization. 芯片组的初始化。In this step the chipset registers are initialized, particularly the chipset base address register (BAR). We’ll have a look deeper into BAR later. For the time being, it’s sufficient that you know BAR controls how the chip registers and memory (if the device has its own memory) are mapped to the system address map. In some chipsets, there is a watch dog timer that must be disabled before memory initialization because it could randomly reset the system. In that case, disabling the watch dog timer is carried out in this step.
- Main memory (RAM) initialization.主内存(RAM)的初始化。 In this step, the memory controller initialization happens. In the past, the memory controller was part of the chipset. Today, that’s no longer the case. The memory controller today is integrated into the CPU. The memory controller initialization and RAM initialization happens together as complementary code, because the platform firmware code must figure out the correct parameters supported by both the memory controller and the RAM modules installed on the system and then initialize both of the components into the “correct” setup.
- Post memory initialization. 后续的一些初始化。Before this step, the platform firmware code is executed from the flash ROM in the motherboard—and if CAR is enabled, the CPU cache acts as the stack. That’s painfully slow compared to “ordinary” code execution in RAM, especially with instructions fetched into the CPU, because the flash ROM is very slow compared to RAM. Therefore, the platform firmware binary usually copies itself to RAM in this step and continues execution there. In the previous step, the main memory (RAM) is initialized. However, there are several more steps required before the main memory (RAM) can be used to execute the platform firmware code:
- Memory test. 内存测试。This is a test performed to make sure RAM is ready to be used because it’s possible that some parts of the RAM are broken. The detail of how the test is carried out depends on the boot time requirement of the system. If the boot time requirement is very fast, in many cases it’s impossible to test all parts of the RAM and only some parts can be tested with some sort of statistical approach on which parts to test to make sure the test covers as wide parts as possible (statistically speaking).
- “Shadowing” the firmware to RAM. 影射firmware到RAM。 “Shadowing” in this context means copying the RAM from the flash ROM to the RAM at address range below the 1MB limit—1 mb is the old 20-bit address mapping limit set for DOS-era hardware. However, the copying is not a trivial copy, because the code will reside in the RAM but in the same address range previously occupied by the flash ROM—this is why it’s called “shadowing.” Some bit twiddling must be done on the chipset by the platform firmware code to control the mapping of the address range to the RAM and the flash ROM. Details of the “bit twiddling” are outside the scope of this article. You can read details of the mapping in the respective chipset datasheet.
- Redirecting memory transaction to the correct target. 将内存重定向到正确的目标上。This is a continuation of the “shadowing” step. The details depends on the platform (CPU and chipset combination), and the runtime setup, i.e., whether to shadow the platform firmware or not at runtime (when the OS runs).
- Setting up the stack. 设置堆栈。This step sets up the stack (in RAM) to be used for further platform firmware code execution. In previous steps, the stack is assumed to be present in the CAR. In this step, the stack is switched from CAR to RAM because the RAM is ready to be used. This is important because the space for stack in CAR is limited compared to RAM.
- Transferring platform firmware execution to RAM. 将固件代码放到RAM上执行。 This is a “jump” to the platform firmware code which is “shadowed” to the RAM in step b.
- Miscellaneous platform enabling. 平台相关的各种的使能。This step depends on the specific system configuration, i.e., the motherboard and supporting chips. Usually, it consists of clock generator chip initialization, to run the platform at the intended speed, and in some platforms this step also consists of initializing the general purpose I/O (GPIO) registers.
- Interrupt enabling. 中断使能。 Previous steps assume that the interrupt is not yet enabled because all of the interrupt hardware is not yet configured. In this step the interrupt hardware such as the interrupt controller(s) and the associated interrupt handler software are initialized. There are several possible interrupt controller hardware in x86/x64, i.e., the 8259 programmable interrupt controller (PIC), the local advanced programmable interrupt controller (LAPIC) present in most CPUs today, and the I/O advanced programmable interrupt controller (IOxAPIC) present in most chipsets today. After the hardware and software required to handle the interrupt are ready, the interrupt is enabled.
- Timer initialization. 时钟初始化。 In this step, the hardware timer is enabled. The timer generates timer interrupt when certain interval is reached. OS and some applications running on top of the OS use the timer to work. There are also several possible pieces of hardware (or some combination) that could act as the timer in x86/x64 platform, i.e., the 8254 programmable interrupt timer (PIT) chip that resides in the chipset, the high precision event timer (HPET) also residing in the chipset—this timer doesn’t need initialization and is used only by the OS, real time clock (RTC) which also resides in the chipset, and the local APIC (LAPIC) timer present in the CPU.
- Memory caching control initialization. 内存缓存机制初始化。 X86/x64 CPU contains memory type range registers (MTRRs) that controls the caching of all memory ranges addressable by the CPU. The caching of the memory ranges depends on the type of hardware present in the respective memory range and it must be initialized accordingly. For example, the memory range(s) occupied by I/O devices such as the PCI bus must be initialized as uncached address range(s)—memory range(s) in this context is as seen from the CPU point of view.
- Application processor(s) initialization. 应用程序处理进程初始化。The non-bootstrap CPU (processor) core is called the application processor (AP) in some documentation; we will use the same naming here. In multicore x86/x64 CPUs, only the BSP is active upon reset. Therefore, the other cores—the AP—must be initialized accordingly before the OS boot-loader takes control of the system. One of the most important things to initialize in the AP is the MTRRs. The MTRRs must be consistent in all CPU cores, otherwise memory read and write could misbehave and bring the system to a halt.
- “Simple” I/O devices initialization. “Simple”IO设备的初始化。“Simple” IO devices in this context are hardware such as super IO (SIO), embedded controller, etc. This initialization depends on the system configuration. The SIO typically controls legacy IO, such as PS/2 and serial interfaces, etc. The embedded controller is mostly found on laptops, it controls things such as buttons on the laptop, the interface from the laptop motherboard to the battery, etc.
- PCI device discovery and initialization. PCI设备的检测和初始化。In this step, PCI devices—by extension the PCIe devices and other devices connected to PCI-compatible bus—are detected and initialized. The devices detected in this step could be part of the chipset and/or other PCI devices in the system, either soldered to the motherboard or in the PCI/PCIe expansion slots. There are several resource assignments to the device happening in this step: IO space assignment, memory mapped IO (MMIO) space assignment, IRQ assignment (for devices that requires IRQ), and expansion ROM detection and execution. The assignment of memory or IO address space happens via the use of BAR. We’ll get into the detail in the PCI bus base address registers initialization section. USB devices initialization happens in this step as well because USB is a PCI bus-compatible protocol. Other non-legacy devices are initialized in this step as well, such as SATA, SPI, etc.
- OS boot-loader execution. OS bootload的执行。This is where the platform firmware hands over the execution to the OS boot-loader, such as GRUB or LILO in Linux or the Windows OS loader.
Now, the boot process carried out by the platform firmware should be clear to you. Particularly the steps where the system address map is initialized in relation to PCI devices, namely step 3c and step 12. All of these steps deal with the BAR in the PCI chip or part of the chipset.
正所谓
正本逐源,知根知本,方得解脱。
The Boot Process at a Glance x86/x64系统启动过程解析的更多相关文章
- System Address Map Initialization in x86/x64 Architecture Part 2: PCI Express-Based Systems
原文 http://resources.infosecinstitute.com/system-address-map-initialization-x86x64-architecture-pa ...
- The Kernel Boot Process.内核引导过程
原文标题:The Kernel Boot Process 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下.一来自己 ...
- 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY
转载自: 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY Navicat Premium(数据库管理工具 ...
- [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装
[原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...
- Ubuntu 16.04 启动错误 "a start job is running for hold until boot process finishes up"
老司机也差点翻船... 升级16.04的时候,将默认启动管理器(default display manager)选为gm3(gnome3)了(应该使用默认的lightgm)如果改成gm3,好像是nvi ...
- 关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别
相信对于很多刚接触打包程序的同志来说,关于x86,x64,Any CPU这三个项目平台,以及解决方案配置Debug和Release有什么区别?这个问题一定有许多的困惑,甚至不乏一些已经工作了很久的老程 ...
- SQL Server 2008 R2 Developer (x86, x64, ia64) – DVD (Chinese-Simplified)
http://blog.sina.com.cn/s/blog_4aedf6370101j9tz.html 1. SQL Server 2008 R2 Developer (x86, x64, ia64 ...
- VOL.2 IE6,7,8(windows vista/7 x86/x64 )单文件版三连发,欢迎大家分享
在上期 VOL.1 利用vmware ThinApp 制作非XP下可以运行的IE6 [无插件版](windows vista/7/8 x86/x64 )中,简要介绍了如何利用vmware Thina ...
- [Tool]利用Advanced Installer建立x86/x64在一起的安装程式
原文 [Tool]利用Advanced Installer建立x86/x64在一起的安装程式 之前使用InstallShield做安装程式时,如果要将程式放在Program Files的话,需要分别针 ...
随机推荐
- Python Django mysqlclient安装和使用
一.安装mysqlclient 网上看到很过通过命令:pip install mysqlclient 进行安装的教程,但是我却始终安装失败,遇到的错误千奇百怪,后来通过自己下载mysqlclient客 ...
- 谷歌浏览器调用activex控件方法
原文转自 https://jingyan.baidu.com/article/af9f5a2d0ebe5543140a4596.html activex是由微软开发,所以在支持上,目前原生态支持的只有 ...
- C#使用消息队列(MSMQ)
最近项目用到消息队列,找资料学习了下.把学习的结果 分享出来 首先说一下,消息队列 (MSMQ Microsoft Message Queuing)是MS提供的服务,也就是Windows操作系统的功能 ...
- Lucid Dream
Lucid Dream 作者:Lo Stigmergy链接:https://www.zhihu.com/question/21260829/answer/35733194 清醒状态下时意识和潜意识基本 ...
- MySQL中You can't specify target table '表名'('sn_app_label') for update in FROM clause错误解决办法
在有些时候有级联关系的数据放在了同一张表中,在写sql语句的时候可能会遇到这样的场景:我要插入两条数据,第一条是父节点,第二条是子节点,关联关系是父节点的自增长id:在写这样的sql语句时有可能就会出 ...
- J.U.C之AQS:阻塞和唤醒线程
此篇博客所有源码均来自JDK 1.8 在线程获取同步状态时如果获取失败,则加入CLH同步队列,通过通过自旋的方式不断获取同步状态,但是在自旋的过程中则需要判断当前线程是否需要阻塞,其主要方法在acqu ...
- HANA数据库无法停止
Symptom: 使用命令HDB stop多次,每次报错为timeout ----------------------- sdpadm@PRDDB01:/usr/sap/SDP/HDB66/prder ...
- Qt布局
常用的布局方法 1. 水平布局类 QHBoxLayout 2. 垂直布局类 QVBoxLayout 3. 网格布局类 QGridLayout QHBoxLayout 对象横向排列开 QVBoxLayo ...
- linux 安装mysql(rpm文件安装)
三 卸载旧版本的MySql (没有的话,则跳过此步骤) 1.查看旧版本MySql rpm -qa | grep mysql 将会列出旧版本MySql的组件列表,如: ...
- Linux命令——pr
参考:Linux命令——column 前言 接触这个命令的初衷是我想把一个很长的单列输出设置成多列输出,奈何column的分列输出机制太智障,直到我发现了pr 参数 pr -# 输出指定的列数. -t ...