OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Nov 21, 2017 11:12 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Second stage bootloader won't show a message
PostPosted: Wed Sep 27, 2017 2:56 pm 
Offline

Joined: Wed Sep 27, 2017 2:50 pm
Posts: 12
Hello.

My second stage boot loader works but when i print a message, it just shows a blank screen. When I do it with the boot loader, it works. Heres my code.

boot.asm

Code:
bits 16
org 0x7c00

Main:
mov ax, 0x7e00
mov es, ax
mov bx, 0

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
int 13h

jmp 0x7e00:0000

cli
hlt

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


kernel.asm

Code:
bits 16
org 0x7e00

jmp main

main:
mov si, msg
call print

print:
lodsb
cmp al, 0
je done
mov ah, 0eh
int 10h
jmp print

done:
ret

cli
hlt


I've tried to troubleshoot. I tried changing the address the code is put in memory. I have seen a message with an equal sign and a S. What seems to be the problem? Sorry, I have took a break from OSDev :/

_________________
Computers aren't to blame... the ones who program them are.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Wed Sep 27, 2017 3:33 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 27, 2004 11:00 pm
Posts: 829
Location: WA
well first there are problems with your bootsector... it won't work on real hardware (though it will probably work on emulators most of the time)

but ignoring that... you haven't defined msg anywhere (that I can see) -- are you sure its set correctly? (your description of the problem sounds suspiciously like printing a nullptr)

also:
your code is broken: it should print the string, and then start running random memory

first you are calling the print function (seems correct as long as your pointer is correct)

then you are returning and falling through into... the same print function you just called (this will actually work correctly, and will print whatever happens to be in SI... probably whatever is after the string that you printed first)

but then your print function returns... but since it wasn't called, you will return to whatever happened to be on the stack before... which means you will be returning to random memory and executing random data (very not good... and on real hardware it may damage the computer)

_________________
## ---- ----- ------ Intel Manuals
OSdev wiki


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Thu Sep 28, 2017 1:47 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 81
mofule wrote:
Code:
Main:
mov ax, 0x7e00
[snip the disk read]
jmp 0x7e00:0000

I think you may misunderstand how real mode segmentation works. The physical address is (segment*16)+offset or it can be written as (segment<<4)+offset

0x7e00:0x0000 is actually physical address (0x7e00<<4)+0x0000 which is 0x7e000 . I don't believe that is what you want. It looks like you really want to us 0x0000:0x7e00 which is (0x0000<<4)+0x7e00 = physical address 0x7e00. You'll want to set up ES:BX for the disk read as ES=0x0000 and BX=0x7e00 as well.

When the BIOS transfers control to your bootloader it will set DL to the drive umber that is booted. You should not use the value of 0 (always Floppy A) when doing disk reads from the boot media. You should use the value in DL passed to the bootloader.

Your final CLI/HLT sequence should be moved so it appears after the call to print so that it doesn't fall into your print function.

You should also never assume ES and DS are set to what you expect. You should always explicitly load them with the values you need. You should also set up the stack pointer (SS;SP) yourself.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Thu Sep 28, 2017 2:06 pm 
Offline

Joined: Wed Sep 27, 2017 2:50 pm
Posts: 12
MichaelPetch wrote:
mofule wrote:
Code:
Main:
mov ax, 0x7e00
[snip the disk read]
jmp 0x7e00:0000

I think you may misunderstand how real mode segmentation works. The physical address is (segment*16)+offset or it can be written as (segment<<4)+offset

0x7e00:0x0000 is actually physical address (0x7e00<<4)+0x0000 which is 0x7e000 . I don't believe that is what you want. It looks like you really want to us 0x0000:0x7e00 which is (0x0000<<4)+0x7e00 = physical address 0x7e00. You'll want to set up ES:BX for the disk read as ES=0x0000 and BX=0x7e00 as well.

When the BIOS transfers control to your bootloader it will set DL to the drive umber that is booted. You should not use the value of 0 (always Floppy A) when doing disk reads from the boot media. You should use the value in DL passed to the bootloader.

Your final CLI/HLT sequence should be moved so it appears after the call to print so that it doesn't fall into your print function.

You should also never assume ES and DS are set to what you expect. You should always explicitly load them with the values you need. You should also set up the stack pointer (SS;SP) yourself.


ive tried using 0x7c00 and that work but 0x7e00 doesnt. Why's that?

_________________
Computers aren't to blame... the ones who program them are.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Fri Sep 29, 2017 8:50 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 27, 2004 11:00 pm
Posts: 829
Location: WA
ok, your jumping to 0x7E00:0000 is actually correct... but many other things aren't, let me try to give a partial list:

for your bootsector:
1)
Code:
int 13h

you haven't set up your stack yet -- the stack the BIOS was using is not guaranteed to be valid (for practical reasons it probably will be, but you really are supposed to set up a stack before using it)

2)
Code:
int 13h

jmp 0x7e00:0000

this will likely work most of the time on most emulators, but will not work on real hardware -- in reality, any time you read from the disk you need to be prepared for read errors and retry the disk read -- this is especially true for the FDD

3)
Code:
cli
hlt

this isn't really an error but it is unnecessary (since the jmp transfers execution elsewhere)

this code could be rewritten better by adding a stack setting code, and then adding code to retry the disk read if the read function returns an error

for your 2nd stage:
4)
Code:
org 0x7e00

this is actually wrong: it should be org 0

the org value is added to addresses by the assembler, and thus should be set to the offset to be added -- the starting offset from DS (not CS, and not the segment)

5)
Code:
jmp main

main:

not really an error, but completely unnecessary
6)
Code:
mov si, msg

where is msg defined? I see it nowhere in the code you posted... most likely this is zero (as that would explain the symptoms you described)

7)
Code:
call print

print:

this works, but it does something unexpected... after calling print, it returns and continues executing here... making it execute print again, this time with SI pointing after the end of your previous string (this will print whatever garbage happened to be in memory after your string...)

to this point this code actually works however, but it causes this error here:

8 )
Code:
ret

this isn't an error itself, but because of problem #7, it becomes an errror...

the first time print is called this works correctly, however because you drop into the print function after returning from the print function this ret returns to whatever was on the stack before... which means you now loose control of the CPU

worse, the CPU will continue executing random instructions from random memory until it gets to an instruction that reads/writes a hardware device, and by doing so sets that device to a bad setting which destroys the computer

while this might not happen, it will certainly not do what you want it to do

9) -- this one is out of order because of the relation between the previous 2
Code:
lodsb

this instruction isn't doing what you think it is -- you haven't set DS, therefore you aren't taking the message from wherever you have it (its not anywhere in the code you posted) but rather taking it from the address 7e00 (your org statement) + offset-of-message-in-file + whatever_DS_base_happens_to_be_set_to...


this 2nd stage could be better rewritten by:
change org to 0
be sure to place the message in the same file with the 2nd stage
set DS as appropriate so it can reach your 2nd stage (where the data is)
move your
Code:
cli
hlt

up to be between the
Code:
call print

line and the
Code:
print:

line


if you make the changes and fixes I described here, your code should work

edit:
do note that some emulators halt execution when they find a HLT instruction with IF=0 (like your cli;hlt instruction pair you have been using) -- sometimes this will happen before the printed text is actually displayed to the screen, if this happens replacing the cli;hlt instruction block with:
Code:
end:
hlt
jmp end

will fix it and allow the text to be displayed properly

_________________
## ---- ----- ------ Intel Manuals
OSdev wiki


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Fri Sep 29, 2017 11:00 am 
Offline

Joined: Wed Sep 27, 2017 2:50 pm
Posts: 12
I've tried all this. I've tried changing addresses. However, my OS does show a S and a 0. I've tried org 0. Sorry for not putting my message in with the code. It is defined.

Messages work in the bootloader but not my second stage. When I try loading my second stage at 0x7c00, it works but I fear that overwrites my bootloader.

Sorry, I took a little break from OSDev. Just trying to get the hang of it again.

_________________
Computers aren't to blame... the ones who program them are.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Fri Sep 29, 2017 12:19 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 27, 2004 11:00 pm
Posts: 829
Location: WA
without repeating myself, I will just say this:

there are only 4 possibilities:
1) you are not storing your 2nd stage in the correct place on the disk (I don't know how you are doing it, so obviously I don't know if you are doing it correctly)
2) you are not actually loading the 2nd stage (the int 13h call is returning an error and not loading the sector at all) -- probably not the case if your using an emulator (but definitely the case if your using a real FDD on a real computer -- see #2 on my previous list)
3) you are not properly defining your string

or, you are correctly defining the string and loading the 2nd stage... in that case we know for sure what the problem is:
4) you are not properly setting up DS (see #9 on the list I previously posted)


note that #4 will prevent it from printing regardless of anything else that may be wrong, it must be fixed before it can work


do note that it printing correctly from the bootsector but not from the 2nd stage is a symptom of not setting DS (it will work in the bootsector on some computers but not on other computers, and never from the 2nd stage)

I highly recommend that you go through my previous post carefully, fix everything I mentioned, then if it still doesn't work post again and include the full (not partial, must include everything in the files -- including the definition of your string), fixed, code

_________________
## ---- ----- ------ Intel Manuals
OSdev wiki


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Fri Sep 29, 2017 3:22 pm 
Offline

Joined: Wed Sep 27, 2017 2:50 pm
Posts: 12
JAAman wrote:
without repeating myself, I will just say this:

there are only 4 possibilities:
1) you are not storing your 2nd stage in the correct place on the disk (I don't know how you are doing it, so obviously I don't know if you are doing it correctly)
2) you are not actually loading the 2nd stage (the int 13h call is returning an error and not loading the sector at all) -- probably not the case if your using an emulator (but definitely the case if your using a real FDD on a real computer -- see #2 on my previous list)
3) you are not properly defining your string

or, you are correctly defining the string and loading the 2nd stage... in that case we know for sure what the problem is:
4) you are not properly setting up DS (see #9 on the list I previously posted)


note that #4 will prevent it from printing regardless of anything else that may be wrong, it must be fixed before it can work


do note that it printing correctly from the bootsector but not from the 2nd stage is a symptom of not setting DS (it will work in the bootsector on some computers but not on other computers, and never from the 2nd stage)

I highly recommend that you go through my previous post carefully, fix everything I mentioned, then if it still doesn't work post again and include the full (not partial, must include everything in the files -- including the definition of your string), fixed, code


I think it's the segmented addressing. Why does my second stage bootloader print a message if it is loaded at 0x7c00 but not 0x7e00? It's not any of these 'bad practices' much. It's the fact that using 0x7e00 doesn't seem to work. I just don't understand why.

_________________
Computers aren't to blame... the ones who program them are.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Fri Sep 29, 2017 3:48 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 27, 2004 11:00 pm
Posts: 829
Location: WA
mofule wrote:
I think it's the segmented addressing. Why does my second stage bootloader print a message if it is loaded at 0x7c00 but not 0x7e00?

as I said, the reason it does print the message if it is loaded at 0x7C00 but doesn't print the message if it is loaded at 0x7E000 is because you haven't set the DS register properly

additionally, if you run it on different computers, on some computers it will print the message if loaded at 0x7C00 and on other computers it won't print the message when loaded at exactly the same address!

in theory it is actually possible that it will print the message correctly when loaded at 0x7E00:0 on some computers! (but not on most computers) but on those computers it will not print the message if it is loaded at 0x7C00

when you run the "lodsb" instruction, the CPU fetches a byte from memory at the address specified by the register combination DS:SI -- you have set SI to the address of the message you want to print, but you left whatever random data the firmware happened to have in DS before calling your bootsector in DS... so obviously this isn't going to work correctly...

therefore, as I have been saying for the last 3 posts now, I will repeat yet again: set DS register correctly and it will automatically start working on some emulators (if you don't fix the rest of the errors I mentioned, it won't work on any real hardware, and will fail on some emulators as well)

Quote:
It's not any of these 'bad practices' much.

none of what I mentioned are "bad practices"... 7 of them are outright errors that will cause it to not work (2 of them are not errors, just unnecessary) -- and one of them (#8 on my list) can actually destroy the computer it is running on (physically damage the hardware such that the computer can never run again and must be thrown in the garbage and replaced with a new computer)



Quote:
It's the fact that using 0x7e00 doesn't seem to work. I just don't understand why.

... you are not actually using address 0x7E00... you are using address 0x7E000 (note the extra zero) -- and it doesn't matter at all what address you use, if you don't set DS correctly it will not work (on the particular emulator you are using, it happens to work at address 0x7C00... but that isn't true for all computers)

in RMode, the segment is multiplied by 16 (moved to the left 1 hexidecimal position) and added to whatever offset address you use

so when you specify a 16bit address (such as SI in the lodsb instruction) where does the CPU get the segment from? from the DS register... which you haven't set to anything and left whatever garbage value the BIOS had in that register before you ran it... and that is not going to work

on the particular emulator you happen to be testing this on, this value happens to contain a 0 (which is why it works when you try to print from 0x7C00) but this is not true for other computers or emulators -- regardless, you must always set DS before using any data (such as your string) always -- this is not "best practices", this is not "you should", this is not "you might want to", the is must because it will not work at all if you don't



edit:
really, fixing the 7 errors I pointed out will cause your code to magically start working, not only on the emulator you are using, but on all emulators and real hardware, and shouldn't be hard to do -- it should take you less time to make those fixes than it took me to write this post

_________________
## ---- ----- ------ Intel Manuals
OSdev wiki


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Sat Sep 30, 2017 4:04 am 
Offline

Joined: Wed Sep 27, 2017 2:50 pm
Posts: 12
JAAman wrote:
mofule wrote:
I think it's the segmented addressing. Why does my second stage bootloader print a message if it is loaded at 0x7c00 but not 0x7e00?

as I said, the reason it does print the message if it is loaded at 0x7C00 but doesn't print the message if it is loaded at 0x7E000 is because you haven't set the DS register properly

additionally, if you run it on different computers, on some computers it will print the message if loaded at 0x7C00 and on other computers it won't print the message when loaded at exactly the same address!

in theory it is actually possible that it will print the message correctly when loaded at 0x7E00:0 on some computers! (but not on most computers) but on those computers it will not print the message if it is loaded at 0x7C00

when you run the "lodsb" instruction, the CPU fetches a byte from memory at the address specified by the register combination DS:SI -- you have set SI to the address of the message you want to print, but you left whatever random data the firmware happened to have in DS before calling your bootsector in DS... so obviously this isn't going to work correctly...

therefore, as I have been saying for the last 3 posts now, I will repeat yet again: set DS register correctly and it will automatically start working on some emulators (if you don't fix the rest of the errors I mentioned, it won't work on any real hardware, and will fail on some emulators as well)

Quote:
It's not any of these 'bad practices' much.

none of what I mentioned are "bad practices"... 7 of them are outright errors that will cause it to not work (2 of them are not errors, just unnecessary) -- and one of them (#8 on my list) can actually destroy the computer it is running on (physically damage the hardware such that the computer can never run again and must be thrown in the garbage and replaced with a new computer)



Quote:
It's the fact that using 0x7e00 doesn't seem to work. I just don't understand why.

... you are not actually using address 0x7E00... you are using address 0x7E000 (note the extra zero) -- and it doesn't matter at all what address you use, if you don't set DS correctly it will not work (on the particular emulator you are using, it happens to work at address 0x7C00... but that isn't true for all computers)

in RMode, the segment is multiplied by 16 (moved to the left 1 hexidecimal position) and added to whatever offset address you use

so when you specify a 16bit address (such as SI in the lodsb instruction) where does the CPU get the segment from? from the DS register... which you haven't set to anything and left whatever garbage value the BIOS had in that register before you ran it... and that is not going to work

on the particular emulator you happen to be testing this on, this value happens to contain a 0 (which is why it works when you try to print from 0x7C00) but this is not true for other computers or emulators -- regardless, you must always set DS before using any data (such as your string) always -- this is not "best practices", this is not "you should", this is not "you might want to", the is must because it will not work at all if you don't



edit:
really, fixing the 7 errors I pointed out will cause your code to magically start working, not only on the emulator you are using, but on all emulators and real hardware, and shouldn't be hard to do -- it should take you less time to make those fixes than it took me to write this post


Do you mean put in the second stage bootloader this?

Code:
mov ax, 0x7e00
mov ds, ax


When I do that, it still shows nothing.

Yes, I understand LODSB simply takes a byte from DS:(E)SI, puts into AL and does increment to the address.
STOSB stores a byte from AL to ES:(E)DI.

Yes, I have got msg defined in the second stage bootloader.

Should it be 0x07e0 or 0x7e00?

The second stage bootloader can actually print a character (INT 10h -> function 0eh with AL=char) but it can't print a message. It's getting on my nerves... I'm using Virtualbox by the way. I'm not using real hardware. I might do soon.

UPDATE: When I use org 0x7c00 on my second stage, it actually prints the message. I want 0x7e00 because 0x7c00 is the bootloader and I don't want to overwrite it. I've also tried 0x1000. That doesn't print the message.

I'm getting sick and tired of this. My code is terrible. I've set DS correctly :( to 0x1000 0x7e00 this that.
The only way to even get a little gibberish printing out would be to change ORG. How do I get my message to 0x7e00?

_________________
Computers aren't to blame... the ones who program them are.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Sat Sep 30, 2017 11:48 am 
Offline

Joined: Wed Sep 27, 2017 2:50 pm
Posts: 12
mofule wrote:
I've tried all this. I've tried changing addresses. However, my OS does show a S and a 0. I've tried org 0. Sorry for not putting my message in with the code. It is defined.

Messages work in the bootloader but not my second stage. When I try loading my second stage at 0x7c00, it works but I fear that overwrites my bootloader.

Sorry, I took a little break from OSDev. Just trying to get the hang of it again.


Now it shows a funny looking C for one of them.

_________________
Computers aren't to blame... the ones who program them are.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Sun Oct 01, 2017 7:12 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1179
Without seeing all of your current code, we can't tell you which bugs you still need to fix.

You might want to use something like Github so you don't have to keep posting your code here. It can get a little annoying trying to scroll through large posts.


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Sun Oct 01, 2017 10:33 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 81
What if you amend the code to look like this (boot.asm):
Code:
bits 16
org 0x7c00

Main:
cld                ; Clear direction flag to ensure instructions like
                   ;    lodsb use forward movement.

xor ax, ax         ; AX=0 (use for segment)
mov ss, ax
mov sp, 0x7c00     ; Set up stack to grow down from 0x0000:0x07c00
                   ;    in region below the bootloader

mov es, ax         ; Read sector starting at 0x0000:0x7e00 (ES:BX)
mov bx, 0x7e00

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; mov dl, 0        ; Don't force to zero. Use value in DL passed by BIOS
                   ;     to our bootloader
int 13h

jmp 0x0000:0x7e00  ; Jump to physical address 0x07e00 by setting CS
                   ;     to 0 and IP to 0x7e00

;cli               ; This code will never execute so remove it
;hlt

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


kernel.asm:
Code:
bits 16
org 0x7c00

Main:
cld                ; Clear direction flag to ensure instructions like
                   ;    lodsb use forward movement.

xor ax, ax         ; AX=0 (use for segment)
mov ss, ax
mov sp, 0x7c00     ; Set up stack to grow down from 0x0000:0x07c00
                   ;    in region below the bootloader

mov es, ax         ; Read sector starting at 0x0000:0x7e00 (ES:BX)
mov bx, 0x7e00

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; mov dl, 0        ; Don't force to zero. Use value in DL passed by BIOS
                   ;     to our bootloader
int 13h

jmp 0x0000:0x7e00  ; Jump to physical address 0x07e00 by setting CS
                   ;     to 0 and IP to 0x7e00

;cli               ; This code will never execute so remove it
;hlt

times 510-($-$$) db 0
dw 0xaa55
root@debianwheezy:~/so/booter147# cat kernel.asm
bits 16
org 0x7e00

; jmp main         ; Not necessary since main is next instruction

main:
xor ax, ax         ; AX=0
mov ds, ax         ; Make sure segment is 0

mov si, msg
call print
cli                ; Do CLI/HLT after we return from print
hlt                ;    Prevent code from getting beyond this point

print:
lodsb
cmp al, 0
je done
mov ah, 0eh
int 10h
jmp print
done:
ret

;Place data here. msg is a message we want to print
msg: db "MyOS"


You can create a 1.44M floppy disk image this way:
Code:
dd if=/dev/zero  of=floppy.img bs=1024 count=1440
dd if=boot.bin   of=floppy.img bs=512 conv=notrunc
dd if=kernel.bin of=floppy.img bs=512 conv=notrunc seek=1


Alternatively if you want to use a segment of 0x07e0 and an offset of 0x0000 then this code should work (boot.asm):
Code:
bits 16
org 0x7c00

Main:
cld                ; Clear direction flag to ensure instructions like
                   ;    lodsb use forward movement.

xor ax, ax         ; AX=0 (use for segment)
mov ss, ax
mov sp, 0x7c00     ; Set up stack to grow down from 0x0000:0x07c00
                   ;    in region below the bootloader

mov es, ax         ; Read sector starting at 0x0000:0x7e00 (ES:BX)
mov bx, 0x7e00

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; mov dl, 0        ; Don't force to zero. Use value in DL passed by BIOS
                   ;     to our bootloader
int 13h

jmp 0x07e0:0x0000  ; Jump to physical address 0x07e00 by setting CS
                   ;     to 0x07e0 and IP to 0x0000

;cli               ; This code will never execute so remove it
;hlt

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


kernel.asm:
Code:
bits 16
org 0x0000         ; Since CS will be 0x07e0 we need an origin of 0x0000
                   ;     0x07e0:0x0000 also represents phys addres 0x07e00
                   ;     0x07e0<<4 + 0x0000 = 0x7e00

; jmp main         ; Not necessary since main is next instruction

main:
mov ax, 0x07e0
mov ds, ax         ; Make sure segments are 0x07e0
mov es, ax

mov si, msg
call print
cli                ; Do CLI/HLT after we return from print
hlt                ;    Prevent code from getting beyond this point

print:
lodsb
cmp al, 0
je done
mov ah, 0eh
int 10h
jmp print
done:
ret

;Place data here. msg is a message we want to print
msg: db "MyOS"


Top
 Profile  
 
 Post subject: Re: Second stage bootloader won't show a message
PostPosted: Sun Oct 01, 2017 12:38 pm 
Offline

Joined: Wed Sep 27, 2017 2:50 pm
Posts: 12
MichaelPetch wrote:
What if you amend the code to look like this (boot.asm):
Code:
bits 16
org 0x7c00

Main:
cld                ; Clear direction flag to ensure instructions like
                   ;    lodsb use forward movement.

xor ax, ax         ; AX=0 (use for segment)
mov ss, ax
mov sp, 0x7c00     ; Set up stack to grow down from 0x0000:0x07c00
                   ;    in region below the bootloader

mov es, ax         ; Read sector starting at 0x0000:0x7e00 (ES:BX)
mov bx, 0x7e00

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; mov dl, 0        ; Don't force to zero. Use value in DL passed by BIOS
                   ;     to our bootloader
int 13h

jmp 0x0000:0x7e00  ; Jump to physical address 0x07e00 by setting CS
                   ;     to 0 and IP to 0x7e00

;cli               ; This code will never execute so remove it
;hlt

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


kernel.asm:
Code:
bits 16
org 0x7c00

Main:
cld                ; Clear direction flag to ensure instructions like
                   ;    lodsb use forward movement.

xor ax, ax         ; AX=0 (use for segment)
mov ss, ax
mov sp, 0x7c00     ; Set up stack to grow down from 0x0000:0x07c00
                   ;    in region below the bootloader

mov es, ax         ; Read sector starting at 0x0000:0x7e00 (ES:BX)
mov bx, 0x7e00

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; mov dl, 0        ; Don't force to zero. Use value in DL passed by BIOS
                   ;     to our bootloader
int 13h

jmp 0x0000:0x7e00  ; Jump to physical address 0x07e00 by setting CS
                   ;     to 0 and IP to 0x7e00

;cli               ; This code will never execute so remove it
;hlt

times 510-($-$$) db 0
dw 0xaa55
root@debianwheezy:~/so/booter147# cat kernel.asm
bits 16
org 0x7e00

; jmp main         ; Not necessary since main is next instruction

main:
xor ax, ax         ; AX=0
mov ds, ax         ; Make sure segment is 0

mov si, msg
call print
cli                ; Do CLI/HLT after we return from print
hlt                ;    Prevent code from getting beyond this point

print:
lodsb
cmp al, 0
je done
mov ah, 0eh
int 10h
jmp print
done:
ret

;Place data here. msg is a message we want to print
msg: db "MyOS"


You can create a 1.44M floppy disk image this way:
Code:
dd if=/dev/zero  of=floppy.img bs=1024 count=1440
dd if=boot.bin   of=floppy.img bs=512 conv=notrunc
dd if=kernel.bin of=floppy.img bs=512 conv=notrunc seek=1


Alternatively if you want to use a segment of 0x07e0 and an offset of 0x0000 then this code should work (boot.asm):
Code:
bits 16
org 0x7c00

Main:
cld                ; Clear direction flag to ensure instructions like
                   ;    lodsb use forward movement.

xor ax, ax         ; AX=0 (use for segment)
mov ss, ax
mov sp, 0x7c00     ; Set up stack to grow down from 0x0000:0x07c00
                   ;    in region below the bootloader

mov es, ax         ; Read sector starting at 0x0000:0x7e00 (ES:BX)
mov bx, 0x7e00

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; mov dl, 0        ; Don't force to zero. Use value in DL passed by BIOS
                   ;     to our bootloader
int 13h

jmp 0x07e0:0x0000  ; Jump to physical address 0x07e00 by setting CS
                   ;     to 0x07e0 and IP to 0x0000

;cli               ; This code will never execute so remove it
;hlt

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


kernel.asm:
Code:
bits 16
org 0x0000         ; Since CS will be 0x07e0 we need an origin of 0x0000
                   ;     0x07e0:0x0000 also represents phys addres 0x07e00
                   ;     0x07e0<<4 + 0x0000 = 0x7e00

; jmp main         ; Not necessary since main is next instruction

main:
mov ax, 0x07e0
mov ds, ax         ; Make sure segments are 0x07e0
mov es, ax

mov si, msg
call print
cli                ; Do CLI/HLT after we return from print
hlt                ;    Prevent code from getting beyond this point

print:
lodsb
cmp al, 0
je done
mov ah, 0eh
int 10h
jmp print
done:
ret

;Place data here. msg is a message we want to print
msg: db "MyOS"


It wasn't the stupid code. It was
Code:
dd
... Yes, I did use dd. However, MichaelPetch suggested to use the seek=1 argument. It showed my message.

Thank you, MichaelPetch! You put an end to my misery. Thank you so much. How can I thank you? It worked. The message showed perfectly.

Now I can start coding my command interpreter. Hehe. And my PS/2 keyboard driver if I can... that might come later. I might actually do some experimenting.

I can't believe it. Finally.

By the way, I'm useless. I blame myself. Well, at least I didn't copy and paste from tutorials (like the average).

_________________
Computers aren't to blame... the ones who program them are.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], GDavid, Google [Bot], Luca1 and 8 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