Flat-real mode; how to take advantange of it?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Flat-real mode; how to take advantange of it?

Post by earlz »

from what i have read I am very confused as example source code shows one thing but the description says another

so can anyone perhaps lead me to anything that tells you how to use it

here is just a simple no segment version of pokeb but it just dont want to work

Code: Select all

push si
push ax
mov esi,LINEAR_ADRESS
mov gs,esi
mov esi,0
mov al,DATA
mov [gs:si],al
pop ax
pop si
in tasm, ideal mode with .386p

i use this as a C proc so the linear_adress is replaced with [bp+2] or something like that and same for data

btw
im sure im switched to 4gb gs, and fs segments cause bochs reports granulairty being 1(kb) and limit being FFFFFh
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Re: Flat-real mode; how to take advantange of it?

Post by gaf »

Hello,
it probably would have been a better idea to post the code that is actually used in your kernel rather than some snippet..

Unlike as in real-mode in pmode the segment register don't hold the actual address but the offset of the descriptor to be used from the start of the gdt (eg: 0x08 - first, 0x10 - second). If you're using flat-mode these values never change and you therefore normally load them only once at system start-up. The 32bit address you want to access either has to be hard-code in the binary or stored in one of the normal registers.

Code: Select all

; pmode entrypoint
mov eax, (descriptor_number*8)
mov fs, eax
...

; your test procedure
mov esi, [address]   ; this is the (phyiscal) 32bit address you want to access
mov eax, [data]      ; get the data from the stack
mov [fs:esi], eax    ; copy it..
im sure im switched to 4gb gs, and fs segments cause bochs reports granulairty being 1(kb) and limit being FFFFFh
That's not possible - either the granularity is 4kb or one byte. Please also post your gdt if it still doesn't work..

regards,
gaf
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Flat-real mode; how to take advantange of it?

Post by earlz »

flat_mode init

Code: Select all


;this code switches to flat real mode or "unreal" mode
;only affects fs and gs for compatibiltiy purposes
;this code was modified for use with tasm
                jmp strt
         DESC386 STRUC
        limlo   dw      ?
        baselo  dw      ?
        basemid db      ?
        dpltype db      ?       ; p(1) dpl(2) s(1) type(4)
        limhi   db      ?       ; g(1) d/b(1) 0(1) avl(1) lim(4)
        basehi  db      ?
DESC386 ENDS
gdt     DESC386 <GDT_END - gdt - 1, gdt, 0, 0, 0, 0>  ; the GDT itself
        DESC386 <0ffffh, 0, 0, 091h, 0ffh, 0>   
        GDT_END:

        strt:



        ; first, calculate the linear address of GDT
        xor     edx,edx         ; clear edx
        xor     eax,eax         ; clear edx
        mov     dx,ds           ; get the data segment
        shl     edx,4           ; shift it over a bit
        add     dword ptr [gdt+2],edx   ; store as GDT linear base addr

        ; now load the GDT into the GDTR
        lgdt    fword ptr gdt   ; load GDT base (286-style 24-bit load)
        mov     bx,1 * size DESC386 ; point to first descriptor
        mov     eax,cr0         ; prepare to enter protected mode
        or      al,1            ; flip the PE bit
        cli                     ; turn off interrupts
        mov     cr0,eax         ; we're now in protected mode

        mov     fs,bx           ; load the FS segment register
        mov gs,bx
        and     al,0FEh         ; clear the PE bit again
        mov     cr0,eax         ; back to real mode
        sti                    ; resume handling interrupts
        ret                     ;
and that was the exact code from my source minus the asm directives and changed those variable names

Code: Select all

void pokeb32(dword linear,byte dat){
	asm push si
	asm push ax
	asm mov esi,linear
	asm mov gs,esi
	asm mov esi,0
	asm mov al,dat
	asm mov [gs:si],al
	asm pop ax
	asm pop si
}

and another thing

"That's not possible - either the granularity is 4kb or one byte. Please also post your gdt if it still doesn't work.. "
well isnt the bit being 1 mean 4kb and the bit being 0 byte


hmmm ok i thought it meant you could have like 32 bits in segment register but offset stayed 16bit

I tried code nearly exactly like that but it didnt work, it just put a weird character in a random spot in video memory(i was trying to write a character to 0b8000h)
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Re: Flat-real mode; how to take advantange of it?

Post by gaf »

Code: Select all

;this code switches to flat real mode or "unreal" mode
;only affects fs and gs for compatibiltiy purposes
;this code was modified for use with tasm
Hmmm, you could have mentioned this earlier, I actually thought we were talking about normal flat mode which is pmode with zero based descriptors..

Code: Select all

gdt
   DESC386 <GDT_END - gdt - 1, gdt, 0, 0, 0, 0>
   DESC386 <0ffffh, 0, 0, 091h, 0ffh, 0>   
GDT_END:
I'd change the last 0xff in your data descriptor to 0xcf as one of the bits according to the intel reference manual has to be zero, otherwise problems with older CPUs might occure.

Table in the intel manual
I tried code nearly exactly like that but it didnt work, it just put a weird character in a random spot in video memory(i was trying to write a character to 0b8000h)
Hard to say what went wrong without knowing the parameters you passed to the poke procedure. It should actually work if 'linear' is 0xB800, but I'm really wondering what's the advantage over normal real-mode then. I've adapted your procedure to use a zero based segment and a 32bit address in esi to access the memory:

Code: Select all

void pokeb32(dword linear, byte dat)
{
   asm push eax
   asm push esi
   asm mov  esi, linear
   asm mov  al, dat
   asm mov  [gs:esi], al
   asm pop  esi
   asm pop  eax
}
Note that you'd have to enable the a20 line-gate first before accessing anything above 1MB though..
well isnt the bit being 1 mean 4kb and the bit being 0 byte
Yep, I just got you wrong, thought "1(kb)" would mean "one kilo-byte grnualrity" and not the state of the bit.
hmmm ok i thought it meant you could have like 32 bits in segment register but offset stayed 16bit
The advantage of unreal-mode over normal real-mode is that it allows offsets of up to 4gb and therefore enables you to span the whole address-space. The segments therefore get somewhat useless which is why you'd normally just set their base to zero (flat real-mode) and do addressing with offsets only.

What remains 16bits are the instructions which might lead to some problems unless you use overrite prefixes.

osdfaq article for unreal-mode
brief tutorial
chis giese's tutorial (pm1.asm)

Note that I'll be away from tomorrow on so that I can't answer to any further questions..

regads,
gaf
Post Reply