Windows 引导启动流程详述(BIOS-UEFI)

news2024/11/25 0:38:05

Windows 启动流程详述

  • BIOS 和 UEFI 的由来
    • BIOS 存在哪里
    • BIOS 程序的功能
    • BIOS 和 UEFI 的发展由来
    • 如何查看当前计算机是什么方式引导启动呢?
    • Linux 下如何查看 BIOS 大小?
  • 启动流程详述
    • 使用 BIOS 进行系统启动流程
    • 使用 UEFI 进行系统启动流程
      • SEC阶段
      • PEI阶段
      • DXE阶段
      • BDS阶段
      • TSL阶段
      • RT阶段
      • AL阶段
  • 总结
  • 参考文献


BIOS 和 UEFI 的由来

BIOS 存在哪里

上个世纪70年代初,“只读内存”(read-only memory,缩写为ROM)发明,开机程序被刷入ROM芯片,计算机通电后,第一件事就是读取它。

在这里插入图片描述
这块芯片里的程序叫做"基本輸出輸入系統"(Basic Input/Output System),简称为BIOS。

BIOS 程序的功能

存储在 ROM 芯片中的这一小段程序就是 BIOS 程序,虽然现在新出现的引导启动方式已经有了 UEFI 启动(或者 EFI 启动),但是其实 UEFI 或者 EFI 的一部分也是存储在这个芯片中。它们在计算机上电后的流程基本是一致的。上电后,硬件操作会将芯片中的程序读到内存中的固定位置,并赋值 PC 和 CS 固定的数值使得 CPU 能够从内存固定的位置去取值执行,从而开始最初的 BIOS 程序执行(这里的 BIOS 程序是指 BIOS 和 UEFI 的统称)。一直以来,我们都将计算机的引导启动程序称为 BIOS ,无论现在它还是否叫 BIOS 或者 UEFI ,我们还是习惯统称其为 BIOS。

BIOS 和 UEFI 的发展由来

最早的 BIOS 就是存放在计算机 ROM 中用于引导开机的一段程序代码(汇编代码)。其功能也很简单纯粹,计算机硬件自检、CMOS设置、寻找存放有操作系统的存储硬件、读取存储硬件的程序、引导操作系统启动、提供硬件 I/O 和硬件中断等基础功能。这些基础功能对于计算机上电后的运行是必不可少的一部分。(就像最简单的 51 单片机一样,最初上电后也需要执行一段最基本的寄存器初始化和内存代码读取的汇编指令)

虽然 BIOS 作为电脑加电启动所必不可少的部分,但是从其于 1975 年诞生之日起近 30 余年, 16 位汇编语言代码,1M 内存寻址,调用中断一条条执行的理念和方式竟然一点都没有改变,虽然经各大主板商不懈努力,BIOS 也有了 ACPI(Advanced Configuration Power Interface)一种基于BIOS 的系统电源管理方案 (是由BIOS实现)提供CPU和外设的电源管理功能;当空闲的时候会被OS调用提供CPU的电源管理。 、USB 设备支持,PnP 即插即用支持等新东西,但是这在根本上没有改变 BIOS 的本质,而 Intel 为了迁就这些旧技术,不得不在一代又一代处理器中保留着 16 位实模式(否则根本无法开机的)。但是,英特尔在 2001 年开发了全新的安腾处理器,采用 IA-64 架构,并推出了全新的 EFI。后来证明,安腾处理器、IA-64 架构没有推广开来,而 EFI 和后继的 UEFI 却发扬光大,成为现在电脑的主要预启动环境。

EFI,是 Extensible Firmware Interface 的词头缩写,直译过来就是可扩展固件接口,它是用模块化、高级语言(主要是 C 语言)构建的一个小型化系统,它和 BIOS 一样,主要在启动过程中完成硬件初始化,但它是直接利用加载 EFI 驱动的方式,识别系统硬件并完成硬件初始化,彻底摒弃读各种中断执行。EFI 驱动并不是直接面向 CPU 的代码,而是由 EFI 字节码编写成, EFI 字节码是专用于 EFI 的虚拟机器指令,需要在 EFI 驱动运行环境 DXE 下解释运行,这样 EFI 既可以实现通配,又提供了良好的兼容。此外,EFI 完全是 32 位或 64 位,摒弃 16 位实模式,在 EFI 中就可以实现处理器的最大寻址,因此可以在任何内存地址存放任何信息。另外,由于 EFI 的驱动开发非常简单,基于 EFI 的驱动模型原则上可以使 EFI 接触到所有硬件功能,在 EFI 上实现文件读写,网络浏览都是完全可能的。BIOS 上的的 CMOS 设置程序在 EFI 上是作为一个个 EFI 程序来执行的,硬件设置是硬件设置程序、而启动管理则是另一个程序,保存 CMOS 又是另一个程序,虽然它们在形式的 Shell 上是在一起的。

EFI 在功能上完全等同于一个轻量化的 OS(操作系统),但是 EFI 在制定时就定位到不足以成为专业 OS 的地位上,首先,它只是一个硬件和操作系统间的一个接口;其次,EFI 不提供中断访问机制,EFI 必须用轮询的方式检查并解释硬件,较 OS 下的驱动执行效率较低,最后,EFI 只有简单的存储器管理机制,在段保护模式下只将存储器分段,所有程序都可以存取任何一段位置,不提供真实的保护服务。

伴随着 EFI,一种全新的 GUID 磁盘分区系统(GPT)被引入支持,传统 MBR 磁盘只能存在 4 个主分区,只有在创建主分区不足 4 个时,可以建立一个扩展分区,再在其上建立被系统识别的逻辑分区,逻辑分区也是有数量的,太多的逻辑分区会严重影响系统启动,MBR硬盘分区最大仅支持2T容量,对于现在的大容量硬盘来说也是浪费。GPT 支持任意多的分区,每个分区大小原则上是无限制的,但实际上受到 OS 的规定限制不能做到无限,不过比 MBR 的 2T 限制是非常重要的进步。GPT 的分区类型由 GUID 表唯一指定,基本不可能出现重复,其中的 EFI 系统分区可以被 EFI 存取,用来存取部分驱动和应用程序,虽然这原则上会使 EFI 系统分区变得不安全,但是一般这里放置的都是些“边缘”数据,即使其被破坏,一般也不会造成严重后果,而且也能够简单的恢复回来。

当 EFI 发展到 1.1 的时候,Intel 决定把 EFI 公之于众,于是后续的 2.0 吸引了众多公司加入,EFI 也不再属于英特尔,而是属于了 Unified EFI Form 的国际组织,EFI 在 2.0 后也遂改称为 UEFIUEFI 其中的 EFI 和原来是一个意思,U 则是 Unified(一元化、统一)的缩写,所以 UEFI 的意思就是“统一的可扩展固件接口”,与前身 EFI 相比,UEFI 主要有以下改进:

  • 首先,UEFI 具有完整的图形驱动功能,之前的 EFI 虽然原则上加入了图形驱动,但为了保证 EFI 和 BIOS 的良好过渡,EFI 多数还是一种类 DOS 界面(仍然是 640480 VGA 分辨率),只支持 PS/2 键盘操作(极少数支持鼠标操作),不支持 USB 键盘和鼠标。到了 UEFI,则是拥有了完整的图形驱动,无论是 PS/2 还是 USB 键盘和鼠标,UEFI 一律是支持的,而且 UEFI 在显卡也支持 GOP VBIOS 的时候,显示的设置界面是显卡高分辨率按 640480或1024*768 显示,因此画面虽小但很清楚,但是这样会导致屏幕周围大片留黑,不过鱼和熊掌不可兼得,除非 UEFI 默认窗口大小也是最高分辨率。
  • 其次,UEFI 具有一个独特的功能,安全启动,而 EFI 是没有安全启动的,安全启动(Secure Boot),实际上通俗的解释是叫做固件验证。开启 UEFI 的安全启动后,主板会根据 TPM 芯片(或者 CPU 内置的 TPM )记录的硬件签名对各硬件判断,只有符合认证的硬件驱动才会被加载,而 Win8 以后的 Windows 则是在操作系统加载的过程中对硬件驱动继续查签名,符合 Windows 记录的硬件才能被 Windows 加载,这在一定程度上降低了启动型程序在操作系统启动前被预加载造成的风险,但是这也会造成系统安装变得垄断。

无论 EFI 还是 UEFI,都必须要有预加载环境、驱动执行环境、驱动程序等必要部分组成,为了支持部分旧设备(如在 UEFI 下挂载传统 MBR 硬盘,不支持 UEFI 启动的显卡在 UEFI 下仍然支持运行等),还需要一个 CSM 兼容性支持模块、EFI 或 UEFI 都是仅支持 GPT 磁盘引导系统的,后面的内容会具体谈一下 EFI 或 UEFI 启动计算机的过程。

从这里,我们就能发现,之前的 BIOS 引导启动需要配合 MBR 的传统磁盘分区进行,而后来者 UEFI 则是引导新的 GPT 磁盘分区进行启动。所以现在主流的启动流程可以简单概括如下两种:

  • BIOS + MBR
  • UEFI + GPT

如何查看当前计算机是什么方式引导启动呢?

在“此电脑”上右键选择“管理”,弹出“计算机管理”选择“磁盘管理”,如果能找到一个“EFI系统分区”,那么就是UEFI引导方式了。
在这里插入图片描述

Linux 下如何查看 BIOS 大小?

Linux 下可以查看 BIOS 大小通过 dmidecode 这个命令来查看。也就是读取 BIOS 的信息。

root@aliyun:~# dmidecode -t bios -q  # 方法一
BIOS Information
        Vendor: SeaBIOS
        Version: 8c24b4c
        Release Date: 04/01/2014
        Address: 0xE8000
        Runtime Size: 96 kB
        ROM Size: 64 kB --- ROM Size,在此可以看到,BIOS 大小为 64K。
        Characteristics:
                BIOS characteristics not supported
                Targeted content distribution is supported
        BIOS Revision: 0.0

root@aliyun:~# cd /sys/class/dmi/id/  # 方法二
root@aliyun:id# ls
bios_date          chassis_serial   modalias        product_serial   sys_vendor
bios_vendor        chassis_type     power           product_uuid     uevent
bios_version       chassis_vendor   product_family  product_version
chassis_asset_tag  chassis_version  product_name    subsystem

启动流程详述

前面,我们讲述了关于 BIOS 和 UEFI 的由来和基本作用。了解了它们在计算机启动过程中所需要发挥的作用后,下面就来详细看一下在计算机上电后它们具体是如何执行和操作来引导操作系统正常启动的。

使用 BIOS 进行系统启动流程

BIOS 用于计算机硬件自检、CMOS 设置、引导操作系统启动、提供硬件 I/O、硬件中断等4项主要功能,因此 BIOS 程序可以分为若干模块,主要有 Boot Block 引导模块、CMOS 设置模块、扩展配置数据(ESCD)模块、DMI 收集硬件数据模块,其中引导模块直接负责执行 BIOS 程序本身入口、计算机基本硬件的检测和初始化,ESCD 用于 BIOS 与 OS 交换硬件配置数据,DMI 则充当了硬件管理工具和系统层之间接口的角色,通过 DMI,用户可以直观地获得硬件的任何信息,CMOS 设置模块就是实现对硬件信息进行设置,并保存在 CMOS 中,是除了启动初始化以外 BIOS 程序最常用的功能。

BIOS 本身是汇编语言代码,是在 16 位实模式下调用 INT 13H 中断执行的,由于 x86-64 是一个高度兼容的指令集,也为了迁就BIOS的16位实模式的运行环境,所以即使现在的 CPU 都已是 64 位,如果还是在 BIOS 启动(基本见于 09 年以前的主板),在开机时仍然都是在 16 位实模式下执行的。16 位实模式直接能访问的内存只有 1MB,就算你安了 4G、8G 或者 16G 还是 32G 内存,到了 BIOS 上一律只先认前 1MB。在这 1MB 内存中,前 640K 称为基本内存,后面 384K 内存留给开机必要硬件和各类 BIOS 本身使用,具体如下图所示:

在这里插入图片描述

  1. 如上图所示,当按下 power on 之后,此时的 CPU 处于 real address mode。由硬件负责将 BIOS 64K 的内容加载到 0xF00000xFFFFF(64K 内存)。并将 CS(code segment) 置为 0xF000,IP(instruction pointer) 置为 0xFFF0。组合起来的内存地址 PC 就是 0xFFFF0
  2. 此时 CPU 从 PC = 0xFFFF0 处开始取指、执行。那么从 0xFFFF00xFFFFF 只有 16Bytes。空间太小了,能放啥呢?但是可以跳到其他地方去执行啊。不错,这里存放的有一条指令是 jmp far f000:e05b, 组合起来就是 0xfe05b。注意这个地址可是在 0xF00000xFFFFF 范围之内,也就是这条指令跳转到 BIOS 内部的代码去执行。从 0xFE05B0xFFFF0 将近 8K 内存,代码不少。
  3. 此时 CPU 从 PC = 0xfe05b 开始取值、执行。具体干啥呢?就是执行所谓的开机自检。检查计算机硬件。同时去找启动扇区,那什么才是启动扇区呢?若 0 盘 0 道 1 扇区最后两个字节分别是 0x55,0xaa,那就是启动区。很像 java class 文件中的魔数,就是标记一下。同时将找到的启动扇区(512Bytes) 复制到内存 0x7C000x7DFF(512Bytes) 处。最后会将 CS 置为 0x0000, IP 置为 0x7C00,组合起来就是 0x7C00
  4. 此时 CPU 从 PC = 0x7C00 开始取值、执行。具体干啥呢?这就是开发人员可以决定的了。在启动扇区上可以是加载 OS Kernel 的代码,硬盘分区,boot loader 等。

将上述细节流程进行概括如下:

  1. 上电并稳定后,CPU执行地址 0xFFFF0H 处指令,此处为BIOS程序;

  2. BIOS 进行硬件自检,没有问题后加载硬盘的第一个扇区到内存0x7c00H 处,第一个扇区为 MBR(Master
    Boot Record),MBR 包含执行程序和分区表;

  3. CPU 开始执行 MBR 程序,查找第一个活动分区,把活动分区的第一个扇区加载到内存中,活动分区第一个扇区为 PBR(Partition Boot Record);

  4. CPU 开始执行 PBR,第一个指令就是跳过 BPB(BIOS Parameter Block)到可执行代码处;BPB 包含比较多参数,有族的大小、MFT 记录大小、MFT 位置等,用于读取 NTFS 文件;

  5. PBR 读取 VBR(Volume BootRecord,占用分区开始的16扇区)剩余的 15 扇区到内存中;接着 CPU 跳转到 0x07C0:027A 处,执行 BOOTMGR 代码(第二个扇区中);

  6. 开始寻找 bootmgr.exe,找不到则寻找 ntldr.exe(win vista之前的系统);

  7. CPU 加载并跳转到 bootmgr.exe 处执行,读取 BCD 文件,如果含有多个系统,则列举显示供用户选择;

  8. 选择的是 Windows 则读取 winload.exe 文件到内存中,CPU 跳转到winload.exe 处执行,读取文件 \windows\bootstat.dat,有需要则显示引导菜单,比如安全引导等等;接着加载内核程序 Ntoskrnl.exe,相关辅助 HAL.dll、CI.dll、PSSHED.dll、BootVID.dll,把 CPU 执行权交给内核程序;

  9. 内核程序执行系统初始化。

在这里插入图片描述

使用 UEFI 进行系统启动流程

前面已经介绍了 UEFI 的由来,所以相比 BIOS 来说 UEFI 会在扩展性、易用性等等方面有很大的改进。下面就来详细讲述 UEFI 的启动执行流程。

一般地,预加载环境和驱动执行环境是存储在 UEFI(UEFI BIOS)芯片中的,当打开电源开关时,电脑的主要部件都开始有了供电,与 BIOS 不同的是,UEFI 预加载环境首先开始执行,负责 CPU 和内存(是全部容量)的初始化工作,这里如出现重要问题,电脑即使有报警喇叭也不会响,因为 UEFI 没有去驱动8255发声,不过预加载环境只检查 CPU 和内存,如果这两个主要硬件出问题,屏幕没显示可以立即确定,另外一些主板会有提供 LED 提示,可根据 CPU 或内存亮灯大致判断故障。

CPU 和内存初始化成功后,驱动执行环境(DXE)载入,当 DXE 载入后,UEFI 就具有了枚举并加载 UEFI 驱动程序的能力,在此阶段,UEFI 会枚举搜索各个硬件的 UEFI 驱动并相继加载,完成硬件初始化工作,这相比 BIOS 的读中断加载速度会快的多,同样如加载显卡的 UEFI 驱动成功,电脑也会出现启动画面,硬件驱动全部加载完毕后,最后同 BIOS 一样,也得去启动操作系统。

在启动操作系统的阶段,同样是根据启动记录的启动顺序,转到相应设备(仅限 GPT 设备,如果启动传统 MBR 设备,则需要打开 CSM 支持)的引导记录,引导操作系统并进入,这里需要注意的是,UEFI 在检测到无任何操作系统启动设备时,会直接进入 UEFI 设置页面,而不是像 BIOS 那样黑屏显示相关信息。

  1. 按下电源键,电源向主板以及其它设备供电,刚开始电压不稳,主板会持续发送 RESET 信号给 CPU,CPU 执行初始化。当电压稳定后,主板停止发送 RESET 信号,CPU 开始执行指令;

  2. CPU 读取 UEFI 指令,执行 UEFI 初始化,执行其它设备的初始化;

  3. 查找 EFI 分区,EFI 分区不需要一定是第一个分区;

  4. 加载 \EFI\Boot\bootx64.efi,在安装 Windows 时实际上会使用\EFI\Microsoft\Boot\bootmgfw.efi 的内容替换到 \EFI\Boot\bootx64.efi,所以\EFI\Boot\bootx64.efi 其实就是 \EFI\Microsoft\Boot\bootmgfw.efi

  5. bootmgfw.efi 会读取 BCD 文件,BCD 是一个数据库文件,如果包含多个系统,信息会包含在 BCD 中,通过显示一个系统列表供用户选择;

  6. BCD 中包含每个系统的引导文件的路径,Windows 的是\Windows\System32\winload.efi,加载到内存中并执行;

  7. winload.efi 读取 \Windows\bootstat.dat 文件,有需要则显示引导菜单,比如安全引导等等;接着加载内核程序 Ntoskrnl.exe,相关辅助HAL.dll、CI.dll、PSSHED.dll、BootVID.dll,把 CPU 执行权交给内核程序;

  8. 内核程序执行系统初始化。

在这里插入图片描述

从 Intel 官方的资料,可以详细讲 UEFI 的执行流程概括成如下七个阶段:

  • SEC(安全验证)->
  • PEI(EFI前期初始化)->
  • DXE(驱动执行环境)->
  • BDS(启动设备选择)->
  • TSL(操作系统加载前期)->
  • RT(系统系统运行阶段)->
  • AL(系统灾难恢复期或关机)

如下图所示:

在这里插入图片描述

详细说明 UEFI 这七个阶段如下:

SEC阶段

作为计算机上电后第一阶段,SEC会做一些与硬件相关的验证,并且将控制权交给PEI Foundation。(注:IA-32和Itanium会有差别)

SEC阶段主要功能:

处理平台启动及重启信号
创建临时存储区域
作为可信系统的根
传递参数给下一阶段(既PEI Foundation)
1、处理平台启动机重启信号:

系统上电信号处理,系统重启信号处理,系统异常信号处理。

2、创建临时存储区域:

SEC阶段需要初始化一些临时内存(这时各种外设及内存并没有被初始化),作为程序的运行载体,仅对CPU和CPU内部Cache作为临时RAM,区别于普通的内存,我们称它为CAR(Cache As RAM)。因为内存并没有初始化,需要将Cache配置成为no-eviction,当read/write miss时候并不会向内存发出miss事件,如果这时向内存发出miss事件会导致平台故障。

3、作为可信系统的根

任何安全设计中,后续模块获得控制的完整性,由调用者证实必须有根,既SEC阶段作为整个可信系统的根。

4、传递参数给下一阶段(既PEI Foundation)

SEC阶段需要为PEI阶段做准备,最终SEC需要把控制权交给PEI。

需要准备如下信息给 PEI Foundation:

  • 当前的系统状态,PEI可以根据这些状态判断系统的健康状况。(注:IA-32和Itanium会有差别)
  • BFV(Boot Firmware Volume)的地址和大小
  • 临时RAM的地址和大小
  • 栈的地址和大小
  • EFI_SEC_HOB_DATA_PPI这个HOB(Optional)

PEI阶段

PEI阶段资源依然十分有限,PEI后期才会初始化内存,主要功能就是初始化一些硬件设备,并且给DXE准备执行环境,通过HOB传递给DXE Foundation,最终将控制权交给DXE Foundation。

初始化内存
准备memory相关的HOB
准备FV相关的HOB
控制权交给DXE Foundation
PEI阶段主要由PEI Foundation、PEIM Dispatcher来处理上述操作。

PEI Foundation:负责初始化gPeiServices和流程执行
PEI Dispatcher:找出系统中所有的PEIM,并根据PEIM之间的依赖关系按顺序执行PEIM,其中CPU/Memory初始化都是由特定的PEIM来完成的,其中DxeIpl来Load DxeCore。

PEI阶段流程

在这里插入图片描述

DXE阶段

这一阶段,内存已经完全可以使用了,这个阶段进行大量的工作,主要是提供:

  • DXE Foundation:负责初始化一系列服务如BootServices/RuntimeServices/DxeServices,和安装一些ConfigurationTable。
  • DXE Dispatcher:负责分发DXE Drivers,包括MM Drivers也是在这个阶段共同分发。
  • DXE Drivers:负责初始化一些Protocol及安装Binding Driver为后续使用。

BDS阶段

BDS阶段理论上也是DXE阶段的一部分,主要负责执行可启动策略,主要包括:

  • 初始化控制台设备
  • 为设备加载相关的驱动,由Binding Driver来决定怎么加载。
  • 为BIOS Setup做准备。
  • 根据系统设置加载和启动可启动选项。

TSL阶段

由 BDS 阶段 LoadImage 并 StartImage 的 grub 镜像。

这一阶段由 grub 执行,资源由 UEFI kernel 提供,当 grub 调用 ExitBootServices 后就进入系统 Runtime 阶段。

RT阶段

这阶段控制权完全交给了 OS,保留 RuntimeServices 交给 OS 使用, MM Mode 脱离于 OS 独立运行。

AL阶段

在 RT 阶段,如果遇到灾难性错误,固件提供错误处理机制和灾难恢复机制,UEFI/PI Spec 都未定义该阶段的行为。

总结

综上对 BIOS 和 UEFI 启动计算机过程的叙述,可以概括为:

  • BIOS 先要对 CPU 初始化,然后跳转到 BIOS 启动处进行 POST 自检,此过程如有严重错误,则电脑会用不同的报警声音提醒,接下来采用读中断的方式加载各种硬件,完成硬件初始化后进入操作系统启动过程;
  • UEFI 则是运行预加载环境先直接初始化 CPU 和内存,CPU 和内存若有问题则直接黑屏,其后启动 PXE 采用枚举方式搜索各种硬件并加载驱动,完成硬件初始化,之后同样进入操作系统启动过程。

此外,BIOS 是 16 位汇编语言程序,只能运行在 16 位实模式,可访问的内存只有 1MB,而 UEFI 是 32 位或 64 位高级语言程序(C 语言程序),突破实模式限制,可以达到要求的最大寻址。

参考文献

Intel 资料:

  • https://edc.intel.com/content/www/us/en/design/products-and-solutions/software-and-services/firmware-and-bios/firmware-interface-table/
  • https://www.intel.cn/content/www/cn/zh/developer/articles/tool/unified-extensible-firmware-interface.html?wapkw=UEFI

知乎资料:

  • https://zhuanlan.zhihu.com/p/483888207
  • https://zhuanlan.zhihu.com/p/342088326
  • https://zhuanlan.zhihu.com/p/54108702
  • https://zhuanlan.zhihu.com/p/283054574
  • https://zhuanlan.zhihu.com/p/36976698#:~:text=1%20BIOS%E5%8A%A0%E7%94%B5%E8%87%AA%E6%A3%80%EF%BC%88Power%20On%20Self%20Test%20–%20POST%EF%BC%89%E3%80%82%202,%E6%A3%80%E6%9F%A5MBR%E7%9A%84%E7%BB%93%E6%9D%9F%E6%A0%87%E5%BF%97%E4%BD%8D%E6%98%AF%E5%90%A6%E7%AD%89%E4%BA%8E55AAH%EF%BC%8C%E8%8B%A5%E4%B8%8D%E7%AD%89%E4%BA%8E%E5%88%99%E8%BD%AC%E5%8E%BB%E5%B0%9D%E8%AF%95%E5%85%B6%E4%BB%96%E5%90%AF%E5%8A%A8%E8%AE%BE%E5%A4%87%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%B2%A1%E6%9C%89%E5%90%AF%E5%8A%A8%E8%AE%BE%E5%A4%87%E6%BB%A1%E8%B6%B3%E8%A6%81%E6%B1%82%E5%88%99%E6%98%BE%E7%A4%BA%22NO%20ROM%20BASIC%22%E7%84%B6%E5%90%8E%E6%AD%BB%E6%9C%BA%E3%80%82%20%E5%BD%93%E6%A3%80%E6%B5%8B%E5%88%B0%E6%9C%89%E5%90%AF%E5%8A%A8%E8%AE%BE%E5%A4%87%E6%BB%A1%E8%B6%B3%E8%A6%81%E6%B1%82%E5%90%8E%EF%BC%8CBIOS%E5%B0%86%E6%8E%A7%E5%88%B6%E6%9D%83%E4%BA%A4%E7%BB%99%E7%9B%B8%E5%BA%94%E5%90%AF%E5%8A%A8%E8%AE%BE%E5%A4%87%E7%9A%84MBR%E3%80%82%203%20%E6%A0%B9%E6%8D%AEMBR%E4%B8%AD%E7%9A%84%E5%BC%95%E5%AF%BC%E4%BB%A3%E7%A0%81%E5%90%AF%E5%8A%A8%20%E5%BC%95%E5%AF%BC%E7%A8%8B%E5%BA%8F%20%E3%80%82

w3school 资料:

  • https://www.w3cschool.cn/bioswqsc/zuxjo6.html

CSDN 资料:

  • https://blog.csdn.net/power_to_go/article/details/106645417#:~:text=x86%20%E6%9E%B6%E6%9E%84%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%201%20%E5%A6%82%E4%B8%8A%E5%9B%BE%E6%89%80%E7%A4%BA%EF%BC%8C%E5%BD%93%E6%8C%89%E4%B8%8B%20power%20on%20%E4%B9%8B%E5%90%8E%EF%BC%8C%E6%AD%A4%E6%97%B6%E7%9A%84%20CPU,%E4%BB%8E%20PC%20%3D%200x7C00%20%E5%BC%80%E5%A7%8B%E5%8F%96%E5%80%BC%E3%80%81%E6%89%A7%E8%A1%8C%E3%80%82%20%E5%85%B7%E4%BD%93%E5%B9%B2%E5%95%A5%E5%91%A2%EF%BC%9F%20%E8%BF%99%E5%B0%B1%E6%98%AF%E5%BC%80%E5%8F%91%E4%BA%BA%E5%91%98%E5%8F%AF%E4%BB%A5%E5%86%B3%E5%AE%9A%E7%9A%84%E4%BA%86%E3%80%82%20

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/701811.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

专项练习15

目录 一、选择题 1、如果要打开名为 “window2"的新窗口,可以通过() 2、下列事件哪个不是由鼠标触发的事件() 3、Angular指令中哪种作用域可以继承父scope 4、下列哪些事件不支持冒泡?()…

微信小程序学习记录2 案例分享<智能家居UI>

效果 思路 页面分为4块 前三块 采用同样的class 替换三张矢量图 绑定三个单片机返回的JSON值 最后一块又分为左右两部分 左边部分 采用switch组件 绑定三个事件 右边部分则是普通的文字

记录生产mysql死锁解决过程

最近生产上每个星期都会有几次死锁告警异常,今天终于给处理了,待后续观察,记录下整个过程。 环境:springboot、mybatis、mysql(RC隔离级别) 表结构: CREATE TABLE table1 (id bigint NOT NULL AUTO_INCREMENT,prize…

ASP.NET Core MVC 从入门到精通系列文章(完)

随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生&#xff0c…

redis高可用与持久化

文章目录 一、Redis 高可用1. 概念2. 高可用技术以及作用2.1 持久化2.2 主从复制2.3 哨兵2.4 集群 二、Redis 持久化1. 持久化的功能2. Redis 持久化方式 三、RDB 持久化1. 概述2. 触发条件2.1 手动触发2.2 自动触发2.3 其他自动发机制 3. 执行流程4. 启动时加载 四、AOF 持久化…

自动驾驶货车编队行驶-车辆通讯应用层数据交互要求

1 范围 本文件规定了合作式自动驾驶货车编队行驶时车辆通信应用层数据交互的通信系统架构、通用要求、 数据交互要求、消息层数据集定义等。本文件仅涉及编队成员内部进行编队控制及成员管理相关的车-车通 信交互,不涉及编队与其他实体(云平台、路侧单元…

关于jetBrains的插件translation的使用

文章目录 前言国内使用问题关于无法翻译问题关于无法语音解析问题关于百度翻译Api获取关于百度引擎的invalid account(未解决)关于阿里翻译Api获取关于阿里翻译引擎Wrong request parameter(未解决)有道翻译Api关于有道Ip Address错误(未解决) 前言 translation是一个非常好用…

chatgpt赋能python:Python长浮点型介绍

Python长浮点型介绍 Python是一种强大的编程语言,通过其众多的数据类型,使开发人员可以快速开发复杂的应用程序。其中,Python长浮点型就是Python支持的一种数据类型。长浮点型是指Python可以处理的浮点数的精度可以高达256位。 Python长浮点…

大像素全景,如何让自己的VR全景变得具有高级感?

一个成功的VR全景作品,如果想要在商业领域上获得一定影响力,那么VR全景本身的质量就是关键,如何让自己的VR全景变得具有高级感呢? 从艺术表达手法上,航拍是对VR全景很好的诠释,通过VR全景航拍,人…

Redis进阶 - Redis分片集群

原文首更地址,阅读效果更佳! Redis进阶 - Redis分片集群 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-advance-sharded-cluster.html 搭建分片集群 主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决&a…

ROS自带OpenCV和本地OpenCV版本冲突问题解决

1、报错信息 首先catkin_make编译功能包没有任何问题,100%生成目标文件,但是报了警告:库文件libmyslam.so需要的是libopencv_core.so.3.4,可能会与libopencv_core.so.3.2冲突。根据工程经验,警告不用管,直…

《设计模式》中介者模式

《设计模式》中介者模式 定义: 中介者模式又称为调停者模式,用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其可以松散耦合,独立地改变它们之间的交互。属于行为型设计模式。 中介者…

前端解析后台返回得文件流导出得 pdf为空

封装的方法 download(res, type, filename) {// 创建blob对象,解析流数据const blob new Blob([res.data], {// 如果后端没返回下载文件类型,则需要手动设置:type: application/pdf;chartsetUTF-8 表示下载文档为pdf,如果是word则…

2023上半年软考系统分析师科目一整理-13

2023上半年软考系统分析师科目一整理-13 给定关系模式 R < U &#xff0c;F >&#xff0c; U {A&#xff0c;B&#xff0c;C&#xff0c;D &#xff0c;E} &#xff0c; F {B→A &#xff0c;D→A &#xff0c;A→E &#xff0c;AC→B }&#xff0c;则 R 的候选关键字为…

2023上半年软考系统分析师科目一整理-11

2023上半年软考系统分析师科目一整理-11 给定关系R(A,B,C,D,E) 和关系S(D,E,F,G&#xff09;&#xff0c;对其进行自然连接运算R ▷◁S后其结果集的属性列为( B )。 A. R.A, R.B, R.C, R.D, R.E, S.D, S.E B. R.A, R.B, R.C, R.D, R.E, S.F, S.G C. R.A, R.B, R.C, R.D, R.E,…

爬虫---某翻译响应解密和sign逆向

目标网址接口&#xff1a;aHR0cHM6Ly9kaWN0LnlvdWRhby5jb20vd2VidHJhbnNsYXRl 仅供学习交流使用&#xff0c;非商业用途&#xff0c;如有侵权&#xff0c;请联系删除!!!仅供学习交流使用&#xff0c;非商业用途&#xff0c;如有侵权&#xff0c;请联系删除!!!仅供学习交流使用&…

软件测试技能,JMeter压力测试教程,设置集合点(十七)

一、前言 LoadRunner 中可以设置一个集合点&#xff0c;设置多个虚拟用户等待到一个时间点&#xff0c;到齐后一起发请求达到并发的目的 jmeter 中使用 同步定时器 Synchronizing Timer实现 LoadRunner 中集合点的功能&#xff0c;模拟多用户并发测试&#xff0c;即多个线程在…

K折交叉验证

目的 模型在一套训练集和数据集上表现优秀&#xff0c;不能说明问题&#xff0c;只有在众多不同的训练集和测试集上表现都优秀&#xff0c;模型才具有真正的泛化能力。 通过交叉验证&#xff0c;验证模型的泛化能力&#xff0c;帮助我们认识模型。 常用方法之K折交叉验证 分…

一步一步学OAK之六:通过OAK相机实现特征检测

目录 特征检测Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 创建pipelineSetup 5: 创建节点创建相机节点创建特征检测节点创建数据交互的节点 Setup 6:设置相关属性设置相机的相关属性设置特征检测器的初始配置 Setup 7: 建立链接关系建立相机和特征跟踪器…

iOS 16 版本适配

1、iOS 16 真机调试时需要在设备的设置 —> 隐私与安全 —> 开发者模式 中打开开发者模式。 2、隐私权限增强&#xff0c;如通过 UIDevice 获取设备名称时&#xff0c;无法获取用户的信息&#xff0c;只能获取设备对应的名称&#xff08;[UIDevice currentDevice].name返…