Page 1 of 1
Converting physical memory address to a linear memory...
Posted: Tue Oct 30, 2007 6:55 am
by sevobal
Hi @all,
now my OS is working in 32-Bit protected mode. Also I'm in video Mode 118h (1024*768). With a function of VBE (in real-mode) I've found out that the physical address for the LFB in this mode is 0xF0000000. That's correct as far as I can verify.
Now I've read in the VBE doc that I can't access this address directly, because it's an physical memory address and I had to convert it into a linear memory address.
So my question is, how can I convert a physical address to a linear address?
Posted: Tue Oct 30, 2007 8:06 am
by JamesM
What a linear address is depends on how your kernel is set up.
When given a virtual (or linear) address, the processor runs that address through it's MMU (memory management units). This handles all the paging-related mapping and also mapping due to segmentation. The resulting address is known as a 'physical' address.
So the mapping from linear->physical depends on whether you have paging and segmentation enabled.
I hope that made sense!
Posted: Tue Oct 30, 2007 8:24 am
by sevobal
JamesM wrote:
So the mapping from linear->physical depends on whether you have paging and segmentation enabled.
Thanks! I don't have Paging enabled, so is it possiblem that the linear and physical address are the same in my case?
Posted: Tue Oct 30, 2007 8:28 am
by AJ
Yes - if you are using flat segments in your GDT (base = 0, limit = 0xFFFFFFFF for everything).
Cheers
Adam
Posted: Tue Oct 30, 2007 9:00 am
by sevobal
okay here we go.
This is my gdt:
Code: Select all
gdtr: dw gdt_end - gdt - 1 ; GDT limit
dd gdt ; (GDT base gets set above)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; global descriptor table (GDT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; null descriptor
gdt: dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24
; linear data segment descriptor
LINEAR_SEL equ $-gdt
dw 0xFFFF ; limit 0xFFFFF
dw 0 ; base 0
db 0
db 0x92 ; present, ring 0, data, expand-up, writable
db 0xCF ; page-granular, 32-bit
db 0
; code segment descriptor
SYS_CODE_SEL equ $-gdt
gdt2: dw 0xFFFF ; limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x9A ; present, ring 0, code, non-conforming, readable
db 0xCF ; page-granular, 32-bit
db 0
; data segment descriptor
SYS_DATA_SEL equ $-gdt
gdt3: dw 0xFFFF ; limit 0xFFFFF
dw 0 ; (base gets set above)
db 0
db 0x92 ; present, ring 0, data, expand-up, writable
db 0xCF ; page-granular, 32-bit
db 0
now I'm using this to access the lfb
Code: Select all
mov ax,LINEAR_SEL
mov es,ax
mov edi, 0xF0000000
again:
mov byte [es:edi],0xff
add edi, 0x01
cmp edi, 0xF0240000
jne again
But it doesn't work. I only got a blank screen without the white pixel. If I do the same with 0xa0000 in edi instead of 0xf0000000 I get some white pixels on the top of the screen (of course not on the whole screen, because a0000 is just a damn small buffer).
Posted: Tue Oct 30, 2007 9:18 am
by JamesM
It looks like your GDT is set up as a flat-memory model, so you're right the mapping from linear->physical is 1:1.
It seems you have another problem elsewhere. Time to put your debugging hat on!
Posted: Tue Oct 30, 2007 10:04 am
by sevobal
For me it's confusing, that the access to 0xa0000 is working perfectly. Also if I go back to textmode and write to 0xb8000 it's working perfect. I can't get the point, why 0xf0000000 isn't working. To debug I uses bochs, where the lfb is at 0xe0000000. But there it's also not working
Just 0xa0000 is working perfectly in graphic modes. But Bochs doesn't throw out an error message or something else, it's just not working.
Posted: Tue Oct 30, 2007 3:38 pm
by Brendan
Hi,
sevobal wrote:For me it's confusing, that the access to 0xa0000 is working perfectly. Also if I go back to textmode and write to 0xb8000 it's working perfect. I can't get the point, why 0xf0000000 isn't working. To debug I uses bochs, where the lfb is at 0xe0000000. But there it's also not working
Just 0xa0000 is working perfectly in graphic modes. But Bochs doesn't throw out an error message or something else, it's just not working.
Are you sure you enable the LFB when you switch to 1024*768 video mode?
For example, you'd want to set bit 14 in the mode number to enable LFB when you're changing the video mode:
Code: Select all
mov bx,0x4000|0x0118 ;bx = mode number with bit 14 set to enable LFB
mov ax,0x4F02 ;ax = VBE function number to set video mode
int 0x10 ;Call VBE to set video mode
cmp ax,0x004F ;Was the function supported and succesful?
jne .oops ; no
Of course you probably should also check which mode number is used for "1024 * 768 * 16 bpp" (the fixed mode numbers in version 1.0 of the standard became optional suggestions in later versions of the standard), and check if that specific mode supports LFB (just because a video card supports LFB for some modes doesn't mean it supports LFB for the mode you want).
Cheers,
Brendan
Posted: Wed Oct 31, 2007 12:54 am
by sevobal
Okay setting bit 14 and every thing worked well. Thank you!