Strange bootloader behavior

I am trying to create a simple OS, only the boot sector and 16-bit real mode with interrupts. I finally was able to make the OS / bootloader, which I tested in a virtual box, and it worked.

Then I burned the image to a CD and downloaded it to my old desktop with Pentium 4, BIOS A05 and 1 GB of RAM, and it worked fine - a simple OS that prints a โ€œtitleโ€ for the top of the screen, all that it does , allows you to enter the screen, with several keys registered to move the cursor.

Then I connected the drive to my 1-year-old laptop with an i5 processor and 2.6 GB of RAM and the A05 BIOS version of Revision, and the cursor seems to move randomly, typing random characters at high speeds, finally stopping at anscii character 235 (part extended symbol table), after which the keyboard works fine, the keys for moving the cursor work fine, just a heading. This is the computer on which I tested it, compiled, burned and burned a CD. (I used Linux Mint 12 OS)

I jumped over all the โ€œhoopsโ€ that I thought I needed to make: I made an iso image that follows El Toritoโ€™s non-emulation download standard, a boot signature of 512 bytes and written to the correct sector.

This is a problem with my code, have I done something, or is it just fine?

Here is my code (NASM x86 syntax):

;************************** ; Note OS, Experimental OS ;************************** [org 0x7C00] [bits 16] start: jmp loader ;jump to the actual start of bootloader times 8 - ($ - $$) db 0 ;pad eight bytes ;********************* ;El Torito Boot Info Table ;********************* ;in nasm, I couldn't figure out how to reserve bytes, in the middle of .text ;so I zeroed it out. times 56 db 0 loader: call cls ;clear the screen mov si, head1 ;setup page headers call printf mov si, head2 call printf jmp note ;start note program cls: mov ah, 0x0F ;get current video mode mov al, 0x00 ;reset register int 0x10 ;get video mode mov ah, 0x00 ;set video mode int 0x10 ;reset screen mov ah, 0x02 ;set cursor pos mov bh, 0x00 ;page 00 mov dh, 0x00 ;row 00 mov dl, 0x00 ;col. 00 int 0x10 ;set pos ret printf: .loop ;our function that loops mov al, [si] ;load byte cmp al, 0 ;if null, end je .end mov ah, 0x0E ;function 0E mov bh, 0x00 ;page 0x00 mov bl, 0x0F ;white text on black background int 0x10 ;print inc si ;increment source index jmp .loop ;repeat .end ret ;return ;******************* ; Note 'Program' ;******************* note: mov ah, 0x00 ;function 00 int 0x16 ;get character cmp al, '`' ;go up line? je setcur cmp al, 0x0D ;enter? je setent cmp al, '+' ;plus? je setplu cmp al, '-' ;minus? je setminu cmp al, '\' ;reset? je loader cmp al, 0x08 ;backspace? je setback mov ah, 0x0E ;function 0E mov bh, 0x00 ;page 00 mov bl, 0x0F ;white on black int 0x10 ;print jmp note ;repeat setcur: mov ah, 0x03 ;get cur pos mov bh, 0x00 ;page 00 int 0x10 ;get pos cmp dh, 0x00 ;are we at top of page? je .begin ;just reset cursor if so sub dh, 0x01 ;go up one line .begin mov dl, 0x00 ;set to beginning of line mov ah, 0x02 ;set cursor function mov bh, 0x00 ;page 00 int 0x10 ;set position jmp note ;read next character setent: mov ah, 0x0E ;write character mov al, 0x0A ;begin line mov bh, 0x00 ;page 00 mov bl, 0x0F ;white on black int 0x10 ;print setplu: mov ah, 0x03 ;get cursor pos mov bh, 0x00 ;page 0x00 int 0x10 ;get pos mov ah, 0x02 ;set cursor pos add dl, 0x01 ;add one to column int 0x10 ;set new pos jmp note ;get next char setminu: mov ah, 0x03 ;get cursor pos mov bh, 0x00 ;page 00 int 0x10 ;get pos mov ah, 0x02 ;set cursor pos sub dl, 0x01 ;sub one to column int 0x10 ;set new pos jmp note ;get next char setback: mov ah, 0x03 ;get cursor pos mov bh, 0x00 ;page 00 int 0x10 ;get pos mov ah, 0x02 ;set cursor pos sub dl, 0x01 ;sub one column int 0x10 ;set pos mov ah, 0x0E ;write char mov al, ' ' ;write space mov bh, 0x00 ;page 00 mov bl, 0x0F ;white on black int 0x10 mov ah, 0x02 ;reset cur pos int 0x10 ;reset jmp note ;****************** ; Our Page Headers ;****************** head1: db '- Note OS Version 1.2-', 0x0A, 0x0D, 0 head2: db '=======================', 0x0A, 0x0D, 0x0A, 0x0D, 0 times 510 - ($ - $$) db 0 dw 0xAA55 

Link (links to which I refer):

Anscii Table: http://www.asciitable.com/

El-Torito Info: http://wiki.osdev.org/El-Torito

EDIT: Here are the keys I programmed and what they do:

enter - works fine now backspace - works fine now plus - moves the cursor to the right minus - moves the cursor to the left `- moves the cursor to the beginning of the previous line \ -" soft reloads "jump almost to the bootloader

+7
source share
2 answers

The problem is here:

 [org 0x7C00] ... start: jmp loader ;jump to the actual start of bootloader ... loader: call cls ;clear the screen mov si, head1 ;setup page headers call printf ... printf: .loop ;our function that loops mov al, [si] ;load byte 

Expected CS=DS=0 when running the code. DS is not guaranteed to be 0. Therefore, when it is nonzero, mov al, [si] reads bytes from some segment other than segment 0, and there may be some garbage, not a copy of your greeting message.

In addition, some BIOSes go to your code using the address 0:0x7C00 , while others use 0x7C0:0 , which means that even CS is not guaranteed to have a fixed value.

Instead, I will do the following:

 [org 0x7C00] [bits 16] start: jmp loader ;jump to the actual start of bootloader ... loader: jmp 0:loader2 ; this far jump guarantees CS=0 loader2: push cs pop ds ; this guarantees DS=0 ; the rest of the code goes here 
+2
source

Wowsers; Now that is a tough question!

Actually, this is too general a programming question that really works here in Stack Overflow, but just to pounce on you in the hope of being useful!

If you get to the point at which it even moves the cursor at all, albeit randomly, I think your bootloader is fine; but to be understandable - does it even display the "title" on I5?

What I would consider here are the interrupt vectors / address strings / etc that you use to move the cursor at all. Are you sure int10 operations are completely generic?

+2
source

All Articles