- 文件:
def.inc
众所周知x86的cpu在启动之后处于实模式, 只能访问前1MiB的内存, 且很多位置是不能随便写的, 因此我们需要提前设计好每个在boot和loader阶段用到的变量存放的位置, 防止因为不小心将数据写入错误的位置而导致boot和loader跑崩
即使查询了大量的内存分布的资料, 在编写boot和loader的阶段仍然发现了很多书籍和网络资料中没有提及的很神秘的内存位置, 只要一动他们, 程序就会跑飞(总之就是非常神秘)
甚至使用BIOS中断调用INT 0x15, EAX = 0xE820
之后获得的内存分布, 也有问题????
花精力最多,印象最深的就是0x00000500
处的内存, 明明都说它是可用的, 为什么…为什么瓦塔西只要碰它它就爆炸
总之, 我们要好好设计一下我们该如何分配我们需要的内存空间, 总的来说可用空间还是蛮大的
内存分布
首先我们直接打开OSDev进行一个看, 虽然和实际可能有所出入, 但大差不差
Start | End | Size | Description | Type | |
---|---|---|---|---|---|
Real Mode Address Space (the first MiB) | |||||
0x00000000 | 0x000003FF | 1 KiB | Real Mode IVT (Interrupt Vector Table) | Unusable in real mode | 640 KiB RAM ("Low memory") |
0x00000400 | 0x000004FF | 256 bytes | BDA (BIOS Data Area) | ||
0x00000500 | 0x00007BFF | 29.75 KiB | Conventional memory | Usable memory | |
0x00007C00 | 0x00007DFF | 512 bytes | Your OS BootSector | ||
0x00007E00 | 0x0007FFFF | 480.5 KiB | Conventional memory | ||
0x00080000 | 0x0009FFFF | 128 KiB | EBDA (Extended BIOS Data Area) | Partially used by the EBDA | |
0x000A0000 | 0x000BFFFF | 128 KiB | Video display memory | Hardware mapped | 384 KiB System / Reserved ("Upper Memory") |
0x000C0000 | 0x000C7FFF | 32 KiB (typically) | Video BIOS | ROM and hardware mapped / Shadow RAM | |
0x000C8000 | 0x000EFFFF | 160 KiB (typically) | BIOS Expansions | ||
0x000F0000 | 0x000FFFFF | 64 KiB | Motherboard BIOS |
说明
我将用到的地址都使用define定义, 放在了def.inc
中, 这样当某个文件用到某个地址时直接引入def.inc
, 然后通过名字就可以很方便的使用了
由于涉及到boot和loader整个生命周期的变量, 因此会有大量的你可能一下子看不明白的地方, 推荐你先浏览一遍, 不需要记住, 在看boot和loader时遇到了设计此文件的变量时再查看.
你会看到大量下面这种格式的内容, 你知道C语言的#define
吧, 一样的用法
1%define AAA BBB ; -CCC DDD b
AAA
: 定义的名字BBB
是十六进制地址, 是变量占用的第一个Byte的地址;
: 后面的是注释CCC
: 是变量占用的最后一个Byte的地址DDD
: 表示共占用了几个字节b
: 表示Byte的简写
常量参数
主要是VBE相关的参数定义
这里的模式号和分辨率等在后期获取VBE时有详细过程
使用DEF_VBE_MODE
定义了你想使用的VBE模式号, 这样loader就会使用指定的模式号配置VBE. 在这里先判断了环境变量中有没有定义, 如果没有在环境变量中定义, 那就使用这个文件中的定义
使用DEF_VBE_MODE_X
, DEF_VBE_MODE_Y
, DEF_VBE_MODE_BITS_RGB
定义了期望的VBE分辨率和色深, 如果没有和定义的完全匹配的, 那就会选择比定义的大的分辨率和色深的模式号
1;=====================================================================
2; Expected VBE MODE ;
3; MODE : vbe mode number ;
4; X : x resolution ;
5; Y : y resolution ;
6; BITS_RGB : bits per pixel ; support 16/24/32 ;
7; If the expected result cannot be found, the largest ;
8; smaller than expected value will be looked for ;
9;--------------------------------------------------------------------;
10%ifndef DEF_VBE_MODE ;
11 %define DEF_VBE_MODE 0x0000 ; ;
12; %define DEF_VBE_MODE 0x0198 ; qemu 2560*1440:32 ;
13; %define DEF_VBE_MODE 0x0190 ; qemu 1920*1080:16 ;
14; %define DEF_VBE_MODE 0x0191 ; qemu 1920*1080:24 ;
15; %define DEF_VBE_MODE 0x0192 ; qemu 1920*1080:32 ;
16; %define DEF_VBE_MODE 0x018d ; qemu 1280*720:16 ;
17; %define DEF_VBE_MODE 0x018e ; qemu 1280*720:24 ;
18; %define DEF_VBE_MODE 0x018f ; qemu 1280*720:32 ;
19; %define DEF_VBE_MODE 0x0114 ; qemu 800*600:16 ;
20; %define DEF_VBE_MODE 0x0115 ; qemu 800*600:24 ;
21%endif ;
22%ifndef DEF_VBE_MODE_X ;
23 %define DEF_VBE_MODE_X 1920 ;
24%endif ;
25%ifndef DEF_VBE_MODE_Y ;
26 %define DEF_VBE_MODE_Y 1080 ;
27%endif ;
28%ifndef DEF_VBE_MODE_BITS_RGB ;
29 %define DEF_VBE_MODE_BITS_RGB 32 ;
30%endif ;
31;=====================================================================
变量
boot和loader的运行过程中, 少不了要用到一些变量, 因此我们需要为变量预留出内存空间
我为变量部分分配的内存区域是0x7E00
-0x8000
启动磁盘序号
当BIOS将运行权交给我们编写的boot后, BIOS已经提前将启动磁盘的编号保存在了dl
寄存器中, 在后续读取磁盘时会用到, 防止读错磁盘
1%define DEF_VAR_BOOT_DRIVE_NUMBER 0x7E00 ; -0x7E00 1 b
VBE模式号
VBE是一种技术标准, 能够让我们能够以统一的方式配置显示画面, 并在画面上显示自己想要的图形
而VBE模式的各种模式号就对应了不同的显示配置, 包含分辨率,刷新率,位深等等, 这个是后续通过BIOS中断调用查询出来的, 查出来之后就存放在0x7E01
起始的2个字节内
1%define DEF_VAR_VBE_MODE 0x7E01 ; -0x7E02 2 b
VBE模式号数量
由于电脑硬件支持的VBE模式号一般都会有很多很多, 因此给一个2字节的变量来保存数量
1%define DEF_VAR_VBE_MODE_SIZE 0x7E03 ; -0x7E04 2 b
E820内存分布大小
我们需要通过BIOS中断调用来获取当前设备有那些可用的内存地址段, BIOS返回的是一段结构体数组, 需要一个变量保存这个数组大小
1%define DEF_VAR_E820_ENTRY_SIZE 0x7E05 ; -0x7E06 2 b
调试变量
保存调试数据, 当还无法显示文字前, 将错误代码保存在某个变量里, 通过查看内存里这块地址的数据来DEBUG(好凄惨的DEBUG方式), 当然也可以存在一个不常用的寄存器里
1%define DEF_VAR_DEBUG_VALUE 0x7E08 ; -0x7E0F 8 b
显示字符串
使用INT 10, AH=13h
显示字符串时, 用于记录当前行
1%define DEF_VAR_DISPLAY_LINE 0x7E10 ; -0x7E10 1 b
直接通过BIOS映射好的文本显示的一块显存显示字符
用于记录当前的位置
1%define DEF_VAR_DISPLAY_POS 0x7E11 ; -0x7E14 4 b
内核大小
从FAT32分区表找到内核文件后, 记录内核大小
1%define DEF_VAR_KERNEL_SIZE 0x7E15 ; -0x7E18 4 b
内核大小
从FAT32分区表找到内核文件后, 记录内核大小
1%define DEF_VAR_KERNEL_SIZE 0x7E15 ; -0x7E18 4 b
VBE模式号过滤
在常量参数哪里定义的数值就保存在这几个地址的内存中, 最后一个DEF_VAR_FILTER_VBE_VALID_MODE
存储了loader最终选择的模式号
1%define DEF_VAR_FILTER_VBE_PERFECT_MODE 0x7E20 ; -0x7E21 2 b ;
2%define DEF_VAR_FILTER_VBE_X 0x7E22 ; -0x7E23 2 b ;
3%define DEF_VAR_FILTER_VBE_Y 0x7E24 ; -0x7E25 2 b ;
4%define DEF_VAR_FILTER_VBE_BITS_RGB 0x7E26 ; -0x7E26 1 b ;
5%define DEF_VAR_FILTER_VBE_VALID_MODE 0x7E27 ; -0x7E28 2 b ;
LBA模式读取磁盘
都什么年代了, 还在用CHS模式读取磁盘
如果你现在使用的是U盘而非软盘, 那么LBA模式显然是一个更好的选择. LBA可以访问更大的地址, 并且现代硬盘, SSD, NVMe也都支持, 更不用费劲的计算柱面-磁头-扇区.
既然选择了LBA方式读取磁盘, 那么必不可少的就需要准备LBA模式需要的数据结构, 也就是DAP
为了直观, 使用c语言的结构体展示DAP的结构
- 由于结构体中
buffer
是段:偏移
的地址形式, 因此拆分为Segment
和Offset
两个部分, 注意x86采用小端内存存储方式, 因此Offset
的地址在Segment
前. - 由于进入64位之前, 我们所能操作的寄存器最大就是32位, 因此为了方便操作, 将结构体中
lba
部分拆分为了High
和Low
两个地址. 注意x86采用小端内存存储方式, 因此Low
的地址在High
前.
1struct DAP {
2 uint8_t size; // 结构体大小(通常为 0x10,即 16 字节)
3 uint8_t reserved; // 保留,必须设为 0
4 uint16_t blocks; // 读取的扇区数
5 uint32_t buffer; // 读取数据的缓冲区地址(16 位模式下是段:偏移地址)
6 uint64_t lba; // 需要读取的 LBA 地址
7};
将上述C语言的结构体转换为汇编形式 bushi
1%define DEF_VAR_DAP_LENGTH 0x10 ;
2%define DEF_VAR_DAP 0x7EF0 ; ;
3%define DEF_VAR_DAP_SIZE 0x7EF0 ; -0x7EF0 1 b ;
4%define DEF_VAR_DAP_UNUSED 0x7EF1 ; -0x7EF1 1 b ;
5%define DEF_VAR_DAP_TOTAL 0x7EF2 ; -0x7EF3 2 b ;
6%define DEF_VAR_DAP_OFFSET 0x7EF4 ; -0x7EF5 2 b ;
7%define DEF_VAR_DAP_SEGMENT 0x7EF6 ; -0x7EF7 2 b ;
8%define DEF_VAR_DAP_LBA_LOW 0x7EF8 ; -0x7EFB 4 b ;
9%define DEF_VAR_DAP_LBA_HIGH 0x7EFC ; -0x7EFF 4 b ;
内存段
每个内存区域都使用了两种方式表示
START
和END
: 内存区域的起始和截至地址SEGMENT
和OFFSET
: 起始地址用段:偏移
方式表示时, 段和偏移分别是什么
FAT32分区结构
如果我们想要从FAT32的分区中读取文件, 那么必然要经历以下步骤
- 从文件列表中找到文件, 也就是根据文件名搜索
ROOT Entry
获取文件的大小, 保存位置等信息 - 因为文件保存在一个个簇上的, 文件可能保存在连续的簇上, 也可能保存在零散的簇上, 因此需要根据
FAT Entry
获取每个簇的下一个簇, 这样才能完整的读取一整个文件
我们能操作的只有内存, 因此, 我们需要把用到的这两个表加载到内存中, 我为每个表都分配了4096
字节的内存空间
在loader中我仅读取了第一个ROOT表
和第一个FAT表
, 并认为根据这两个就可以完整找出内核并加载. 如果第一个ROOT Entry
中找不到内核, 就认为内核不存在.
实际的FAT32分区远不只有1个ROOT表
和1个FAT表
, 毕竟FAT表大小 = 簇数 × 4字节
, ROOT表大小更是没有上限
但如果要实现支持动态加载ROOT表
和FAT表
, 代码就过于麻烦了, 所以我们权且当作, 我们一定能从第一个ROOT表
找到内核信息, 也一定能从第一个FAT表
查处内核占用的所有簇
1;=====================================================================
2;= FAT32 Root Entry (4,096 bytes) =
3;=====================================================================
4%define DEF_AREA_FAT32_ROOT_ENTRY_START 0x8000 ;
5%define DEF_AREA_FAT32_ROOT_ENTRY_END 0x9000 ;
6%define DEF_AREA_FAT32_ROOT_ENTRY_SEGMENT 0x0800 ;
7%define DEF_AREA_FAT32_ROOT_ENTRY_OFFSET 0x0000 ;
8;=====================================================================
9
10;=====================================================================
11;= FAT32 FAT Entry (4,096 bytes) =
12;=====================================================================
13%define DEF_AREA_FAT32_FAT_ENTRY_START 0x9000 ;
14%define DEF_AREA_FAT32_FAT_ENTRY_END 0xA000 ;
15%define DEF_AREA_FAT32_FAT_ENTRY_SEGMENT 0x0900 ;
16%define DEF_AREA_FAT32_FAT_ENTRY_OFFSET 0x0000 ;
17;=====================================================================
E820内存信息
也就是通过INT 0x15, EAX=0xE820
查询出来的内存信息数据保存的位置
返回的数据是一个数组, 每一项的结构如下
1struct e820_entry {
2 uint64_t base_addr; // 内存区域的起始地址
3 uint64_t length; // 内存区域的长度(字节)
4 uint32_t type; // 内存类型(详见下表)
5};
Type 值 | 描述 | 说明 |
---|---|---|
1 | 可用内存(RAM) | 可供操作系统使用 |
2 | 保留内存(Reserved) | 可能用于 BIOS、芯片组等,OS 不可用 |
3 | ACPI 可回收(ACPI Reclaimable) | ACPI 相关数据,操作系统可用后释放 |
4 | ACPI NVS(Non-Volatile Storage) | ACPI 固定存储区,OS 不能使用 |
5 | 坏内存(Bad Memory) | 不可用,防止 OS 访问 |
1;=====================================================================
2;= E820 ENTRY (4,096 bytes) =
3;=====================================================================
4%define DEF_AREA_E820_ENTRY_START 0xA000 ;
5%define DEF_AREA_E820_ENTRY_END 0xB000 ;
6%define DEF_AREA_E820_ENTRY_SEGMENT 0x0A00 ;
7%define DEF_AREA_E820_ENTRY_OFFSET 0x0000 ;
8;=====================================================================
VBE数据信息
分为三部分, 自上到下分别是
VBE Info
: 最终选定的模式号的详细信息Selected VBE Mode Info
: 符合分辨率,色深条件的VBE模式号及信息VBE Mode Info
: 所有的VBE模式号及信息
由于VBE的结构体每一个就要占用512字节, 且字段太多, 就不在这里展示了
1;=====================================================================
2;= VBE Info (512 bytes) =
3;=====================================================================
4%define DEF_AREA_VBE_INFO_START 0xB000 ;
5%define DEF_AREA_VBE_INFO_END 0xB200 ;
6%define DEF_AREA_VBE_INFO_SEGMENT 0x0B00 ;
7%define DEF_AREA_VBE_INFO_OFFSET 0x0000 ;
8;=====================================================================
9
10;=====================================================================
11;= Selected VBE Mode Info (3,584 bytes) =
12;=====================================================================
13%define DEF_AREA_SELECTED_VBE_MODE_INFO_START 0xB200 ;
14%define DEF_AREA_SELECTED_VBE_MODE_INFO_END 0xC000 ;
15%define DEF_AREA_SELECTED_VBE_MODE_INFO_SEGMENT 0x0B20 ;
16%define DEF_AREA_SELECTED_VBE_MODE_INFO_OFFSET 0x0000 ;
17;=====================================================================
18
19;=====================================================================
20;= VBE Mode Info (65,536 bytes) =
21;=====================================================================
22%define DEF_AREA_VBE_MODE_INFO_START 0x020000 ;
23%define DEF_AREA_VBE_MODE_INFO_END 0x030000 ;
24%define DEF_AREA_VBE_MODE_INFO_SEGMENT 0x002000 ;
25%define DEF_AREA_VBE_MODE_INFO_OFFSET 0x000000 ;
26;=====================================================================
loader
我们为loader分配了64KiB的内存
1;=====================================================================
2;= Loader (65,536 bytes) =
3;=====================================================================
4%define DEF_AREA_LOADER_START 0x010000 ;
5%define DEF_AREA_LOADER_END 0x020000 ;
6%define DEF_AREA_LOADER_SEGMENT 0x001000 ;
7%define DEF_AREA_LOADER_OFFSET 0x000000 ;
8;=====================================================================
页表
1;=====================================================================
2;= Page Table (65,536 bytes) =
3;=====================================================================
4%define DEF_AREA_PAGE_TABLE_START 0x030000 ;
5%define DEF_AREA_PAGE_TABLE_END 0x040000 ;
6%define DEF_AREA_PAGE_TABLE_SEGMENT 0x003000 ;
7%define DEF_AREA_PAGE_TABLE_OFFSET 0x000000 ;
8;=====================================================================
堆栈
当使用某些堆栈指令时, 被压栈的数据的存放位置
1;=====================================================================
2;= Stack (131,080 bytes) =
3;=====================================================================
4%define DEF_AREA_STACK_START 0x050000 ;
5%define DEF_AREA_STACK_END 0x070008 ;
6%define DEF_AREA_STACK_SEGMENT 0x005000 ;
7%define DEF_AREA_STACK_OFFSET 0x000000 ;
8;=====================================================================
kernel 内核
因为LBA无法读取数据到1MiB以上的内存地址, 因此我们需要将内核读取到缓冲区, 再移动到1MiB以上的位置
注意64KiB仅为缓冲区大小, 内核可以远超过64KiB, 理论上4GiB以内的内核都能给你读进来, 当然要是BIOS没有在4GiB附近占用一些内存的话, 64GiB都能读
KERNEL BUF
: 内核读取的缓冲区KERNEL
: 内核位置
1;=====================================================================
2;= KERNEL BUF (65,536 bytes) =
3;=====================================================================
4%define DEF_AREA_KERNEL_BUF_START 0x040000 ;
5%define DEF_AREA_KERNEL_BUF_END 0x050000 ;
6%define DEF_AREA_KERNEL_BUF_SEGMENT 0x004000 ;
7%define DEF_AREA_KERNEL_BUF_OFFSET 0x000000 ;
8;=====================================================================
9
10;=====================================================================
11;= KERNEL =
12;=====================================================================
13%define DEF_AREA_KERNEL_START 0x100000 ;
14%define DEF_AREA_KERNEL_SEGMENT 0x010000 ;
15%define DEF_AREA_KERNEL_OFFSET 0x000000 ;
16;=====================================================================
完整def.inc
1;=====================================================================
2; Expected VBE MODE ;
3; MODE : vbe mode number ;
4; X : x resolution ;
5; Y : y resolution ;
6; BITS_RGB : bits per pixel ; support 16/24/32 ;
7; If the expected result cannot be found, the largest ;
8; smaller than expected value will be looked for ;
9;--------------------------------------------------------------------;
10%ifndef DEF_VBE_MODE ;
11 %define DEF_VBE_MODE 0x0000 ; ;
12; %define DEF_VBE_MODE 0x0198 ; qemu 2560*1440:32 ;
13; %define DEF_VBE_MODE 0x0190 ; qemu 1920*1080:16 ;
14; %define DEF_VBE_MODE 0x0191 ; qemu 1920*1080:24 ;
15; %define DEF_VBE_MODE 0x0192 ; qemu 1920*1080:32 ;
16; %define DEF_VBE_MODE 0x018d ; qemu 1280*720:16 ;
17; %define DEF_VBE_MODE 0x018e ; qemu 1280*720:24 ;
18; %define DEF_VBE_MODE 0x018f ; qemu 1280*720:32 ;
19; %define DEF_VBE_MODE 0x0114 ; qemu 800*600:16 ;
20; %define DEF_VBE_MODE 0x0115 ; qemu 800*600:24 ;
21%endif ;
22%ifndef DEF_VBE_MODE_X ;
23 %define DEF_VBE_MODE_X 1920 ;
24%endif ;
25%ifndef DEF_VBE_MODE_Y ;
26 %define DEF_VBE_MODE_Y 1080 ;
27%endif ;
28%ifndef DEF_VBE_MODE_BITS_RGB ;
29 %define DEF_VBE_MODE_BITS_RGB 32 ;
30%endif ;
31;=====================================================================
32
33;=====================================================================
34;= Variable (512 bytes) =
35;=====================================================================
36%define DEF_AREA_VAR_START 0x7E00 ;
37%define DEF_AREA_VAR_END 0x8000 ;
38%define DEF_AREA_VAR_SEGMENT 0x07E0 ;
39%define DEF_AREA_VAR_OFFSET 0x0000 ;
40;--------------------------------------------------------------------;
41%define DEF_VAR_BOOT_DRIVE_NUMBER 0x7E00 ; -0x7E00 1 b ;
42%define DEF_VAR_VBE_MODE 0x7E01 ; -0x7E02 2 b ;
43%define DEF_VAR_VBE_MODE_SIZE 0x7E03 ; -0x7E04 2 b ;
44%define DEF_VAR_E820_ENTRY_SIZE 0x7E05 ; -0x7E06 2 b ;
45; reserved 0x7E07 ; -0x7E07 ;
46%define DEF_VAR_DEBUG_VALUE 0x7E08 ; -0x7E0F 8 b ;
47%define DEF_VAR_DISPLAY_LINE 0x7E10 ; -0x7E10 1 b ;
48%define DEF_VAR_DISPLAY_POS 0x7E11 ; -0x7E14 4 b ;
49%define DEF_VAR_KERNEL_SIZE 0x7E15 ; -0x7E18 4 b ;
50; reserved 0x7E19 ; -0x7E1F ;
51%define DEF_VAR_FILTER_VBE_PERFECT_MODE 0x7E20 ; -0x7E21 2 b ;
52%define DEF_VAR_FILTER_VBE_X 0x7E22 ; -0x7E23 2 b ;
53%define DEF_VAR_FILTER_VBE_Y 0x7E24 ; -0x7E25 2 b ;
54%define DEF_VAR_FILTER_VBE_BITS_RGB 0x7E26 ; -0x7E26 1 b ;
55%define DEF_VAR_FILTER_VBE_VALID_MODE 0x7E27 ; -0x7E28 2 b ;
56; reserved 0x7E29 ; -0x7EEF ;
57%define DEF_VAR_DAP_LENGTH 0x10 ;
58%define DEF_VAR_DAP 0x7EF0 ; ;
59%define DEF_VAR_DAP_SIZE 0x7EF0 ; -0x7EF0 1 b ;
60%define DEF_VAR_DAP_UNUSED 0x7EF1 ; -0x7EF1 1 b ;
61%define DEF_VAR_DAP_TOTAL 0x7EF2 ; -0x7EF3 2 b ;
62%define DEF_VAR_DAP_OFFSET 0x7EF4 ; -0x7EF5 2 b ;
63%define DEF_VAR_DAP_SEGMENT 0x7EF6 ; -0x7EF7 2 b ;
64%define DEF_VAR_DAP_LBA_LOW 0x7EF8 ; -0x7EFB 4 b ;
65%define DEF_VAR_DAP_LBA_HIGH 0x7EFC ; -0x7EFF 4 b ;
66; reserved 0x7F00 ; -0x7FFF ;
67;--------------------------------------------------------------------;
68
69;=====================================================================
70;= FAT32 Root Entry (4,096 bytes) =
71;=====================================================================
72%define DEF_AREA_FAT32_ROOT_ENTRY_START 0x8000 ;
73%define DEF_AREA_FAT32_ROOT_ENTRY_END 0x9000 ;
74%define DEF_AREA_FAT32_ROOT_ENTRY_SEGMENT 0x0800 ;
75%define DEF_AREA_FAT32_ROOT_ENTRY_OFFSET 0x0000 ;
76;=====================================================================
77
78;=====================================================================
79;= FAT32 FAT Entry (4,096 bytes) =
80;=====================================================================
81%define DEF_AREA_FAT32_FAT_ENTRY_START 0x9000 ;
82%define DEF_AREA_FAT32_FAT_ENTRY_END 0xA000 ;
83%define DEF_AREA_FAT32_FAT_ENTRY_SEGMENT 0x0900 ;
84%define DEF_AREA_FAT32_FAT_ENTRY_OFFSET 0x0000 ;
85;=====================================================================
86
87;=====================================================================
88;= E820 ENTRY (4,096 bytes) =
89;=====================================================================
90%define DEF_AREA_E820_ENTRY_START 0xA000 ;
91%define DEF_AREA_E820_ENTRY_END 0xB000 ;
92%define DEF_AREA_E820_ENTRY_SEGMENT 0x0A00 ;
93%define DEF_AREA_E820_ENTRY_OFFSET 0x0000 ;
94;=====================================================================
95
96;=====================================================================
97;= VBE Info (512 bytes) =
98;=====================================================================
99%define DEF_AREA_VBE_INFO_START 0xB000 ;
100%define DEF_AREA_VBE_INFO_END 0xB200 ;
101%define DEF_AREA_VBE_INFO_SEGMENT 0x0B00 ;
102%define DEF_AREA_VBE_INFO_OFFSET 0x0000 ;
103;=====================================================================
104
105;=====================================================================
106;= Selected VBE Mode Info (3,584 bytes) =
107;=====================================================================
108%define DEF_AREA_SELECTED_VBE_MODE_INFO_START 0xB200 ;
109%define DEF_AREA_SELECTED_VBE_MODE_INFO_END 0xC000 ;
110%define DEF_AREA_SELECTED_VBE_MODE_INFO_SEGMENT 0x0B20 ;
111%define DEF_AREA_SELECTED_VBE_MODE_INFO_OFFSET 0x0000 ;
112;=====================================================================
113
114;=====================================================================
115;= Reserved 0xC000 - 0xFFFF =
116;=====================================================================
117
118;=====================================================================
119;= Loader (65,536 bytes) =
120;=====================================================================
121%define DEF_AREA_LOADER_START 0x010000 ;
122%define DEF_AREA_LOADER_END 0x020000 ;
123%define DEF_AREA_LOADER_SEGMENT 0x001000 ;
124%define DEF_AREA_LOADER_OFFSET 0x000000 ;
125;=====================================================================
126
127;=====================================================================
128;= VBE Mode Info (65,536 bytes) =
129;=====================================================================
130%define DEF_AREA_VBE_MODE_INFO_START 0x020000 ;
131%define DEF_AREA_VBE_MODE_INFO_END 0x030000 ;
132%define DEF_AREA_VBE_MODE_INFO_SEGMENT 0x002000 ;
133%define DEF_AREA_VBE_MODE_INFO_OFFSET 0x000000 ;
134;=====================================================================
135
136;=====================================================================
137;= Page Table (65,536 bytes) =
138;=====================================================================
139%define DEF_AREA_PAGE_TABLE_START 0x030000 ;
140%define DEF_AREA_PAGE_TABLE_END 0x040000 ;
141%define DEF_AREA_PAGE_TABLE_SEGMENT 0x003000 ;
142%define DEF_AREA_PAGE_TABLE_OFFSET 0x000000 ;
143;=====================================================================
144
145;=====================================================================
146;= KERNEL BUF (65,536 bytes) =
147;=====================================================================
148%define DEF_AREA_KERNEL_BUF_START 0x040000 ;
149%define DEF_AREA_KERNEL_BUF_END 0x050000 ;
150%define DEF_AREA_KERNEL_BUF_SEGMENT 0x004000 ;
151%define DEF_AREA_KERNEL_BUF_OFFSET 0x000000 ;
152;=====================================================================
153
154;=====================================================================
155;= Stack (131,080 bytes) =
156;=====================================================================
157%define DEF_AREA_STACK_START 0x050000 ;
158%define DEF_AREA_STACK_END 0x070008 ;
159%define DEF_AREA_STACK_SEGMENT 0x005000 ;
160%define DEF_AREA_STACK_OFFSET 0x000000 ;
161;=====================================================================
162
163;=====================================================================
164;= Reserved 0x060000 - 0x080000 =
165;=====================================================================
166
167;=====================================================================
168;= KERNEL =
169;=====================================================================
170%define DEF_AREA_KERNEL_START 0x100000 ;
171%define DEF_AREA_KERNEL_SEGMENT 0x010000 ;
172%define DEF_AREA_KERNEL_OFFSET 0x000000 ;
173;=====================================================================
除另有声明外,本博客文章均采用 知识共享 (Creative Commons) 署名 4.0 国际许可协议 进行许可。转载请注明原作者与文章出处。