From 2d91eebbf1fc9335269207602b360ec485aaf7bb Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Tue, 17 Dec 2019 17:39:03 +0100 Subject: don't embed stage2 of bootloader as binary blob - use smart section naming --- Makefile | 11 ++++----- loader_linker.ld | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ loader_stage1.c | 21 +++++++++-------- loader_stage1.ld | 56 --------------------------------------------- loader_stage2.c | 2 -- loader_stage2.ld | 44 ----------------------------------- 6 files changed, 85 insertions(+), 119 deletions(-) create mode 100644 loader_linker.ld delete mode 100644 loader_stage1.ld delete mode 100644 loader_stage2.ld diff --git a/Makefile b/Makefile index d1d66fa..35cc48c 100644 --- a/Makefile +++ b/Makefile @@ -30,17 +30,14 @@ PL_0_test.elf : PL0_test.o uart.o kernel.elf : boot.o kernel.o uart.o PL_0_test_embeddable.o demo_functionality.o paging.o libkernel_renamed.o interrupt_vector.o interrupts.o arm-none-eabi-gcc -T linker.ld -o $@ $(ELFFLAGS) $^ -loader_stage2.elf : loader_stage2.o uart.o - arm-none-eabi-gcc -T loader_stage2.ld -o $@ $(ELFFLAGS) $^ +loader.elf : boot.o loader_stage1.o loader_stage2.o uart.o + arm-none-eabi-gcc -T loader_linker.ld -o $@ $(ELFFLAGS) $^ -loader_stage2.img : loader_stage2.elf +loader.img : loader.elf arm-none-eabi-objcopy $^ -O binary $@ +# check if the resulting image is not too big test -n "$$(find $@ -size -16384c)" || exit -1 -loader.elf : boot.o loader_stage1.o loader_stage2_embeddable.o - arm-none-eabi-gcc -T loader_stage1.ld -o $@ $(ELFFLAGS) $^ - - qemu-elf : kernel.elf qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $^ diff --git a/loader_linker.ld b/loader_linker.ld new file mode 100644 index 0000000..a8942f6 --- /dev/null +++ b/loader_linker.ld @@ -0,0 +1,70 @@ +ENTRY(_start) + +SECTIONS +{ + /* Starts at LOADER_ADDR. */ + /* Warning! Internet says RPis in 32-bit mode load binary at 0x8000! */ + /* My experiments do, however, show, that qemu emulating RPi2 */ + /* loads it at 0x10000! (took some pain to find out) */ + + /* . = 0x10000; */ + + /* rpi-open-firmware, on the other hand, loads it at 0x2000000 */ + /* (and this should be not-so-hard to change by modifying the */ + /* firmware) */ + + . = 0x2000000; + + /* For AArch64, use . = 0x80000; Unless this too is wrong */ + + __start = .; + __text_stage1_start = .; + .text_stage1 : + { + KEEP(*(.text.boot)) + *(.text.boot) + *(.text.stage1main) + } + . = ALIGN(4096); /* align to page size */ + __text_stage1_end = .; + + __stage2_start = .; + __text_start = .; + .text : + { + KEEP(*(.text.stage2main)) + *(.text.boot) + } + . = ALIGN(4096); /* align to page size */ + __text_end = .; + + __rodata_start = .; + .rodata : + { + *(.rodata) + } + . = ALIGN(4096); /* align to page size */ + __rodata_end = .; + + __data_start = .; + .data : + { + *(.data) + } + . = ALIGN(4096); /* align to page size */ + __data_end = .; + + __bss_start = .; + .bss : + { + bss = .; + *(.bss) + } + . = ALIGN(4096); /* align to page size */ + __bss_end = .; + __bss_size = __bss_end - __bss_start; + + __stage2_end = .; + __stage2_size = __stage2_end - __stage2_start; + __end = .; +} diff --git a/loader_stage1.c b/loader_stage1.c index d209c15..aca439c 100644 --- a/loader_stage1.c +++ b/loader_stage1.c @@ -2,24 +2,25 @@ #include #include -char *const stage2_addr = ((void*) 0x4000); +#define STAGE2_ADDR ((volatile char*) 0x4000) -// there's one tricky thing about embedding file in executable; -// mainly, symbols are visible to c code as extern chars, but the actual +// There's one tricky thing about managing executable's own code. +// Mainly, symbols are visible to c code as extern chars, but the actual // values are their adresses... see the code below extern char - _binary_loader_stage2_img_start, - _binary_loader_stage2_img_end, - _binary_loader_stage2_img_size; + __stage2_start, + __stage2_end, + __stage2_size; +__attribute__((section(".text.stage1main"))) void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags) { - // stage2 of the bootloader is a blob embedded in executable; + // stage2 of the bootloader is part of executable; // copy it over to it's destination place // TODO implement a memcpy() somewhere and use it instead of loops - for (size_t i = 0; i < (size_t) &_binary_loader_stage2_img_size; i++) - stage2_addr[i] = (&_binary_loader_stage2_img_start)[i]; + for (size_t i = 0; i < (size_t) &__stage2_size; i++) + STAGE2_ADDR[i] = (&__stage2_start)[i]; // jump to stage2 - ((void(*)(uint32_t, uint32_t, uint32_t))stage2_addr)(r0, r1, atags); + ((void(*)(uint32_t, uint32_t, uint32_t))STAGE2_ADDR)(r0, r1, atags); } diff --git a/loader_stage1.ld b/loader_stage1.ld deleted file mode 100644 index 18fe477..0000000 --- a/loader_stage1.ld +++ /dev/null @@ -1,56 +0,0 @@ -ENTRY(_start) - -SECTIONS -{ - /* Starts at LOADER_ADDR. */ - /* Warning! Internet says RPis in 32-bit mode load binary at 0x8000! */ - /* My experiments do, however, show, that qemu emulating RPi2 */ - /* loads it at 0x10000! (took some pain to find out) */ - - /* . = 0x10000; */ - - /* rpi-open-firmware, on the other hand, loads it at 0x2000000 */ - /* (and this should be not-so-hard to change by modifying the */ - /* firmware) */ - - . = 0x2000000; - - /* For AArch64, use . = 0x80000; Unless this too is wrong */ - - __start = .; - __text_start = .; - .text : - { - KEEP(*(.text.boot)) - *(.text) - } - . = ALIGN(4096); /* align to page size */ - __text_end = .; - - __rodata_start = .; - .rodata : - { - *(.rodata) - } - . = ALIGN(4096); /* align to page size */ - __rodata_end = .; - - __data_start = .; - .data : - { - *(.data) - } - . = ALIGN(4096); /* align to page size */ - __data_end = .; - - __bss_start = .; - .bss : - { - bss = .; - *(.bss) - } - . = ALIGN(4096); /* align to page size */ - __bss_end = .; - __bss_size = __bss_end - __bss_start; - __end = .; -} diff --git a/loader_stage2.c b/loader_stage2.c index e221dda..7b5087a 100644 --- a/loader_stage2.c +++ b/loader_stage2.c @@ -36,5 +36,3 @@ stage2(uint32_t r0, uint32_t r1, uint32_t atags) asm volatile("bx %0" :: "r" (kernel_load_addr) : "memory"); } -void *const _start = ((void*) stage2); // for linker script - diff --git a/loader_stage2.ld b/loader_stage2.ld deleted file mode 100644 index 8f215e9..0000000 --- a/loader_stage2.ld +++ /dev/null @@ -1,44 +0,0 @@ -ENTRY(_start) - -SECTIONS -{ - /* stage2 bootloader gets loaded at 0x4000 */ - . = 0x4000; - __start = .; - __text_start = .; - .text : - { - /* have entry point at the beginning */ - KEEP(*(.text.stage2main)) - *(.text) - } - . = ALIGN(4096); /* align to page size */ - __text_end = .; - - __rodata_start = .; - .rodata : - { - *(.rodata) - } - . = ALIGN(4096); /* align to page size */ - __rodata_end = .; - - __data_start = .; - .data : - { - *(.data) - } - . = ALIGN(4096); /* align to page size */ - __data_end = .; - - __bss_start = .; - .bss : - { - bss = .; - *(.bss) - } - . = ALIGN(4096); /* align to page size */ - __bss_end = .; - __bss_size = __bss_end - __bss_start; - __end = .; -} -- cgit v1.2.3