1 year ago
#370960
jack101yello
Why does Bochs say "No bootable devices found" when I concatenate a kernel to my boot sector?
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 $< -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
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)
assembly
kernel
bootloader
osdev
bochs
0 Answers
Your Answer