OSDev.org
https://forum.osdev.org/

Protected Modes and Interrupts
https://forum.osdev.org/viewtopic.php?f=1&t=17136
Page 1 of 1

Author:  samoz [ Sun Jun 01, 2008 1:49 pm ]
Post subject:  Protected Modes and Interrupts

Hey guys, I was following along with the "Making your own ToyOS (Part 3)" inside the Linux Gazette. http://linuxgazette.net/issue82/raghu.html

Here is the code that I ended up with:


Code:
org 0x07c00
jmp short begin_boot

bootmesg db "Our OS boot sector loading......"
pm_mesg db "Switching to protected mode....."

dw 512
db 1
dw 1
db 2
dw 0x000e0
dw 0x0b40
db 0x0f0
dw 9
dw 18
dw 2
dw 0

print_mesg:
        mov ah, 0x13
        mov al, 0x00
        mov bx, 0x0007
        mov cx, 0x20
        mov dx, 0x0000
        int 0x10
        ret

get_key:
        mov ah, 0x00
        int 0x16
        ret

clrscr:
        mov ax, 0x0600
        mov cx, 0x0000
        mov dx, 0x174f
        mov bh, 0
        int 0x10
        ret

begin_boot:
        call clrscr
        mov bp, bootmesg
        call print_mesg
        call get_key
bits 16
        call clrscr
        mov ax, 0xb800
        mov gs, ax
        mov word [gs:0], 0x641
        call get_key
        mov bp, pm_mesg
        call print_mesg
        call get_key
        call clrscr
        cli
        lgdt[gdtr]
        mov eax, cr0
        or al, 0x01
        mov cr0, eax
        jmp codesel:go_pm

bits 32
go_pm:
        mov ax, datasel
        mov ds, ax
        mov es, ax
        mov ax, videosel
        mov gs, ax
        mov word [gs:0], 0x741

       ;;;;;;;;;;;;;;;;;;;
       ;;;;;; This is where i need help
       ;;;;;;;;;;;;;;;;;;;
       mov ax, 0x0600
       mov cx, 0x0000
       mov dx, 0x174f
       mov bh, 0
       int 0x10
       

spin: jmp spin

bits 16
gdtr:
        dw gdt_end-gdt-1
        dd gdt
gdt
nullsel equ $-gdt
gdt0
        dd 0
        dd 0
codesel equ $-gdt
code_gdt
        dw 0x0ffff
        dw 0x0000
        db 0x00
        db 0x09a
        db 0x0cf

        db 0x00
datasel equ $-gdt
data_gdt
        dw 0x0ffff
        dw 0x0000
        db 0x00
        db 0x092
        db 0x0cf
        db 0x00
videosel equ $-gdt
        dw 3999
        dw 0x8000
        db 0x0b
        db 0x92
        db 0x00
        db 0x00
gdt_end




All the code above is taken from the tutorial, except for the portion that I commented above.

The OS boots fine when I don't include the area that I commented about, but when I include the marked code, the computer resets itself after it gets to the end, instead of looping... Why is this?

If it matters, I'm running this on Bochs on an OpenSUSE machine.

Author:  suthers [ Sun Jun 01, 2008 2:05 pm ]
Post subject: 

Bloody hell.
Sorry but people should read up before they start coding, You can't call interrupts in protected mode.
Jules

edit: you can't call BIOS interrupts in protected mode

Author:  svdmeer [ Sun Jun 01, 2008 2:18 pm ]
Post subject: 

And doing the whole stuff in the bootsector... :shock:

Try to write some code loading a larger binary so you get space to develop any further.

Author:  kmtdk [ Sun Jun 01, 2008 2:30 pm ]
Post subject: 

a littel optimising, insted of scrolling, just switch to mode 3. This clears the screen.

but when you are in pmode, as suthers said, you cant call "old" int's- for exempel the int 0x10.
insted write directy to the screen, the screen text mode is normaly in memory, at 0xb8000; in pmode. In real mode it is: 0xb800:0x0000.

Author:  suthers [ Sun Jun 01, 2008 2:57 pm ]
Post subject: 

sorry for getting annoyed, but there have been quite a few posts in this style around the forum lately.
At the same time I will say that God knows when I first started OSdev, I was the worst beginner ever, but I was quickly sent down the right path by the people here... (Thank you) and I shouldn't have gotten annoyed since this is your first post...
Oh and welcome to osdev.org :)
Jules

edit: actually to be entirely truthful I can be pretty newbish myself even after being corrected...
second edit: Oh and when you call interrupts in protected mode if the CPU doesn't find an ISR (or IDT in this case... ), it triples faults, hence the reset...
Third edit: or if the present bit in the IDT's descriptor for the interrupt being called is set to 0. :wink:

Author:  samoz [ Sun Jun 01, 2008 6:13 pm ]
Post subject: 

You said that I should call a larger binary, how do I do this? tutorial/link?

And you said mode 3? What is this? tutorial/link?

Sorry for the dumb questions, I just am having a hard time understanding how OS programming works so far.

Author:  neon [ Sun Jun 01, 2008 6:34 pm ]
Post subject: 

samoz wrote:
You said that I should call a larger binary, how do I do this? tutorial/link?


The 1st stage bootloader (Which is what you have) is limited to 512 bytes. It doesnt matter how big it is on disk, the BIOS only loads the 1st 512 bytes.

Because of this, you are limited to 512 bytes--which is not that much room.

Because of this, you would normally have the 1st stage bootloader load another program (Such as either your kernel or a 2nd stage loader).

How to so this depends on what you want to do and possibly your file system.

samoz wrote:
And you said mode 3? What is this? tutorial/link?


Text mode 3--Its the video mode you are in set by the BIOS for historical reasons.

Author:  bewing [ Sun Jun 01, 2008 11:06 pm ]
Post subject: 

Um, yes ... the fundamental problem is that you are switching to pmode too soon. You need to insert your own code before the pmode switch.

You seem to have some basic understanding of how to interact with the BIOS (with that INT 0x10 call). But, as said above, you cannot use the BIOS after you switch to pmode.

The point is that you NEED to interact with the BIOS to get any further than you are right now. You NEED to be using quite a few BIOS INT functions BEFORE you enter pmode.

How do you load a second stage bootloader, or more of your first stage bootloader, or your kernel? You use INT 0x13 calls, before you enter pmode. Exactly which ones? Well, it depends on if you want to load from a simulated hard disk, or a simulated floppy on bochs.

You can start reading from this wiki page:
http://www.osdev.org/wiki/ATA_in_x86_Re ... %28BIOS%29

Author:  samoz [ Mon Jun 02, 2008 9:27 am ]
Post subject: 

I think I'm starting to get a better idea of what you guys are pointing out to me, now that I've read some more. As I said before, this was a tutorial I was following.

So since I can't use interrupts in protected mode, that means that I should use some alternate method of implementing the same things. Is this where an Interrupt Descriptor Table comes in to play?

Author:  suthers [ Mon Jun 02, 2008 10:49 am ]
Post subject: 

No the IDT doesn't come into play yet.
You need to be able to write a function to write stuff to your screen, when you first pass into pmode, the video memory is located at 0x0B8000, so you need to write to that now, the screen is 80 x 25 characters and each character is made up of two bytes, byte 1: ASCII char, byte 2: attributes.
To help you I'll give you a little pointer:
Here's some code I wrote to do what you want:
Code:
PutStr_32:       
   .next_char: 
    lodsb 
    or al, al           
    jz .end       
    mov byte [ds:ecx], al
   inc ecx
   mov byte [ds:ecx], dl
   inc ecx   
    jmp .next_char   
   .end:
    ret 

You load the address you want to output to in ecx(0x0B8000), the address of the string (has to be null terminated)you want to print in esi and the attributes in dl (personally 0x04, red char on black background) , the lodsb, loads one byte from esi into al then increments esi, then it checks for a null terminator then it moves the char into the write position in vid mem and then increments ecx and writes the attributes, the loops until it finds a null pointer at which point it breaks....
Hope you understand the explanation (yah I would be bead at writing tutorials, its not very clear...), ask if you don't...
Jules

edit: if you go hear: http://www.osdever.net/bkerndev/index.php then click Printing On screen, its explained very well

Author:  suthers [ Mon Jun 02, 2008 10:57 am ]
Post subject: 

But you also want to be able to either load your kernel or a second stage bootloader as quickly as possible, because of the 512b limit, you'll be running out of space quickly (my bootloader is exactly 512b long, no null filling...), so you want to read your kernel of disk while your still in real mode so you can do it through BIOS interrupts, because theres no way you can fit a Pmode floppy driver into your bootloader.... (well it might be, I've never tried, simply because its stupid and pointless...)
Jules

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/