为什么Bochs说“找不到启动设备”当我将内核与引导部门相连时?
当我运行 Bochs 而不在引导扇区后添加内核时(即,当映像文件只是我的引导扇区时),它运行得很好。当我运行 Bochs 并在引导扇区后连接内核时,Bochs 表示未找到可引导设备。为什么会出现这个问题?我也愿意提供所需的任何额外信息,但我不太确定与此问题相关的内容。
编辑:
我的 Bochs 配置文件:
floppya: 1_44="os-image", status=inserted
boot: a
我的 kernel.c:
extern void main() {
char* video_memory = (char*) 0xb8000; // Pointer to the first text cell in video memory
*video_memory = 'X'; // Sets the value of video_memory to an X.
}
我的引导扇区:
; A boot sector that boots a C kernel in a 32-bit protected mode
[org 0x7c00] ; Tell the assembler where to load the boot sector
KERNEL_OFFSET equ 0x1000 ; Memory offset for kernel
mov [BOOT_DRIVE], dl
mov bp, 0x9000 ; Set up the stack
mov sp, bp
mov bx, MSG_REAL_MODE ; Use BX as a parameter to the function call
call print_string ; Tell the user that we have booted into 16-bit real mode
call load_kernel ; Load the kernel
call switch_to_pm
jmp $ ; Hang indefinitely
%include "Printing/print_string.asm"
%include "Disk/diskload.asm"
%include "pm/gdt.asm"
%include "Printing/print_string_pm.asm"
%include "pm/switch_to_pm.asm"
[bits 16]
load_kernel:
mov bx, MSG_LOAD_KERNEL ; Announce that we are loading the kernel
call print_string
mov bx, KERNEL_OFFSET
mov dh, 15
mov dl, [BOOT_DRIVE]
call disk_load
ret
[bits 32]
BEGIN_PM:
mov ebx, MSG_PROT_MODE
call print_string_pm
call KERNEL_OFFSET ; Move to where the kernel is and pray
jmp $
; Data
BOOT_DRIVE db 0
MSG_REAL_MODE db "Started in 16-bit Real Mode", 0
MSG_PROT_MODE db "Successfully landed in 32-bit Protected Mode", 0
MSG_LOAD_KERNEL db "Loading kernel into memory", 0
times 510-($-$$) db 0 ; Padding
dw 0xaa55 ; Magic number to denote boot sector
我的最终映像二进制文件:
Starting at 0x0:
88 16 e5 7c bd 00 90 89 ec bb e6 7c e8 08 00 e8
af 00 e8 7d 00 eb fe 60 b4 0e eb 00 8a 07 3c 00
74 07 cd 10 83 c3 01 eb f3 61 c3 52 b4 02 88 f0
b5 00 b6 00 b1 02 cd 13 72 06 5a 38 c6 75 01 c3
bb 48 7c e8 d1 ff eb fe 44 69 73 6b 20 72 65 61
64 20 65 72 72 6f 72 21 00 00 00 00 00 00 00 00
00 ff ff 00 00 00 9a cf 00 ff ff 00 00 00 92 cf
00 17 00 59 7c 00 00 60 ba 00 80 0b 00 8a 03 b4
0f 3c 00 74 0b 66 89 02 83 c3 01 83 c2 02 eb ed
61 c3 fa 0f 01 16 71 7c 0f 20 c0 66 83 c8 01 0f
22 c0 ea a7 7c 08 00 66 b8 10 00 8e d8 8e d0 8e
c0 8e e0 8e e8 bd 00 00 09 00 89 ec e8 13 00 00
00 bb 2f 7d e8 50 ff bb 00 10 b6 0f 8a 16 e5 7c
e8 58 ff c3 bb 02 7d 00 00 e8 99 ff ff ff e8 1d
93 ff ff eb fe 00 53 74 61 72 74 65 64 20 69 6e
20 31 36 2d 62 69 74 20 52 65 61 6c 20 4d 6f 64
65 00 53 75 63 63 65 73 73 66 75 6c 6c 79 20 6c
61 6e 64 65 64 20 69 6e 20 33 32 2d 62 69 74 20
50 72 6f 74 65 63 74 65 64 20 4d 6f 64 65 00 4c
6f 61 64 69 6e 67 20 6b 65 72 6e 65 6c 20 69 6e
74 6f 20 6d 65 6d 6f 72 79 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
e8 02 00 00 00 eb fe f3 0f 1e fb 55 89 e5 83 ec
10 c7 45 fc 00 80 0b 00 8b 45 fc c6 00 58 90 c9
c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...
Starting at 0x1000:
14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01
1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00
e7 ef ff ff 1a 00 00 00 00 45 0e 08 85 02 42 0d
05 52 c5 0c 04 04 00 00 00 00 00 00 00 00 00 00
...
Starting at 0x08047200:
04 00 00 00 0c 00 00 00 05 00 00 00 47 4e 55 00
02 00 00 c0 04 00 00 00 03 00 00 00
我之前没有注意到,也不知道为什么,在最后一个集合之前有一个巨大的零填充二进制末尾的非零十六进制代码。
我的 makefile:
all: os-image
os-image: boot_sect.bin kernel.bin
cat $^ > os-image
kernel.bin: kernel_entry.o kernel.o
ld -melf_i386 -o kernel.bin -Ttext 0x1000 $^ --oformat binary
kernel.o : kernel.c
gcc -fno-pie -ffreestanding -m32 -c $< -o $@
kernel_entry.o : kernel_entry.asm
nasm $< -f elf -o $@
boot_sect.bin : boot_sect.asm
nasm $< -f bin -o $@
clean:
rm -fr *.bin *.o os-image *.map
使用注释中建议的 Makefile 运行 objdump -Dx kernel.elf 的输出:
kernel.elf: file format elf32-i386
kernel.elf
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00001000
Program Header:
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
filesz 0x000000b4 memsz 0x000000b4 flags r--
LOAD off 0x00001000 vaddr 0x00001000 paddr 0x00001000 align 2**12
filesz 0x00000021 memsz 0x00000021 flags r-x
LOAD off 0x00002000 vaddr 0x00002000 paddr 0x00002000 align 2**12
filesz 0x00000038 memsz 0x00000038 flags r--
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
filesz 0x00000000 memsz 0x00000000 flags rwx
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000021 00001000 00001000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .eh_frame 00000038 00002000 00002000 00002000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .comment 0000002b 00000000 00000000 00002038 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00001000 l d .text 00000000 .text
00002000 l d .eh_frame 00000000 .eh_frame
00000000 l d .comment 00000000 .comment
00000000 l df *ABS* 00000000 kernel_entry.asm
00000000 l df *ABS* 00000000 kernel.c
00000000 *UND* 00000000 _start
00004000 g .eh_frame 00000000 __bss_start
00001007 g F .text 0000001a main
00004000 g .eh_frame 00000000 _edata
00004000 g .eh_frame 00000000 _end
Disassembly of section .text:
00001000 <main-0x7>:
1000: e8 02 00 00 00 call 1007 <main>
1005: eb fe jmp 1005 <main-0x2>
00001007 <main>:
1007: f3 0f 1e fb endbr32
100b: 55 push %ebp
100c: 89 e5 mov %esp,%ebp
100e: 83 ec 10 sub $0x10,%esp
1011: c7 45 fc 00 80 0b 00 movl $0xb8000,-0x4(%ebp)
1018: 8b 45 fc mov -0x4(%ebp),%eax
101b: c6 00 58 movb $0x58,(%eax)
101e: 90 nop
101f: c9 leave
1020: c3 ret
Disassembly of section .eh_frame:
00002000 <__bss_start-0x2000>:
2000: 14 00 adc $0x0,%al
2002: 00 00 add %al,(%eax)
2004: 00 00 add %al,(%eax)
2006: 00 00 add %al,(%eax)
2008: 01 7a 52 add %edi,0x52(%edx)
200b: 00 01 add %al,(%ecx)
200d: 7c 08 jl 2017 <main+0x1010>
200f: 01 1b add %ebx,(%ebx)
2011: 0c 04 or $0x4,%al
2013: 04 88 add $0x88,%al
2015: 01 00 add %eax,(%eax)
2017: 00 1c 00 add %bl,(%eax,%eax,1)
201a: 00 00 add %al,(%eax)
201c: 1c 00 sbb $0x0,%al
201e: 00 00 add %al,(%eax)
2020: e7 ef out %eax,$0xef
2022: ff (bad)
2023: ff 1a lcall *(%edx)
2025: 00 00 add %al,(%eax)
2027: 00 00 add %al,(%eax)
2029: 45 inc %ebp
202a: 0e push %cs
202b: 08 85 02 42 0d 05 or %al,0x50d4202(%ebp)
2031: 52 push %edx
2032: c5 0c 04 lds (%esp,%eax,1),%ecx
2035: 04 00 add $0x0,%al
...
Disassembly of section .comment:
00000000 <.comment>:
0: 47 inc %edi
1: 43 inc %ebx
2: 43 inc %ebx
3: 3a 20 cmp (%eax),%ah
5: 28 55 62 sub %dl,0x62(%ebp)
8: 75 6e jne 78 <main-0xf8f>
a: 74 75 je 81 <main-0xf86>
c: 20 39 and %bh,(%ecx)
e: 2e 34 2e cs xor $0x2e,%al
11: 30 2d 31 75 62 75 xor %ch,0x75627531
17: 6e outsb %ds:(%esi),(%dx)
18: 74 75 je 8f <main-0xf78>
1a: 31 7e 32 xor %edi,0x32(%esi)
1d: 30 2e xor %ch,(%esi)
1f: 30 34 2e xor %dh,(%esi,%ebp,1)
22: 31 29 xor %ebp,(%ecx)
24: 20 39 and %bh,(%ecx)
26: 2e 34 2e cs xor $0x2e,%al
29: 30 00 xor %al,(%eax)
I am following along with this guide in order to try to write my own (very basic) operating system. I have gotten my boot sector to run with Bochs perfectly fine (I've just tested it with writing to the screen and whatnot). Following the guide, I then wrote a very basic kernel (a C program that just prints an X on the screen), and (after compiling it to a .o file with gcc and then linking it into to a .bin with ld) I concatenated it after my boot sector into an overall kernel image file. I have checked the hex of the file, and it most certainly is my boot sector, complete with the "magic number" at 0x1fe and 0x1ff, and then the kernel immediately after the magic number.
When I run Bochs without adding the kernel after my boot sector (that is, when the image file is just my boot sector), it runs perfectly fine. When I run Bochs with the kernel concatenated after my boot sector, Bochs says that no bootable devices were found. Why is this issue happening? I am also willing to provide any additionally information needed, but I wasn't quite sure what would be pertinent to this issue.
Edit:
My Bochs config file:
floppya: 1_44="os-image", status=inserted
boot: a
My kernel.c:
extern void main() {
char* video_memory = (char*) 0xb8000; // Pointer to the first text cell in video memory
*video_memory = 'X'; // Sets the value of video_memory to an X.
}
My boot sector:
; A boot sector that boots a C kernel in a 32-bit protected mode
[org 0x7c00] ; Tell the assembler where to load the boot sector
KERNEL_OFFSET equ 0x1000 ; Memory offset for kernel
mov [BOOT_DRIVE], dl
mov bp, 0x9000 ; Set up the stack
mov sp, bp
mov bx, MSG_REAL_MODE ; Use BX as a parameter to the function call
call print_string ; Tell the user that we have booted into 16-bit real mode
call load_kernel ; Load the kernel
call switch_to_pm
jmp $ ; Hang indefinitely
%include "Printing/print_string.asm"
%include "Disk/diskload.asm"
%include "pm/gdt.asm"
%include "Printing/print_string_pm.asm"
%include "pm/switch_to_pm.asm"
[bits 16]
load_kernel:
mov bx, MSG_LOAD_KERNEL ; Announce that we are loading the kernel
call print_string
mov bx, KERNEL_OFFSET
mov dh, 15
mov dl, [BOOT_DRIVE]
call disk_load
ret
[bits 32]
BEGIN_PM:
mov ebx, MSG_PROT_MODE
call print_string_pm
call KERNEL_OFFSET ; Move to where the kernel is and pray
jmp $
; Data
BOOT_DRIVE db 0
MSG_REAL_MODE db "Started in 16-bit Real Mode", 0
MSG_PROT_MODE db "Successfully landed in 32-bit Protected Mode", 0
MSG_LOAD_KERNEL db "Loading kernel into memory", 0
times 510-($-$) db 0 ; Padding
dw 0xaa55 ; Magic number to denote boot sector
My final image binary file:
Starting at 0x0:
88 16 e5 7c bd 00 90 89 ec bb e6 7c e8 08 00 e8
af 00 e8 7d 00 eb fe 60 b4 0e eb 00 8a 07 3c 00
74 07 cd 10 83 c3 01 eb f3 61 c3 52 b4 02 88 f0
b5 00 b6 00 b1 02 cd 13 72 06 5a 38 c6 75 01 c3
bb 48 7c e8 d1 ff eb fe 44 69 73 6b 20 72 65 61
64 20 65 72 72 6f 72 21 00 00 00 00 00 00 00 00
00 ff ff 00 00 00 9a cf 00 ff ff 00 00 00 92 cf
00 17 00 59 7c 00 00 60 ba 00 80 0b 00 8a 03 b4
0f 3c 00 74 0b 66 89 02 83 c3 01 83 c2 02 eb ed
61 c3 fa 0f 01 16 71 7c 0f 20 c0 66 83 c8 01 0f
22 c0 ea a7 7c 08 00 66 b8 10 00 8e d8 8e d0 8e
c0 8e e0 8e e8 bd 00 00 09 00 89 ec e8 13 00 00
00 bb 2f 7d e8 50 ff bb 00 10 b6 0f 8a 16 e5 7c
e8 58 ff c3 bb 02 7d 00 00 e8 99 ff ff ff e8 1d
93 ff ff eb fe 00 53 74 61 72 74 65 64 20 69 6e
20 31 36 2d 62 69 74 20 52 65 61 6c 20 4d 6f 64
65 00 53 75 63 63 65 73 73 66 75 6c 6c 79 20 6c
61 6e 64 65 64 20 69 6e 20 33 32 2d 62 69 74 20
50 72 6f 74 65 63 74 65 64 20 4d 6f 64 65 00 4c
6f 61 64 69 6e 67 20 6b 65 72 6e 65 6c 20 69 6e
74 6f 20 6d 65 6d 6f 72 79 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
e8 02 00 00 00 eb fe f3 0f 1e fb 55 89 e5 83 ec
10 c7 45 fc 00 80 0b 00 8b 45 fc c6 00 58 90 c9
c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...
Starting at 0x1000:
14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01
1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00
e7 ef ff ff 1a 00 00 00 00 45 0e 08 85 02 42 0d
05 52 c5 0c 04 04 00 00 00 00 00 00 00 00 00 00
...
Starting at 0x08047200:
04 00 00 00 0c 00 00 00 05 00 00 00 47 4e 55 00
02 00 00 c0 04 00 00 00 03 00 00 00
I didn't notice before that, nor do I have any idea why, there is a huge padding of zeroes before that last collection of nonzero hex codes at the end of the binary.
My makefile:
all: os-image
os-image: boot_sect.bin kernel.bin
cat $^ > os-image
kernel.bin: kernel_entry.o kernel.o
ld -melf_i386 -o kernel.bin -Ttext 0x1000 $^ --oformat binary
kernel.o : kernel.c
gcc -fno-pie -ffreestanding -m32 -c lt; -o $@
kernel_entry.o : kernel_entry.asm
nasm lt; -f elf -o $@
boot_sect.bin : boot_sect.asm
nasm lt; -f bin -o $@
clean:
rm -fr *.bin *.o os-image *.map
The output from running objdump -Dx kernel.elf
with the Makefile suggested in the comments:
kernel.elf: file format elf32-i386
kernel.elf
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00001000
Program Header:
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
filesz 0x000000b4 memsz 0x000000b4 flags r--
LOAD off 0x00001000 vaddr 0x00001000 paddr 0x00001000 align 2**12
filesz 0x00000021 memsz 0x00000021 flags r-x
LOAD off 0x00002000 vaddr 0x00002000 paddr 0x00002000 align 2**12
filesz 0x00000038 memsz 0x00000038 flags r--
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
filesz 0x00000000 memsz 0x00000000 flags rwx
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000021 00001000 00001000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .eh_frame 00000038 00002000 00002000 00002000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .comment 0000002b 00000000 00000000 00002038 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00001000 l d .text 00000000 .text
00002000 l d .eh_frame 00000000 .eh_frame
00000000 l d .comment 00000000 .comment
00000000 l df *ABS* 00000000 kernel_entry.asm
00000000 l df *ABS* 00000000 kernel.c
00000000 *UND* 00000000 _start
00004000 g .eh_frame 00000000 __bss_start
00001007 g F .text 0000001a main
00004000 g .eh_frame 00000000 _edata
00004000 g .eh_frame 00000000 _end
Disassembly of section .text:
00001000 <main-0x7>:
1000: e8 02 00 00 00 call 1007 <main>
1005: eb fe jmp 1005 <main-0x2>
00001007 <main>:
1007: f3 0f 1e fb endbr32
100b: 55 push %ebp
100c: 89 e5 mov %esp,%ebp
100e: 83 ec 10 sub $0x10,%esp
1011: c7 45 fc 00 80 0b 00 movl $0xb8000,-0x4(%ebp)
1018: 8b 45 fc mov -0x4(%ebp),%eax
101b: c6 00 58 movb $0x58,(%eax)
101e: 90 nop
101f: c9 leave
1020: c3 ret
Disassembly of section .eh_frame:
00002000 <__bss_start-0x2000>:
2000: 14 00 adc $0x0,%al
2002: 00 00 add %al,(%eax)
2004: 00 00 add %al,(%eax)
2006: 00 00 add %al,(%eax)
2008: 01 7a 52 add %edi,0x52(%edx)
200b: 00 01 add %al,(%ecx)
200d: 7c 08 jl 2017 <main+0x1010>
200f: 01 1b add %ebx,(%ebx)
2011: 0c 04 or $0x4,%al
2013: 04 88 add $0x88,%al
2015: 01 00 add %eax,(%eax)
2017: 00 1c 00 add %bl,(%eax,%eax,1)
201a: 00 00 add %al,(%eax)
201c: 1c 00 sbb $0x0,%al
201e: 00 00 add %al,(%eax)
2020: e7 ef out %eax,$0xef
2022: ff (bad)
2023: ff 1a lcall *(%edx)
2025: 00 00 add %al,(%eax)
2027: 00 00 add %al,(%eax)
2029: 45 inc %ebp
202a: 0e push %cs
202b: 08 85 02 42 0d 05 or %al,0x50d4202(%ebp)
2031: 52 push %edx
2032: c5 0c 04 lds (%esp,%eax,1),%ecx
2035: 04 00 add $0x0,%al
...
Disassembly of section .comment:
00000000 <.comment>:
0: 47 inc %edi
1: 43 inc %ebx
2: 43 inc %ebx
3: 3a 20 cmp (%eax),%ah
5: 28 55 62 sub %dl,0x62(%ebp)
8: 75 6e jne 78 <main-0xf8f>
a: 74 75 je 81 <main-0xf86>
c: 20 39 and %bh,(%ecx)
e: 2e 34 2e cs xor $0x2e,%al
11: 30 2d 31 75 62 75 xor %ch,0x75627531
17: 6e outsb %ds:(%esi),(%dx)
18: 74 75 je 8f <main-0xf78>
1a: 31 7e 32 xor %edi,0x32(%esi)
1d: 30 2e xor %ch,(%esi)
1f: 30 34 2e xor %dh,(%esi,%ebp,1)
22: 31 29 xor %ebp,(%ecx)
24: 20 39 and %bh,(%ecx)
26: 2e 34 2e cs xor $0x2e,%al
29: 30 00 xor %al,(%eax)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论