Bootloader won't load kernel

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
tomplast
Posts: 2
Joined: Thu Jun 13, 2013 11:38 pm

Bootloader won't load kernel

Post by tomplast »

Hi fellow programmers :).

I work with c# professionally but I want to code in a "real language" on my spare time so I decided to take up the good ol' Assembly coding once again :). I have "stealed" some code from different places to try and create a bootloader with loads a kernel from the second sector of the floppy drive. The only problem is that the kernel never get's loaded I think, I would be very grateful if any of you could take a look at it :).

I know I'm very rusty when it comes to Assembly and especially os development, so please bare with me :). I'm here to learn and improve, all help is much appreciated :).

bootloader.asm

Code: Select all

org 0x7c00

jmp start

;Data
heading_message db ‘** bluberry Boot Loader **’, 0x0d, 0x0a, 0
loading_message db ‘   Loading kernel…’, 0x0d, 0x0a, 0

PrintString:
lodsb
or al, al
jz PrintString_Complete

mov ah, 0x0e
int 0×10
jmp PrintString

PrintString_Complete:
ret

LoadKernel:
mov ah, 0×2 ;BIOS read sector function
mov al, 0×1 ;Number of sectors to read
mov ch, 0×0 ;Track
mov cl, 0×2 ;Sector
mov dh, 0×0 ;Head
mov dl, 0×0 ;Drive
mov bx, 0×2000
mov es, bx
mov bx, 0×0000
int 0×13

mov ax, 0×2000
mov ds, ax
push word 0×2000
push word 0
retf
;jmp 0×2000:0×0000

start:
mov si, heading_message
call PrintString

mov si, loading_message
call PrintString

call LoadKernel

times 510 – ($ – $$) db 0
dw 0xAa55
kernel.asm

Code: Select all

jmp start
kernel_loaded db ‘Welcome to blueberry’, 0

PrintString:
lodsb
or al, al
jz PrintString_Complete

mov ah, 0x0e
int 0×10
jmp PrintString

PrintString_Complete:
ret

start:
mov si, kernel_loaded
call PrintString

jmp $
P.S I'm using QEMU for trying out my code and using the following to "bake" my bootloader and kernel together:
dd if=bootloader.bin of=fda.bin bs=512 count=1
dd if=kernel.bin of=fda.bin bs=512 count=1 seek=512
D.S
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader won't load kernel

Post by iansjack »

This is not really the place to teach assembly basics. I think you need to start with some simpler examples and single-step through them, using a debugger, until you are happy that you understand what is happening. For starters, just try loading a single sector into a particular location and check that that works as expected.
tomplast
Posts: 2
Joined: Thu Jun 13, 2013 11:38 pm

Re: Bootloader won't load kernel

Post by tomplast »

iansjack wrote:This is not really the place to teach assembly basics. I think you need to start with some simpler examples and single-step through them, using a debugger, until you are happy that you understand what is happening. For starters, just try loading a single sector into a particular location and check that that works as expected.
I appreciate the advice but I prefer to learning by trying and the bootloader works. It's just the loading of the second sector that won't work, I would appreciate any insights you have into the problem.
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader won't load kernel

Post by iansjack »

There is no better way of learning, and understanding, assembler code than single-stepping through it in a debugger. You are going to come up against far more esoteric problems than this; get into good habits and learn your debugging techniques now.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Bootloader won't load kernel

Post by DavidCooper »

The numbers in registers to set up the loading of the 2nd sector are all correct, so you can't be far away from getting it working. It's just possible that you're loading your kernel on top of the stack. You should also do something about that ugly push-push far ret which ought to be a far call [edit: I actually meant far jump]. Something you could try is printing part of the message in the kernel using code in the boot sector before jumping to the kernel - that would show up if it has actually loaded. You could, for example, write an extra print routine to print a few bytes out of the middle of the message.

I don't work with assembler so I don't know how your code gets tied together, but if you use a hex editor to extract the first two sectors from your disk and post the hex here, I can read what the resulting machine code does and tell you where it's failing. You shouldn't really need that kind of help though as there are plenty of debugging techniques you can apply first to find out where the problem lies. You can look to see if the 2nd sector is loading, you can check to see if something else is loading in the place it's supposed to load, you can collect the bytes that have loaded in and see if SI is going to be loaded with the right address for the string to be printed (though you can do that more easily by looking directly at your machine code with a hex editor), etc.

Edit: And don't assume the drive number is 0 - use the value passed to you in DL by the BIOS instead.
Last edited by DavidCooper on Sat Jun 15, 2013 1:31 pm, edited 2 times in total.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Bootloader won't load kernel

Post by Prochamber »

You didn't setup a stack or set the data segment. You should not trust BIOS to have done either of those correctly.

You need to setup a stack first.

Code: Select all

cli                           ; Always clear interrupts before changing the stack
mov ax, 0x0000       ; Set a stack location before the bootloader code
mov ss, ax
mov sp, 0x7C00
sti                           ; Remember to restore interrupt
This code will setup a stack just before the bootloader, the stack works backwards (lower addresses), so it will use addresses below 0x0000:7C00.

You will need to setup the Data Segment (DS register) before you can do any memory access, i.e reading characters from a string.
Since you have ORG'd to 0x7C00 you will need to set it to a zero offset.

Code: Select all

mov ax, 0x0000
mov ds, ax
Last edited by Prochamber on Sat Jun 15, 2013 11:53 pm, edited 1 time in total.
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: Bootloader won't load kernel

Post by Griwes »

s/mov sp, 0x07C0/mov sp, 0x7C00/

Learn to do your addressing properly before answering a question.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Bootloader won't load kernel

Post by Prochamber »

Griwes wrote:s/mov sp, 0x07C0/mov sp, 0x7C00/

Learn to do your addressing properly before answering a question.
There is nothing wrong with my addressing. I've done a lot in real mode and I know how the addressing works.
I use a similar stack in the bootloader for my own operating system.

Your code would put the stack at the address 0x07C0:7C00 = 0xF800, which would still work but would use a different area.
The aim of my code was to use otherwise unoccupied space (below the bootloader).
Source: OSDev - x86 Memory Map

Yes, I used the address of the bootloader but it won't actually put any data to the bootloader because the address will be decreased before storing any data.
Source: The Art of Assembly (16 bit edition) - Chapter 6 - The PUSH and POP Instructions.
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Bootloader won't load kernel

Post by Mikemk »

tomplast wrote:

Code: Select all

int 0×10

Code: Select all

0x0123
Is it just me or do half the OP's x's look like the multiplication sign character?
How are you compiling this?
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
AndrewBuckley
Member
Member
Posts: 95
Joined: Thu Jan 29, 2009 9:13 am

Re: Bootloader won't load kernel

Post by AndrewBuckley »

Prochamber please reread the change offered by Griwes. his change does not affect your stask segment, only where you put the pointer. you're off by 4 bits magnitude.
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Bootloader won't load kernel

Post by Prochamber »

Merlin wrote:Prochamber please reread the change offered by Griwes. his change does not affect your stask segment, only where you put the pointer. you're off by 4 bits magnitude.
Oh, now I get it.
I accidental wrote 0x07C0 instead of 0x7C00 in the code. I've correct my post.
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
computertrick
Member
Member
Posts: 71
Joined: Wed May 29, 2013 1:07 pm

Re: Bootloader won't load kernel

Post by computertrick »

You should install gcc on linux and access qemu's debug console and read from the memory address 0x2000 using the xp command to see if their has been any data loaded in their you could also use x/20 0x2000 which would print 20 bytes and if you wanted to disassemble use x/20i 0x2000
1100110100010011
Rew
Member
Member
Posts: 28
Joined: Mon Oct 29, 2012 2:26 pm

Re: Bootloader won't load kernel

Post by Rew »

For early on development and getting acquainted with both assembly syntax and the intricacies of the x86 command set, I found bochs with built in debugger to be a convenient and invaluable tool. Also, you will need to find your preferred tool for disassembling and finding addresses of interest. Treat debugging assembly as if you were in visual studio, you want to see what is happening, so put a breakpoint at the beginning of your start function. Step each instruction. Check ESP and map to your disassembler addresses. Check all your "local variables" (registers) and "static variables" (memory locations) after each step and you will quickly find where your path diverges from expected.

Most importantly, when something does not work as expected, I find it easiest to check "http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html" and read the documentation on the instruction in question. When diagnosing a problem and you can't figure out what is wrong, review "Volume 1". The review it again, then again so you find what you missed the first 10 times through. In this case, section 3.3 and 3.4.2 might have helpful information to review. After that, reread the instruction and you will probably see what you missed setting up beforehand to make it work.

As mentioned by others, the things I would focus on for right now when debugging are segment registers and stack location. The reason for focusing on these can be found in the first paragraph or two of the documentation of the call instruction and jump instruction.



P.S. As harsh as it seems, as can be observed by the first couple responses, this community is critical of basic code specific questions for the most part. There is an abundance of knowledge and helpful individuals with regards to O.S. and architecture design and theory. But, if you're going to succeed in an O.S. project, you will need to setup an environment where you can be self sufficient on debugging code, and rely on the community for technical knowledge. Some people are a bit abrasive about this point, but truly for this type of project there is no better help then encouraging someone to learn how an architecture works by debugging or finding enough to ask the community about a specific technical question they don't understand.
Post Reply