romell
Posts: 25
Joined: Mon Jul 23, 2012 6:57 pm

Virtual memory and linking

Tue Jul 31, 2012 2:04 pm

Hi,

I have some, mostly theoretical issues when setting up my virtual memory system. What I want is a single binary (the kernel) to be loaded into continuous physical memory starting at 0x00008000. Only a very small part of the code that is responsible for setting up an initial page table and activating the MMU should be linked to run in this address space. The rest of the code should live somewhere in the top half of the virtual memory, leaving room for user space processes at the bottom.

Is this possible or do I need to rethink it? Another possibility is of course a two step process where I first set up the virtual memory and then load the main kernel from the SD card, but I would really like to avoid that...

User avatar
Cycl0ne
Posts: 102
Joined: Mon Jun 25, 2012 8:03 am

Re: Virtual memory and linking

Tue Jul 31, 2012 3:51 pm

you have to get yourself some infos on OS Design.
http://wiki.osdev.org
is a good place to start.

Linux, Windows, MacOSx, all compile their binaries (programms) to 0x0. so if you put your kernel at 0x0800, you have to write your own compiler/linker tools.
Most 32 bit OS tend to use a 2:2 approach (2gig user, 2gig system, so that all user calls to system will end up at an adress bigger 0x8000 0000. this makes it easier (and faster) for system calls. Negative effect: you program can only use 2gig adress space. OSX tends to use 4:4 allocation, but this brings the look aside buffer into big trouble, cause every user <-> system call you need to refresh the whole virtual adress mapping.

So you should first read the link above and think about your proposal.

in my OS design all is flat. i dont use virtual adress space. thus i have the problem to relocate the binary files when loading them into ram. :-( but every concept has its pros and cons.

romell
Posts: 25
Joined: Mon Jul 23, 2012 6:57 pm

Re: Virtual memory and linking

Tue Jul 31, 2012 5:08 pm

Thanks for the link, I will check it out.

Maybe I was a bit unclear about the placement of the kernel. I don't it placed at virtual address 0x8000 and it doesn't really matter where its placed in physical memory as long as I can boot into it and set up an initial page table (identity mapping). My problem is more related to how I can instruct the linker to make parts of the code to be executed in the upper part of the address space, while still being loaded into the lower part together with the other code.

Sorry for the messy explanation, I will try to summarize my intended program flow:

* The whole binary gets loaded into physical address 0x8000 with MMU turned off. (Just like any other bare metal program)
* A small assembly routine sets up a temporary page table with an identity mapping to itself and a virtual-to-physical mapping for the remaining part of the kernel, e.g. 0xA0000000->[main kernel entry point]
* Turn on MMU and jump to 0xA0000000.

This is where I expect strange things to happen if the program is linked using absoute addresses starting from 0x8000...

I hope this makes at least some sense. Any ideas?

Velko
Posts: 7
Joined: Mon Feb 20, 2012 9:50 pm

Re: Virtual memory and linking

Tue Jul 31, 2012 7:52 pm

Well, it makes perfect sense to me.

I've been playing around with similar setup on both x86 and ARM (qemu-system-arm, haven't had time to try it on actual RasPi). All you need is slightly more sophisticated linker script. Something like this (you may notice that I prefer 3:1 userspace/kernel split):

Code: Select all

ENTRY (_start)
load_start = 0x8000;
virt_start = 0xC0000000;
SECTIONS
{
    . = load_start;
    .lowtext :
    {
        *(.lowtext)
    }
    . = . + virt_start;
    .text : AT(code_start - virt_start) 
    { 
        code_start = .;
        *(.text*)
    }
    /* other higher half sections goes here */
}
You write all the code meant to run linked at 0x8000 in separate sections .lowtext, the rest goes into regular .text. When linked together, there will be 2 sections, continuous by physical addresses, but "higher-half" .text will start at 0xC0000000 + 0x8000 + whatever the size of .lowtext is. Having it this way, instead of forcing .text to start at "round" address (0xC0000000 in this case) makes it much, much easier to set up the initial page tables.

As long as you do not do function calls between these 2 sections (except for that one special jump to higher-half), you'll be fine.

And setting up initial page table needs not to be pure assembly. You can use C for it as well, using GCC attributes __section__ to compile functions into .lowtext section.

romell
Posts: 25
Joined: Mon Jul 23, 2012 6:57 pm

Re: Virtual memory and linking

Tue Jul 31, 2012 8:51 pm

Thank you Velko, that was exactly what I was looking for! I will try it out tomorrow. Too many beers for any decent coding now I'm afraid. :)

dwelch67
Posts: 954
Joined: Sat May 26, 2012 5:32 pm

Re: Virtual memory and linking

Wed Aug 01, 2012 1:27 am

http://github.com/dwelch67/raspberrypi/ the extest example starts by coming up bare metal and sets up a minimal mmu table and enables the mmu. I matched real and virtual but just as easy to make the virtual somewhere else. get the ARM ARM and ARM TRM for the processor core.

romell
Posts: 25
Joined: Mon Jul 23, 2012 6:57 pm

Re: Virtual memory and linking

Fri Aug 03, 2012 11:42 pm

It works! :D My kernel is now running in the upper parts of virtual memory. I'm currently using a 3:1 split between user and kernel space, but I will probably change that to 1:1 since there seems to be a nice hardware support for that kind of split (see section 6.12.1 of the ARM TRM).

The linker script provided by Velko sort of worked. I had to remove the "AT()" command to stop the linker from spitting out a 1GB+ binary..

zeoneo
Posts: 46
Joined: Sun Sep 30, 2018 6:54 am

Re: Virtual memory and linking

Sun May 19, 2019 10:36 am

@romell, what did you do about exception vector table?

Currently I have exception table setup at 0x0. Can we change the exception table base address ?
Let there be some light .../\...

LdB
Posts: 1102
Joined: Wed Dec 07, 2016 2:29 pm

Re: Virtual memory and linking

Sun May 19, 2019 11:55 am

VBAR register sets it anywhere you like on a 4K byte aligned boundary, reset value is 0x0

I assume you are after EL1
http://infocenter.arm.com/help/index.js ... ECBDH.html

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 22053
Joined: Sat Jul 30, 2011 7:41 pm

Re: Virtual memory and linking

Sun May 19, 2019 3:36 pm

zeoneo wrote:
Sun May 19, 2019 10:36 am
@romell, what did you do about exception vector table?

Currently I have exception table setup at 0x0. Can we change the exception table base address ?
Wow, that's a nearly 7 year thread necro. A new record I think.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
"My grief counseller just died, luckily, he was so good, I didn't care."

fruitoftheloom
Posts: 19483
Joined: Tue Mar 25, 2014 12:40 pm
Location: Delightful Dorset

Re: Virtual memory and linking

Sun May 19, 2019 4:15 pm

zeoneo wrote:
Sun May 19, 2019 10:36 am
@romell, what did you do about exception vector table?

Currently I have exception table setup at 0x0. Can we change the exception table base address ?

Bit late to ask ?
romell
Joined: Mon Jul 23, 2012 7:57 pm
Last active: Sat Nov 01, 2014 12:25 am
adieu

My other Computer is an Asus CS10 ChromeBit running Chrome Operating System.
HP Envy 4500 Wireless Printer supported by HPLIP software in Raspbian Stretch.

zeoneo
Posts: 46
Joined: Sun Sep 30, 2018 6:54 am

Re: Virtual memory and linking

Mon May 20, 2019 5:08 am

LdB wrote:
Sun May 19, 2019 11:55 am
VBAR register sets it anywhere you like on a 4K byte aligned boundary, reset value is 0x0

I assume you are after EL1
http://infocenter.arm.com/help/index.js ... ECBDH.html
Yeah that's what I was exactly looking for. Thanks Ldb.
jamesh wrote: Wow, that's a nearly 7 year thread necro. A new record I think.
I will break few more records here. :D

Two things I love about raspberrypi are
1. Raspberry Pi itself
2. Community folks who are open to help people out.

Thank you guys.
Let there be some light .../\...

Return to “Bare metal, Assembly language”