Page 1 of 2

Bugs on bootloader

Posted: Sat Jun 26, 2004 7:02 am
by Vladaz
Hello. I have programmed my simple bootloader that boots from floppy and writes me "Hello, World!". The source:

Code: Select all

[BITS 16]
[ORG 0x7C00]

start:
   mov si, msg
   call Print

msg db "Hello, World!"

Print:
     mov ah,0x0E              
     mov bh,0x00              
.NextChar:
     lodsb
     or al,al
     jz .return               
     int 0x10                 
     jmp .NextChar
.return:
     ret

times 510-($-$$) db 0
dw 0xAA55
But it writes me not that text, but some strange symbols that lenght is about 2 lines. What I have to do to fix that bug?

Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 7:50 am
by pkd
try setting DS to 0x00, as it may not be set to zero on boot.

hope this helps

pkd

Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 7:53 am
by Brendan
Hi,

The instruction "lodsb" loads AL with the value at DS:SI, and increments or decrements SI depending on the direction flag. Your code doesn't set DS, so it could be wrong. Your code doesn't clear the direction flag either, so it could be wrong too.

Code: Select all

[BITS 16]
[ORG 0x0]

start:
   jmp 0x00:here

msg db "Hello, World!"

here:
   xor ax,ax
   mov ds,ax
   mov es,ax
   mov fs,ax
   mov gs,ax
   cli
   mov ss,ax
   mov sp,0x7c00

   mov si, msg
   call Print

.die:
   jmp .die


Print:
     mov ah,0x0E           ???
     mov bh,0x00           ???
     cld
     lodsb
.doChar:
     int 0x10              ???
     cld
     lodsb
     test al,al
     jne .doChar
.return:
     ret

times 510-($-$$) db 0
dw 0xAA55
Cheers,

Brendan

Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 10:21 am
by Vladaz
I tried this source that you wrote me, but it didn't write me Hello, World! or anything.

Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 11:22 am
by DennisCGc
Vladaz wrote:

Code: Select all

[BITS 16]
[ORG 0x7C00]

start:
???mov si, msg
???call Print

msg db "Hello, World!"

Print:
     mov ah,0x0E           ???
     mov bh,0x00           ???
.NextChar:
     lodsb
     or al,al
     jz .return            ???
     int 0x10              ???
     jmp .NextChar
.return:
     ret

times 510-($-$$) db 0
dw 0xAA55
Hmm, try:

Code: Select all

[BITS 16]
[ORG 0x7C00]

start:
   xor  ax,ax
   mov ds,ax
   mov es,ax
   mov ss,ax
   mov sp,0xfffe ;just to be sure.....
   mov si, msg
   call Print

msg db "Hello, World!",0 ;0 must be included!

Print:
     cld
.NextChar
     lodsb
     or al,al
     jz .return               
     mov ah,0x0E              
     mov bx,0700h
     int 0x10         
     jmp .NextChar
.return:
     ret

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


Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 11:49 am
by Vladaz
That code doesn't work on Bochs. It writes me:
Bochs is exiting with the following message:
[CPU ] prefetch: RIP > CS.limit

Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 12:55 pm
by FlashBurn
You are missing an instruction behind "call Print" write jmp $ there, because if you don?t do that it will execute the code that comes behind and this is your string. Put the string to the end of the file!

Edit::

And as said, the string needs to be 0-terminated!

Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 4:36 pm
by Vladaz
OK. Everything is OK now. Thanks! 8)
But I have some more questions about that code:
1. Do I have to null all segments, or just i need to null DS, ES, SS segments?
2. What means this line: mov sp,0xfffe ?
3. Why cld must be written in Print procedure?
Code:

Code: Select all

[BITS 16]
[ORG 0x7C00]

start:
  xor ax,ax
  mov ds,ax
  mov es,ax
  mov ss,ax
  mov sp,0xfffe ;just to be sure.....
  
  mov si, msg
  call Print

  jmp $

Print:
    cld
.NextChar
    lodsb
    or al,al
    jz .return              
    mov ah,0x0E              
    mov bh,0x00
    int 0x10        
    jmp .NextChar
.return:
    ret

msg db "Hello, World!",0 ;0 must be included!

times 510-($-$$) db 0
dw 0xAA55
I would be thankful if you answer me those questions.

Re:Bugs on bootloader

Posted: Sat Jun 26, 2004 5:51 pm
by Cemre
1. Do I have to null all segments, or just i need to null DS, ES, SS segments?
if org is 0x7C00 you "have to" zero DS.
because you use a "lodsb" which by default
loads from DS:SI ( "D"ata "S"egment :
"S"ource "I"ndex [ source pointer ] )
ES and SS is not necessary, but remember
it is good to have a known stack so put
SS:SP to somewhere ( not necessarily
0x0000:something ) and you also even
dont need to zero CS but because org
is 0x7C00, you need to zero it.
2. What means this line: mov sp,0xfffe ?
mov ax , 0 ( xor ax , ax )
mov ss , ax
mov sp , 0xFFFE

puts the stack to 0x0000:0xFFFE ( a really
good place for stack, but better in my
opinion is 0x9000:0xFFFE )
3. Why cld must be written in Print procedure?
lodsb does the following

mov al , [ DS:SI ]
if DF=clear SI++ else SI--

DF is direction flag ( in flags register. lodsb
increments SI if DF is zero, decrements if
it is set (1). CLD clears the direction flag
and thus lodsb loads and increments SI, you can
not trust the DF to be reset so you must clear
it on entry to "Print" yourself.

it would be a little funny but it IS possible to write
a string in reverse direction by first putting the SI to
the end of the string and using STD ( set DF ) instead
of CLD, who would ever want this is another question.

Re:Bugs on bootloader

Posted: Sun Jun 27, 2004 6:49 am
by Vladaz
So in your 2th answer i need to write like this:
mov ax , 0
...
mov ss , 0x9000
mov sp , 0xFFFE
?

Re:Bugs on bootloader

Posted: Sun Jun 27, 2004 7:20 am
by DennisCGc
Vladaz wrote: So in your 2th answer i need to write like this:
mov ax , 0
...
mov ss , 0x9000
mov sp , 0xFFFE
?
No... you can't set the SS directly which means you can't simply do this:

Code: Select all

mov ss, 0x9000
But this will work:

Code: Select all

mov ax,0x9000
mov ss,ax
Think of where to put your stack safely..
0x0:0xfffe would be safe enough for a bootloader.....
So, program as this:

Code: Select all

xor ax,ax ;could also be mov ax,0
mov ss,ax ;can't set mov ss,0 directly, use ax or another register to set segment selectors!
mov sp,0xfffe ; set offset of the stack to 0xfffe
HTH

Re:Bugs on bootloader

Posted: Mon Jun 28, 2004 2:27 am
by Candy
Hint: until you've taken over the computer the BIOS may write to its EBDA, which is at the exact point where you place the stack. That is, 0x9FFFE (and positions around that).

Place your stack below that point. Somewhere around 0x80000 should be OK, taking even the 512k machines into account. See linux bootloader comments for information.

Re:Bugs on bootloader

Posted: Tue Jun 29, 2004 5:21 pm
by Vladaz
Ok. I have learnt about PMode, and I think i know something ::)
But I have new problem. My bootloader doesn't boot my kernel and i think there is a problem with PMode.
Please help me. Maybe you know something and maybe you'll see problems and bugs in my source.
Bootloader code:

Code: Select all

[BITS 16]
[ORG 0x7C00]

Start:
   mov [bootDrive], dl
   
   xor ax, ax
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov ss, ax
   mov sp, 0xFFFE

   mov si, msgInit
   call Print

   call A20

   call SectorLoader

   cli
   
   xor ax, ax
   mov ds, ax

   lgdt [gdt_desc]

   mov eax, cr0
   or eax, 1
   mov cr0, eax

   jmp 0x08:go_pm

Code: Select all

[BITS 32]

go_pm:
   mov ax, 0x08
   mov ds, ax
   mov ss, ax

   mov esp, 0x90000

   jmp 0x90000

   jmp $

Code: Select all

[BITS 16]

;;;;; Procedures

Print: 
   cld
.nextChar
   lodsb
   or al, al
   jz .end
   mov ah, 0x0E
   mov bh, 0x00
   int 10h
   jmp .nextChar
.end
   ret

Code: Select all

A20:
   cli
   xor cx, cx

.clear_buffer
   in al, 0x64
   test al, 0x2
   loopnz .clear_buffer
   
   mov al, 0xD1
   out 0x64, al

.clear_buffer2
   in al, 0x64
   test al, 0x2
   loopnz .clear_buffer2
   
   mov al, 0xDF ; set A20 line
   out 0x60, al
   mov cx, 0xFF

.wait_kbc
   out 0xED, ax
   loop .wait_kbc
.end
   sti

   mov si, msgDot
   call Print

   ret

Code: Select all

SectorLoader:
   mov ah, 0x02
   mov al, 0x14
   mov ch, 0x00
   mov cl, 0x02
   mov dh, 0x00
   mov dl, [bootDrive]
   
   mov bx, 0x9000
   mov es, bx
   mov bx, 0x0000
.readsector
   int 13h
   jc .readsector

   mov si, msgDot
   call Print
.end
   ret

Code: Select all

;;;;; GDT
gdt:

gdt_null:
   dd 0

gdt_code:
   dw 0xFFFF
   dw 0x0
   db 0x0   
   db 0x9A
   db 0xCF
   db 0x0

gdt_data: 
   dw 0xFFFF
   dw 0x0
   db 0x0
   db 0x92
   db 0xCF
   db 0x0

gdt_end

gdt_desc:
   db gdt_end - gdt
   dw gdt

;;;;; Variables
msgInit db "Initializing",0
msgDot db ".",0
bootDrive db 0

;;;;; Important
times 510-($-$$) db 0
dw 0xAA55
Thanks

Re:Bugs on bootloader

Posted: Wed Jun 30, 2004 1:35 am
by Brendan
Hi,

I've only had a quick look, but..
Vladaz wrote:

Code: Select all

go_pm:
   mov ax, 0x08
   mov ds, ax
   mov ss, ax
Your data segment is 0x10 not 0x08!

Cheers,

Brendan

Re:Bugs on bootloader

Posted: Wed Jun 30, 2004 9:29 am
by Vladaz
I changed those lines to this:

Code: Select all

go_pm:
  mov ax, 0x10
  mov ds, ax
  mov ss, ax
But it still doesn't work. :(