svn commit: r261855 - head/sys/arm/arm
Andrew Turner
andrew at FreeBSD.org
Thu Feb 13 21:30:55 UTC 2014
Author: andrew
Date: Thu Feb 13 21:30:54 2014
New Revision: 261855
URL: http://svnweb.freebsd.org/changeset/base/261855
Log:
Allow the kernel to be loaded at any 1MiB address. This requirement is
because we use the 1MiB section maps as they only need a single pagetable.
To allow this we only use pc relative loads to ensure we only load from
physical addresses until we are running from a known virtual address.
As a side effect any data from before or 64MiB after the kernel needs to
be mapped in to be used. This should not be an issue for kernels loaded
with ubldr as it places this data just after the kernel. It will be a
problem when loading directly from anything using the Linux ABI that
places the ATAG data outside this range, for example U-Boot.
Modified:
head/sys/arm/arm/locore.S
Modified: head/sys/arm/arm/locore.S
==============================================================================
--- head/sys/arm/arm/locore.S Thu Feb 13 20:41:25 2014 (r261854)
+++ head/sys/arm/arm/locore.S Thu Feb 13 21:30:54 2014 (r261855)
@@ -148,15 +148,31 @@ Lunmapped:
* Build page table from scratch.
*/
- /* Load the page tables physical address */
- ldr r1, Lstartup_pagetable
- ldr r2, =(KERNVIRTADDR - KERNPHYSADDR)
+ /* Find the delta between VA and PA */
+ adr r0, Lpagetable
+ ldr r1, [r0]
+ sub r2, r1, r0
+ /* At this point: r2 = VA - PA */
+
+ /*
+ * Find the physical address of the table. After these two
+ * instructions:
+ * r1 = va(pagetable)
+ *
+ * r0 = va(pagetable) - (VA - PA)
+ * = va(pagetable) - VA + PA
+ * = pa(pagetable)
+ */
+ ldr r1, [r0, #4]
sub r0, r1, r2
/*
* Map PA == VA
*/
- ldr r5, =(PHYSADDR)
+ /* Find the start kernels load address */
+ adr r5, _start
+ ldr r2, =(L1_S_OFFSET)
+ bic r5, r2
mov r1, r5
mov r2, r5
/* Map 64MiB, preserved over calls to build_pagetables */
@@ -165,7 +181,7 @@ Lunmapped:
/* Create the kernel map to jump to */
mov r1, r5
- ldr r2, =(KERNBASE)
+ ldr r2, =(KERNVIRTADDR)
bl build_pagetables
#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
@@ -223,16 +239,16 @@ mmu_done:
virt_done:
mov r1, #28 /* loader info size is 28 bytes also second arg */
subs sp, sp, r1 /* allocate arm_boot_params struct on stack */
- bic sp, sp, #7 /* align stack to 8 bytes */
mov r0, sp /* loader info pointer is first arg */
+ bic sp, sp, #7 /* align stack to 8 bytes */
str r1, [r0] /* Store length of loader info */
str r9, [r0, #4] /* Store r0 from boot loader */
str r8, [r0, #8] /* Store r1 from boot loader */
str ip, [r0, #12] /* store r2 from boot loader */
str fp, [r0, #16] /* store r3 from boot loader */
- ldr r5, =KERNPHYSADDR /* load KERNPHYSADDR as the physical address */
str r5, [r0, #20] /* store the physical address */
- ldr r5, Lstartup_pagetable
+ adr r4, Lpagetable /* load the pagetable address */
+ ldr r5, [r4, #4]
str r5, [r0, #24] /* store the pagetable address */
mov fp, #0 /* trace back starts here */
bl _C_LABEL(initarm) /* Off we go */
@@ -279,16 +295,19 @@ build_pagetables:
RET
+Lpagetable:
+ .word .
+ .word pagetable
+
Lvirtaddr:
.word KERNVIRTADDR
Lphysaddr:
.word KERNPHYSADDR
Lreal_start:
.word _start
-Lend:
+Lend:
.word _edata
-Lstartup_pagetable:
- .word pagetable
+
#ifdef SMP
Lstartup_pagetable_secondary:
.word temp_pagetable
More information about the svn-src-all
mailing list