Page 1 of 2

SOLVED: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 6:34 pm
by thestew42
I wrote a boot sector that loads another section of code and jumps to it, but the second "stage" that I load doesn't always work. I decided to test that it loaded and jumped correctly by printing an 'A' to the screen:

Code: Select all

[BITS 16]		;16 bit code generation

;************************************************
;Procedure START
;Main program start
;************************************************
Main:
	;Print character
	mov     ah, 0x0E
	mov     bh, 0x00
	mov     bl, 0x07
	mov	al, 65
	int     0x10
	
	;Idle
	jmp $
The previous code works as expected. Then I tried to store the character and print it:

Code: Select all

[BITS 16]		;16 bit code generation

;************************************************
;Procedure START
;Main program start
;************************************************
Main:
	;Print character
	mov     ah, 0x0E
	mov     bh, 0x00
	mov     bl, 0x07
	mov	al, loadedChar
	int     0x10
	
	;Idle
	jmp $
	
loadedChar db 65
When I run this, it prints a funny character that looks like a cross with a loop at the top where the 'A' should be. I'm kinda new with assembly so the problem may be extremely obvious, but it seems correct to me. Even when I move 'loadedChar db 65' in front of the printing code like you would in an HLL it still doesn't work.

Any help would be appreciated. Thanks for reading.

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 7:55 pm
by Zenith
Try doing

Code: Select all

mov al, [loadedChar]
IIRC, if you're using NASM, FASM, etc., this should reference the stored variable in memory instead of using the offset of 'loadedChar' as an immediate operand.

Hope this helps!

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 8:51 pm
by thestew42
Hmm. That seems like it would do the trick, but the code still doesn't work. Now, I get a smiley face instead of the ever-anticipated 'A'. The code is now

Code: Select all

[BITS 16]      ;16 bit code generation

;************************************************
;Procedure START
;Main program start
;************************************************
Main:
   ;Print character
   mov     ah, 0x0E
   mov     bh, 0x00
   mov     bl, 0x07
   mov     al, [loadedChar]
   int     0x10
   
   ;Idle
   jmp $
   
loadedChar db 65

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:04 pm
by sngskunk
Here use this asm function to print:

Code: Select all

message db "Hello World", 0x00  ; String to print

mov  si, message  ; Moves the message in to si register
call  print ; Prints string to memory

print:
  pusha
 
  .LOOP:
    lodsb
    or  al, al
    jz .DONE
    mov  ah, 0x0E
    int  0x10
    jmp  .LOOP

  .DONE:
    popa
    ret

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:12 pm
by thestew42
This works in the boot sector, but not in the loaded code. It seems like there is something else contributing to this problem. Its just strange because as long as I put the character value directly in the mov al, ... line, it works. With the posted print function, it just puts a space.

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:19 pm
by bewing
That means that your "second stage" is not being linked properly. The code does not correctly understand what address it is running at, or what address your loadedChar "array" is stored at. Look at your linker script to find out what is wrong.

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:29 pm
by thestew42
I'm actually not using a linker script (or if I am, I don't know what I'm talking about which is entirely possible). I'm just assembling like this:

nasm -o LOADER.BIN loader.asm

where loader.asm is:

Code: Select all

[BITS 16]      ;16 bit code generation

;************************************************
;Procedure START
;Main program start
;************************************************
Main:
   ;Print character
   mov     ah, 0x0E
   mov     bh, 0x00
   mov     bl, 0x07
   mov     al, [loadedChar]
   int     0x10
   
   ;Idle
   jmp $
   
loadedChar db 65
I just copy that to the disk.

Now you said it has to do with the code not knowing where it is running. Does this mean I need an [ORG ...] line somewhere?

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:36 pm
by sngskunk
call nasm like this:

Code: Select all

nasm -fbin -o LOADER.BIN loader.asm
that makes it a binary file, what you are getting most likely a elf object file.

I almost forgot you need to setup your data segments and stack to, you might have already I dont know but you could give this a try:

Code: Select all

cli
xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0x8000
mov ss, ax
mov sp, 0xFFFF
sti

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:45 pm
by thestew42
I tried that but I still have the exact same problem. I set up the stack in the boot sector like this:

Code: Select all

mov     ax, 0x0000
	mov     ss, ax
	mov     sp, 0xFFFF
	sti
I'm not sure if I'm supposed to do it again. Even when I do, it doesn't work.

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:50 pm
by sngskunk
did you compile it as a binary?

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:50 pm
by Omega
here is what I do:

Code: Select all

nasm -w-orphan-labels -f bin boot.asm -o boot.bin
nasm -w-orphan-labels -f bin boot2.asm -o boot2.bin
c:\djgpp\bin\makeboot a.img boot.bin boot2.bin
Seems to work for me. I just can't get my gosh forsaken kernel to load!! Hope you have better luck.

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:54 pm
by thestew42
I'm pretty sure it's a binary. As I said, it works as long as I don't read the character from a variable.

Re: Second Stage Boot Loader Not Functioning

Posted: Thu Jun 19, 2008 9:59 pm
by Omega
Sounds like a stack issue.

Re: Second Stage Boot Loader Not Functioning

Posted: Fri Jun 20, 2008 5:13 am
by bewing
Yes, if you are not using a linker, you most definitely do need an ORG line somewhere. Where is your first stage bootloader placing this code in RAM? And how is the code supposed to know where the data is located, if you don't tell it?

Re: Second Stage Boot Loader Not Functioning

Posted: Fri Jun 20, 2008 7:44 am
by Combuster
To summarize:

0) know what the CS:IP value is when your code gets entered.
1) add an ORG statement to match that IP.
2) make sure DS and ES equal CS before using them (you use them when referencing memory) Note that the snippet provided above sets DS and ES to zero, which might not match the value of CS.
3) its good practice to set up a stack too so that you can use PUSH, POP and bios calls safely (and make #1 easier)