1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 # --- T2-COPYRIGHT-NOTE-BEGIN ---
3 # T2 SDE: package/*/arcload/13_initrd_support.patch
4 # Copyright (C) 2020 - 2024 The T2 SDE Project
6 # This Copyright note is generated by scripts/Create-CopyPatch,
7 # more information can be found in the files COPYING and README.
9 # This patch file is dual-licensed. It is available under the license the
10 # patched project is licensed under, as long as it is an OpenSource license
11 # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
12 # of the GNU General Public License version 2 as used by the T2 SDE.
13 # --- T2-COPYRIGHT-NOTE-END ---
15 diff -urNad arcload-0.5~
/loader
/block.c arcload-0.5
/loader
/block.c
16 --- arcload-0.5~
/loader
/block.c
2006-01-20 05:06:27.000000000 +0000
17 +++ arcload-0.5
/loader
/block.c
2007-09-26 16:49:18.000000000 +0000
22 + dev-
>size
= i-
>file.size
;
26 diff -urNad arcload-0.5~
/loader
/block.h arcload-0.5
/loader
/block.h
27 --- arcload-0.5~
/loader
/block.h
2006-01-18 03:46:45.000000000 +0000
28 +++ arcload-0.5
/loader
/block.h
2007-09-26 16:49:18.000000000 +0000
36 INT bopen
(BDEV
*dev
, CHAR
*path
);
37 diff -urNad arcload-0.5~
/loader
/config.c arcload-0.5
/loader
/config.c
38 --- arcload-0.5~
/loader
/config.c
2006-01-20 05:06:50.000000000 +0000
39 +++ arcload-0.5
/loader
/config.c
2007-09-26 16:49:18.000000000 +0000
45 +#define S_SYSINITRD 11
47 static char
*token_names
[] = {
59 static int is_space
(char ch
)
61 static int rx_token
(int token
, char
*text
, int
*s_state
, char
**label
, int n_label
, int
*label_count
,
62 char
*image
, int n_image
, char
**append
, int n_append
,
63 char
*append_space
, int
*append_space_ptr
, int n_append_space
,
64 - int
*append_count
, char
*descr
, char
*lastl
, int
*s_level
, int
*s_ignore
,
66 + int
*append_count
, char
*initrd
, int n_initrd
, char
*descr
, char
*lastl
,
67 + int
*s_level
, int
*s_ignore
, char
*system
)
75 + if(!strcmp
(text
, "initrd")) {
76 + *s_state
= S_INITRD
;
90 + if(token
!= T_STRING
)
91 + return token_bomb
(token
, text
, *s_state
, image
, "STRING");
93 + if((*s_state
== S_INITRD
) && !strcmp
(text
, "system")) {
94 + strcpy
(initrd
, system
);
95 + *s_state
= S_SYSINITRD
;
99 + if((*s_state
== S_INITRD
) && !strcmp
(text
, "absolute")) {
100 + *s_state
= S_SYSINITRD
;
104 + if(strlen
(text
) >= (n_initrd
- strlen
(initrd
))) {
105 + printf("Error: N_INITRD exceeded.\n\r");
110 + strcat
(initrd
, text
);
117 if(rx_token
(a
, b
, &s_state
, label
, n_label
, label_count
, image
, \
118 n_image
, append
, n_append
, append_space
, \
119 &append_space_ptr
, n_append_space
, append_count
, \
120 + initrd
, n_initrd
, \
121 descr
, lastl
, &s_level
, &s_ignore
, system
)) { \
126 void parseconfig
(char
**label
, int n_label
, int
*label_count
, char
*image
,
127 int n_image
, char
**append
, int n_append
, char
*append_space
,
128 - int n_append_space
, int
*append_count
, char
*system
)
129 + int n_append_space
, int
*append_count
, char
*initrd
, int n_initrd
,
133 char str
[STRING_LEN
], descr
[STRING_LEN
], lastl
[STRING_LEN
];
134 diff -urNad arcload-0.5~
/loader
/config.h arcload-0.5
/loader
/config.h
135 --- arcload-0.5~
/loader
/config.h
2005-09-02 13:56:02.000000000 +0000
136 +++ arcload-0.5
/loader
/config.h
2007-09-26 16:49:18.000000000 +0000
138 * append_space
- in-out parameter
, will contain append as linear string
139 * n_append_space
- input parameter
, size of append_space
140 * append_count
- output parameter
, count of kernel arguments
141 + * initrd
- output parameter
, will contain path to initrd image
142 + * n_initrd
- input parameter
, contains maximum length of initrd
144 * if image
[0] == 0 on output
, we failed
147 char
*image
, int n_image
,
148 char
**append
, int n_append
,
149 char
*append_space
, int n_append_space
,
150 - int
*append_count
, char
*system
);
151 + int
*append_count
, char
*initrd
, int n_initrd
,
154 /* this
function parses text label format into an array
155 * I
'm pretty sure that by know you can guess the meanings */
156 diff -urNad arcload-0.5~/loader/main.c arcload-0.5/loader/main.c
157 --- arcload-0.5~/loader/main.c 2007-09-26 16:48:57.000000000 +0000
158 +++ arcload-0.5/loader/main.c 2007-09-26 16:49:40.000000000 +0000
161 * ARCload (c) 2005 Stanislaw Skowronek
162 + * Copyright (C) 2007 Julien BLACHE
165 #include <arclib/arc.h>
169 #define N_APPEND_SPACE 2048
170 +#define N_INITRD 256
173 #define READBLOCK 16384
176 #define ARENA 1048576
178 +/* See load_initrd() */
179 +#define STACK_PAGES 4
181 +#define KSEG0ADDR(addr) (((addr) & 0x1fffffff) | 0x80000000)
183 +/* #define RD_DEBUG */
186 unsigned char e_ident[EI_NIDENT];
191 +/* End address of kernel image */
192 +ULONG kernel_end = 0;
194 +/* Maximum page size supported by the machine */
195 +unsigned long max_page_size = 0;
198 INT checkmemmap(ULONG elf_start, ULONG elf_size)
200 MEMORYDESCRIPTOR *md;
205 -ULONG vtophys(ULONG addr)
206 +ULONG vtophys(ULONG addr, int warn)
209 - if((addr & 0xC0000000) != 0x80000000)
210 + if(warn && ((addr & 0xC0000000) != 0x80000000))
211 printf("Warning: kernel is in a mapped area!\n\r");
213 return (addr & 0x1FFFFFFF);
215 if((addr >> 62) == 2)
216 return (addr & ((1UL << 40) - 1));
220 if((addr >> 60) == 15) {
221 - if((addr & 0xC0000000UL) != 0x80000000UL)
222 + if(warn && ((addr & 0xC0000000UL) != 0x80000000UL))
223 printf("Warning: kernel is in a mapped area!\n\r");
225 return (addr & 0x1FFFFFFF);
228 - printf("Warning: kernel is in a mapped area!\n\r");
230 + printf("Warning: kernel is in a mapped area!\n\r");
232 return (addr & ((1UL << 40) - 1));
236 +static int load_file(BDEV *file, UCHAR *ptr, ULONG size)
242 + i = ((size > READBLOCK) ? READBLOCK : size);
243 + if(bread(file, i, ptr) < 0) {
244 + printf("failed at %u!\n\r", pos);
257 Elf64_Addr load_elf32(Elf32_Ehdr *hdr, BDEV *file)
259 Elf32_Phdr ph[N_PHDR];
268 /* Not Relocatable? */
269 if(hdr->e_type != ET_EXEC) {
270 printf("ELF file is not executable.\n\r");
276 + * The offset of the first segment should be equal to the
277 + * maximal page size supported by the machine.
279 + if(max_page_size == 0) {
280 + max_page_size = ph[nph].p_offset;
283 if(ph[nph].p_type != PT_LOAD)
286 @@ -144,31 +192,29 @@
287 /* Realize LOAD headers */
288 for(i = 0; i < nph; i++) {
289 /* Check the Memory Map */
290 - if(checkmemmap(vtophys(ph[i].p_vaddr), ph[i].p_memsz)) {
291 + if(checkmemmap(vtophys(ph[i].p_vaddr, 1), ph[i].p_memsz)) {
292 printf("File can't be loaded into current memory map.
\n\r");
296 /* Load the ELF into memory */
297 - printf("Reading
%u bytes...
", (ULONG)ph[i].p_filesz);
298 - left = ph[i].p_filesz;
300 ptr = (UCHAR *)ph[i].p_vaddr;
302 + printf("Loading kernel
at 0x
%p
; reading
%u bytes...
", ptr, (ULONG)ph[i].p_filesz);
304 bseek(file, ph[i].p_offset);
306 - j = ((left > READBLOCK) ? READBLOCK : left);
307 - if(bread(file, j, ptr)<0) {
308 - printf("failed
at %u
!\n\r", (ULONG)pos);
316 - ptr = (UCHAR *)(ph[i].p_vaddr + ph[i].p_filesz);
317 + ret = load_file(file, ptr, ph[i].p_filesz);
322 + ptr += ph[i].p_filesz;
323 for(pos = ph[i].p_filesz; pos < ph[i].p_memsz; pos++)
326 + /* Save the end of the kernel image, needed to load the initrd */
327 + if((ULONG)ptr > kernel_end)
328 + kernel_end = (ULONG)ptr;
331 return (Elf64_Addr) hdr->e_entry;
332 @@ -178,10 +224,12 @@
333 Elf64_Addr load_elf64(Elf64_Ehdr *hdr, BDEV *file)
335 Elf64_Phdr ph[N_PHDR];
344 /* Not Relocatable? */
345 if(hdr->e_type != ET_EXEC) {
346 printf("ELF
file is not executable.
\n\r");
352 + * The offset of the first segment should be equal to the
353 + * maximal page size supported by the machine.
355 + if(max_page_size == 0) {
356 + max_page_size = ph[nph].p_offset;
359 if(ph[nph].p_type != PT_LOAD)
362 @@ -222,39 +278,33 @@
363 /* Realize LOAD headers */
364 for(i = 0; i < nph; i++) {
365 /* Check the Memory Map */
366 - if(checkmemmap(vtophys(ph[i].p_vaddr), ph[i].p_memsz)) {
367 + if(checkmemmap(vtophys(ph[i].p_vaddr, 1), ph[i].p_memsz)) {
368 printf("File can
't be loaded into current memory map.\n\r");
372 /* Load the ELF into memory */
373 - printf("Reading %u bytes... ", (ULONG)ph[i].p_filesz);
374 - left = ph[i].p_filesz;
377 ptr = (UCHAR *)(Elf32_Addr)ph[i].p_vaddr;
379 ptr = (UCHAR *)ph[i].p_vaddr;
382 + printf("Loading kernel at 0x%p; reading %u bytes... ", ptr, (ULONG)ph[i].p_filesz);
384 bseek(file, ph[i].p_offset);
386 - j = ((left > READBLOCK) ? READBLOCK : left);
387 - if(bread(file, j, ptr)<0) {
388 - printf("failed at %u!\n\r", (ULONG)pos);
397 - ptr = (UCHAR *)(Elf32_Addr)(ph[i].p_vaddr + ph[i].p_filesz);
399 - ptr = (UCHAR *)(ph[i].p_vaddr + ph[i].p_filesz);
401 + ret = load_file(file, ptr, ph[i].p_filesz);
406 + ptr += ph[i].p_filesz;
407 for(pos = ph[i].p_filesz; pos < ph[i].p_memsz; pos++)
410 + /* Save the end of the kernel image, needed to load the initrd */
411 + if((ULONG)ptr > kernel_end)
412 + kernel_end = (ULONG)ptr;
420 - /* Is is an ELF binary? */
421 + /* Is it an ELF binary? */
422 if((hdr.e_ident[0] != 0x7f) ||
423 (hdr.e_ident[1] != 'E
') ||
424 (hdr.e_ident[2] != 'L
') ||
425 @@ -322,6 +372,181 @@
429 +int load_initrd(char *fname, char **append, int n_append,
430 + char *append_space, int n_append_space, int *append_count)
440 + MEMORYDESCRIPTOR *current = NULL;
444 + ULONG stack = vtophys((ULONG) &end, 0);
446 + kernel_end = vtophys(kernel_end, 0) + 8 * max_page_size;
448 + printf("Loading initrd %s ...\n\r", fname);
451 + printf("RD: Max page size seems to be 0x%x\n\r", max_page_size);
455 + if(bopen(&file, fname)) {
456 + printf("Opening %s failed.\n\r", fname);
459 + if (!file.size) file.size = 7 * 1024 * 1024; /* zero for bootp(): */
460 + /* Find a free memory region big enough to hold the initrd image */
461 + current = ArcGetMemoryDescriptor(current);
463 + printf("Can't
find any valid memory descriptors
!\n\r");
468 + printf("RD
: stack
at 0x
%p
, kernel ends
at 0x
%p
\n\r", stack, kernel_end);
471 + while ((current = ArcGetMemoryDescriptor(current)) != NULL) {
472 + if(current->Type == FreeMemory) {
473 + start = current->BasePage << PAGESHIFT;
474 + end = start + (current->PageCount << PAGESHIFT);
476 + printf("RD
: considering area
0x
%p
- 0x
%p
, %u pages
\n\r", start, end, current->PageCount);
478 + /* Leave some more room for our stack - at that point we don't need that much */
479 + if((stack >= start) && (stack < end)) {
481 + printf("RD
: area includes stack
\n\r");
483 + end = (stack - (STACK_PAGES << PAGESHIFT)) & ~((1 << PAGESHIFT) - 1);
486 + /* Did we load the kernel there already ? */
487 + if((kernel_end > start) && (kernel_end < end)) {
489 + printf("RD
: area includes kernel
\n\r");
491 + start = (kernel_end + (1 << PAGESHIFT)) & ~((1 << PAGESHIFT) - 1);
494 + if((end < start) || (end - start) < (file.size + max_page_size)) {
496 + printf("RD
: area too small
: %u needs
%u
\n\r", (end - start), (file.size + max_page_size));
502 + printf("RD
: area
0x
%p
- 0x
%p OK
for initrd
\n\r", start, end);
509 + printf("initrd can
't be loaded into current memory map\n\r");
514 + /* Turn the physical start address into a KSEG0 address */
515 + start = KSEG0ADDR(start);
518 + * Turn the physical address into an uncached XKPHYS address
519 + * This should probably be flagged as FIXME.
521 + start = start | 0xa800000000000000;
525 + * Compute initrd address: must be page-aligned; as we don't know
526 + * what page size the kernel uses
, we
'll use the max page size we
527 + * determined from the ELF file structure when loading the kernel.
529 + initrd_addr = (start + max_page_size) & ~(max_page_size - 1);
531 + /* Load the initrd image into memory */
532 + printf("Loading initrd at 0x%p; reading %u bytes... ", initrd_addr, file.size);
534 + ret = load_file(&file, (UCHAR *)initrd_addr, file.size);
538 + /* Add rd_start= and rd_size= to the kernel arguments */
540 + if(*append_count + 2 >= n_append) {
541 + printf("Error: N_APPEND exceeded.\n\r");
545 + /* Get the tail of the append_space currently used */
546 + if(*append_count == 0) {
547 + append_ptr = append_space;
549 + append_ptr = append[(*append_count) - 1];
550 + append_ptr += strlen(append_ptr) + 1;
554 + /* The kernel wants a KSEG0 address and takes care of the sign extension */
555 + initrd_addr = KSEG0ADDR(initrd_addr);
559 + len = sprintf(buf, "rd_start=0x%x", initrd_addr);
562 + printf("APPEND: '%s
'\n\r", buf);
565 + if((append_ptr - append_space + len + 1) > n_append_space) {
566 + printf("Error: N_APPEND_SPACE exceeded.\n\r");
570 + strcpy(append_ptr, buf);
571 + append[*append_count] = append_ptr;
574 + append_ptr += len + 1;
577 + len = sprintf(buf, "rd_size=0x%x", file.size);
580 + printf("APPEND: '%s
'\n\r", buf);
583 + if((append_ptr - append_space + len + 1) > n_append_space) {
584 + printf("Error: N_APPEND_SPACE exceeded.\n\r");
588 + strcpy(append_ptr, buf);
589 + append[*append_count] = append_ptr;
596 +/* Failed to do something, close and return */
605 unsigned fixup_trampolines_data[]={
606 0x03e00821, 0x04110001, 0x00000000, 0xdfe30014,
608 char append_space[N_APPEND_SPACE];
611 + char initrd[N_INITRD];
613 unsigned long arena_start;
615 - printf("ARCLoad version " VERSION " (c) 2004-5 Stanislaw Skowronek\n\r");
618 + printf("ARCLoad version " VERSION " (c)2004-5 Stanislaw Skowronek, (c)2006-2024 Ren\xe9 Rebe\n\r");
624 arena_start = (((ULONG)__start) - ARENA)&~((1UL<<PAGESHIFT)-1);
625 - if(checkmemmap(vtophys(arena_start), ARENA)) {
626 + if(checkmemmap(vtophys(arena_start, 1), ARENA)) {
627 printf("Internal error: dynamic memory arena allocation failed.\n\r");
628 - printf("Attempted: 0x%p bytes at 0x%p.\n\r", ARENA, vtophys(((ULONG)__start) - ARENA));
629 + printf("Attempted: 0x%p bytes at 0x%p.\n\r", ARENA, vtophys(((ULONG)__start) - ARENA, 1));
632 arclib_malloc_add(arena_start, ARENA);
634 printf("Loading configuration for '%s
'...\n\r", text_label);
635 parselabel(text_label, label, N_LABEL, &label_count, label_space, N_LABEL_SPACE);
637 - parseconfig(label, N_LABEL, &label_count, image, N_IMAGE, append, N_APPEND, append_space, N_APPEND_SPACE, &append_count, system);
640 + parseconfig(label, N_LABEL, &label_count, image, N_IMAGE, append, N_APPEND, append_space, N_APPEND_SPACE, &append_count, initrd, N_INITRD, system);
649 + ret = load_initrd(initrd, append, N_APPEND, append_space, N_APPEND_SPACE, &append_count);
656 kernel_entry = (VOID(*)(INT, CHAR **, CHAR **))entry32;
657 --- arcload-0.5/loader/main.c.vanilla 2021-08-31 17:28:51.865158898 +0200
658 +++ arcload-0.5/loader/main.c 2021-08-31 18:03:45.529308219 +0200
659 @@ -112,20 +112,25 @@
663 -static int load_file(BDEV *file, UCHAR *ptr, ULONG size)
664 +static int load_file(BDEV *file, UCHAR *ptr, LONG size)
670 - i = ((size > READBLOCK) ? READBLOCK : size);
671 - if(bread(file, i, ptr) < 0) {
673 + if (size < 0) i = READBLOCK;
674 + else i = ((size > READBLOCK) ? READBLOCK : size);
675 + if((i = bread(file, i, ptr)) < 0) {
676 printf("failed at %u!\n\r", pos);
682 + if ((size < 0) && (i < READBLOCK)) {
698 printf("Opening %s failed.\n\r", fname);
701 - if (!file.size) file.size = 7 * 1024 * 1024; /* zero for bootp(): */
702 + initrd_size = file.size ? file.size : 32*1024*1024; /* zero for bootp(): */
703 /* Find a free memory region big enough to hold the initrd image */
704 current = ArcGetMemoryDescriptor(current);
707 start = end = 0; continue;
710 - if((end < start) || (end - start) < (file.size + max_page_size)) {
711 + if((end < start) || (end - start) < (initrd_size + max_page_size)) {
713 - printf("RD: area too small: %u needs %u\n\r", (end - start), (file.size + max_page_size));
714 + printf("RD: area too small: %u needs %u\n\r", (end - start), (initrd_size + max_page_size));
719 initrd_addr = (start + max_page_size) & ~(max_page_size - 1);
721 /* Load the initrd image into memory */
722 - printf("Loading initrd at 0x%p; reading %u bytes... ", initrd_addr, file.size);
723 + printf("Loading initrd at 0x%p; reading %u bytes... ", initrd_addr, initrd_size);
725 - ret = load_file(&file, (UCHAR *)initrd_addr, file.size);
726 + ret = load_file(&file, (UCHAR *)initrd_addr, file.size ? file.size : -1);