Skip to content

Commit fce2bc2

Browse files
author
Russell King
committed
Merge tag 'efi-arm-no-relocate-for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux into misc
Simplify EFI handover to decompressor The EFI stub in the ARM kernel runs in the context of the firmware, which means it usually runs with the caches and MMU on. Currently, we relocate the zImage so it appears in the first 128 MiB, disable the MMU and caches and invoke the decompressor via its ordinary entry point. However, since we can pass the base of DRAM directly, there is no need to relocate the zImage, which also means there is no need to disable and re-enable the caches and create new page tables etc. This also allows systems whose DRAM start address is not a round multiple of 128 MB to decompress the kernel proper to the base of memory, ensuring that all memory is usable at runtime.
2 parents 2318976 + d0f9ca9 commit fce2bc2

File tree

3 files changed

+43
-86
lines changed

3 files changed

+43
-86
lines changed

arch/arm/boot/compressed/head.S

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -287,28 +287,22 @@ not_angel:
287287
*/
288288
mov r0, pc
289289
cmp r0, r4
290-
ldrcc r0, LC0+28
290+
ldrcc r0, .Lheadroom
291291
addcc r0, r0, pc
292292
cmpcc r4, r0
293293
orrcc r4, r4, #1 @ remember we skipped cache_on
294294
blcs cache_on
295295

296-
restart: adr r0, LC0
297-
ldmia r0, {r1, r2, r3, r6, r11, r12}
298-
ldr sp, [r0, #24]
299-
300-
/*
301-
* We might be running at a different address. We need
302-
* to fix up various pointers.
303-
*/
304-
sub r0, r0, r1 @ calculate the delta offset
305-
add r6, r6, r0 @ _edata
296+
restart: adr r0, LC1
297+
ldr sp, [r0]
298+
ldr r6, [r0, #4]
299+
add sp, sp, r0
300+
add r6, r6, r0
306301

307302
get_inflated_image_size r9, r10, lr
308303

309304
#ifndef CONFIG_ZBOOT_ROM
310305
/* malloc space is above the relocated stack (64k max) */
311-
add sp, sp, r0
312306
add r10, sp, #0x10000
313307
#else
314308
/*
@@ -322,18 +316,13 @@ restart: adr r0, LC0
322316
mov r5, #0 @ init dtb size to 0
323317
#ifdef CONFIG_ARM_APPENDED_DTB
324318
/*
325-
* r0 = delta
326-
* r2 = BSS start
327-
* r3 = BSS end
328319
* r4 = final kernel address (possibly with LSB set)
329320
* r5 = appended dtb size (still unknown)
330321
* r6 = _edata
331322
* r7 = architecture ID
332323
* r8 = atags/device tree pointer
333324
* r9 = size of decompressed image
334325
* r10 = end of this image, including bss/stack/malloc space if non XIP
335-
* r11 = GOT start
336-
* r12 = GOT end
337326
* sp = stack pointer
338327
*
339328
* if there are device trees (dtb) appended to zImage, advance r10 so that the
@@ -381,7 +370,6 @@ restart: adr r0, LC0
381370
/* temporarily relocate the stack past the DTB work space */
382371
add sp, sp, r5
383372

384-
stmfd sp!, {r0-r3, ip, lr}
385373
mov r0, r8
386374
mov r1, r6
387375
mov r2, r5
@@ -400,7 +388,6 @@ restart: adr r0, LC0
400388
mov r2, r5
401389
bleq atags_to_fdt
402390

403-
ldmfd sp!, {r0-r3, ip, lr}
404391
sub sp, sp, r5
405392
#endif
406393

@@ -537,6 +524,10 @@ dtb_check_done:
537524
mov pc, r0
538525

539526
wont_overwrite:
527+
adr r0, LC0
528+
ldmia r0, {r1, r2, r3, r11, r12}
529+
sub r0, r0, r1 @ calculate the delta offset
530+
540531
/*
541532
* If delta is zero, we are running at the address we were linked at.
542533
* r0 = delta
@@ -660,13 +651,18 @@ not_relocated: mov r0, #0
660651
LC0: .word LC0 @ r1
661652
.word __bss_start @ r2
662653
.word _end @ r3
663-
.word _edata @ r6
664654
.word _got_start @ r11
665655
.word _got_end @ ip
666-
.word .L_user_stack_end @ sp
667-
.word _end - restart + 16384 + 1024*1024
668656
.size LC0, . - LC0
669657

658+
.type LC1, #object
659+
LC1: .word .L_user_stack_end - LC1 @ sp
660+
.word _edata - LC1 @ r6
661+
.size LC1, . - LC1
662+
663+
.Lheadroom:
664+
.word _end - restart + 16384 + 1024*1024
665+
670666
.Linflated_image_size_offset:
671667
.long (input_data_end - 4) - .
672668

@@ -1434,37 +1430,26 @@ reloc_code_end:
14341430

14351431
#ifdef CONFIG_EFI_STUB
14361432
ENTRY(efi_enter_kernel)
1437-
mov r7, r0 @ preserve image base
1438-
mov r4, r1 @ preserve DT pointer
1433+
mov r4, r0 @ preserve image base
1434+
mov r8, r1 @ preserve DT pointer
14391435

1440-
mov r0, r4 @ DT start
1441-
add r1, r4, r2 @ DT end
1442-
bl cache_clean_flush
1436+
mrc p15, 0, r0, c1, c0, 0 @ read SCTLR
1437+
tst r0, #0x1 @ MMU enabled?
1438+
orreq r4, r4, #1 @ set LSB if not
14431439

1444-
mov r0, r7 @ relocated zImage
1445-
ldr r1, =_edata @ size of zImage
1446-
add r1, r1, r0 @ end of zImage
1440+
mov r0, r8 @ DT start
1441+
add r1, r8, r2 @ DT end
14471442
bl cache_clean_flush
14481443

1449-
@ The PE/COFF loader might not have cleaned the code we are
1450-
@ running beyond the PoU, and so calling cache_off below from
1451-
@ inside the PE/COFF loader allocated region is unsafe unless
1452-
@ we explicitly clean it to the PoC.
1453-
adr r0, call_cache_fn @ region of code we will
1454-
adr r1, 0f @ run with MMU off
1455-
bl cache_clean_flush
1456-
bl cache_off
1444+
adr r0, 0f @ switch to our stack
1445+
ldr sp, [r0]
1446+
add sp, sp, r0
14571447

1458-
@ Set parameters for booting zImage according to boot protocol
1459-
@ put FDT address in r2, it was returned by efi_entry()
1460-
@ r1 is the machine type, and r0 needs to be 0
1461-
mov r0, #0
1462-
mov r1, #0xFFFFFFFF
1463-
mov r2, r4
1464-
add r7, r7, #(__efi_start - start)
1465-
mov pc, r7 @ no mode switch
1448+
mov r5, #0 @ appended DTB size
1449+
mov r7, #0xFFFFFFFF @ machine ID
1450+
b wont_overwrite
14661451
ENDPROC(efi_enter_kernel)
1467-
0:
1452+
0: .long .L_user_stack_end - .
14681453
#endif
14691454

14701455
.align

arch/arm/boot/compressed/vmlinux.lds.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,11 @@ SECTIONS
6363
_etext = .;
6464

6565
.got.plt : { *(.got.plt) }
66+
#ifndef CONFIG_EFI_STUB
6667
_got_start = .;
6768
.got : { *(.got) }
6869
_got_end = .;
70+
#endif
6971

7072
/* ensure the zImage file size is always a multiple of 64 bits */
7173
/* (without a dummy byte, ld just ignores the empty section) */
@@ -74,6 +76,9 @@ SECTIONS
7476
#ifdef CONFIG_EFI_STUB
7577
.data : ALIGN(4096) {
7678
__pecoff_data_start = .;
79+
_got_start = .;
80+
*(.got)
81+
_got_end = .;
7782
/*
7883
* The EFI stub always executes from RAM, and runs strictly before the
7984
* decompressor, so we can make an exception for its r/w data, and keep it

drivers/firmware/efi/libstub/arm32-stub.c

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
199199
unsigned long kernel_base;
200200
efi_status_t status;
201201

202-
/*
203-
* Verify that the DRAM base address is compatible with the ARM
204-
* boot protocol, which determines the base of DRAM by masking
205-
* off the low 27 bits of the address at which the zImage is
206-
* loaded. These assumptions are made by the decompressor,
207-
* before any memory map is available.
208-
*/
209-
kernel_base = round_up(dram_base, SZ_128M);
202+
/* use a 16 MiB aligned base for the decompressed kernel */
203+
kernel_base = round_up(dram_base, SZ_16M) + TEXT_OFFSET;
210204

211205
/*
212206
* Note that some platforms (notably, the Raspberry Pi 2) put
@@ -215,41 +209,14 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
215209
* base of the kernel image is only partially used at the moment.
216210
* (Up to 5 pages are used for the swapper page tables)
217211
*/
218-
kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE;
219-
220-
status = reserve_kernel_base(kernel_base, reserve_addr, reserve_size);
212+
status = reserve_kernel_base(kernel_base - 5 * PAGE_SIZE, reserve_addr,
213+
reserve_size);
221214
if (status != EFI_SUCCESS) {
222215
pr_efi_err("Unable to allocate memory for uncompressed kernel.\n");
223216
return status;
224217
}
225218

226-
/*
227-
* Relocate the zImage, so that it appears in the lowest 128 MB
228-
* memory window.
229-
*/
230-
*image_addr = (unsigned long)image->image_base;
231-
*image_size = image->image_size;
232-
status = efi_relocate_kernel(image_addr, *image_size, *image_size,
233-
kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0);
234-
if (status != EFI_SUCCESS) {
235-
pr_efi_err("Failed to relocate kernel.\n");
236-
efi_free(*reserve_size, *reserve_addr);
237-
*reserve_size = 0;
238-
return status;
239-
}
240-
241-
/*
242-
* Check to see if we were able to allocate memory low enough
243-
* in memory. The kernel determines the base of DRAM from the
244-
* address at which the zImage is loaded.
245-
*/
246-
if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
247-
pr_efi_err("Failed to relocate kernel, no low memory available.\n");
248-
efi_free(*reserve_size, *reserve_addr);
249-
*reserve_size = 0;
250-
efi_free(*image_size, *image_addr);
251-
*image_size = 0;
252-
return EFI_LOAD_ERROR;
253-
}
219+
*image_addr = kernel_base;
220+
*image_size = 0;
254221
return EFI_SUCCESS;
255222
}

0 commit comments

Comments
 (0)