百科问答小站 logo
百科问答小站 font logo



为什么把内核镜像放在u盘里,电脑(BIOS)加载失败? 第1页

  

user avatar   prettykernel 网友的相关建议: 
      

你是自己写的 32 位操作系统是吗 ?

你只要是 2010 年之后买的电脑,基本上都是 UEFI 方式启动的,MBR (boot sector) 根本就不会执行,boot sector 中只有数据部分是有用的。

以 linux 内核为例,x86 boot protocol 中明确讲了 boot sector 和 setup sectors 的布局。这两者位于内核压缩映像开头,主要用于 bootloader 和 linux kernel 之间交换数据。

启动方式大致如下:

系统上电,跳转到 reset vector (0xfffffff0,这是 x86 的规定),这里映射到 UEFI 映像末尾(UEFI 映像在一块 flash 芯片中,通过 SPI 总线连到 CPU),是一条 jmp 指令,跳转到 UEFI 开头执行,然后一路初始化到 64 位 long mode,然后 UEFI 加载 bootloader,例如 grub2。

注意,现在是 identity map,即物理地址等于虚拟地址。

grub2 调用 UEFI 提供的接口,加载 bzImage (/boot/vmlinuz) 到 0x100000 (1M),对应 startup_32/64,移动到合适位置,然后解压缩,跳转到解压缩后的 startup_32/64 (大于等于 16MB 且对齐到 CONFIG_PHYSICAL_ALIGN 的某个地址),继续执行。startup_32 和 startup_64 之间的偏移是固定的 512B。

如果你用虚拟机。那么默认是使用 BIOS 方式,当然可以执行 MBR 了。你把虚拟机启动方式改为 UEFI ,一样会重启。对于 linux,就是执行到 arch/x86/boot/header.S#L72,导致重启。该文件中的数据就是 boot sector 和 setup sectors,布局参考 Documentation/x86/boot.rst

我简单注释一下导致重启的代码 (arch/x86/boot/header.S 中的所有代码在 UEFI 引导方式下正常启动时都不会执行):

       bs_die:  # Allow the user to press a key, then reboot  xorw %ax, %ax  int $0x16  # Keyboard Service。输入 %ah = 0x00 表示从键盘读入字符,输出 %ah 为键盘扫描码,%al 为字符的 ASCII   int $0x19  # 将第一个扇区的内容载入 0000:7C00   # int 0x19 should never return. In case it does anyway, invoke the BIOS reset code...  ljmp $0xf000, $0xfff0    # 跳转到 UEFI 中的 0xfffffff0     

你之所以搞不清楚,是因为你不明白现代的 bootstrap 流程,你在网上找到的几乎所有资料都讲的是 BIOS 时代的事情(就是跳转到 0x7C00 那一套东西),UEFI 时代的启动流程细节基本没有。

在 UEFI+GPT(现代硬盘分区格式) 中,系统上电时,是 UEFI 加载 bootable device (硬盘/U盘) 中的 FAT32 格式的 EFI Part System 中的 bootx64.efi,该文件可以是由 grub2 等 bootloader 编译而来,也可以是开启 efi stub 机制的 linux 内核编译而来。而硬盘的前 32KB 根本没用,你在网上看到的什么 boot.img,core.img 之类的东西都是过时的 (都在硬盘前 32KB)。

UEFI 启动方式下,boot sector 并不是硬盘第一个扇区(MBR),而是内核映像 bzImage (/boot/vmlinuz) 的前 512 字节,后面紧跟着的几个 512 字节是 setup sectors (见前文),再后面是内核 ELF 文件 vmlinux 压缩后的产物。

UEFI 是一个很大的话题,我就不展开了 (以后有时间补)。总之,你不用纠结这个问题,继续用 BIOS 方式即可。学习操作系统编写时,引导加载流程并不是重点,中断机制,内存管理,任务调度,等等才是。尤其 64 位和 32 位有较大的不同,细节资料基本都来自英文文档,需要花一些时间学习。




  

相关话题

  如何评价阿里云的第三代神龙架构? 
  页表是否包含着进程中所有的页? 
  请问如何区分c语言中float和double的用法? 
  为什么我用c++写的游戏那么简陋? 
  当你学会了什么之后感觉自己的编程算是入门了? 
  C++之父是谭浩强吗? 
  如果我发布了一款编程语言,后缀名是.c,那么这能算是一门新的编程语言吗? 
  相比其他语言,C、C++究竟快在哪里? 
  为什么现在国内各大高校仍选用谭浩强的《C 程序设计》为教材? 
  现在的编程语言越来越多,为什么 C 和 C++ 还没有被现在的时代淘汰呢? 

前一个讨论
什么是耳机智商税?
下一个讨论
为什么有些男人喜欢身材丰满的女生?





© 2024-06-26 - tinynew.org. All Rights Reserved.
© 2024-06-26 - tinynew.org. 保留所有权利