basic paging

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.
GLneo

Re:basic paging

Post by GLneo »

so all i need is get + free physpage, and then assemble them in vurtual memory? sounds simple, but im confused does each prog get its own page directory or what, how does it know?
AR

Re:basic paging

Post by AR »

The program doesn't "know" as such, yes each process has it's own directory. On UNIX systems you have the brk() system call which simply allocates more heap (it determines how many pages need to be added/subtracted and maps them accordingly).

In your user program the inital program code, data and bss would be mapped by the kernel as well as the first page of stack, the process calls the userspace malloc() which in turn checks it's internal counters and can then run a system call to request more heap memory if it needs it.
GLneo

Re:basic paging

Post by GLneo »

so for multitasking wend a new prosess is up, i have to switch the page_directory pointer in cr3?
AR

Re:basic paging

Post by AR »

Usually yes, unless you are running all processes in the same address space.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:basic paging

Post by distantvoices »

Nice read this is.

Althou, I have to add, that the stuff which puts the pages into the page dir/page tables might also be considered a part of physical memory management - it takes a physical page from the available pages or returns a physical page.

the virtual memory management deals with adress space issues inside the processes: say f.ex: mmap(op,start,limit) inserts [limit pages] into the tree of allocations of the process, if op is MAP_ADRESS (or similar, as you like).

The actual inserting of pages into the page tables is done by the page fault handler, which looks into the allocation tree of the faulting process. that's a proposal of course. :-)

stay safe.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
GLneo

Re:basic paging

Post by GLneo »

ok i think im ready for paging but i'm(as allways)confused about what hapens for intrupts like irq or isr, i've heard you got to map your kernel for every prosses at some thing like 3GB - 4GB. my kernel is at 0x1000 to top of low memory(1MB) what happens to my irq function pointers that point to low memory when my kernel is mapped up high, or do i have to put my kernel in the location it is mapped (3GB - 4GB) physicly ???, thx ;D
Ushma

Re:basic paging

Post by Ushma »

GLneo wrote: do i have to put my kernel in the location it is mapped (3GB - 4GB) physicly ???, thx ;D
This should be of use to you:

http://www.osdev.org/osfaq2/index.php/HigherHalfKernel
GLneo

Re:basic paging

Post by GLneo »

thx, that helped a lot so what i need to do is for every prosess liner map my kernel 0x1000 - 0x20000, then vertual it at 0xC0000000, mabey i'm confused is that wright???
Kim

Re:basic paging

Post by Kim »

You could create some sections linked at 1MB and then your real kernel at 3GB, but loaded at 1MB+sections before kernel.

Something like this:

[tt]
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .inittext PROGBITS 00100000 001000 001000 00 AX 0 0 16
[ 2] .initdata PROGBITS 00101000 002000 001000 00 WA 0 0 8
[ 3] .initbss NOBITS 00102000 003000 002000 00 WA 0 0 4
[ 4] .text PROGBITS c0000000 003000 001000 00 AX 0 0 16
[ 5] .data PROGBITS c0001000 004000 001000 00 WA 0 0 8
[ 6] .bss NOBITS c0002000 005000 004000 00 WA 0 0 4
[ 7] .shstrtab STRTAB 00000000 005000 000039 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x00100000 0x00100000 0x01000 0x01000 R E 0x1000
LOAD 0x002000 0x00101000 0x00101000 0x01000 0x03000 RW 0x1000
LOAD 0x003000 0xc0000000 0x00104000 0x01000 0x01000 R E 0x1000
LOAD 0x004000 0xc0001000 0x00105000 0x01000 0x05000 RW 0x1000

Section to Segment mapping:
Segment Sections...
00 .inittext
01 .initdata .initbss
02 .text
03 .data .bss
[/tt]

Works well for me, init code is a small asm stub to setup stack and includes multiboot header, this stub then calls some code in pascal that maps the kernel in the virtual address space and enables paging and finally jumps into the kernel code.

You will need a linker script to link the image how you want it.
You will have to change the sections of the objects that include your init code. Objcopy will do this for you.

[tt]
..\..\bin\objcopy --rename-section .text=.inittext --rename-section .data=.initdata --rename-section .bss=.initbss ..\..\output\kernel\obj\stub\initstub.o ..\..\output\kernel\obj\stub\initstub.o
..\..\bin\objcopy --rename-section .text=.inittext --rename-section .data=.initdata --rename-section .bss=.initbss ..\..\output\kernel\obj\init.o ..\..\output\kernel\obj\init.o
[/tt]
GLneo

Re:basic paging

Post by GLneo »

:o :o :o :o :o :o i have no idea what that means, was i right or not ???
Ushma

Re:basic paging

Post by Ushma »

GLneo wrote: :o :o :o :o :o :o i have no idea what that means, was i right or not ???
GLneo wrote: thx, that helped a lot so what i need to do is for every prosess liner map my kernel 0x1000 - 0x20000, then vertual it at 0xC0000000, mabey i'm confused is that wright???
If you mean physically locate your kernel at some location in physical memory, and then map it virtually to some other place, yes.

When your kernel runs, it's going to expect that its data, code, et cetera is at the location to which you linked it. If you link it to 0xC0000000, it's going to expect to find everything starting at that address.

Now, when you were loading your kernel into memory, it's highly unlikely that you put it that high in memory (that would require 3+ gig of RAM). Instead, it's at some lower address like 0x100000. But the kernel thinks it's located at 0xC0000000, and will access its memory as though it is. If you were to run it just like that, it would access memory that is likely non-existent, and certainly doesn't contain what it expects.

So instead you want to set things up so that when the kernel asks for code/data/etc. in memory up there, it gets it from where it's physically located. You use the hardware to help you.

The page I suggested above on the wiki describes some ways to accomplish this.
GLneo

Re:basic paging

Post by GLneo »

thx, it is finaly starting to make sense after weeks of no coding i think i can continue osdeving ;)

p.s. one last thing how do i start my kernel if it isn't linked to where it is(i mean start paging, before paging lets my kernel think right???)
Ushma

Re:basic paging

Post by Ushma »

GLneo wrote: how do i start my kernel if it isn't linked to where it is(i mean start paging, before paging lets my kernel think right???)
Some sort of address translation needs to be going on before you jump to any kernel code that is linked to 0xC0000000. The wiki page describes some ways to accomplish that.

If you're rolling your own bootloader, you can have it set up the necessary paging/segmentation tricks before the jump to kernel code.

If you're not, then you need some code that is linked to whatever position works for how the bootloader loads your kernel that can set up the necessary translations before jumping to any kernel code that is linked to the virtual address at which you *want* your kernel. I think this is what Kim was suggesting above.

Again, consult that wiki page. It has what you ask for.
GLneo

Re:basic paging

Post by GLneo »

ok, i've got 2 ".o" files that need to be linked to 0x1000 and the rest to 0xC0000000 my linker script is:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
  .text  0xC0000000 : {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(0);
  }
  .data  : {
    data = .; _data = .; __data = .;
    *(.data)
    . = ALIGN(0);
  }
  .bss  :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    bssend = .;
    . = ALIGN(0);
  }
  bsslength = (bssend - bss) / 4;
  end = .; _end = .; __end = .;
}
but i don't know how to get it to link some files to different addresses, ??? , thx
Post Reply