inaciose
Posts: 15
Joined: Thu Aug 24, 2017 3:34 pm

Returning from C functions after setup mmu

Mon Oct 02, 2017 12:35 am

I'm having an hard time understanding why returning from c functions wont work.

The code is loaded at 8000 to be run at 0x80008000 after nmu is configured. but initialy runs at 0x8000

linker.ld: .init 0x80008000 : AT(0x8000)

Boot on entry.s there is, as sequence:
- the cpu is put in svc with interrupts disabled
- the stack pointer is set to 0x2000
- call a c function (bl main1)
- the stack pointer is relocated to 0x80002xxxx
- call a c function (bl main2)
- loopq

On main1()
- call uartinit
- put msg ok
- call mmuinit

On mmuinit
it set the tables from 0x3000 to 0x4000, and from 0x4000 to 0x8000
The va 0x80000000 is maped to pa 0x, and the devspace is also taked in account.
at end, with mmu already enable, the put msg using virtual address is show ok
next the function should return, but it never did. because the next message was never shows.

Sometimes, with small changes in the code, the strings the _puts are sending just stops and every thing hangs.
If the full message was: "this is a long message", just prints: "this is a lon" and hangs.

Anyone experiences this kind of situation enabling the mmu?

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

Re: Returning from C functions after setup mmu

Mon Oct 02, 2017 6:59 pm

where is the mmu init code physically? you have it mapped into the space at the same address it is executing as yes? so that it can actually exit with the mmu on? likeise the return address points at a valid address with the mmu on?

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

Re: Returning from C functions after setup mmu

Mon Oct 02, 2017 7:00 pm

if as an experiment you map the whole world one to one, virtual=physical, does that work with the mmu enabled?

inaciose
Posts: 15
Joined: Thu Aug 24, 2017 3:34 pm

Re: Returning from C functions after setup mmu

Mon Oct 02, 2017 9:19 pm

Thank you for your reply.

it is not on experiment (a simple sample code) but the initial code boot of xv6 for for pi (bcm2836), that don't boot in raspeberry pi 1 B, as it supposed.

The mmu setup code its somewhat similar to your sample: https://github.com/dwelch67/raspberrypi/tree/master/mmu

The main difference is that code is linked to run at 0x80008000 and it is loaded at 0x8000. It also start run at 0x8000.
So when we map the virtual addresses 0x80000000 to 0x0, it didn't need to map 0x0 to 0x0.
See the linker.ld: https://github.com/zhiyihuang/xv6_rpi_p ... /kernel.ld
Relevant part:

.init 0x80008000 : AT(0x8000) {
*(.init)
}
where is the mmu init code physically? you have it mapped into the space at the same address it is executing as yes? so that it can actually exit with the mmu on? likeise the return address points at a valid address with the mmu on?
Yes, the linker load them at 0x8000, start running it at 0x8000, and when mmu is enabled with va 0x80000000 mapped to 0x0 for lenght 0x0C000000.

Boot entry
https://github.com/zhiyihuang/xv6_rpi_p ... ce/entry.s
Set the stackpointer
Jump mmuinit0

mmu.c
https://github.com/zhiyihuang/xv6_rpi_p ... urce/mmu.c

The problems can be checked if you try to output anything inside mmu.c (mmuinit0).

One observation is that with -O2 the compiler didn't put some bx lr at the end of functions assembler. I removed also.
Other observation is that the original xv6 code put the stackpoint at 0x3000 on entry.s and on mmuinit0 begining it zeroed all the memory from 0x2000 to 0x8000, the mmu tables start at 0x3000. So i also tried to move the stackpointer to 0x2000.

The 2 points to fail return from functions should be: mmu transition to enable, and stackpointer corruption. I'm correct?

By the way I would be grateful if you can try to run this xv6 port to pi 1, bellow, and tell me if you are successfully boot it

git clone https://github.com/zhiyihuang/xv6_rpi_port.git
cd xv6_rpi_port
make

Then, in a duplicated raspbian sdcard just replace you regular kernel.img by copy the generated kernel.img to your sdcard boot partition.
Or just send the kernel image with a serial bootloader

If during compiling you have problems with the libcsud.a, I manage to recompile it and replace that file whit the new one.

https://github.com/Chadderz121/csud

The command I use to compile libcsud.a for raspi:

make driver TYPE=STANDALONE TARGET=RPI GNU=arm-none-eabi-

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

Re: Returning from C functions after setup mmu

Tue Oct 03, 2017 1:37 am

what i am suggesting is divide the problem in half. Is the problem the mmu setup, or the mmu init, or other. If you switch to a one to one virtual = physical and that works THEN modify one thing, the location of the program. If you want to run 0x80008000 code at 0x8000 you have to insure it is position independent up to the point it the mmu is enabled, or you build that code for 0x8000 and then the mmu init is position independent.

I see you are using inline assembly and perhaps that is the issue, start with real assembly first then if really needed for some reason use inline.

dont understand the bx lr comment, a pop pc is in theory fine (I just discovered an issue with pop pc in the arm11 mpcore that it will continue to execute the instructions that follow, gcc puts data there so for certain data patterns that represent certain instructions it causes problems. gcc folks would rather me bandaid their flaw in executing data, but I just received another arm11 mpcore I am going to test, as well as some other cores, I suspect as usual gcc folks wont care and will ignore it...

Anyway pop pc or bx lr or if there is a tail optimization a branch to another function which does the return are all fine.

Did you take this one step at a time or did you dive in and try several things at once?

inaciose
Posts: 15
Joined: Thu Aug 24, 2017 3:34 pm

Re: Returning from C functions after setup mmu

Tue Oct 03, 2017 12:33 pm

Yes, I did it step by step, but never get it right.
Today I have been able to boot it successfully.

There are one problem during the debug, that prevents its correct boot.

Initiating the uart 2 times, goes wrong. I believe it's the source of hanging during puts strings on uart, and its effect is strange, because affect early puts commandants.

Besides that, in the original program:
The stackpointer memory is zeroed, That way the c function can't correctely return.
The code for entry.s and the mmuinit are to far way from each other.

To put it work, I needed:
rearrange the linker file an the makefile, to put the mmu code close to entry
dont zero the stackmemory
Don't init the uart the second time, because I init early to debug.

Thanks for your help dwe.

Return to “Bare metal”

Who is online

Users browsing this forum: albiorixza and 4 guests