Ninjarider wrote:something that confuses me
the segment selectors which we plan to use to access memory over 1MB are loaded
how do you go about adding registers to be able to access over the 1 meg limit. does the value of gs determine which registers can access the full 4 gig?
No. You need to load the descriptor in the segment registers with which you want to access the entire 4GB. For example, if you wanted to use all the segment registers (in order to be able to place the stack and to execute code above 1MB as well), you would need to do:
Code: Select all
mov ax, 1 shl 3
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
;Then, you still need to jump to protected mode code, using a code descriptor...
(but in this case, make sure that the descriptors have 16-bits default address size... The one I declared above didn't have, but as I didn't load ss nor cs, it wasn't important...)
The following are the correct 16-bit descriptors:
Code: Select all
macro gdt_entry base,limit,flags {
dw limit and 0xFFFF
dw base and 0xFFFF
db (base shr 16) and 0xFF
db flags
db ((limit shr 16) and 0xF) or 0x80
db (base shr 24) and 0xFF
}
;(...)
gdt_entry 0x00000000, 0xFFFFF, 10010010b ;Ring 0, data, expand-up, r/w, 16-bit PM
gdt_entry 0x00000000, 0xFFFFF, 10011010b ;Ring 0, code, expand-up, r/x, 16-bit PM
Then, undo everything when to clear back the PE bit.
Better thinking, I don't understand why someone would want to place code above 1MB in unreal mode, because the good thing about unreal mode is being able to call the BIOS and use 32-bit offsets as well, but if you put your code above 1MB you won't be able to call the BIOS, cause it wouldn't be able to return to your program... Unless you wrap the BIOS calls with some code that is under 1MB, which is a possibility...
macro gdt_entry base,limit,flags {
dw limit and 0xFFFF
dw base and 0xFFFF
db (base shr 16) and 0xFF
db flags
db ((limit shr 16) and 0xF) or 0xC0
db (base shr 24) and 0xFF
}
the above confuses me because in asm, or atleast masm, i dont think thats possible. that and what does all that mean. were do you get it?
Don't you know how to declare data in ASM?
* dw declares a word
* db declares a byte
Now, that, is a macro that declares the GDT descriptor, in the place where you invoke it, based on the macro parameters, which are packed in the way the processor understands them.
The macro is in FASM syntax, which is a bit strange from the point of view of the average NASM user...
i don't want to copy some code into my kernel and say that it just works, don't know how but it does. I would like to know that when i want to i can change any available settings.
Good attitude.
JJ