OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Nov 14, 2018 1:57 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Qemu and my OS crashing
PostPosted: Sun Jul 01, 2018 1:03 am 
Offline

Joined: Sun Jul 01, 2018 1:01 am
Posts: 1
Here's my code:
Code:
bits 16 ; 16-bit Real Mode
org 0x7c00 ; BIOS boot origin

jmp main ;Jump to start main() entry-point

Message db "Hello, world! Starting YetAnotherDecentBootloader", 0x0
MessageB db "A bootloader written by Ari Eythorsson for his operations system, YADOS", 0x0
AnyKey db "Press any key to reboot...", 0x0

;Print characters to the screen
Println:
    lodsb ;Load string
    or al, al
    jz complete
    mov ah, 0x0e    
    int 0x10 ;BIOS Interrupt 0x10 - Used to print characters on the screen via Video Memory
    jmp Println ;Loop      
complete:
    call PrintNwL

;Prints empty new lines like '\n' in C/C++    
PrintNwL:
    mov al, 0   ; null terminator '\0'
    stosb       ; Store string

    ;Adds a newline break '\n'
    mov ah, 0x0E
    mov al, 0x0D
    int 0x10
    mov al, 0x0A
    int 0x10
   ret

;Reboot the Machine
Reboot:
    mov si, AnyKey
    call Println
    call GetPressedKey

    ;Sends us to the end of the memory
    ;causing reboot
    db 0x0ea
    dw 0x0000
    dw 0xffff

;Gets the pressed key
GetPressedKey:
    mov ah, 0
    int 0x16  ;BIOS Keyboard Service
    ret

;Bootloader entry-code
main:
   cli ;Clear interrupts
   ;Setup stack segments
   mov ax,cs             
   mov ds,ax   
   mov es,ax               
   mov ss,ax               
   sti ;Enable interrupts

   ;Print the first characters 
   mov si, Message
   call Println

   mov si, MessageB
   call Println

   call PrintNwL
   call PrintNwL

   call Reboot

   times 510 - ($-$$) db 0 ;Fill the rest of the bootloader with zeros
   dw 0xAA55 ;Boot signature

And the error is Trying to execute code outside RAM or ROM at 0x00000000000a0000
I've tried a lot to fix this, thank you guys


Top
 Profile  
 
 Post subject: Re: Qemu and my OS crashing
PostPosted: Sun Jul 01, 2018 1:35 am 
Offline

Joined: Sun Jul 07, 2013 7:29 pm
Posts: 16
My guess it is related to segment memory addressing used in real mode.

I am looking at qemu multiboot trampoline code and I see they calculate segment offset and add to the symbol address. Something like this (did not test in QEMU):

# calculate offset from %cs segment register
mov %cs, %eax
shl $0x4, %eax

# add the offset to funcion
mov $myfunc, %ebx
add %eax, %ebx

# and then jump
jmp *%ebx


Top
 Profile  
 
 Post subject: Re: Qemu and my OS crashing
PostPosted: Sun Jul 01, 2018 2:54 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3303
Location: Chichester, UK
Your code works just fine for me.

What assembler are you using and what is your command line? What is your qemu command line?


Top
 Profile  
 
 Post subject: Re: Qemu and my OS crashing
PostPosted: Sun Jul 01, 2018 8:39 am 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 475
Location: USA
Hi,

You tell the assembler that all offsets will begin at 0x7C00, here:
Code:
org 0x7c00 ; BIOS boot origin

However, here, you place an unknown value into ds, es, and ss.
Code:
main:
   cli ;Clear interrupts
   ;Setup stack segments
   mov ax,cs             
   mov ds,ax   
   mov es,ax               
   mov ss,ax               
   sti ;Enable interrupts

   ;Print the first characters 
   mov si, Message
   call Println

At this point, cs can be anything. Since you told the assembler all offsets were at 0x7C00, you need the segment portion to be 0x0000.

For example, let's say that on entry to your code, the BIOS has placed the value of 0x07C0 in to CS -- A very common value for a BIOS. With this in mind, the processor actually takes:
Code:
   mov si, DS:Message     ; DS: is implied (actually, implied later in the PrintLn routine)
   call Println

and coverts the physical address to:
Code:
   mov  [ds:si],(0x07C0 << 4) + (0x7C00 + offset of Message)

Hence, the physical address used is actually:
Code:
0xF800 + offset of Message

Same thing happens on the call instruction. Even though the call is a relative call, the assembler thinks that the offset of "PrintLn" is somewhere past 0x7C00. If CS is 0x07C0, the physical call could easily be within the BIOS somewhere.

Even though many tutorials and other web sites say that you need to set CS and/or set DS (and ES) to CS, they are wrong. You have no idea what CS will be. It is completely up to the BIOS POST code to set CS as long as the CS:IP pair points to physical address 0x07C00.

The best thing to do is to set DS (and ES, SS, etc) to 0x07C0 and tell the assembler to use an offset of 0x0000.
Code:
org 0x0000 ; BIOS boot origin
   xor  ax,ax
   mov  ds,ax   
   mov  es,ax               
   mov  ss,ax               
   mov  sp,0x7C00

Don't even touch CS. Don't "extract" the value from it, and definitely don't set it to something. As long as you don't use a CS: override or use other instructions that use the CS segment register, you don't even care what CS:IP is. Besides, in a boot sector (the first stage code), you would never use any instructions like this anyway.

Ben
- http://www.fysnet.net/osdesign_book_series.htm


Top
 Profile  
 
 Post subject: Re: Qemu and my OS crashing
PostPosted: Sun Jul 01, 2018 12:01 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1334
BenLunt wrote:
The best thing to do is to set DS (and ES, SS, etc) to 0x07C0 and tell the assembler to use an offset of 0x0000.

I disagree; setting segment registers to 0 and telling the assembler to use an offset of 0x7C00 is better since it makes linear addresses equivalent to physical addresses. Something like this:
Code:
org 0x7C00
   xor  ax,ax
   mov  ds,ax   
   mov  es,ax               
   mov  ss,ax               
   mov  sp,0x7C00


No matter which option you choose, there are a handful of (typically uncommon) addressing modes for the CALL and JMP instructions that you can't use until after you do a far JMP to set CS.


Top
 Profile  
 
 Post subject: Re: Qemu and my OS crashing
PostPosted: Sun Jul 01, 2018 5:57 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 475
Location: USA
Octocontrabass wrote:
BenLunt wrote:
The best thing to do is to set DS (and ES, SS, etc) to 0x07C0 and tell the assembler to use an offset of 0x0000.

I disagree; setting segment registers to 0 and telling the assembler to use an offset of 0x7C00 is better since it makes linear addresses equivalent to physical addresses. Something like this:

Which looking back, I didn't even write the code correctly. I put the org at 0x0000 *and* the segs at 0x0000. Man, it's been a long week...

Thanks,
Ben


Top
 Profile  
 
 Post subject: Re: Qemu and my OS crashing
PostPosted: Mon Jul 02, 2018 10:10 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 67
Funny, all this talk of segments and assembler directives, and no one ever told the OP that he was also trying to use "call" and "int" before setting up a stack... He set SS, but SP was untouched all the way to the first "call", and that subroutine would use interrupts. Neither of which is well-advised before you know SP to be out of the way of your code, your data, and the BIOS data areas.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 15 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group