1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 # --- T2-COPYRIGHT-NOTE-BEGIN ---
3 # This copyright note is auto-generated by scripts/Create-CopyPatch.
5 # T2 SDE: package/*/arcload/13_initrd_support.patch
6 # Copyright (C) 2020 - 2021 The T2 SDE Project
8 # More information can be found in the files COPYING and README.
10 # This patch file is dual-licensed. It is available under the license the
11 # patched project is licensed under, as long as it is an OpenSource license
12 # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
13 # of the GNU General Public License as published by the Free Software
14 # Foundation; either version 2 of the License, or (at your option) any later
16 # --- T2-COPYRIGHT-NOTE-END ---
18 diff -urNad arcload-0.5~
/loader
/block.c arcload-0.5
/loader
/block.c
19 --- arcload-0.5~
/loader
/block.c
2006-01-20 05:06:27.000000000 +0000
20 +++ arcload-0.5
/loader
/block.c
2007-09-26 16:49:18.000000000 +0000
25 + dev-
>size
= i-
>file.size
;
29 diff -urNad arcload-0.5~
/loader
/block.h arcload-0.5
/loader
/block.h
30 --- arcload-0.5~
/loader
/block.h
2006-01-18 03:46:45.000000000 +0000
31 +++ arcload-0.5
/loader
/block.h
2007-09-26 16:49:18.000000000 +0000
39 INT bopen
(BDEV
*dev
, CHAR
*path
);
40 diff -urNad arcload-0.5~
/loader
/config.c arcload-0.5
/loader
/config.c
41 --- arcload-0.5~
/loader
/config.c
2006-01-20 05:06:50.000000000 +0000
42 +++ arcload-0.5
/loader
/config.c
2007-09-26 16:49:18.000000000 +0000
48 +#define S_SYSINITRD 11
50 static char
*token_names
[] = {
62 static int is_space
(char ch
)
64 static int rx_token
(int token
, char
*text
, int
*s_state
, char
**label
, int n_label
, int
*label_count
,
65 char
*image
, int n_image
, char
**append
, int n_append
,
66 char
*append_space
, int
*append_space_ptr
, int n_append_space
,
67 - int
*append_count
, char
*descr
, char
*lastl
, int
*s_level
, int
*s_ignore
,
69 + int
*append_count
, char
*initrd
, int n_initrd
, char
*descr
, char
*lastl
,
70 + int
*s_level
, int
*s_ignore
, char
*system
)
78 + if(!strcmp
(text
, "initrd")) {
79 + *s_state
= S_INITRD
;
93 + if(token
!= T_STRING
)
94 + return token_bomb
(token
, text
, *s_state
, image
, "STRING");
96 + if((*s_state
== S_INITRD
) && !strcmp
(text
, "system")) {
97 + strcpy
(initrd
, system
);
98 + *s_state
= S_SYSINITRD
;
102 + if((*s_state
== S_INITRD
) && !strcmp
(text
, "absolute")) {
103 + *s_state
= S_SYSINITRD
;
107 + if(strlen
(text
) >= (n_initrd
- strlen
(initrd
))) {
108 + printf("Error: N_INITRD exceeded.\n\r");
113 + strcat
(initrd
, text
);
120 if(rx_token
(a
, b
, &s_state
, label
, n_label
, label_count
, image
, \
121 n_image
, append
, n_append
, append_space
, \
122 &append_space_ptr
, n_append_space
, append_count
, \
123 + initrd
, n_initrd
, \
124 descr
, lastl
, &s_level
, &s_ignore
, system
)) { \
129 void parseconfig
(char
**label
, int n_label
, int
*label_count
, char
*image
,
130 int n_image
, char
**append
, int n_append
, char
*append_space
,
131 - int n_append_space
, int
*append_count
, char
*system
)
132 + int n_append_space
, int
*append_count
, char
*initrd
, int n_initrd
,
136 char str
[STRING_LEN
], descr
[STRING_LEN
], lastl
[STRING_LEN
];
137 diff -urNad arcload-0.5~
/loader
/config.h arcload-0.5
/loader
/config.h
138 --- arcload-0.5~
/loader
/config.h
2005-09-02 13:56:02.000000000 +0000
139 +++ arcload-0.5
/loader
/config.h
2007-09-26 16:49:18.000000000 +0000
141 * append_space
- in-out parameter
, will contain append as linear string
142 * n_append_space
- input parameter
, size of append_space
143 * append_count
- output parameter
, count of kernel arguments
144 + * initrd
- output parameter
, will contain path to initrd image
145 + * n_initrd
- input parameter
, contains maximum length of initrd
147 * if image
[0] == 0 on output
, we failed
150 char
*image
, int n_image
,
151 char
**append
, int n_append
,
152 char
*append_space
, int n_append_space
,
153 - int
*append_count
, char
*system
);
154 + int
*append_count
, char
*initrd
, int n_initrd
,
157 /* this
function parses text label format into an array
158 * I
'm pretty sure that by know you can guess the meanings */
159 diff -urNad arcload-0.5~/loader/main.c arcload-0.5/loader/main.c
160 --- arcload-0.5~/loader/main.c 2007-09-26 16:48:57.000000000 +0000
161 +++ arcload-0.5/loader/main.c 2007-09-26 16:49:40.000000000 +0000
164 * ARCload (c) 2005 Stanislaw Skowronek
165 + * Copyright (C) 2007 Julien BLACHE
168 #include <arclib/arc.h>
172 #define N_APPEND_SPACE 2048
173 +#define N_INITRD 256
176 #define READBLOCK 16384
179 #define ARENA 1048576
181 +/* See load_initrd() */
182 +#define STACK_PAGES 4
184 +#define KSEG0ADDR(addr) (((addr) & 0x1fffffff) | 0x80000000)
186 +/* #define RD_DEBUG */
189 unsigned char e_ident[EI_NIDENT];
194 +/* End address of kernel image */
195 +ULONG kernel_end = 0;
197 +/* Maximum page size supported by the machine */
198 +unsigned long max_page_size = 0;
201 INT checkmemmap(ULONG elf_start, ULONG elf_size)
203 MEMORYDESCRIPTOR *md;
208 -ULONG vtophys(ULONG addr)
209 +ULONG vtophys(ULONG addr, int warn)
212 - if((addr & 0xC0000000) != 0x80000000)
213 + if(warn && ((addr & 0xC0000000) != 0x80000000))
214 printf("Warning: kernel is in a mapped area!\n\r");
216 return (addr & 0x1FFFFFFF);
218 if((addr >> 62) == 2)
219 return (addr & ((1UL << 40) - 1));
223 if((addr >> 60) == 15) {
224 - if((addr & 0xC0000000UL) != 0x80000000UL)
225 + if(warn && ((addr & 0xC0000000UL) != 0x80000000UL))
226 printf("Warning: kernel is in a mapped area!\n\r");
228 return (addr & 0x1FFFFFFF);
231 - printf("Warning: kernel is in a mapped area!\n\r");
233 + printf("Warning: kernel is in a mapped area!\n\r");
235 return (addr & ((1UL << 40) - 1));
239 +static int load_file(BDEV *file, UCHAR *ptr, ULONG size)
245 + i = ((size > READBLOCK) ? READBLOCK : size);
246 + if(bread(file, i, ptr) < 0) {
247 + printf("failed at %u!\n\r", pos);
260 Elf64_Addr load_elf32(Elf32_Ehdr *hdr, BDEV *file)
262 Elf32_Phdr ph[N_PHDR];
271 /* Not Relocatable? */
272 if(hdr->e_type != ET_EXEC) {
273 printf("ELF file is not executable.\n\r");
279 + * The offset of the first segment should be equal to the
280 + * maximal page size supported by the machine.
282 + if(max_page_size == 0) {
283 + max_page_size = ph[nph].p_offset;
286 if(ph[nph].p_type != PT_LOAD)
289 @@ -144,31 +192,29 @@
290 /* Realize LOAD headers */
291 for(i = 0; i < nph; i++) {
292 /* Check the Memory Map */
293 - if(checkmemmap(vtophys(ph[i].p_vaddr), ph[i].p_memsz)) {
294 + if(checkmemmap(vtophys(ph[i].p_vaddr, 1), ph[i].p_memsz)) {
295 printf("File can't be loaded into current memory map.
\n\r");
299 /* Load the ELF into memory */
300 - printf("Reading
%u bytes...
", (ULONG)ph[i].p_filesz);
301 - left = ph[i].p_filesz;
303 ptr = (UCHAR *)ph[i].p_vaddr;
305 + printf("Loading kernel
at 0x
%p
; reading
%u bytes...
", ptr, (ULONG)ph[i].p_filesz);
307 bseek(file, ph[i].p_offset);
309 - j = ((left > READBLOCK) ? READBLOCK : left);
310 - if(bread(file, j, ptr)<0) {
311 - printf("failed
at %u
!\n\r", (ULONG)pos);
319 - ptr = (UCHAR *)(ph[i].p_vaddr + ph[i].p_filesz);
320 + ret = load_file(file, ptr, ph[i].p_filesz);
325 + ptr += ph[i].p_filesz;
326 for(pos = ph[i].p_filesz; pos < ph[i].p_memsz; pos++)
329 + /* Save the end of the kernel image, needed to load the initrd */
330 + if((ULONG)ptr > kernel_end)
331 + kernel_end = (ULONG)ptr;
334 return (Elf64_Addr) hdr->e_entry;
335 @@ -178,10 +224,12 @@
336 Elf64_Addr load_elf64(Elf64_Ehdr *hdr, BDEV *file)
338 Elf64_Phdr ph[N_PHDR];
347 /* Not Relocatable? */
348 if(hdr->e_type != ET_EXEC) {
349 printf("ELF
file is not executable.
\n\r");
355 + * The offset of the first segment should be equal to the
356 + * maximal page size supported by the machine.
358 + if(max_page_size == 0) {
359 + max_page_size = ph[nph].p_offset;
362 if(ph[nph].p_type != PT_LOAD)
365 @@ -222,39 +278,33 @@
366 /* Realize LOAD headers */
367 for(i = 0; i < nph; i++) {
368 /* Check the Memory Map */
369 - if(checkmemmap(vtophys(ph[i].p_vaddr), ph[i].p_memsz)) {
370 + if(checkmemmap(vtophys(ph[i].p_vaddr, 1), ph[i].p_memsz)) {
371 printf("File can
't be loaded into current memory map.\n\r");
375 /* Load the ELF into memory */
376 - printf("Reading %u bytes... ", (ULONG)ph[i].p_filesz);
377 - left = ph[i].p_filesz;
380 ptr = (UCHAR *)(Elf32_Addr)ph[i].p_vaddr;
382 ptr = (UCHAR *)ph[i].p_vaddr;
385 + printf("Loading kernel at 0x%p; reading %u bytes... ", ptr, (ULONG)ph[i].p_filesz);
387 bseek(file, ph[i].p_offset);
389 - j = ((left > READBLOCK) ? READBLOCK : left);
390 - if(bread(file, j, ptr)<0) {
391 - printf("failed at %u!\n\r", (ULONG)pos);
400 - ptr = (UCHAR *)(Elf32_Addr)(ph[i].p_vaddr + ph[i].p_filesz);
402 - ptr = (UCHAR *)(ph[i].p_vaddr + ph[i].p_filesz);
404 + ret = load_file(file, ptr, ph[i].p_filesz);
409 + ptr += ph[i].p_filesz;
410 for(pos = ph[i].p_filesz; pos < ph[i].p_memsz; pos++)
413 + /* Save the end of the kernel image, needed to load the initrd */
414 + if((ULONG)ptr > kernel_end)
415 + kernel_end = (ULONG)ptr;
423 - /* Is is an ELF binary? */
424 + /* Is it an ELF binary? */
425 if((hdr.e_ident[0] != 0x7f) ||
426 (hdr.e_ident[1] != 'E
') ||
427 (hdr.e_ident[2] != 'L
') ||
428 @@ -322,6 +372,181 @@
432 +int load_initrd(char *fname, char **append, int n_append,
433 + char *append_space, int n_append_space, int *append_count)
443 + MEMORYDESCRIPTOR *current = NULL;
447 + ULONG stack = vtophys((ULONG) &end, 0);
449 + kernel_end = vtophys(kernel_end, 0) + 8 * max_page_size;
451 + printf("Loading initrd %s ...\n\r", fname);
454 + printf("RD: Max page size seems to be 0x%x\n\r", max_page_size);
458 + if(bopen(&file, fname)) {
459 + printf("Opening %s failed.\n\r", fname);
462 + if (!file.size) file.size = 7 * 1024 * 1024; /* zero for bootp(): */
463 + /* Find a free memory region big enough to hold the initrd image */
464 + current = ArcGetMemoryDescriptor(current);
466 + printf("Can't
find any valid memory descriptors
!\n\r");
471 + printf("RD
: stack
at 0x
%p
, kernel ends
at 0x
%p
\n\r", stack, kernel_end);
474 + while ((current = ArcGetMemoryDescriptor(current)) != NULL) {
475 + if(current->Type == FreeMemory) {
476 + start = current->BasePage << PAGESHIFT;
477 + end = start + (current->PageCount << PAGESHIFT);
479 + printf("RD
: considering area
0x
%p
- 0x
%p
, %u pages
\n\r", start, end, current->PageCount);
481 + /* Leave some more room for our stack - at that point we don't need that much */
482 + if((stack >= start) && (stack < end)) {
484 + printf("RD
: area includes stack
\n\r");
486 + end = (stack - (STACK_PAGES << PAGESHIFT)) & ~((1 << PAGESHIFT) - 1);
489 + /* Did we load the kernel there already ? */
490 + if((kernel_end > start) && (kernel_end < end)) {
492 + printf("RD
: area includes kernel
\n\r");
494 + start = (kernel_end + (1 << PAGESHIFT)) & ~((1 << PAGESHIFT) - 1);
497 + if((end < start) || (end - start) < (file.size + max_page_size)) {
499 + printf("RD
: area too small
: %u needs
%u
\n\r", (end - start), (file.size + max_page_size));
505 + printf("RD
: area
0x
%p
- 0x
%p OK
for initrd
\n\r", start, end);
512 + printf("initrd can
't be loaded into current memory map\n\r");
517 + /* Turn the physical start address into a KSEG0 address */
518 + start = KSEG0ADDR(start);
521 + * Turn the physical address into an uncached XKPHYS address
522 + * This should probably be flagged as FIXME.
524 + start = start | 0xa800000000000000;
528 + * Compute initrd address: must be page-aligned; as we don't know
529 + * what page size the kernel uses
, we
'll use the max page size we
530 + * determined from the ELF file structure when loading the kernel.
532 + initrd_addr = (start + max_page_size) & ~(max_page_size - 1);
534 + /* Load the initrd image into memory */
535 + printf("Loading initrd at 0x%p; reading %u bytes... ", initrd_addr, file.size);
537 + ret = load_file(&file, (UCHAR *)initrd_addr, file.size);
541 + /* Add rd_start= and rd_size= to the kernel arguments */
543 + if(*append_count + 2 >= n_append) {
544 + printf("Error: N_APPEND exceeded.\n\r");
548 + /* Get the tail of the append_space currently used */
549 + if(*append_count == 0) {
550 + append_ptr = append_space;
552 + append_ptr = append[(*append_count) - 1];
553 + append_ptr += strlen(append_ptr) + 1;
557 + /* The kernel wants a KSEG0 address and takes care of the sign extension */
558 + initrd_addr = KSEG0ADDR(initrd_addr);
562 + len = sprintf(buf, "rd_start=0x%x", initrd_addr);
565 + printf("APPEND: '%s
'\n\r", buf);
568 + if((append_ptr - append_space + len + 1) > n_append_space) {
569 + printf("Error: N_APPEND_SPACE exceeded.\n\r");
573 + strcpy(append_ptr, buf);
574 + append[*append_count] = append_ptr;
577 + append_ptr += len + 1;
580 + len = sprintf(buf, "rd_size=0x%x", file.size);
583 + printf("APPEND: '%s
'\n\r", buf);
586 + if((append_ptr - append_space + len + 1) > n_append_space) {
587 + printf("Error: N_APPEND_SPACE exceeded.\n\r");
591 + strcpy(append_ptr, buf);
592 + append[*append_count] = append_ptr;
599 +/* Failed to do something, close and return */
608 unsigned fixup_trampolines_data[]={
609 0x03e00821, 0x04110001, 0x00000000, 0xdfe30014,
611 char append_space[N_APPEND_SPACE];
614 + char initrd[N_INITRD];
616 unsigned long arena_start;
618 - printf("ARCLoad version " VERSION " (c) 2004-5 Stanislaw Skowronek\n\r");
621 + printf("ARCLoad version " VERSION " (c)2004-5 Stanislaw Skowronek, (c)2006-2021 Ren\xe9 Rebe\n\r");
627 arena_start = (((ULONG)__start) - ARENA)&~((1UL<<PAGESHIFT)-1);
628 - if(checkmemmap(vtophys(arena_start), ARENA)) {
629 + if(checkmemmap(vtophys(arena_start, 1), ARENA)) {
630 printf("Internal error: dynamic memory arena allocation failed.\n\r");
631 - printf("Attempted: 0x%p bytes at 0x%p.\n\r", ARENA, vtophys(((ULONG)__start) - ARENA));
632 + printf("Attempted: 0x%p bytes at 0x%p.\n\r", ARENA, vtophys(((ULONG)__start) - ARENA, 1));
635 arclib_malloc_add(arena_start, ARENA);
637 printf("Loading configuration for '%s
'...\n\r", text_label);
638 parselabel(text_label, label, N_LABEL, &label_count, label_space, N_LABEL_SPACE);
640 - parseconfig(label, N_LABEL, &label_count, image, N_IMAGE, append, N_APPEND, append_space, N_APPEND_SPACE, &append_count, system);
643 + parseconfig(label, N_LABEL, &label_count, image, N_IMAGE, append, N_APPEND, append_space, N_APPEND_SPACE, &append_count, initrd, N_INITRD, system);
652 + ret = load_initrd(initrd, append, N_APPEND, append_space, N_APPEND_SPACE, &append_count);
659 kernel_entry = (VOID(*)(INT, CHAR **, CHAR **))entry32;
660 --- arcload-0.5/loader/main.c.vanilla 2021-08-31 17:28:51.865158898 +0200
661 +++ arcload-0.5/loader/main.c 2021-08-31 18:03:45.529308219 +0200
662 @@ -112,20 +112,25 @@
666 -static int load_file(BDEV *file, UCHAR *ptr, ULONG size)
667 +static int load_file(BDEV *file, UCHAR *ptr, LONG size)
673 - i = ((size > READBLOCK) ? READBLOCK : size);
674 - if(bread(file, i, ptr) < 0) {
676 + if (size < 0) i = READBLOCK;
677 + else i = ((size > READBLOCK) ? READBLOCK : size);
678 + if((i = bread(file, i, ptr)) < 0) {
679 printf("failed at %u!\n\r", pos);
685 + if ((size < 0) && (i < READBLOCK)) {
701 printf("Opening %s failed.\n\r", fname);
704 - if (!file.size) file.size = 7 * 1024 * 1024; /* zero for bootp(): */
705 + initrd_size = file.size ? file.size : 7*1024*1024; /* zero for bootp(): */
706 /* Find a free memory region big enough to hold the initrd image */
707 current = ArcGetMemoryDescriptor(current);
710 start = end = 0; continue;
713 - if((end < start) || (end - start) < (file.size + max_page_size)) {
714 + if((end < start) || (end - start) < (initrd_size + max_page_size)) {
716 - printf("RD: area too small: %u needs %u\n\r", (end - start), (file.size + max_page_size));
717 + printf("RD: area too small: %u needs %u\n\r", (end - start), (initrd_size + max_page_size));
722 initrd_addr = (start + max_page_size) & ~(max_page_size - 1);
724 /* Load the initrd image into memory */
725 - printf("Loading initrd at 0x%p; reading %u bytes... ", initrd_addr, file.size);
726 + printf("Loading initrd at 0x%p; reading %u bytes... ", initrd_addr, initrd_size);
728 - ret = load_file(&file, (UCHAR *)initrd_addr, file.size);
729 + ret = load_file(&file, (UCHAR *)initrd_addr, file.size ? file.size : -1);