自制操作系统day3(.nas .sys .img)(引导区和启动区)(bios解释)(显卡模式)(保护模式和实模式)(键盘BIOS中断调用)等等(ai辅助整理)

day3

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


helloos e


解释.nas .sys .img,以及他们之间的关系

在操作系统开发中,这些文件类型有特定的作用和关系:

  1. .nas 文件 (NASK汇编源文件)
  • 这是使用NASK汇编器编写的汇编语言源代码文件
  • 包含低级硬件操作指令,如你提供的ipl.nas就是引导加载程序
  • 需要经过汇编器编译生成二进制文件
  1. .sys 文件 (系统文件)
  • 通常是操作系统的核心组件
  • 在你的Makefile中由haribote.nas编译生成haribote.sys
  • 包含操作系统的主要功能代码
  • 会被加载到内存中执行
  1. .img 文件 (磁盘映像文件)
  • 完整的磁盘镜像,模拟物理软盘/硬盘
  • 在你的项目中由ipl.binharibote.sys组合生成
  • 包含引导扇区(ipl)和操作系统核心(sys)
  • 可直接用于虚拟机或写入物理介质

它们的关系链:

ipl.nas → [编译] → ipl.bin → [组合]
                                     → haribote.img
haribote.nas → [编译] → haribote.sys → [组合]

在Makefile中体现为:


ipl.bin : ipl.nas Makefile
    $(NASK) ipl.nas ipl.bin ipl.lst

haribote.sys : haribote.nas Makefile
    $(NASK) haribote.nas haribote.sys haribote.lst

haribote.img : ipl.bin haribote.sys Makefile
    $(EDIMG) 指令组合生成img文件

简单说:.nas是源代码,.sys是编译后的系统核心,.img是包含引导程序和系统核心的完整磁盘映像。

代码存储顺序

在引导扇区被BIOS加载到内存0x7C00后,代码和数据在内存中的顺序如下:

  1. 内存布局顺序
0x7C00: JMP entry          ; 跳转指令(3字节)
0x7C03: DB 0x90            ; 填充字节(1字节)
0x7C04: "HARIBOTE"        ; 8字节OEM标识
0x7C0C: 引导扇区参数区     ; 从0x7C0C开始的FAT12 BPB(BIOS Parameter Block)数据结构
...
0x7C??: entry:             ; 实际引导代码开始处
...
0x7DFE: 0x55, 0xAA         ; 引导扇区结束标志

  1. 执行流程
  • BIOS加载512字节引导扇区到0x7C00
  • 从0x7C00处开始执行,第一条指令就是JMP entry
  • 跳转到entry:标签处执行实际引导代码
  1. 关键点
  • 前3字节必须是跳转指令或NOP+跳转
  • 0x7C03-0x7C0B是OEM标识区
  • 0x7C0C-0x7C35是标准FAT12 BPB结构
  • 引导代码从entry:标签开始
  • 最后2字节(0x7DFE-0x7DFF)必须是0x55AA

这种布局是FAT12文件系统引导扇区的标准要求,确保BIOS和操作系统都能正确识别。

这个文件

ipl是引导扇区的文件

haribote.nas 是最简单的操作系统

fin:

HLT

JMP fin

以上内容可以总结为:一般向一个空软盘保存文件时,

  1. 文件名会写在0x002600以后的地方;
  2. 文件的内容会写在0x004200以后的地方。

我们将操作系统本身的内容写到名为
haribote.sys文件中,再把它保存到磁盘映像里,然后我们从启动区执行这个
haribote.sys就行了。接下来我们就来做这件事

引导区和启动区

在操作系统开发中,引导区和启动区是两个关键概念,它们协同工作来完成系统启动过程:

  1. 引导区 (Boot Sector)
  • 位于磁盘的第一个扇区(512字节)
  • 包含BIOS加载的初始引导代码(如你的ipl.nas编译后的内容)
  • 必须以0x55 0xAA作为结束标志
  • 主要功能是加载并移交控制权给启动区
  1. 启动区 (Loader)
  • 通常位于磁盘的后续扇区
  • 包含更复杂的启动逻辑(如你的haribote.sys)
  • 负责:
    • 设置保护模式
    • 加载内核到内存
    • 初始化基本硬件
    • 最终跳转到内核入口

在你的代码中体现为:

; 引导区代码 (ipl.nas)
        ORG     0x7c00          ; BIOS加载引导区到0x7c00
        ; ... FAT12头信息 ...
entry:
        ; 初始化寄存器
        ; 读取启动区(haribote.sys)到内存0x8200
        ; 如果成功则跳转到0x8200执行

在Makefile中的构建关系:

ipl.bin : ipl.nas               # 编译引导区
haribote.sys : haribote.nas     # 编译启动区
haribote.img : ipl.bin haribote.sys  # 组合成完整镜像

典型启动流程:

  1. BIOS → 引导区(0x7c00)
  2. 引导区 → 启动区(0x8200)
  3. 启动区 → 内核

这种分离设计使得:

  • 引导区保持简单可靠(只做最基本加载)
  • 启动区可以实现复杂功能
  • 方便后续扩展和维护

org伪指令再度解释

ORG 指令在汇编语言中是一个非常重要的伪指令,它的作用是设置程序在内存中的加载地址。具体到你的代码:


       ORG     0x7c00          ; 程序加载到内存的地址(BIOS默认加载引导扇区到0x7c00)

关键点解释:

  1. 0x7c00 是BIOS固定将引导扇区加载到的内存地址
  2. 所有后续的标号(label)地址计算都会基于这个基地址
  3. 如果没有ORG指令:
    • 汇编器会假设程序从0x0000开始
    • 导致生成的实际内存地址错误

例如当你的代码中有:

entry:
    MOV AX,0

实际内存地址会是 0x7c00 + (entry的偏移量)

在引导程序开发中必须正确设置ORG,因为:

  • BIOS固定加载引导扇区到0x7c00
  • 所有跳转指令和内存访问都依赖正确的地址计算
  • 错误的ORG值会导致程序无法正确执行

bios解释

BIOS(Basic Input/Output System)是计算机启动时最先运行的固件程序,它负责硬件初始化和操作系统加载。以下是关键解释和常用功能:

BIOS核心作用

  1. 硬件检测(POST自检)
    • 检查CPU、内存、硬盘等关键硬件
    • 通过蜂鸣代码报告错误(如"一长两短"表示显卡故障)
  2. 引导加载
    • 读取磁盘第一个扇区(MBR/VBR)到内存0x7C00
    • 移交控制权给引导程序(如你的ipl.nas)
  3. 硬件抽象层
    • 提供标准化的硬件访问接口(通过中断调用)

常用BIOS中断(INT指令)

在你的代码中已使用的关键中断:

  1. 磁盘服务(INT 0x13)
MOV AH,0x02  ; 读扇区功能
MOV AL,1     ; 读取扇区数
MOV DL,0x00  ; 驱动器号(0x00=A:)
INT 0x13     ; 调用磁盘服务

  1. 视频服务(INT 0x10)

MOV AH,0x0E  ; 显示字符功能
MOV AL,'A'   ; 要显示的字符
INT 0x10     ; 调用视频服务

  1. 其他常用中断
  • INT 0x16 键盘服务
    • AH=0x00 读取键盘输入
  • INT 0x19 系统重启
  • INT 0x1A 实时时钟服务

现代替代方案

  1. UEFI(统一可扩展固件接口)
    • 更快的启动速度
    • 支持GPT分区和>2TB磁盘
    • 图形化配置界面
  2. Coreboot(开源固件)
    • 谷歌Chromebook采用
    • 启动速度极快(约1秒)

在你的操作系统中,BIOS中断是硬件控制的核心方式,后续开发可能会用到更多中断服务。

显卡模式

设定AH=0x00后,调用显卡BIOS的函数,这样就可以切换显示模式了。我们还可
以在支持网页(AT)BIOS里看看。
设置显卡模式(video mode)
AH=0x00;
AL=模式:(省略了一些不重要的画面模式)
0x03:16色字符模式,80 × 25
0x12:VGA 图形模式,640 × 480 × 4位彩色模式,独特的4面存储模式
0x13:VGA 图形模式,320 × 200 × 8位彩色模式,调色板模式
0x6a:扩展VGA 图形模式,800 × 600 × 4位彩色模式,独特的4面存储模式
(有的显卡不支持这个模式)
返回值:无

[VRAM]里保存的是0xa0000。在电脑的世界里,VRAM指的是显卡内存(video
RAM),也就是用来显示画面的内存。这一块内存当然可以像一般的内存一样存
储数据,但VRAM的功能不仅限于此,它的各个地址都对应着画面上的像素,可以
利用这一机制在画面上绘制出五彩缤纷的图案。
其实VRAM分布在内存分布图上好几个不同的地方。这是因为,不同画面模式的像
素数也不一样。当画面模式为〇×时使用这个VRAM;而画面模式为◇△时可能使
用那个VRAM,像这样,不同画面模式可以使用的内存也不一样。所以我们就预先
把要使用的VRAM地址保存在BOOT_INFO里以备后用。
这次VRAM的值是0xa0000。这个值又是从哪儿得来的呢?还是来看看我们每次都
参考的(AT)BIOS支持网页。在INT 0x10的说明的最后写着,这种画面模式
下“VRAM是0xa0000~0xaffff的64KB”。
另外,我们还把画面的像素数、颜色数,以及从BIOS取得的键盘信息都保存了起
来。保存位置是在内存0x0ff0附近。从内存分布图上看,这一块并没被使用,所以
应该没问题。

关于es和bios

MOV ES,AX 为什么要在这里设置es

在汇编代码中 MOV ES,AX 这条指令的作用是设置 ES (Extra Segment) 段寄存器的值。这里的具体原因和上下文相关:

  1. 前一条指令 MOV AX,0x0820 将 AX 设置为 0x0820
  2. 这里将 ES 设置为 0x0820 是为了指定后续磁盘读取操作的目标内存地址

在实模式下,内存访问使用"段:偏移"的寻址方式。这里设置 ES=0x0820 表示:

  • 磁盘读取的数据将被加载到内存地址 ES:BX = 0x0820:0x0000
  • 计算物理地址 = (ES << 4) + BX = 0x8200 + 0x0000 = 0x8200

选择 0x0820 这个值是因为:

  1. 引导扇区(0x7c00-0x7dff)已经被使用
  2. 0x8200 是引导程序之后的一个安全区域
  3. 这个位置不会覆盖BIOS数据区或其他关键内存区域

后续的磁盘读取操作(INT 0x13)将使用这个ES值作为目标内存段地址。

问题:这个不是附加段寄存器吗,读取不是默认ds吗

在x86实模式下,磁盘读取操作(INT 0x13, AH=0x02)使用的是ES:BX作为目标缓冲区地址,而不是DS段寄存器。这是BIOS磁盘服务的设计规范。

具体原因如下:

  1. BIOS的INT 0x13/AH=0x02(读磁盘)功能明确规定:
    • ES:BX 必须指向接收数据的缓冲区
    • 这是BIOS接口的硬性规定,不是由程序员决定的
  2. 在您的代码中:
        MOV     AX,0x0820       ; 设置目标内存地址ES:BX=0x0820:0x0000
        MOV     ES,AX           ; ES=0x0820
        MOV     BX,0            ; BX=0x0000
        ; ...
        INT     0x13            ; 调用BIOS磁盘服务,数据将被读到ES:BX(0x0820:0x0000)

  1. DS(数据段寄存器)通常用于普通的内存访问指令(如MOV [SI],AL),但BIOS中断服务有自己特定的寄存器使用规则。
  2. 这样设计的原因可能是:
    • BIOS服务需要明确指定目标缓冲区,而不依赖当前DS值
    • 保持灵活性,允许读取数据到任意内存位置
    • 历史遗留设计,早期x86架构的约定

所以在这个场景下,必须使用ES而不是DS,这是由BIOS接口规范决定的,不是程序员的自主选择。


helloos h


关于.img二进制文件002600处的.sys文件名解释

根据您提供的工程文件和问题,我来解释为什么haribote.img映像文件中会出现HARIBOTESYS文件名以及文件内容的位置:

  1. 文件名来源

    • 文件名HARIBOTESYS不是来自ipl10.nas,而是来自haribote.sys文件本身

    • 在Makefile中,haribote.sys是通过以下命令生成的:

      
      haribote.sys : haribote.nas Makefile
          $(NASK) haribote.nas haribote.sys haribote.lst
      
      
    • haribote.sys被写入映像文件时,FAT12文件系统会自动为其创建目录项

  2. 文件内容位置(0x004200)

    • 文件内容出现在0x004200是因为FAT12文件系统的结构:
      • 引导扇区(0x0000-0x01FF)
      • FAT表(0x0200-0x13FF)
      • 根目录区(0x1400-0x25FF)
      • 数据区从0x2600开始
    • haribote.sys的内容被放在数据区的第一个可用簇
  3. 为什么在ipl10.nas看不到

    • ipl10.nas只是引导程序,负责加载操作系统

    • 文件名和文件内容是由构建过程(make img)和FAT12文件系统自动处理的

    • 在Makefile的haribote.img目标中,haribote.sys被复制到映像文件中:

      
      haribote.img : ipl10.bin haribote.sys Makefile
          $(EDIMG)   imgin:..\..\..\tolset\z_tools\fdimg0at.tek \
              wbinimg src:ipl10.bin len:512 from:0 to:0 \
              copy from:haribote.sys to:@: \
              imgout:haribote.img
      
      
  4. 二进制编辑器的观察

    • 0x002600附近是根目录区,存储了HARIBOTESYS文件名(11字符,空格填充)
    • 0x004200是文件内容区域,存储了haribote.sys的实际内容

总结:文件名和文件内容的位置是由FAT12文件系统结构和构建过程决定的,不是直接在ipl10.nas中指定的。make img命令会自动处理这些文件系统元数据的创建和文件内容的放置。


文件名HARIBOTESYS(11字符)与HARIBOTE(8字符)的区别源于FAT12文件系统的目录项命名规则。以下是具体原因:

  1. FAT12文件系统规范

    • 根目录区的每个文件名条目固定为11字节(8字节主名 + 3字节扩展名)
    • 文件名会被自动转换为大写并填充空格
    • 如果文件名不足11字节,系统会用空格(0x20)填充
  2. 在您的工程中

    • haribote.sys编译后的文件名会被FAT12处理为:
      • 主名:HARIBOTE(8字符,自动截断)
      • 扩展名:SYS(3字符)
      • 组合为HARIBOTESYS(无分隔点,共11字符)
  3. 与ipl10.nas中的HARIBOTE区别

    • ipl10.nas中的HARIBOTE(12行)是磁盘卷标(8字节),不是文件名

    • 卷标和文件名在FAT12中是独立存储的:

      DB      "HARIBOTE"      ; 启动盘名称(8字节)
      DB      "HARIBOTEOS "   ; 卷标(11字节)
      
      
  4. 自动转换过程

    • edimg工具处理haribote.sys时:

      copy from:haribote.sys to:@:  # 自动转换为FAT12目录项
      
      
    • 工具会:

      1. 去除文件名中的点(.)
      2. 主名补足8字符(不够补空格)
      3. 扩展名补足3字符
      4. 全部转为大写

因此haribote.sysHARIBOTESYS是FAT12文件系统的自动命名规范,而ipl10.nas中的HARIBOTE是独立的磁盘标识信息。

关于启动区地址的处理问题(bios缓冲)

MOV [0x0ff0],CH ; 保存实际读取的柱面数
JMP 0xc200 ; 跳转到加载的程序,这个跳转地址怎么计算出来的

在FAT12文件系统中,0xC200这个跳转地址是通过以下步骤计算得出的:

  1. 内存加载位置计算

    • 引导扇区(IPL)被BIOS加载到0x7C00
    • 程序将操作系统内核(haribote.sys)读取到内存地址0x8000开始的位置
      • 计算方式:0x0820:0x0000 (ES:BX)
      • 物理地址 = 0x0820 << 4 + 0x0000 = 0x8200
      • 但实际从0x8000开始是因为BIOS磁盘读取会使用额外的缓冲区
  2. 内核入口点偏移

    • haribote.sys的汇编代码通常会在开头定义ORG 0xc200指令
    • 这个地址是固定的约定值,由开发工具链决定
  3. 地址组成

    • 0xC200 = 0x8000(加载基址) + 0x4200(内核偏移)
    • 其中0x4200haribote.sys编译时确定的入口点偏移
  4. Makefile中的对应关系: 在Makefile中,edimg工具会自动处理这个地址映射:

    
    haribote.img : ipl10.bin haribote.sys Makefile
        $(EDIMG) imgin:... \
            wbinimg src:ipl10.bin len:512 from:0 to:0 \
            copy from:haribote.sys to:@: \  # 自动计算加载地址
            imgout:haribote.img
    
    

这个地址是开发环境预先约定好的,确保:

  1. 不会覆盖BIOS数据区(0x0000-0x7FFF)
  2. 不会覆盖引导程序(0x7C00-0x7DFF)
  3. 留有足够空间给内核代码和数据

如果需要修改这个地址,需要同时修改:

  1. ipl10.nas中的跳转指令
  2. haribote.nas中的ORG指令
  3. Makefile中的地址映射参数

问题:但实际从0x8000开始是因为BIOS磁盘读取会使用额外的缓冲区,额外的缓冲区为什么是0x0200

在x86实模式下,BIOS磁盘读取操作(INT 0x13)使用的额外缓冲区大小是0x0200(512字节),这是由以下原因决定的:

  1. 扇区大小匹配

    • 标准磁盘扇区大小固定为512字节
    • BIOS需要确保缓冲区足够存放一个完整扇区
    • 0x0200(十六进制) = 512(十进制)
  2. 内存地址计算

    • 代码中设置 ES=0x0820, BX=0x0000

    • 物理地址计算:(ES << 4) + BX = 0x8200

    • 但实际数据从0x8000开始是因为:

      
      MOV AX,0x0820  ; ES将被设为0x0820
      MOV ES,AX
      ; 此时ES:BX = 0x0820:0x0000 → 物理地址0x8200
      
      
    • 这里存在一个常见的误解,实际BIOS可能会使用0x8000-0x81FF作为临时缓冲区

  3. BIOS内部机制

    • 某些BIOS实现会在传输数据时使用额外的临时缓冲区
    • 这个缓冲区通常位于0x8000-0x81FF(也是512字节)
    • 最终数据会被复制到请求的目标地址(0x8200)
  4. 代码中的证据: 在读取循环中,每次成功读取后调整ES值:

    next:
        MOV AX,ES
        ADD AX,0x0020  ; 每次增加0x200(512)字节
        MOV ES,AX
    
    

    这个增量0x0020左移4位就是0x0200,正好匹配扇区大小

  5. 内存布局考虑

    • 0x8000以上的区域通常不会被系统占用
    • 这样的设计避免了覆盖BIOS数据区(0x0000-0x7FFF)
    • 也避开了引导扇区本身(0x7C00-0x7DFF)

所以0x0200这个值不是随意选择的,而是严格匹配磁盘扇区大小和x86内存分段机制的必然结果。

make.bat程序解释

问题:…\tolset\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9。解释一下这里的%1等的含义

在Windows批处理文件(.bat)中,%1%9是批处理参数占位符,用于接收调用批处理文件时传入的命令行参数。具体解释如下:

  1. 参数表示

    • %1 表示第一个参数
    • %2 表示第二个参数
    • %9 表示第九个参数
  2. 在您的make.bat中的使用

    
    ..\..\..\tolset\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
    
    

    这行代码会将调用make.bat时传入的所有参数(最多9个)原样传递给make.exe

  3. 实际使用示例

    • 当您执行:实际执行的命令是:其中:

      
      make.bat run clean
      
      
      ..\..\..\tolset\z_tools\make.exe run clean
      
      
      • %1 = “run”
      • %2 = “clean”
      • %3%9为空
  4. 与Makefile的关系

    • 这些参数通常对应Makefile中的目标名,如:
      • img
      • run
      • clean
      • src_only
  5. 特殊参数

    • %0 表示批处理文件本身的名字(这里没用)
    • 超过9个参数需要用shift命令处理

这种设计使得make.bat可以作为一个简单的包装器(wrapper),将所有参数透明地传递给真正的make.exe工具。

键盘BIOS中断调用

INT 0x16 是x86架构中的键盘BIOS中断调用,用于处理键盘输入。在您的代码中具体使用的是 AH=0x02 功能,以下是详细解释:

haribote.nas
;(从BIOS获取键盘LED状态)
MOV     AH,0x02        ; 功能号0x02 - 获取键盘LED状态
INT     0x16           ; 调用键盘BIOS中断
MOV     [LEDS],AL      ; 将结果(AL)保存到内存LEDS位置(0x0ff1)

功能细节:

  1. 输入参数
    • AH=0x02:指定要获取键盘LED状态
  2. 输出参数
    • AL寄存器返回一个字节,包含以下位标志:
      • Bit 0 (0x01): Scroll Lock状态 (1=ON)
      • Bit 1 (0x02): Num Lock状态 (1=ON)
      • Bit 2 (0x04): Caps Lock状态 (1=ON)
      • 其他位保留(为0)
  3. 内存保存
    • 结果被存入 0x0ff1 (LEDS常量定义的位置)
    • 这个值后续可能被操作系统用来同步键盘LED状态
  4. 硬件交互
    • 该中断会直接查询键盘控制器的状态寄存器
    • 不需要实际按键操作就能获取当前LED状态
  5. 典型用途
    • 操作系统启动时初始化键盘状态
    • 保存当前键盘LED状态供后续使用
    • 实现键盘状态指示灯同步

这个调用是早期PC兼容系统中获取键盘状态的标准方法,在现代系统中可能被更高级的API取代,但在裸机编程中仍然有效。

INT 0x16 (键盘BIOS中断) 中,除了 AH=0x02 (获取键盘LED状态) 外,还有其他常用的功能号。以下是主要的键盘BIOS功能及其说明:

1. AH=0x00 - 读取键盘输入

MOV AH,0x00
INT 0x16    ; 返回: AH=扫描码, AL=ASCII码

  • 阻塞等待键盘输入
  • 返回的扫描码可用于识别特殊键(如F1-F12,方向键等)

2. AH=0x01 - 检查键盘缓冲区

MOV AH,0x01
INT 0x16    ; ZF=0有按键, ZF=1无按键

  • 非阻塞检查是否有按键
  • 如果有按键,可通过AH=0x00读取

3. AH=0x02 - 获取键盘标志(已在代码中使用)

MOV AH,0x02
INT 0x16    ; AL=标志字节

  • 返回Shift/Ctrl/Alt等状态
  • 也返回LED状态(Scroll Lock, Num Lock, Caps Lock)

4. AH=0x05 - 写入键盘缓冲区


MOV AH,0x05
MOV CH,扫描码
MOV CL,ASCII码
INT 0x16    ; AL=0成功, AL=1缓冲区满

  • 模拟按键输入
  • 可用于自动化测试

5. AH=0x10 - 扩展键盘读取(AT键盘)


MOV AH,0x10
INT 0x16    ; AH=扫描码, AL=ASCII码

  • 支持102键扩展键盘
  • 能识别更多特殊键

在您的操作系统开发中,最可能用到的是 AH=0x00AH=0x01 来实现键盘输入功能。例如:


wait_key:
    MOV AH,0x00
    INT 0x16    ; 等待按键
    CMP AL,0x1B ; 检查是否是ESC键
    JE exit
    JMP wait_key

这些功能共同构成了PC兼容系统的基本键盘输入体系。

关于BOOT_INFO中的储存地址的确认

CYLS EQU 0x0ff0 ; 引导扇区设置的读取柱面数
LEDS EQU 0x0ff1 ; 键盘LED状态存储位置
VMODE EQU 0x0ff2 ; 显示模式(色彩位数)
SCRNX EQU 0x0ff4 ; 屏幕水平分辨率(X)
SCRNY EQU 0x0ff6 ; 屏幕垂直分辨率(Y)
VRAM EQU 0x0ff8 ;

问题:显存起始地址这些地址是怎么确认的

这些内存地址的确定是基于以下几个关键因素:

  1. 引导程序约定

    • ipl10.nas中,引导程序(IPL)将实际读取的柱面数保存在0x0ff0

      MOV [0x0ff0],CH  ; 保存柱面数到0x0ff0
      
      
    • 这个地址选择在0x7c00-0x7dff(引导扇区)和0x8000(内核加载区)之间的空闲区域

  2. 内存安全区域

    • 0x0ff0-0x0fff是BIOS和引导程序都不会使用的"安全区域"

    • 典型PC内存布局:

      
      0x00000-0x003FF : BIOS中断向量表
      0x00400-0x004FF : BIOS数据区
      0x7C00-0x7DFF   : 引导扇区加载位置
      0xA0000-0xBFFFF : 显存区域
      
      
  3. 信息传递需求

    • 这些地址用于引导程序(IPL)向内核传递硬件信息:
      • 0x0ff0:读取的柱面数
      • 0x0ff1:键盘状态
      • 0x0ff2-0x0ff7:显示参数
      • 0x0ff8:显存地址(固定为0xA0000)
  4. 对齐考虑

    • 地址按数据类型对齐:

      
      CYLS    EQU 0x0ff0  ; 单字节(实际使用CH寄存器)
      LEDS    EQU 0x0ff1  ; 单字节
      VMODE   EQU 0x0ff2  ; 单字节
      SCRNX   EQU 0x0ff4  ; 字(2字节对齐)
      SCRNY   EQU 0x0ff6  ; 字(2字节对齐)
      VRAM    EQU 0x0ff8  ; 双字(4字节对齐)
      
      
  5. 历史兼容性

    • 这些地址是早期PC开发中形成的约定
    • 在《30天自制操作系统》等教程中被标准化使用

这种设计确保了:

  1. 不会覆盖BIOS关键数据
  2. 内核可以可靠地获取硬件信息
  3. 各参数有足够空间存储
  4. 兼容大多数x86实模式环境

书中一部分解释

看一下程序就能明白,设置画面模式之后,还把画面模式的信息保存在了内存里。
这是因为,以后我们可能要支持各种不同的画面模式,这就需要把现在的设置信息
保存起来以备后用。我们暂且将启动时的信息称为BOOT_INFO。INFO是英文
information(信息)的缩写。
■■■■■
[VRAM]里保存的是0xa0000。在电脑的世界里,VRAM指的是显卡内存(video
RAM),也就是用来显示画面的内存。这一块内存当然可以像一般的内存一样存
储数据,但VRAM的功能不仅限于此,它的各个地址都对应着画面上的像素,可以
利用这一机制在画面上绘制出五彩缤纷的图案。
其实VRAM分布在内存分布图上好几个不同的地方。这是因为,不同画面模式的像
素数也不一样。当画面模式为〇×时使用这个VRAM;而画面模式为◇△时可能使
用那个VRAM,像这样,不同画面模式可以使用的内存也不一样。所以我们就预先
把要使用的VRAM地址保存在BOOT_INFO里以备后用。
这次VRAM的值是0xa0000。这个值又是从哪儿得来的呢?还是来看看我们每次都
参考的(AT)BIOS支持网页。在INT 0x10的说明的最后写着,这种画面模式
下“VRAM是0xa0000~0xaffff的64KB”。
另外,我们还把画面的像素数、颜色数,以及从BIOS取得的键盘信息都保存了起
来。保存位置是在内存0x0ff0附近。从内存分布图上看,这一块并没被使用,所以
应该没问题。


harib00i


保护模式和实模式

保护模式和实模式是x86架构CPU的两种主要运行模式,它们在内存访问、特权级别和功能支持等方面有显著差异:

  1. 实模式(Real Mode)
    • 特点
      • 16位模式,兼容最早的8086处理器
      • 直接物理内存寻址(1MB地址空间)
      • 使用段寄存器:偏移地址的寻址方式(段地址×16+偏移)
      • 无内存保护机制,所有代码具有相同特权级
    • 应用场景
      • 计算机启动时的初始模式
      • 运行传统的DOS程序
      • 在操作系统引导阶段使用
  2. 保护模式(Protected Mode)
    • 特点
      • 32位/64位模式(支持更大地址空间)
      • 支持虚拟内存和分页机制
      • 引入特权级(0-3级)和内存保护
      • 使用段选择子和描述符表的复杂内存管理
      • 支持多任务和任务隔离
    • 优势
      • 可访问4GB物理内存(32位)
      • 提供硬件级的内存保护
      • 支持现代操作系统功能(如虚拟内存、多任务)
  3. 关键区别: | 特性 | 实模式 | 保护模式 | |------------|------------------|------------------| | 地址空间 | 1MB | 4GB(32位) | | 寻址方式 | 段:偏移(16+16) | 段选择子+偏移 | | 特权级别 | 无 | 0-3级(Ring0-3) | | 内存保护 | 无 | 有 | | 任务隔离 | 无 | 支持 |
  4. 模式切换
    • 从实模式切换到保护模式需要:
      1. 设置GDT(全局描述符表)
      2. 设置CR0寄存器的保护模式位
      3. 执行远跳转刷新流水线

在您提供的代码中,[INSTRSET "i486p"]和后续的CR0寄存器操作正是完成了从实模式到保护模式的切换过程。保护模式是现代操作系统运行的基础模式。

关于c-机器语言

首先,使用cc1.exe从bootpack.c生成bootpack.gas。
第二步,使用gas2nask.exe从bootpack.gas生成bootpack.nas。
第三步,使用nask.exe从bootpack.nas生成bootpack.obj。
第四步,使用obi2bim.exe从bootpack.obj生成bootpack.bim。
最后,使用bim2hrb.exe从bootpack.bim生成bootpack.hrb。

英特尔家谱:

8086→80186→286→386→486→Pentium→PentiumPro→PentiumII→PentiumIII→Pentiu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值