Page 1 of 1

Virtual Memory Tips (using brokenthorn.com guide)

Posted: Sun Nov 24, 2013 5:48 pm
by Luca91
Hi mates,
after some days of study, I've implemented the virtual memory manager using brokenthorn.com guide (that is GREAT!).
Well the problem is that in this guide, a custom bootloader is used, and the paging is enable there..
I'm using grub as bootloader, so what I did to solve this problem was to just add that code in my bootstrap.asm (before to call the kernel main function).

Apparently it works.. but I'm not so happy with this solution... I'm sure that there is a better (and perhaps more elegant) way to do this..

Here is my bootstrap asm code:

Code: Select all

;
; bootstrap.asm -- Kernel start location. Also defines multiboot header.
;           Based on Bran's kernel development tutorial file start.asm
;

MBOOT_PAGE_ALIGN    equ 1<<0    ; Load kernel and modules on a page boundary
MBOOT_MEM_INFO      equ 1<<1    ; Provide your kernel with memory info
MBOOT_HEADER_MAGIC  equ 0x1BADB002 ; Multiboot Magic value
; NOTE: We do not use MBOOT_AOUT_KLUDGE. It means that GRUB does not
; pass us a symbol table.
MBOOT_HEADER_FLAGS  equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO
MBOOT_CHECKSUM      equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS)


[BITS 32]                       ; All instructions should be 32-bit.

[GLOBAL mboot]                  ; Make 'mboot' accessible from C.
[EXTERN code]                   ; Start of the '.text' section.
[EXTERN bss]                    ; Start of the .bss section.
[EXTERN end]                    ; End of the last loadable section.

mboot:
    dd  MBOOT_HEADER_MAGIC      ; GRUB will search for this value on each
                                ; 4-byte boundary in your kernel file
    dd  MBOOT_HEADER_FLAGS      ; How GRUB should load your file / settings
    dd  MBOOT_CHECKSUM          ; To ensure that the above values are correct
    
    dd  mboot                   ; Location of this descriptor
    dd  code                    ; Start of kernel '.text' (code) section.
    dd  bss                     ; End of kernel '.data' section.
    dd  end                     ; End of kernel.
    dd  start                   ; Kernel entry point (initial EIP).

[GLOBAL start]                  ; Kernel entry point.
[EXTERN kmain]                   ; This is the entry point of our C code



%define		PAGE_DIR		0x9C000


%define		PAGE_TABLE_0		0x9D000


%define		PAGE_TABLE_768		0x9E000


%define		PAGE_TABLE_ENTRIES	1024


%define		PRIV				3 ; attributes (page is present;page is writable; supervisor mode)



start:
    pusha										

    mov		eax, PAGE_TABLE_0					
    mov		ebx, 0x0 | PRIV						
    mov		ecx, PAGE_TABLE_ENTRIES				
.loop:
    mov		dword [eax], ebx					
    add		eax, 4								
    add		ebx, 4096							
    loop	.loop								

    mov		eax, PAGE_TABLE_0 | PRIV		
    mov		dword [PAGE_DIR], eax

    mov		eax, PAGE_TABLE_768 | PRIV		
    mov		dword [PAGE_DIR+(768*4)], eax

    mov		eax, PAGE_DIR
    mov		cr3, eax

    mov		eax, cr0
    or		eax, 0x80000000     
    mov		cr0, eax             ;enable paging
 
    mov		eax, PAGE_TABLE_768			
    mov		ebx, 0x100000 | PRIV			
    mov		ecx, PAGE_TABLE_ENTRIES			
.loop2:
    mov		dword [eax], ebx				
    add		eax, 4							
    add		ebx, 4096						
    loop	.loop2							

    popa


    ; Load multiboot information:
    push    ebx

    ; Execute the kernel:
    cli                         ; Disable interrupts.
    call kmain                   ; call our main() function.
    jmp $                       ; Enter an infinite loop, to stop the processor
                                ; executing whatever rubbish is in the memory
                                ; after our kernel!



But is Virtual Memory really working ?? Well I'd say yes, since I don't get any page fault and I read the cr0 register to be sure it is set correctly..

Sorry for my bad english, it is late night here and i'm very tired :oops:

Re: Virtual Memory Tips (using brokenthorn.com guide)

Posted: Sun Nov 24, 2013 10:45 pm
by mrstobbe
Luca91 wrote:Apparently it works.. but I'm not so happy with this solution... I'm sure that there is a better (and perhaps more elegant) way to do this..
Setting up a very basic "see-through" paging structure like you've done here is generally what you do when you first enter the kernel (or at stage-2 bootloading). A little deeper your kernel however, you would want to actually map physical memory, keep track of it, and have a paging structure appropriate for it. For example, one of the first things linux (after determining the memory map, and dealing with some minor things) does is create map of all physical pages, then sets up up its own paging so that the top-half and the bottom half of the physical memory area points back at to the same physical address. Something like this most certainly should be done a bit deeper in your kernel after you've done some basic pre-requisite checks, mapped physical memory, and setup an "early-boot" heap of some kind... where it can be managed more elegantly.

How you've actually got that setup seems perfectly reasonable though in terms of "bootstraping" your kernel. It's not going to be anymore elegant than that for your initial "see-through" paging to access the lower part of extended memory.

Understand? Am I missing a question here?

EDIT: typo

Re: Virtual Memory Tips (using brokenthorn.com guide)

Posted: Mon Nov 25, 2013 1:38 am
by Brendan
Hi,
Luca91 wrote:But is Virtual Memory really working ?? Well I'd say yes, since I don't get any page fault and I read the cr0 register to be sure it is set correctly..
I'd say paging is working if you're lucky.

If you're not lucky, your code trashed its own stack, or trashed the BIOS' EBDA, or trashed "multi-boot information" that you will need later. For multi-boot the only memory that you can assume is safe to use is memory in your own ".bss" section (for all other memory you can't assume and must examine the memory map provided by GRUB while avoiding any RAM that is already being used).


Cheers,

Brendan

Re: Virtual Memory Tips (using brokenthorn.com guide)

Posted: Mon Nov 25, 2013 7:50 am
by Luca91
I'd say paging is working if you're lucky.
If you're not lucky, your code trashed its own stack, or trashed the BIOS' EBDA, or trashed "multi-boot information" that you will need later. For multi-boot the only memory that you can assume is safe to use is memory in your own ".bss" section (for all other memory you can't assume and must examine the memory map provided by GRUB while avoiding any RAM that is already being used).
Cheers,
Brendan
Well I already use the multiboot infos and I can confirm that they works.. By the way I understand that there is better way to do this..
Setting up a very basic "see-through" paging structure like you've done here is generally what you do when you first enter the kernel (or at stage-2 bootloading). A little deeper your kernel however, you would want to actually map physical memory, keep track of it, and have a paging structure appropriate for it. For example, one of the first things linux (after determining the memory map, and dealing with some minor things) does is create map of all physical pages, then sets up up its own paging so that the top-half and the bottom half of the physical memory area points back at to the same physical address. Something like this most certainly should be done a bit deeper in your kernel after you've done some basic pre-requisite checks, mapped physical memory, and setup an "early-boot" heap of some kind... where it can be managed more elegantly.
How you've actually got that setup seems perfectly reasonable though in terms of "bootstraping" your kernel. It's not going to be anymore elegant than that for your initial "see-through" paging to access the lower part of extended memory.
Understand? Am I missing a question here?
Well, ofcourse I've already a working physical memory manager.. I was just thinking if there is a way to enable paging just after the kernel boot, instead that at bootsrap time :)

Re: Virtual Memory Tips (using brokenthorn.com guide)

Posted: Mon Nov 25, 2013 9:33 am
by mrstobbe
Luca91 wrote:Well, ofcourse I've already a working physical memory manager.. I was just thinking if there is a way to enable paging just after the kernel boot, instead that at bootsrap time :)
Sure, unless you wanted to enter long mode before kentry (which it doesn't look like you're planning to do). You can use standard C structs/arrays for everything (make sure they're packed appropriately), allocate your paging structure, and change cr0/cr3 accordingly with either inline assembly or the assembler of your choice.