为什么我的引导加载程序不加载我的内核?
Why doesn't my bootloader load my kernel?
我已经编写了 OS 在程序集上启动的最小实现:
[BITS 16]
[ORG 0x7C00]
start:
mov ax, cs
mov ds, ax
mov ss, ax
mov sp, start
mov ax, 0x1100
mov es, ax
mov bx, 0x0000
mov dl, 1
mov dh, 0
mov ch, 0
mov cl, 2
mov al, 1
mov ah, 0x02
int 0x13
mov ax, 0x1200
mov es, ax
mov bx, 0x0000
mov dl, 1
mov dh, 0
mov ch, 0
mov cl, 3
mov al, 1
mov ah, 0x02
int 0x13
cli
lgdt [gdt_info]
in al, 0x92
or al, 2
out 0x92, al
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x8:protected_mode
gdt:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
;base=0, size=4Gb, P=1, DPL=0, S=1(user),
;Type=1(code), Access=00A, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
;base=0, size=4Gb, P=1, DPL=0, S=1(user),
;Type=0(data), Access=0W0, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
gdt_info:
dw gdt_info - gdt
dw gdt, 0
[BITS 32]
protected_mode:
mov ax, 0x10
mov es, ax
mov ds, ax
mov ss, ax
call 0x11000
times (512 - ($ - start) - 2) db 0
db 0x55, 0xAA
以及 C 中内核的最小实现:
extern "C" int kmain();
__declspec(naked) void startup()
{
__asm {
call kmain;
}
}
#define VIDEO_BUF_PTR (0xb8000)
void out_str(int color, const char* ptr, unsigned int strnum)
{
unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR;
video_buf += 80 * 2 * strnum;
while (*ptr)
{
video_buf[0] = (unsigned char)*ptr;
video_buf[1] = color;
video_buf += 2;
ptr++;
}
}
extern "C" int kmain()
{
const char* hello = "Welcome to HelloWorldOS (gcc edition)!";
out_str(0x07, hello, 0);
while (1)
{
__asm hlt;
}
return 0;
}
使用 Microsoft C 编译器编译内核
引导转换器:Yasm
要从 PE 内核中获取数据,请使用 dumpbin 并获取:
Microsoft (R) COFF/PE Dumper Version 14.28.29335.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file kernel.bin
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
2 number of sections
604FC5B3 time date stamp Mon Mar 15 23:38:11 2021
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
103 characteristics
Relocations stripped
Executable
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
14.28 linker version
200 size of code
200 size of initialized data
0 size of uninitialized data
1000 entry point (00011000)
1000 base of code
2000 base of data
10000 image base (00010000 to 00012FFF)
1000 section alignment
200 file alignment
6.00 operating system version
0.00 image version
6.00 subsystem version
0 Win32 version
3000 size of image
200 size of headers
636 checksum
1 subsystem (Native)
500 DLL characteristics
NX compatible
No structured exception handler
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
1000 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
0 [ 0] RVA [size] of Import Directory
0 [ 0] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
0 [ 0] RVA [size] of Base Relocation Directory
2044 [ 1C] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global Pointer Directory
0 [ 0] RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
0 [ 0] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
0 [ 0] RVA [size] of COM Descriptor Directory
0 [ 0] RVA [size] of Reserved Directory
SECTION HEADER #1
.text name
AE virtual size
1000 virtual address (00011000 to 000110AD)
200 size of raw data
200 file pointer to raw data (00000200 to 000003FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute Read
SECTION HEADER #2
.data name
B0 virtual size
2000 virtual address (00012000 to 000120AF)
200 size of raw data
400 file pointer to raw data (00000400 to 000005FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write
Debug Directories
Time Type Size RVA Pointer
-------- ------- -------- -------- --------
604FC5B3 coffgrp 50 00002060 460
Summary
1000 .data
1000 .text
作为模拟器使用Qemu
结果我得到:
Booting from Hard disk...
Boot failed: could not read the boot disk
Booting from from Floppy...
仅此而已。那么为什么我的 OS 不起作用?我认为问题出在引导加载程序上,但我不确定。 (我才开始学习操作系统,所以我对它了解不多)。我必须运行满足我所有的条件
只需输入
qemu-system-x86_64 -boot order=ab -drive file=boot.BIN,format=raw,index=0,if=floppy -drive file=kernel.BIN,format=raw,index=1,if=floppy -L "C:\Program Files\qemu"
而不是
qemu-system-x86_64 -fda boot.BIN -fdb kernel.BIN -L "C:\Program Files\qemu"
我已经编写了 OS 在程序集上启动的最小实现:
[BITS 16]
[ORG 0x7C00]
start:
mov ax, cs
mov ds, ax
mov ss, ax
mov sp, start
mov ax, 0x1100
mov es, ax
mov bx, 0x0000
mov dl, 1
mov dh, 0
mov ch, 0
mov cl, 2
mov al, 1
mov ah, 0x02
int 0x13
mov ax, 0x1200
mov es, ax
mov bx, 0x0000
mov dl, 1
mov dh, 0
mov ch, 0
mov cl, 3
mov al, 1
mov ah, 0x02
int 0x13
cli
lgdt [gdt_info]
in al, 0x92
or al, 2
out 0x92, al
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x8:protected_mode
gdt:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
;base=0, size=4Gb, P=1, DPL=0, S=1(user),
;Type=1(code), Access=00A, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
;base=0, size=4Gb, P=1, DPL=0, S=1(user),
;Type=0(data), Access=0W0, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
gdt_info:
dw gdt_info - gdt
dw gdt, 0
[BITS 32]
protected_mode:
mov ax, 0x10
mov es, ax
mov ds, ax
mov ss, ax
call 0x11000
times (512 - ($ - start) - 2) db 0
db 0x55, 0xAA
以及 C 中内核的最小实现:
extern "C" int kmain();
__declspec(naked) void startup()
{
__asm {
call kmain;
}
}
#define VIDEO_BUF_PTR (0xb8000)
void out_str(int color, const char* ptr, unsigned int strnum)
{
unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR;
video_buf += 80 * 2 * strnum;
while (*ptr)
{
video_buf[0] = (unsigned char)*ptr;
video_buf[1] = color;
video_buf += 2;
ptr++;
}
}
extern "C" int kmain()
{
const char* hello = "Welcome to HelloWorldOS (gcc edition)!";
out_str(0x07, hello, 0);
while (1)
{
__asm hlt;
}
return 0;
}
使用 Microsoft C 编译器编译内核 引导转换器:Yasm 要从 PE 内核中获取数据,请使用 dumpbin 并获取:
Microsoft (R) COFF/PE Dumper Version 14.28.29335.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file kernel.bin
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
2 number of sections
604FC5B3 time date stamp Mon Mar 15 23:38:11 2021
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
103 characteristics
Relocations stripped
Executable
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
14.28 linker version
200 size of code
200 size of initialized data
0 size of uninitialized data
1000 entry point (00011000)
1000 base of code
2000 base of data
10000 image base (00010000 to 00012FFF)
1000 section alignment
200 file alignment
6.00 operating system version
0.00 image version
6.00 subsystem version
0 Win32 version
3000 size of image
200 size of headers
636 checksum
1 subsystem (Native)
500 DLL characteristics
NX compatible
No structured exception handler
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
1000 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
0 [ 0] RVA [size] of Import Directory
0 [ 0] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
0 [ 0] RVA [size] of Base Relocation Directory
2044 [ 1C] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global Pointer Directory
0 [ 0] RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
0 [ 0] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
0 [ 0] RVA [size] of COM Descriptor Directory
0 [ 0] RVA [size] of Reserved Directory
SECTION HEADER #1
.text name
AE virtual size
1000 virtual address (00011000 to 000110AD)
200 size of raw data
200 file pointer to raw data (00000200 to 000003FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute Read
SECTION HEADER #2
.data name
B0 virtual size
2000 virtual address (00012000 to 000120AF)
200 size of raw data
400 file pointer to raw data (00000400 to 000005FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write
Debug Directories
Time Type Size RVA Pointer
-------- ------- -------- -------- --------
604FC5B3 coffgrp 50 00002060 460
Summary
1000 .data
1000 .text
作为模拟器使用Qemu 结果我得到:
Booting from Hard disk...
Boot failed: could not read the boot disk
Booting from from Floppy...
仅此而已。那么为什么我的 OS 不起作用?我认为问题出在引导加载程序上,但我不确定。 (我才开始学习操作系统,所以我对它了解不多)。我必须运行满足我所有的条件
只需输入
qemu-system-x86_64 -boot order=ab -drive file=boot.BIN,format=raw,index=0,if=floppy -drive file=kernel.BIN,format=raw,index=1,if=floppy -L "C:\Program Files\qemu"
而不是
qemu-system-x86_64 -fda boot.BIN -fdb kernel.BIN -L "C:\Program Files\qemu"