x86 CPU寻址
- 8086/8088 20根地址线 寻址空间1M
- 80286 24根地址线 寻址空间16M
- 80386 32根地址线 寻址空间4G
现代CPU的寻址空间,应该和具体CPU设计有关,用AlderLake某款CPU做过一个窥探,UEFI Shell下用mem指令不断去测试,发现最大能dump的地址是512G,用Tool Dump CPU类型的HOB发现SizeOfMemorySpace成员对应的地址转化为10进制为39,2的39次方刚好为512G,所以应该表示的是地址线为39根
1M以下内存区域
主要分为两大块
DOS 640KB
- 00000000 - 000002FF(768 bytes) - Interrupt Vector Table
- 00000300 - 000003FF(256 bytes) - BIOS Stack Area
- 00000400 - 000004FF(256 bytes) - BIOS Data
- 00000500 - 00009FFF(640K - 前三个区域) - Applications Memory Area
A-F六个段,每个段64KB,合计384KB
MBR分区
4个分区表占据64 byte,加上其它的448字节,组成了一个0扇区
#pragma pack(1)
///
/// MBR Partition Entry
///
typedef struct {
UINT8 BootIndicator;
UINT8 StartHead;
UINT8 StartSector;
UINT8 StartTrack;
UINT8 OSIndicator;
UINT8 EndHead;
UINT8 EndSector;
UINT8 EndTrack;
UINT8 StartingLBA[4];
UINT8 SizeInLBA[4];
} MBR_PARTITION_RECORD;
///
/// MBR Partition Table
///
typedef struct {
UINT8 BootStrapCode[440];
UINT8 UniqueMbrSignature[4];
UINT8 Unknown[2];
MBR_PARTITION_RECORD Partition[4];
UINT16 Signature;
} MASTER_BOOT_RECORD;
#pragma pack()
汇编实例
一直对Legacy感受不深,写一个汇编程序,研究下Legacy Boot,利用NASM编译Start.asm为bin文件,再用HXD将二进制数据拷贝到U盘扇区0,BIOS设为Legacy启动
mov ax,0b800h
mov ds,ax
mov byte [0x00],'A'
mov byte [0x02],'s'
mov byte [0x04],'m'
mov byte [0x06],' '
mov byte [0x08],'T'
mov byte [0x0a],'e'
mov byte [0x0c],'s'
mov byte [0x0e],'t'
mov byte [0x10],' '
mov byte [0x12],'F'
mov byte [0x14],'o'
mov byte [0x16],'r'
mov byte [0x18],' '
mov byte [0x1a],'L'
mov byte [0x1c],'e'
mov byte [0x1e],'g'
mov byte [0x20],'a'
mov byte [0x22],'c'
mov byte [0x24],'y'
mov byte [0x26],' '
jmp $
times 510 - ($-$$) db 0
db 0x55,0xaa
编译command
nasm -f bin Start.asm -o Start.bin
刻录到U盘
插入U盘格式化Fat32(文件系统没试过是否有影响)
HxD -> 工具 -> 读取硬盘 -> 物理地址 -> 实际U盘
文件 -> 打开 -> 选择编译的bin文件
将bin文件的非00字节拷贝到U盘0扇区
BIOS设置
Legacy是比较古老的东西,Intel也说过将不支持Legacy,淘汰掉这个古老的玩意,所以新的主板可能只支持UEFI启动,如果支持Legacy的话,需要在BIOS下改点东西,才可以支持程序的运行
运行结果
总结
U盘没有做成DOS和Shell盘,Legacy Boot时还是会有Boot Option,校验0扇区Signature后,会去执行前440字节存放的二进制代码,本例中没有效用完440 byte,看来Legacy Boot时0扇区这一段代码是用来跳转寻找OS BootLoader的