Changeset 63a045c in mainline for boot/arch/riscv64/src/main.c


Ignore:
Timestamp:
2018-10-10T17:41:44Z (6 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9286475
Parents:
63c1dd5
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-10-10 17:11:15)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-10-10 17:41:44)
Message:

Unify handling of compressed init data and use regular tar + gzip to achieve it

There are two issues this commit solves.

First is that architecture-specific code duplicates most of the init binary
handling in each architecture, each with miniscule and confusing variations.
After this commit, the init binary expansion is almost entirely handled by
unified generic code.

Second is that the way we used to generate the incorporated data is somewhat
convoluted. Previously we have a Python script which generates a zip archive
with individual deflate-compressed files and accompanying header and C files
which contain structures describing the archive contents.
The zip file is then extracted and the individual deflate-compressed files are
included in the binary via assembler code.
Since gas doesn't take particular care to be consistent between architectures,
the assembly portions are also not uniform and the build script needs to know
particulars of the architecture's assembly.

Instead of doing that, after this commit we first gzip each included file, then
we pack the gzipped files into a tar archive, and then we include the archive
into the binary using objcopy.
Linker script provides symbols for the start and end of the archive,
and the payload is in a self-describing format, so there is no need for any
generated code.

Note that we are doing the opposite of the conventional .tar.gz format.
It would be somewhat inconvenient to use .tar.gz since the uncompressed files
need to be aligned to page size, so we'd have to first decompress the entire
payload to determine the final position of the files (and hence the required
amount of memory).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/riscv64/src/main.c

    r63c1dd5 r63a045c  
    4141#include <str.h>
    4242#include <halt.h>
    43 #include <inflate.h>
    44 #include "../../components.h"
     43#include <payload.h>
    4544
    4645static bootinfo_t bootinfo;
     
    6968        printf(" %p: boot info structure\n", &bootinfo);
    7069
    71         uintptr_t top = BOOT_OFFSET;
     70        uint8_t *load_addr = (uint8_t *) BOOT_OFFSET;
     71        uintptr_t kernel_addr = PA2KA(load_addr);
    7272
    73         for (size_t i = 0; i < COMPONENTS; i++) {
    74                 printf(" %p: %s image (%zu/%zu bytes)\n", components[i].addr,
    75                     components[i].name, components[i].inflated,
    76                     components[i].size);
     73        printf(" %p: inflate area\n", load_addr);
     74        printf(" %p: kernel entry point\n", (void *) kernel_addr);
    7775
    78                 uintptr_t tail = (uintptr_t) components[i].addr +
    79                     components[i].size;
    80                 if (tail > top) {
    81                         printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
    82                             components[i].name, (void *) tail, (void *) top);
    83                         halt();
     76        /* Find the end of the memory zone containing the load address. */
     77        uint8_t *end = NULL;
     78        for (size_t i = 0; i < bootinfo.memmap.cnt; i++) {
     79                memzone_t z = bootinfo.memmap.zones[i];
     80
     81                if (z.start <= (void *) load_addr &&
     82                    z.start + z.size > (void *) load_addr) {
     83                        end = z.start + z.size;
    8484                }
    8585        }
    8686
    87         printf(" %p: inflate area\n", (void *) top);
    88 
    89         void *kernel_entry = NULL;
    90         void *dest[COMPONENTS];
    91         size_t cnt = 0;
    92         bootinfo.taskmap.cnt = 0;
    93 
    94         for (size_t i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
    95                 top = ALIGN_UP(top, PAGE_SIZE);
    96 
    97                 if (i > 0) {
    98                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr =
    99                             (void *) PA2KA(top);
    100                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size =
    101                             components[i].inflated;
    102 
    103                         str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name,
    104                             BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
    105 
    106                         bootinfo.taskmap.cnt++;
    107                 } else
    108                         kernel_entry = (void *) PA2KA(top);
    109 
    110                 dest[i] = (void *) top;
    111                 top += components[i].inflated;
    112                 cnt++;
    113         }
    114 
    115         printf(" %p: kernel entry point\n", kernel_entry);
    116 
    117         if (top >= bootinfo.physmem_start + bootinfo.memmap.total) {
    118                 printf("Not enough physical memory available.\n");
    119                 printf("The boot image is too large. Halting.\n");
    120                 halt();
    121         }
    122 
    123         printf("\nInflating components ... ");
    124 
    125         for (size_t i = cnt; i > 0; i--) {
    126                 printf("%s ", components[i - 1].name);
    127 
    128                 int err = inflate(components[i - 1].addr, components[i - 1].size,
    129                     dest[i - 1], components[i - 1].inflated);
    130 
    131                 if (err != EOK) {
    132                         printf("\n%s: Inflating error %d, halting.\n",
    133                             components[i - 1].name, err);
    134                         halt();
    135                 }
    136         }
    137 
    138         printf(".\n");
     87        // TODO: Cache-coherence callback?
     88        extract_payload(&bootinfo.taskmap, load_addr, end, kernel_addr, NULL);
    13989
    14090        printf("Booting the kernel...\n");
Note: See TracChangeset for help on using the changeset viewer.