1 year ago

#370960

test-img

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

Accepted video resources