sarthak
sarthak

Reputation: 794

Creating x86 bootloader

I am writing a bootloader as follows:

bits 16
[org 0x7c00]
KERN_OFFSET equ 0x1000
mov [BOOTDISK], dl
mov dl, 0x0 ;0 is for floppy-disk
mov ah, 0x2 ;Read function for the interrupt
mov al, 0x15 ;Read 15 sectors conating kernel
mov ch, 0x0 ;Use cylinder 0
mov cl, 0x2 ;Start from the second sector which contains kernel
mov dh, 0x0 ;Read head 0 
mov bx, KERN_OFFSET
int 0x13
jc disk_error
cmp al, 0x15
jne disk_error
jmp KERN_OFFSET:0x0
jmp $

disk_error:
jmp $


BOOTDISK: db 0

times 510-($-$$) db 0
dw 0xaa55

The kernel is a simple C program which prints "e" on the VGA display (seen on QEmu):

void main()
{
 extern void put_in_mem();
 char c = 'e';
 put_in_mem(c, 0xA0);
}

I am using this code in 16 bit (real mode) in QEmu so I am using the compiler bcc for this code using:

bcc -ansi -c -o kernel.o kernel.c

I have the following questions:
1. When I try to disassemble this code, using

objdump -D -b binary -mi386 kernel.o

I get an output like this (only initial portion of output):

kernel.o:     file format binary

Disassembly of section .data:

00000000 <.data>:
   0:   a3 86 01 00 2a          mov    %eax,0x2a000186
   5:   3e 00 00                add    %al,%ds:(%eax)
   8:   00 22                   add    %ah,(%edx)
   a:   00 00                   add    %al,(%eax)
   c:   00 19                   add    %bl,(%ecx)
   e:   00 00                   add    %al,(%eax)
   10:  00 55 55                add    %dl,0x55(%ebp)
   13:  55                      push   %ebp
   14:  55                      push   %ebp
   15:  00 00                   add    %al,(%eax)
   17:  00 02                   add    %al,(%edx)
   19:  22 00                   and    (%eax),%al

This output does not seem to correspond to the kernel.c file I made. For example I could not see where 'e' is stored as ASCII 0x65 or where is the call to put_in_mem made. Is something wrong with the way I am disassembling the code?

  1. To make the object file of the kernel for QEmu I used the following command:
ld86 -o kernel -d kernel.o put_in_mem.o

Here put_in_mem.o is the object file created after assembling the put_in_mem.asm file which contains the definition of the function put_in_mem() used in kernel.c.
Then floppy image for QEmu is made using:

cat boot.o kernel > floppy_img

But when I try to look at the address 0x10000 (using GDB), where the kernel was supposed to be present after loading (using the boot.asm program), it was not present.
Why is this happening?
Further, in ld command we used -Ttext option to specify the load address of the binary, should we use some similar option here with ld86?

Upvotes: 3

Views: 363

Answers (1)

Jester
Jester

Reputation: 58822

Your kernel.o is in an object file format not understood by objdump so it tries to disassemble everything in it, including headers and whatnot. Try to disassemble the linked output kernel instead. Also objdump might not understand 16 bit code. Better try objdump86 if you have that available.

As to why it's not present: you are looking at the wrong place. You are loading it to offset 0x1000 (3 zeroes) but you are looking at 0x10000 (4 zeroes). Also note that you don't set up ES which is bad practice. Maybe you intended to set ES to 0x1000 and BX to 0x0000 and then you would find your kernel at 0x10000 physical address.

The -Ttext doesn't influence loading, it only specifies where the code expects to find itself.

Upvotes: 3

Related Questions