Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 63a045c in mainline


Ignore:
Timestamp:
2018-10-10T17:41:44Z (3 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master
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).

Files:
7 added
32 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile

    r63c1dd5 r63a045c  
    134134
    135135clean_dist:
    136         rm -f $(INITRD).img $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE) $(COMPS).o $(COMPS)_desc.o $(COMPS).zip $(LINK)
     136        rm -f $(INITRD).img $(COMPS).o $(COMPS).tar $(LINK)
    137137        find $(USPACE_PATH)/dist -mindepth 1 -maxdepth 1 -type f -exec rm \{\} \;
    138138        rm -f $(USPACE_PATH)/dist/app/*
  • boot/Makefile.build

    r63c1dd5 r63a045c  
    9898depend: $(PRE_DEPEND)
    9999
    100 $(COMPS).s: $(COMPS).zip
    101         unzip -p $< $@ > $@
     100%.gz: %
     101        gzip -n -k -f $<
    102102
    103 $(COMPS).h: $(COMPS).zip
    104         unzip -p $< $@ > $@
     103$(COMPS).tar: $(addsuffix .gz, $(COMPONENTS))
     104        tar --mtime='2032-01-01 00:00:00' --group=0 --owner=0 --no-acls --no-selinux --no-xattrs --format=ustar --transform 's/.*\///g' -cvf $@ $^
    105105
    106 $(COMPS)_desc.c: $(COMPS).zip
    107         unzip -p $< $@ > $@
    108 
    109 $(COMPONENTS_DEFLATE): $(COMPS).zip
    110         unzip -p $< $@ > $@
    111 
    112 $(COMPS).zip: $(COMPONENTS)
    113         $(MKARRAY) --deflate $(COMPS) $(COMP) "$(AS_PROLOG)" ".section .components, \"a\"" $^
     106$(COMPS).o: $(COMPS).tar
     107        # Create empty object file.
     108        $(CC) -x c -c -o $@.new $(DEFS) $(CFLAGS) - </dev/null
     109        # Add .payload section to it.
     110        $(OBJCOPY) --add-section '.payload'=$< $@.new $@
    114111
    115112include Makefile.initrd
  • boot/Makefile.common

    r63c1dd5 r63a045c  
    260260        $(INITRD).img
    261261
    262 COMPONENTS_DEFLATE := $(addsuffix .deflate,$(notdir $(COMPONENTS)))
    263262
    264263LINK = arch/$(BARCH)/_link.ld
  • boot/arch/arm32/Makefile.inc

    r63c1dd5 r63a045c  
    9696        arch/$(BARCH)/src/mm.c \
    9797        arch/$(BARCH)/src/putchar.c \
    98         $(COMPS).s \
    99         $(COMPS)_desc.c \
     98        $(COMPS).o \
    10099        genarch/src/division.c \
    101100        generic/src/memstr.c \
     
    105104        generic/src/str.c \
    106105        generic/src/version.c \
    107         generic/src/inflate.c
    108 
    109 PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
     106        generic/src/inflate.c \
     107        generic/src/gzip.c \
     108        generic/src/tar.c \
     109        generic/src/payload.c
  • boot/arch/arm32/_link.ld.in

    r63c1dd5 r63a045c  
    66        . = BOOT_BASE;
    77        .text : {
     8                loader_start = .;
    89                *(BOOTSTRAP);
    910                *(.text);
     
    1112        . = BOOT_BASE + 0x8000;
    1213        .data : {
    13                 bdata_start = .;
    1414                *(BOOTPT);      /* bootstrap page table */
    1515                *(BOOTSTACK);   /* bootstrap stack */
     
    2323                *(.bss);        /* uninitialized static variables */
    2424                *(COMMON);      /* global variables */
    25                 *(.components);
     25                loader_end = .;
     26                payload_start = .;
     27                *(.payload);
     28                payload_end = .;
    2629        }
    27         bdata_end = .;
    2830
    2931        /DISCARD/ : {
  • boot/arch/arm32/include/arch/types.h

    r63c1dd5 r63a045c  
    5454        size_t cnt;
    5555        task_t tasks[TASKMAP_MAX_RECORDS];
     56} taskmap_t;
     57
     58typedef struct {
     59        taskmap_t taskmap;
    5660} bootinfo_t;
    5761
  • boot/arch/arm32/src/main.c

    r63c1dd5 r63a045c  
    4949#include <inflate.h>
    5050#include <arch/cp15.h>
    51 #include "../../components.h"
     51#include <payload.h>
    5252
    53 #define TOP2ADDR(top)  (((void *) PA2KA(BOOT_OFFSET)) + (top))
    54 
    55 extern void *bdata_start;
    56 extern void *bdata_end;
    57 
    58 static inline void clean_dcache_poc(void *address, size_t size)
     53static void clean_dcache_poc(void *address, size_t size)
    5954{
    6055        const uintptr_t addr = (uintptr_t) address;
     
    9186        version_print();
    9287
    93         printf("Boot data: %p -> %p\n", &bdata_start, &bdata_end);
     88        printf("Boot loader: %p -> %p\n", loader_start, loader_end);
    9489        printf("\nMemory statistics\n");
    9590        printf(" %p|%p: bootstrap stack\n", &boot_stack, &boot_stack);
     
    9994            (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET);
    10095
    101         for (size_t i = 0; i < COMPONENTS; i++) {
    102                 printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].addr,
    103                     components[i].addr, components[i].name, components[i].inflated,
    104                     components[i].size);
    105         }
     96        // FIXME: Use the correct value.
     97        uint8_t *kernel_dest = (uint8_t *) BOOT_OFFSET;
     98        uint8_t *ram_end = kernel_dest + (1 << 24);
    10699
    107         void *dest[COMPONENTS];
    108         size_t top = 0;
    109         size_t cnt = 0;
    110         bootinfo.cnt = 0;
    111         for (size_t i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
    112                 top = ALIGN_UP(top, PAGE_SIZE);
    113 
    114                 if (i > 0) {
    115                         bootinfo.tasks[bootinfo.cnt].addr = TOP2ADDR(top);
    116                         bootinfo.tasks[bootinfo.cnt].size = components[i].inflated;
    117 
    118                         str_cpy(bootinfo.tasks[bootinfo.cnt].name,
    119                             BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
    120 
    121                         bootinfo.cnt++;
    122                 }
    123 
    124                 dest[i] = TOP2ADDR(top);
    125                 top += components[i].inflated;
    126                 cnt++;
    127         }
    128 
    129         printf("\nInflating components ... ");
    130 
    131         for (size_t i = cnt; i > 0; i--) {
    132                 void *tail = components[i - 1].addr + components[i - 1].size;
    133                 if (tail >= dest[i - 1]) {
    134                         printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
    135                             components[i].name, tail, dest[i - 1]);
    136                         halt();
    137                 }
    138 
    139                 printf("%s ", components[i - 1].name);
    140 
    141                 int err = inflate(components[i - 1].addr, components[i - 1].size,
    142                     dest[i - 1], components[i - 1].inflated);
    143                 if (err != EOK) {
    144                         printf("\n%s: Inflating error %d\n", components[i - 1].name, err);
    145                         halt();
    146                 }
    147                 /* Make sure data are in the memory, ICache will need them */
    148                 clean_dcache_poc(dest[i - 1], components[i - 1].inflated);
    149         }
    150 
    151         printf(".\n");
     100        extract_payload(&bootinfo.taskmap, kernel_dest, ram_end,
     101            PA2KA(kernel_dest), clean_dcache_poc);
    152102
    153103        /* Flush PT too. We need this if we disable caches later */
  • boot/arch/ia64/Makefile.inc

    r63c1dd5 r63a045c  
    4848        arch/$(BARCH)/src/pal_asm.S \
    4949        arch/$(BARCH)/src/putchar.c \
    50         $(COMPS).s \
    51         $(COMPS)_desc.c \
     50        $(COMPS).o \
    5251        genarch/src/efi.c \
    5352        genarch/src/division.c \
     
    5958        generic/src/str.c \
    6059        generic/src/version.c \
    61         generic/src/inflate.c
     60        generic/src/inflate.c \
     61        generic/src/tar.c \
     62        generic/src/gzip.c \
     63        generic/src/payload.c
    6264
    6365ifeq ($(MACHINE),ski)
     
    9799        platform/ski
    98100endif
    99 
    100 PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
  • boot/arch/ia64/_link.ld.in

    r63c1dd5 r63a045c  
    44SECTIONS {
    55        .boot 0x4400000: AT (0x4400000) {
     6                loader_start = .;
    67                *(BOOTSTRAP);
    78                *(.text);
     
    1617                *(.bss);                /* uninitialized static variables */
    1718                *(COMMON);
    18                 *(.components);
     19                loader_end = .;
     20                payload_start = .;
     21                *(.payload);
     22                payload_end = .;
    1923        }
    2024
  • boot/arch/ia64/include/arch/types.h

    r63c1dd5 r63a045c  
    4040        size_t size;
    4141        char name[BOOTINFO_TASK_NAME_BUFLEN];
    42 } binit_task_t;
     42} task_t;
    4343
    4444typedef struct {
    4545        size_t cnt;
    46         binit_task_t tasks[TASKMAP_MAX_RECORDS];
    47 } binit_t;
     46        task_t tasks[TASKMAP_MAX_RECORDS];
     47} taskmap_t;
    4848
    4949typedef struct {
     
    5454
    5555typedef struct {
    56         binit_t taskmap;
     56        taskmap_t taskmap;
    5757
    5858        memmap_item_t memmap[MEMMAP_ITEMS];
  • boot/arch/ia64/src/main.c

    r63c1dd5 r63a045c  
    4343#include <str.h>
    4444#include <errno.h>
    45 #include <inflate.h>
    46 #include "../../components.h"
     45#include <payload.h>
    4746
    4847#define DEFAULT_MEMORY_BASE             0x4000000ULL
     
    150149        version_print();
    151150
     151        printf("Boot loader: %p -> %p\n", loader_start, loader_end);
    152152        printf(" %p|%p: boot info structure\n", &bootinfo, &bootinfo);
    153153        printf(" %p|%p: kernel entry point\n",
     
    156156            (void *) LOADER_ADDRESS, (void *) LOADER_ADDRESS);
    157157
    158         size_t i;
    159         for (i = 0; i < COMPONENTS; i++)
    160                 printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
    161                     components[i].addr, components[i].name,
    162                     components[i].inflated, components[i].size);
    163 
    164         void *dest[COMPONENTS];
    165         size_t top = KERNEL_ADDRESS;
    166         size_t cnt = 0;
    167         bootinfo.taskmap.cnt = 0;
    168         for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
    169                 top = ALIGN_UP(top, PAGE_SIZE);
    170 
    171                 if (i > 0) {
    172                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr =
    173                             (void *) top;
    174                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size =
    175                             components[i].inflated;
    176 
    177                         str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name,
    178                             BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
    179 
    180                         bootinfo.taskmap.cnt++;
    181                 }
    182 
    183                 dest[i] = (void *) top;
    184                 top += components[i].inflated;
    185                 cnt++;
    186         }
    187 
    188         printf("\nInflating components ... ");
    189 
    190         /*
    191          * We will use the next available address for a copy of each component to
    192          * make sure that inflate() works with disjunctive memory regions.
    193          */
    194         top = ALIGN_UP(top, PAGE_SIZE);
    195 
    196         for (i = cnt; i > 0; i--) {
    197                 printf("%s ", components[i - 1].name);
    198 
    199                 /*
    200                  * Copy the component to a location which is guaranteed not to
    201                  * overlap with the destination for inflate().
    202                  */
    203                 memmove((void *) top, components[i - 1].addr, components[i - 1].size);
    204 
    205                 int err = inflate((void *) top, components[i - 1].size,
    206                     dest[i - 1], components[i - 1].inflated);
    207 
    208                 if (err != EOK) {
    209                         printf("\n%s: Inflating error %d, halting.\n",
    210                             components[i - 1].name, err);
    211                         halt();
    212                 }
    213         }
    214 
    215         printf(".\n");
    216 
    217158        read_efi_memmap();
    218159        read_sal_configuration();
    219160        read_pal_configuration();
    220161
     162        uint8_t *kernel_start = (uint8_t *) KERNEL_ADDRESS;
     163        uint8_t *ram_end = NULL;
     164
     165        /* Find the end of the memory area occupied by the kernel. */
     166        for (unsigned i = 0; i < bootinfo.memmap_items; i++) {
     167                memmap_item_t m = bootinfo.memmap[i];
     168                if (m.type == MEMMAP_FREE_MEM &&
     169                    m.base <= (uintptr_t) kernel_start &&
     170                    m.base + m.size > (uintptr_t) kernel_start) {
     171                        ram_end = (uint8_t *) (m.base + m.size);
     172                }
     173        }
     174
     175        if (ram_end == NULL) {
     176                printf("Memory map doesn't contain usable area at kernel's address.\n");
     177                halt();
     178        }
     179
     180        // FIXME: Correct kernel's logical address.
     181        extract_payload(&bootinfo.taskmap, kernel_start, ram_end,
     182            (uintptr_t) kernel_start, NULL);
     183
    221184        printf("Booting the kernel ...\n");
    222185        jump_to_kernel(&bootinfo);
  • boot/arch/mips32/Makefile.inc

    r63c1dd5 r63a045c  
    7676        arch/$(BARCH)/src/main.c \
    7777        arch/$(BARCH)/src/putchar.c \
    78         $(COMPS).s \
    79         $(COMPS)_desc.c \
     78        $(COMPS).o \
    8079        genarch/src/division.c \
    8180        genarch/src/multiplication.c \
     
    8685        generic/src/str.c \
    8786        generic/src/version.c \
    88         generic/src/inflate.c
    89 
    90 PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
     87        generic/src/inflate.c \
     88        generic/src/gzip.c \
     89        generic/src/tar.c \
     90        generic/src/payload.c
  • boot/arch/mips32/_link.ld.in

    r63c1dd5 r63a045c  
    88#endif
    99        .text : {
     10                loader_start = .;
    1011                *(BOOTSTRAP);
    1112                *(.text);
     
    2122                *(.bss);        /* uninitialized static variables */
    2223                *(COMMON);      /* global variables */
    23                 *(.components);
     24                loader_end = .;
     25                payload_start = .;
     26                *(.payload);
     27                payload_end = .;
    2428        }
    2529
  • boot/arch/mips32/include/arch/types.h

    r63c1dd5 r63a045c  
    4646
    4747typedef struct {
     48        size_t cnt;
     49        task_t tasks[TASKMAP_MAX_RECORDS];
     50} taskmap_t;
     51
     52typedef struct {
    4853#if defined(MACHINE_lmalta) || defined(MACHINE_bmalta)
    4954        uint32_t sdram_size;
    5055#endif
    5156        uint32_t cpumap;
    52         size_t cnt;
    53         task_t tasks[TASKMAP_MAX_RECORDS];
     57        taskmap_t taskmap;
    5458} bootinfo_t;
    5559
  • boot/arch/mips32/src/asm.S

    r63c1dd5 r63a045c  
    147147
    148148FUNCTION_BEGIN(jump_to_kernel)
    149         /*
    150          * TODO:
    151          *
    152          * Make sure that the I-cache, D-cache and memory are mutually
    153          * coherent before passing control to the copied code.
    154          */
    155149        j $a0
    156150        nop
  • boot/arch/mips32/src/main.c

    r63c1dd5 r63a045c  
    3939#include <str.h>
    4040#include <errno.h>
    41 #include <inflate.h>
    42 #include "../../components.h"
    43 
    44 #define TOP2ADDR(top)  (((void *) PA2KA(BOOT_OFFSET)) + (top))
     41#include <payload.h>
    4542
    4643static bootinfo_t *bootinfo = (bootinfo_t *) PA2KA(BOOTINFO_OFFSET);
     
    6360            (void *) PA2KA(LOADER_OFFSET), (void *) LOADER_OFFSET);
    6461
    65         size_t i;
    66         for (i = 0; i < COMPONENTS; i++)
    67                 printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
    68                     (uintptr_t) components[i].addr >= PA2KSEG(0) ?
    69                     (void *) KSEG2PA(components[i].addr) :
    70                     (void *) KA2PA(components[i].addr),
    71                     components[i].name, components[i].inflated,
    72                     components[i].size);
     62        uint8_t *kernel_start = (uint8_t *) PA2KA(BOOT_OFFSET);
     63        // FIXME: Use the correct value.
     64        uint8_t *ram_end = kernel_start + (1 << 24);
    7365
    74         void *dest[COMPONENTS];
    75         size_t top = 0;
    76         size_t cnt = 0;
    77         bootinfo->cnt = 0;
    78         for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
    79                 top = ALIGN_UP(top, PAGE_SIZE);
     66        // TODO: Make sure that the I-cache, D-cache and memory are coherent.
     67        //       (i.e. provide the clear_cache callback)
    8068
    81                 if (i > 0) {
    82                         bootinfo->tasks[bootinfo->cnt].addr = TOP2ADDR(top);
    83                         bootinfo->tasks[bootinfo->cnt].size = components[i].inflated;
    84 
    85                         str_cpy(bootinfo->tasks[bootinfo->cnt].name,
    86                             BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
    87 
    88                         bootinfo->cnt++;
    89                 }
    90 
    91                 dest[i] = TOP2ADDR(top);
    92                 top += components[i].inflated;
    93                 cnt++;
    94         }
    95 
    96         printf("\nInflating components ... ");
    97 
    98         for (i = cnt; i > 0; i--) {
    99 #ifdef MACHINE_msim
    100                 void *tail = dest[i - 1] + components[i].inflated;
    101                 if (tail >= ((void *) PA2KA(LOADER_OFFSET))) {
    102                         printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
    103                             components[i].name, tail, (void *) PA2KA(LOADER_OFFSET));
    104                         halt();
    105                 }
    106 #endif
    107 
    108                 printf("%s ", components[i - 1].name);
    109 
    110                 int err = inflate(components[i - 1].addr, components[i - 1].size,
    111                     dest[i - 1], components[i - 1].inflated);
    112 
    113                 if (err != EOK) {
    114                         printf("\n%s: Inflating error %d, halting.\n",
    115                             components[i - 1].name, err);
    116                         halt();
    117                 }
    118         }
    119 
    120         printf(".\n");
     69        extract_payload(&bootinfo->taskmap, kernel_start, ram_end,
     70            (uintptr_t) kernel_start, NULL);
    12171
    12272        printf("Copying CPU map ... \n");
    12373
    12474        bootinfo->cpumap = 0;
    125         for (i = 0; i < CPUMAP_MAX_RECORDS; i++) {
     75        for (int i = 0; i < CPUMAP_MAX_RECORDS; i++) {
    12676                if (cpumap[i] != 0)
    12777                        bootinfo->cpumap |= (1 << i);
  • boot/arch/ppc32/Makefile.inc

    r63c1dd5 r63a045c  
    6161        arch/$(BARCH)/src/main.c \
    6262        arch/$(BARCH)/src/ofw.c \
    63         $(COMPS).s \
    64         $(COMPS)_desc.c \
     63        $(COMPS).o \
    6564        genarch/src/ofw.c \
    6665        genarch/src/ofw_tree.c \
     
    7473        generic/src/str.c \
    7574        generic/src/version.c \
    76         generic/src/inflate.c
    77 
    78 PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
     75        generic/src/inflate.c \
     76        generic/src/gzip.c \
     77        generic/src/tar.c \
     78        generic/src/payload.c
  • boot/arch/ppc32/_link.ld.in

    r63c1dd5 r63a045c  
    44        . = 0x08000000;
    55        .text : {
     6                loader_start = .;
    67                *(BOOTSTRAP);
    78                *(REALMODE);
     
    1819                *(.bss);        /* uninitialized static variables */
    1920                *(COMMON);      /* global variables */
    20                 *(.components);
     21                loader_end = .;
     22                payload_start = .;
     23                *(.payload);
     24                payload_end = .;
    2125        }
    2226
  • boot/arch/ppc32/src/main.c

    r63c1dd5 r63a045c  
    4141#include <str.h>
    4242#include <errno.h>
    43 #include <inflate.h>
    44 #include "../../components.h"
     43#include <payload.h>
    4544
    4645#define BALLOC_MAX_SIZE  131072
     
    7473            (void *) LOADER_ADDRESS, loader_address_pa);
    7574
    76         size_t i;
    77         for (i = 0; i < COMPONENTS; i++)
    78                 printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
    79                     ofw_translate(components[i].addr), components[i].name,
    80                     components[i].inflated, components[i].size);
     75        size_t uncompressed_size = payload_uncompressed_size();
     76        printf("Payload uncompressed size: %d bytes\n", uncompressed_size);
    8177
    82         size_t dest[COMPONENTS];
    83         size_t top = 0;
    84         size_t cnt = 0;
    85         bootinfo.taskmap.cnt = 0;
    86         for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
    87                 top = ALIGN_UP(top, PAGE_SIZE);
    88 
    89                 if (i > 0) {
    90                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr =
    91                             (void *) PA2KA(top);
    92                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size =
    93                             components[i].inflated;
    94 
    95                         str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name,
    96                             BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
    97 
    98                         bootinfo.taskmap.cnt++;
    99                 }
    100 
    101                 dest[i] = top;
    102                 top += components[i].inflated;
    103                 cnt++;
    104         }
    105 
    106         if (top >= (size_t) loader_address_pa) {
     78        if (uncompressed_size >= (size_t) loader_address_pa) {
    10779                printf("Inflated components overlap loader area.\n");
    10880                printf("The boot image is too large. Halting.\n");
     
    11890        void *inflate_base;
    11991        void *inflate_base_pa;
    120         ofw_alloc("inflate area", &inflate_base, &inflate_base_pa, top,
    121             loader_address_pa);
     92        ofw_alloc("inflate area", &inflate_base, &inflate_base_pa,
     93            uncompressed_size, loader_address_pa);
    12294        printf(" %p|%p: inflate area\n", inflate_base, inflate_base_pa);
    12395
    124         uintptr_t balloc_start = ALIGN_UP(top, PAGE_SIZE);
     96        uintptr_t balloc_start = ALIGN_UP(uncompressed_size, PAGE_SIZE);
    12597        size_t pages = (balloc_start + ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE)) >>
    12698            PAGE_WIDTH;
     
    135107        check_overlap("translate table", transtable_pa, pages);
    136108
    137         printf("\nInflating components ... ");
    138 
    139         for (i = cnt; i > 0; i--) {
    140                 printf("%s ", components[i - 1].name);
    141 
    142                 int err = inflate(components[i - 1].addr, components[i - 1].size,
    143                     inflate_base + dest[i - 1], components[i - 1].inflated);
    144 
    145                 if (err != EOK) {
    146                         printf("\n%s: Inflating error %d, halting.\n",
    147                             components[i - 1].name, err);
    148                         halt();
    149                 }
    150         }
    151 
    152         printf(".\n");
     109        /* Inflate components. */
     110        extract_payload(&bootinfo.taskmap, inflate_base,
     111            inflate_base + uncompressed_size, PA2KA(0), NULL);
    153112
    154113        printf("Setting up boot allocator ...\n");
     
    163122
    164123        printf("Setting up translate table ...\n");
    165         for (i = 0; i < pages; i++) {
     124        for (size_t i = 0; i < pages; i++) {
    166125                uintptr_t off = i << PAGE_WIDTH;
    167126                void *phys;
  • boot/arch/riscv64/Makefile.inc

    r63c1dd5 r63a045c  
    4141        arch/$(BARCH)/src/ucb.c \
    4242        arch/$(BARCH)/src/putchar.c \
    43         $(COMPS).s \
    44         $(COMPS)_desc.c \
     43        $(COMPS).o \
    4544        generic/src/memstr.c \
    4645        generic/src/printf_core.c \
     
    4948        generic/src/str.c \
    5049        generic/src/version.c \
    51         generic/src/inflate.c
    52 
    53 PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
     50        generic/src/inflate.c \
     51        generic/src/gzip.c \
     52        generic/src/tar.c \
     53        generic/src/payload.c
  • boot/arch/riscv64/_link.ld.in

    r63c1dd5 r63a045c  
    77
    88        .text : {
     9                loader_start = .;
    910                *(BOOTSTRAP);
    1011                *(.text);
     
    3536                *(.bss);        /* uninitialized static variables */
    3637                *(COMMON);      /* global variables */
    37                 *(.components);
     38                loader_end = .;
     39                payload_start = .;
     40                *(.payload);
     41                payload_end = .;
    3842        }
    3943
  • 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");
  • boot/arch/sparc64/Makefile.inc

    r63c1dd5 r63a045c  
    5959        arch/$(BARCH)/src/main.c \
    6060        arch/$(BARCH)/src/ofw.c \
    61         $(COMPS).s \
    62         $(COMPS)_desc.c \
     61        $(COMPS).o \
    6362        genarch/src/ofw.c \
    6463        genarch/src/ofw_tree.c \
     
    7069        generic/src/str.c \
    7170        generic/src/version.c \
    72         generic/src/inflate.c
    73 
    74 PRE_DEPEND = $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE)
     71        generic/src/inflate.c \
     72        generic/src/gzip.c \
     73        generic/src/tar.c \
     74        generic/src/payload.c
  • boot/arch/sparc64/_link.ld.in

    r63c1dd5 r63a045c  
    44        . = 0x4000;
    55        .boot : {
     6                loader_start = .;
    67                *(BOOTSTRAP);
    78                *(.text);
     
    1516                *(.bss);        /* uninitialized static variables */
    1617                *(COMMON);      /* global variables */
    17                 *(.components);
     18                loader_end = .;
     19                payload_start = .;
     20                *(.payload);
     21                payload_end = .;
    1822        }
    1923
  • boot/arch/sparc64/src/main.c

    r63c1dd5 r63a045c  
    4242#include <str.h>
    4343#include <errno.h>
    44 #include <inflate.h>
    45 #include "../../components.h"
     44#include <payload.h>
    4645
    4746/* The lowest ID (read from the VER register) of some US3 CPU model */
     
    217216            (void *) LOADER_ADDRESS, (void *) loader_address_pa);
    218217
    219         size_t i;
    220         for (i = 0; i < COMPONENTS; i++)
    221                 printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].addr,
    222                     ofw_translate(components[i].addr), components[i].name,
    223                     components[i].inflated, components[i].size);
    224 
    225         void *dest[COMPONENTS];
    226         size_t top = KERNEL_ADDRESS;
    227         size_t cnt = 0;
    228         bootinfo.taskmap.cnt = 0;
    229         for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
    230                 top = ALIGN_UP(top, PAGE_SIZE);
    231 
    232                 if (i > 0) {
    233                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr =
    234                             (void *) top;
    235                         bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size =
    236                             components[i].inflated;
    237 
    238                         str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name,
    239                             BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
    240 
    241                         bootinfo.taskmap.cnt++;
    242                 }
    243 
    244                 dest[i] = (void *) top;
    245                 top += components[i].inflated;
    246                 cnt++;
    247         }
    248 
    249         printf("\nInflating components ... ");
    250 
    251         for (i = cnt; i > 0; i--) {
    252                 printf("%s ", components[i - 1].name);
    253 
    254                 /*
    255                  * At this point, we claim and map the physical memory that we
    256                  * are going to use. We should be safe in case of the virtual
    257                  * address space because the OpenFirmware, according to its
    258                  * SPARC binding, should restrict its use of virtual memory to
    259                  * addresses from [0xffd00000; 0xffefffff] and [0xfe000000;
    260                  * 0xfeffffff].
    261                  */
    262                 ofw_claim_phys(bootinfo.physmem_start + dest[i - 1],
    263                     ALIGN_UP(components[i - 1].inflated, PAGE_SIZE));
    264 
    265                 ofw_map(bootinfo.physmem_start + dest[i - 1], dest[i - 1],
    266                     ALIGN_UP(components[i - 1].inflated, PAGE_SIZE), -1);
    267 
    268                 int err = inflate(components[i - 1].addr, components[i - 1].size,
    269                     dest[i - 1], components[i - 1].inflated);
    270 
    271                 if (err != EOK) {
    272                         printf("\n%s: Inflating error %d, halting.\n",
    273                             components[i - 1].name, err);
    274                         halt();
    275                 }
    276         }
    277 
    278         printf(".\n");
     218        /*
     219         * At this point, we claim and map the physical memory that we
     220         * are going to use. We should be safe in case of the virtual
     221         * address space because the OpenFirmware, according to its
     222         * SPARC binding, should restrict its use of virtual memory to
     223         * addresses from [0xffd00000; 0xffefffff] and [0xfe000000;
     224         * 0xfeffffff].
     225         */
     226
     227        size_t sz = ALIGN_UP(payload_uncompressed_size(), PAGE_SIZE);
     228        ofw_claim_phys((void *) (bootinfo.physmem_start + KERNEL_ADDRESS), sz);
     229        ofw_map((void *) (bootinfo.physmem_start + KERNEL_ADDRESS),
     230            (void *) KERNEL_ADDRESS, sz, -1);
     231
     232        /* Extract components. */
     233
     234        // TODO: Cache-coherence callback?
     235        extract_payload(&bootinfo.taskmap, (void *) KERNEL_ADDRESS,
     236            (void *) KERNEL_ADDRESS + sz, KERNEL_ADDRESS, NULL);
    279237
    280238        /*
     
    283241         */
    284242        printf("Setting up boot allocator ...\n");
    285         void *balloc_base = (void *) ALIGN_UP(top, PAGE_SIZE);
     243        void *balloc_base = (void *) KERNEL_ADDRESS + sz;
    286244        ofw_claim_phys(bootinfo.physmem_start + balloc_base, BALLOC_MAX_SIZE);
    287245        ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
  • boot/generic/include/inflate.h

    r63c1dd5 r63a045c  
    3232#include <stddef.h>
    3333
    34 extern int inflate(void *, size_t, void *, size_t);
     34extern int inflate(const void *, size_t, void *, size_t);
    3535
    3636#endif
  • boot/generic/src/inflate.c

    r63c1dd5 r63a045c  
    104104        size_t destcnt;   /**< Position in the output buffer */
    105105
    106         uint8_t *src;     /**< Input buffer */
     106        const uint8_t *src;     /**< Input buffer */
    107107        size_t srclen;    /**< Input buffer size */
    108108        size_t srccnt;    /**< Position in the input buffer */
     
    319319    uint16_t *symbol)
    320320{
    321         /* Decoded bits */
     321        /* Decode bits */
    322322        uint16_t code = 0;
    323323
     
    331331        size_t index = 0;
    332332
    333         size_t len;  /* Current number of bits in the code */
     333        /* Current number of bits in the code */
     334        size_t len;
     335
    334336        for (len = 1; len <= MAX_HUFFMAN_BIT; len++) {
    335337                /* Get next bit */
     
    625627 *
    626628 */
    627 int inflate(void *src, size_t srclen, void *dest, size_t destlen)
     629int inflate(const void *src, size_t srclen, void *dest, size_t destlen)
    628630{
    629631        /* Initialize the state */
     
    634636        state.destcnt = 0;
    635637
    636         state.src = (uint8_t *) src;
     638        state.src = (const uint8_t *) src;
    637639        state.srclen = srclen;
    638640        state.srccnt = 0;
  • kernel/arch/arm32/include/arch/arch.h

    r63c1dd5 r63a045c  
    5353        size_t cnt;
    5454        utask_t tasks[TASKMAP_MAX_RECORDS];
     55} taskmap_t;
     56
     57typedef struct {
     58        taskmap_t taskmap;
    5559} bootinfo_t;
    5660
  • kernel/arch/arm32/src/arm32.c

    r63c1dd5 r63a045c  
    6767void arm32_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
    6868{
    69         init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
     69        init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
    7070
    7171        size_t i;
    7272        for (i = 0; i < init.cnt; i++) {
    73                 init.tasks[i].paddr = KA2PA(bootinfo->tasks[i].addr);
    74                 init.tasks[i].size = bootinfo->tasks[i].size;
     73                init.tasks[i].paddr = KA2PA(bootinfo->taskmap.tasks[i].addr);
     74                init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
    7575                str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
    76                     bootinfo->tasks[i].name);
     76                    bootinfo->taskmap.tasks[i].name);
    7777        }
    7878
  • kernel/arch/ia64/include/arch/bootinfo.h

    r63c1dd5 r63a045c  
    3636#define MEMMAP_FREE_MEM 0
    3737
    38 /** Size of buffer for storing task name in binit_task_t. */
     38/** Size of buffer for storing task name in utask_t. */
    3939#define BOOTINFO_TASK_NAME_BUFLEN 32
    4040
     
    4343        size_t size;
    4444        char name[BOOTINFO_TASK_NAME_BUFLEN];
    45 } binit_task_t;
     45} utask_t;
    4646
    4747typedef struct {
    4848        size_t cnt;
    49         binit_task_t tasks[TASKMAP_MAX_RECORDS];
    50 } binit_t;
     49        utask_t tasks[TASKMAP_MAX_RECORDS];
     50} taskmap_t;
    5151
    5252typedef struct {
     
    5757
    5858typedef struct {
    59         binit_t taskmap;
     59        taskmap_t taskmap;
    6060
    6161        memmap_item_t memmap[MEMMAP_ITEMS];
  • kernel/arch/mips32/include/arch/arch.h

    r63c1dd5 r63a045c  
    5656
    5757typedef struct {
     58        size_t cnt;
     59        utask_t tasks[TASKMAP_MAX_RECORDS];
     60} taskmap_t;
     61
     62typedef struct {
    5863#if defined(MACHINE_lmalta) || defined(MACHINE_bmalta)
    5964        uint32_t sdram_size;
    6065#endif
    6166        uint32_t cpumap;
    62         size_t cnt;
    63         utask_t tasks[TASKMAP_MAX_RECORDS];
     67        taskmap_t taskmap;
    6468} bootinfo_t;
    6569
  • kernel/arch/mips32/src/mips32.c

    r63c1dd5 r63a045c  
    8888void mips32_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
    8989{
    90         init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
     90        init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
    9191
    9292        size_t i;
    9393        for (i = 0; i < init.cnt; i++) {
    94                 init.tasks[i].paddr = KA2PA(bootinfo->tasks[i].addr);
    95                 init.tasks[i].size = bootinfo->tasks[i].size;
     94                init.tasks[i].paddr = KA2PA(bootinfo->taskmap.tasks[i].addr);
     95                init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
    9696                str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
    97                     bootinfo->tasks[i].name);
     97                    bootinfo->taskmap.tasks[i].name);
    9898        }
    9999
Note: See TracChangeset for help on using the changeset viewer.