LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
elf.c
Go to the documentation of this file.
1/* devtree preparation & initrd handling
2
3Copyright (C) 2010-2011 Hector Martin "marcan" <hector@marcansoft.com>
4
5This code is licensed to you under the terms of the GNU GPL, version 2;
6see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
7*/
8
9#include <fcntl.h>
10#include <libfdt/libfdt.h>
11#include <nocfe/cfe.h>
12#include <ppc/cache.h>
13#include <ppc/register.h>
14#include <ppc/timebase.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <time/time.h>
19#include <unistd.h>
21
22#include "elf.h"
23#include "elf_abi.h"
24#include "xetypes.h"
25
26#define ELF_DEVTREE_START ((void *)0x85FE0000)
27#define ELF_DEVTREE_MAX_SIZE 0x00010000
28#define MAX_CMDLINE_SIZE 255
29
30#define INITRD_RELOC_START ((void *)0x86000000)
31#define INITRD_MAX_SIZE (32 * 1024 * 1024) // 0x02000000
32
33// Address where the elf loading code is relocated.
34/* TODO: must keep this synced with lis %r4,0x86f8
35 and lis %r4,0x06f8 in elf_hold_thread elf_run.S */
36#define ELF_CODE_STACK_END ((void *)0x87F80000)
37#define ELF_CODE_RELOC_START ((void *)0x87F80000)
38#define ELF_CODE_MAX_SIZE 0x00080000
39
40// Temporary buffer to hold loaded elf data.
41#define ELF_TEMP_BEGIN ((void *)0x88000000)
42#define ELF_MAX_SIZE 0x05FE0000
43
44// ELF file relocation address.
45#define ELF_DATA_RELOC_START ((void *)0x8DFE0000)
46#define ELF_ARGV_BEGIN ((void *)0x93FC0000)
47#define ELF_GET_RELOCATED(x) \
48 (ELF_CODE_RELOC_START + ((unsigned long)(x) - (unsigned long)elfldr_start))
49#define ELF_GET_RELOCATED_REAL(x) (void*)((uint64_t)ELF_GET_RELOCATED(x) & 0x1FFFFFFF)
50
51#define ELF_DEBUG 0
52#if ELF_DEBUG
53#define elf_debug_printf printf
54#else
55#define elf_debug_printf(...)
56#endif
57
58extern void shutdown_drivers();
59
60// section start/end, defined by the compiler
61extern unsigned char elfldr_start[], elfldr_end[], pagetable_end[];
62extern void elf_call_real(uint64_t function, ...);
63extern void elf_run(unsigned long entry, unsigned long devtree);
64extern void elf_hold_thread();
65
66extern volatile unsigned long elf_secondary_hold_addr;
67extern volatile unsigned long elf_secondary_count;
68
69static char bootargs[MAX_CMDLINE_SIZE];
70
71static uint8_t *initrd_start = NULL;
72static size_t initrd_size = 0;
73
74static char _filename[256] = {0};
75static char _filepath[256] = {0};
76static char _device[256] = {0};
77
78static inline __attribute__((always_inline)) void elf_putch(unsigned char c) {
79 while (!((*(volatile uint32_t *)(0xea001000 + 0x18)) & 0x02000000))
80 ;
81 *(volatile uint32_t *)(0xea001000 + 0x14) = (c << 24) & 0xFF000000;
82}
83
84static inline __attribute__((always_inline)) void elf_puts(unsigned char *s) {
85 while (*s)
86 elf_putch(*s++);
87}
88
89static inline __attribute__((always_inline)) void
90elf_int2hex(unsigned long long n, unsigned char w, unsigned char *str) {
91 unsigned char i, d;
92
93 str += w;
94 *str = 0;
95
96 for (i = 0; i < w; ++i) {
97 d = (n >> (i << 2)) & 0x0f;
98 *--str = (d <= 9) ? d + 48 : d + 55;
99 };
100}
101
102static inline __attribute__((always_inline)) void elf_memset(unsigned char *dst,
103 int v, int l) {
104 while (l--)
105 *dst++ = v;
106}
107
108static inline __attribute__((always_inline)) void
109elf_memcpy(unsigned char *dst, const unsigned char *src, int l) {
110 while (l--)
111 *dst++ = *src++;
112}
113
114#define LINESIZE 128
115static inline __attribute__((always_inline)) void
116elf_sync(volatile void *addr) {
117 asm volatile("dcbst 0, %0" : : "b"(addr));
118 asm volatile("sync");
119 asm volatile("icbi 0, %0" : : "b"(addr));
120 asm volatile("isync");
121}
122
123static inline __attribute__((always_inline)) void
124elf_sync_before_exec(unsigned char *dst, int l) {
125 dst = (unsigned char *)((unsigned long)dst & (~(LINESIZE - 1)));
126
127 l += (LINESIZE - 1);
128 l &= ~(LINESIZE - 1);
129
130 while (l > 0) {
131 elf_sync(dst);
132 dst += LINESIZE;
133 l -= LINESIZE;
134 }
135}
136
137static inline __attribute__((always_inline)) void
138elf_smc_send_message(const unsigned char *msg) {
139 while ((read32(0xEA001000 + 0x84) & 4) == 0)
140 ;
141
142 write32(0xEA001000 + 0x84, 4);
143 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 0));
144 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 4));
145 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 8));
146 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 12));
147 write32(0xEA001000 + 0x84, 0);
148}
149
150static inline __attribute__((always_inline)) void elf_smc_set_led(int override,
151 int value) {
152 uint8_t buf[16];
153 elf_memset(buf, 0, 16);
154
155 buf[0] = 0x99;
156 buf[1] = override;
157 buf[2] = value;
158
159 elf_smc_send_message(buf);
160}
161
162// Stage 2 of prepare run: This function is called in real-mode.
163// WARNING: elf_prepare_run_s2 is relocated and you CANNOT call regular functions from here! The application *will* trap.
164// As a consequence of the relocation, the following optimizations are required to prevent function calls that will fail:
165// - optimize("O2") is required to prevent calls to _savegpr
166// - optimize("no-tree-loop-distribute-patterns") prevents GCC from replacing loops with calls to library functions
167static void
168 __attribute__((section(".elfldr"), used, noreturn, flatten, optimize("O2", "no-tree-loop-distribute-patterns")))
169 elf_prepare_run_s2(void *self, uint32_t entry, int mem_size) {
170 // GCC is allowed to optimize away writes to 0, so do a stupid trick.
171 volatile void* volatile zero = 0x0;
172
173 // Final copy, and synchronize icache. This is the point of no return.
174 elf_memcpy(zero, (void*)((uint64_t)ELF_TEMP_BEGIN & 0x1FFFFFFF), mem_size);
175 elf_sync_before_exec(zero, mem_size);
176
177 // Send secondary threads into the elf.
178 *(volatile unsigned long *)(ELF_GET_RELOCATED_REAL(
179 &elf_secondary_hold_addr)) = entry + 0x60;
180
181 // load the argv struct (if this isn't the kernel)
182 if (entry != 0) {
183 // disable argument for linux
184 void *new_argv = (void*)(0x00000008 + entry);
185 elf_memcpy(new_argv, (void*)((uint64_t)ELF_ARGV_BEGIN & 0x1FFFFFFF), sizeof(struct __argv));
186 elf_sync_before_exec(new_argv, sizeof(struct __argv));
187 }
188
189 // call elf_run() in elf_run.S
190 void (*call)(unsigned long, unsigned long) = ELF_GET_RELOCATED_REAL(elf_run);
191 call(entry, ((uint64_t)ELF_DEVTREE_START) & 0x1fffffff);
192
193 // This should never be reached.
194 for (;;)
195 ;
196}
197
198// WARNING: elf_prepare_run is relocated and you CANNOT call regular functions from here! The application *will* trap.
199// As a consequence of the relocation, the following optimizations are required to prevent function calls that will fail:
200// - optimize("O2") is required to prevent calls to _savegpr
201// - optimize("no-tree-loop-distribute-patterns") prevents GCC from replacing loops with calls to library functions
202static void
203 __attribute__((section(".elfldr"), used, noreturn, flatten, optimize("O2", "no-tree-loop-distribute-patterns")))
204 elf_prepare_run(void *addr, uint32_t size) {
205 Elf32_Ehdr *ehdr;
206 Elf32_Shdr *shdr;
207 Elf32_Phdr *phdr;
208 int i;
209
210 int mem_size = 0;
211 uint32_t pagetable_size = (uint32_t)pagetable_end & 0x1FFFFFFF;
212
213 ehdr = (Elf32_Ehdr *)addr;
214 shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
215 (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
216 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
217
218 for (i = 0; i < ehdr->e_phnum; ++i) {
219#if ELF_DEBUG
220 elf_smc_set_led(1, (i << 4) & 0xF0); // flash green LEDs
221#endif
222
223 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff + (i * sizeof(Elf32_Phdr)));
224
225 // Skip program headers with no size
226 // Older linked homebrew has a GNU_EH_FRAME header with a physaddr in virtual space
227 if (phdr->p_memsz == 0)
228 continue;
229
230 // Track the high address (even for pages we don't load)
231 if (phdr->p_paddr + phdr->p_memsz > mem_size) {
232 mem_size = phdr->p_paddr + phdr->p_memsz;
233 }
234
235 if (phdr->p_type == PT_LOAD || phdr->p_type == PT_DYNAMIC ||
236 phdr->p_type == PT_NOTE) {
237 // Zero then copy into our temporary memory...
238 elf_memset(ELF_TEMP_BEGIN + phdr->p_paddr, 0, phdr->p_memsz);
239 elf_memcpy(ELF_TEMP_BEGIN + phdr->p_paddr, addr + phdr->p_offset,
240 phdr->p_filesz);
241 }
242 }
243
244 if (mem_size == 0) {
245 // Uh-oh, no loading occurred. We're boned.
246 elf_smc_set_led(1, 0x0F);
247 while (1)
248 ;
249 }
250
251#if ELF_DEBUG
252 elf_smc_set_led(1, 0x87); // 1 green 3 red
253#endif
254
255 void (*call_real)(void *, uint32_t, int) = ELF_GET_RELOCATED(elf_call_real);
256 call_real(ELF_GET_RELOCATED_REAL(elf_prepare_run_s2), ehdr->e_entry,
257 mem_size);
258
259 // Call these just so they aren't optimized out (this isn't reached).
261 elf_prepare_run_s2(NULL, 0, 0);
262
263 // This should never be reached.
264 for (;;)
265 ;
266}
267
268char *argv_GetFilename(const char *argv) {
269 char *tmp;
270
271 if (argv == NULL)
272 return NULL;
273
274 tmp = strrchr(argv, '/');
275
276 if (tmp == NULL)
277 return NULL;
278
279 strcpy(_filename, tmp + 1);
280
281 return _filename;
282}
283
284char *argv_GetFilepath(const char *argv) {
285 char *tmp;
286
287 if (argv == NULL)
288 return NULL;
289
290 tmp = strrchr(argv, '/');
291
292 if (tmp == NULL)
293 return NULL;
294
295 strncpy(_filepath, argv, tmp - argv);
296
297 return _filepath;
298}
299
300char *argv_GetDevice(const char *argv) {
301 char *tmp;
302
303 if (argv == NULL)
304 return NULL;
305
306 tmp = strrchr(argv, ':');
307
308 if (tmp == NULL)
309 return NULL;
310
311 strncpy(_device, argv, tmp - argv);
312
313 return _device;
314}
315
316void elf_setArgcArgv(int argc, char *argv[]) {
317 int i;
318
319 // create argv struct and initialize it
320 struct __argv args;
321 memset(&args, 0, sizeof(struct __argv));
322 args.magic = ARGV_MAGIC;
323 args.argc = argc;
324
325 // set the start of the argv array
326 args.argv = (char *)ELF_ARGV_BEGIN + sizeof(struct __argv);
327 char *position = args.argv + (sizeof(char *) * argc);
328
329 // copy all the argument strings
330 for (i = 0; i < argc; i++) {
331 strcpy(position, argv[i]);
332 args.argv[i] = position;
333 position += strlen(argv[i]);
334
335 // be sure its null terminated
336 strcpy(position, "\0");
337 position++;
338 }
339
340 // move the struct to its final position
341 memmove(ELF_ARGV_BEGIN, &args, sizeof(args));
342 elf_sync_before_exec(ELF_ARGV_BEGIN, sizeof(args) + position);
343}
344
345static int elf_VerifyHeaders(void *addr, int size) {
346 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
347 Elf32_Shdr *shdr;
348 Elf32_Phdr *phdr;
349 unsigned char *strtab = 0;
350
351 if (ehdr->e_ident[0] != ELFMAG0 || ehdr->e_ident[1] != ELFMAG1 ||
352 ehdr->e_ident[2] != ELFMAG2 || ehdr->e_ident[3] != ELFMAG3) {
353 printf("ELF: Magic incorrect\n");
354 return -1;
355 }
356
357 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
358 printf("ELF: Not a 32-bit file!\n Did you forget to convert it?\n");
359 return -1;
360 }
361
362 shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
363 (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
364 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
365
366 if (shdr->sh_type == SHT_STRTAB) {
367 strtab = (unsigned char *)(addr + shdr->sh_offset);
368 }
369
370 for (int i = 0; i < ehdr->e_phnum; i++) {
371 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff + (i * sizeof(Elf32_Phdr)));
372 if (phdr->p_offset + phdr->p_filesz > size) {
373 printf("ELF: Program header %d exceeds file size! (0x%.8X > 0x%.8X)\n",
374 i, phdr->p_offset + phdr->p_filesz, size);
375 return -1;
376 }
377 }
378
379 return 0;
380}
381
382static uint32_t elf_getMappedSize(uint32_t addr, int size) {
383 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
384 Elf32_Phdr *phdr = (Elf32_Phdr *)addr + ehdr->e_phoff;
385 uint32_t current_max_addr = 0;
386
387 for (int i = 0; i < ehdr->e_phnum; i++) {
388 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff + (i * sizeof(Elf32_Phdr)));
389
390 if(phdr->p_paddr + phdr->p_memsz > current_max_addr && phdr->p_memsz) {
391 current_max_addr = phdr->p_paddr + phdr->p_memsz;
392 }
393 }
394
395 return current_max_addr;
396}
397
398int elf_runFromMemory(void *addr, int size) {
399 uint64_t start_time;
400 volatile uint32_t *elf_secondary_count_ptr =
402 int i;
403
404 if (elf_VerifyHeaders(addr, size) != 0) {
405 printf(" * Elf headers invalid, abort!\n", addr);
406 return -1;
407 }
408
409 uint32_t mapped_size = elf_getMappedSize(addr, size);
410
411 if (mapped_size >= ELF_MAX_SIZE) {
412 printf(" * Elf is too large, abort! (size = 0x%.8X)\n", mapped_size);
413 return -1;
414 }
415
417 printf(" * Internal error: elfldr code is too large! (size = 0x%.8X)\n",
419 return -1;
420 }
421
422 printf(" * Executing @ 0x%.8X size 0x%.8X...\n", addr, mapped_size);
424
425 // relocate our code
428
429 // relocate elf data
430 memcpy(ELF_DATA_RELOC_START, addr, size);
431
432 elf_debug_printf(" - Waiting for secondary threads...\n");
433
434 // get all threads to be on hold in the relocated zone
435 // TODO: timeout and reset
436 *elf_secondary_count_ptr = 0;
438 elf_debug_printf(" - ");
439 for (i = 1; i < 6; ++i) {
441 ;
442
443 while (*elf_secondary_count_ptr < i) {
444 udelay(100);
445 }
446
447#if ELF_DEBUG
449 elf_debug_printf(" - %d", i);
450#endif
451 }
452 elf_debug_printf("\n");
453
454 elf_debug_printf(" - elf_prepare_run\n");
455
456 // call elf_prepare_run()
457 void (*call)(void *, uint32_t) = ELF_GET_RELOCATED(elf_prepare_run);
459
460 // never called, make sure the function survives linking
461 elf_prepare_run(NULL, 0);
462 return 0;
463}
464
465int elf_runFromDisk(char *filename) {
466 int f = open(filename, O_RDONLY);
467 if (f < 0) {
468 return f;
469 }
470
471 struct stat s;
472 stat(filename, &s);
473
474 int size = s.st_size;
475 void *buf = malloc(size);
476
477 int r = read(f, buf, size);
478 if (r < 0) {
479 close(f);
480 return r;
481 }
482
483 elf_runFromMemory(buf, r);
484
485 return 0;
486}
487
488int elf_runWithDeviceTree(void *elf_addr, int elf_size, void *dt_addr,
489 int dt_size) {
490 int res, node;
491 uint32_t cpufreq;
492
493 if (dt_size > ELF_DEVTREE_MAX_SIZE) {
494 printf(" ! device tree too big (> %d bytes)\n", ELF_DEVTREE_MAX_SIZE);
495 return -1;
496 }
498
500 if (res < 0) {
501 printf(" ! fdt_open_into() failed\n");
502 return res;
503 }
504
505 node = fdt_path_offset(ELF_DEVTREE_START, "/chosen");
506 if (node < 0) {
507 printf(" ! /chosen node not found in devtree\n");
508 return node;
509 }
510
511 if (bootargs[0]) {
512 res = fdt_setprop(ELF_DEVTREE_START, node, "bootargs", bootargs,
513 strlen(bootargs) + 1);
514 if (res < 0) {
515 printf(" ! couldn't set chosen.bootargs property\n");
516 return res;
517 }
518 }
519
520 if (initrd_start && initrd_size) {
521 kernel_relocate_initrd(initrd_start, initrd_size);
522
523 u64 start, end;
524 start = (u32)PHYSADDR((u32)initrd_start);
525 res = fdt_setprop(ELF_DEVTREE_START, node, "linux,initrd-start", &start,
526 sizeof(start));
527 if (res < 0) {
528 printf(" ! couldn't set chosen.linux,initrd-start property\n");
529 return res;
530 }
531
532 end = (u32)PHYSADDR(((u32)initrd_start + (u32)initrd_size));
533 res = fdt_setprop(ELF_DEVTREE_START, node, "linux,initrd-end", &end,
534 sizeof(end));
535 if (res < 0) {
536 printf(" ! couldn't set chosen.linux,initrd-end property\n");
537 return res;
538 }
539 res = fdt_add_mem_rsv(ELF_DEVTREE_START, start, initrd_size);
540 if (res < 0) {
541 printf(" ! couldn't add reservation for the initrd\n");
542 return res;
543 }
544 }
545
546 node = fdt_path_offset(ELF_DEVTREE_START, "/memory");
547 if (node < 0) {
548 printf(" ! /memory node not found in devtree\n");
549 return node;
550 }
551 /*
552 res = fdt_add_mem_rsv(ELF_DEVTREE_START, (uint64_t)ELF_DEVTREE_START,
553 ELF_DEVTREE_MAX_SIZE); if (res < 0){ printf("couldn't add reservation for
554 the devtree\n"); return;
555 }
556 */
557
558 switch (xenon_get_speed()) {
559 case XENON_SPEED_FULL:
560 case XENON_SPEED_3_2: {
561 cpufreq = 3200000000;
562 break;
563 }
564 case XENON_SPEED_1_3: {
565 cpufreq = 1300000000;
566 break;
567 }
568 case XENON_SPEED_1_2: {
569 cpufreq = 1200000000;
570 break;
571 }
572 default: {
573 printf(" ! Weird CPU speed, assuming 3.2GHz\n");
574 cpufreq = 3200000000;
575 break;
576 }
577 }
578
579 node = fdt_path_offset(ELF_DEVTREE_START, "/cpus/Xenon,PPE@0");
580 if (node < 0) {
581 printf(" ! /cpus/Xenon,PPE@0 node not found in devtree\n");
582 return node;
583 }
584
585 res = fdt_setprop(ELF_DEVTREE_START, node, "clock-frequency", &cpufreq,
586 sizeof(cpufreq));
587 if (res < 0) {
588 printf(" ! couldn't set /cpus/Xenon,PPE@0.clock-frequency property\n");
589 return res;
590 }
591
592 node = fdt_path_offset(ELF_DEVTREE_START, "/cpus/Xenon,PPE@1");
593 if (node < 0) {
594 printf(" ! /cpus/Xenon,PPE@1 node not found in devtree\n");
595 return node;
596 }
597
598 res = fdt_setprop(ELF_DEVTREE_START, node, "clock-frequency", &cpufreq,
599 sizeof(cpufreq));
600 if (res < 0) {
601 printf(" ! couldn't set /cpus/Xenon,PPE@1.clock-frequency property\n");
602 return res;
603 }
604
605 node = fdt_path_offset(ELF_DEVTREE_START, "/cpus/Xenon,PPE@2");
606 if (node < 0) {
607 printf(" ! /cpus/Xenon,PPE@2 node not found in devtree\n");
608 return node;
609 }
610
611 res = fdt_setprop(ELF_DEVTREE_START, node, "clock-frequency", &cpufreq,
612 sizeof(cpufreq));
613 if (res < 0) {
614 printf(" ! couldn't set /cpus/Xenon,PPE@2.clock-frequency property\n");
615 return res;
616 }
617
619 if (res < 0) {
620 printf(" ! fdt_pack() failed\n");
621 return res;
622 }
623
625 printf(" * Device tree prepared\n");
626
627 elf_runFromMemory(elf_addr, elf_size);
628
629 return -1; // If this point is reached, elf execution failed
630}
631
632int kernel_prepare_initrd(void *start, size_t size) {
633 if (size > INITRD_MAX_SIZE) {
634 printf(" ! Initrd bigger than INITRD_MAX_SIZE (32 MB), Aborting!\n");
635 return -1;
636 }
637
638 if (initrd_start != NULL)
639 free(initrd_start);
640
641 initrd_start = (uint8_t *)malloc(size);
642
643 memcpy(initrd_start, start, size);
644 initrd_size = size;
645 return 0;
646}
647
648void kernel_relocate_initrd(void *start, size_t size) {
649 printf(" * Relocating initrd...\n");
650
652 memcpy(INITRD_RELOC_START, start, size);
654
655 initrd_start = INITRD_RELOC_START;
656 initrd_size = size;
657
658 printf(" * Initrd at %p/0x%lx: %ld bytes (%ldKiB)\n", initrd_start,
659 (u32)PHYSADDR((u32)initrd_start), initrd_size, initrd_size / 1024);
660}
661
663 if (initrd_start != NULL)
664 free(initrd_start);
665
666 initrd_start = NULL;
667 initrd_size = 0;
668}
669
670void kernel_build_cmdline(const char *parameters, const char *root) {
671 bootargs[0] = 0;
672
673 if (root) {
674 strlcat(bootargs, "root=", MAX_CMDLINE_SIZE);
675 strlcat(bootargs, root, MAX_CMDLINE_SIZE);
676 strlcat(bootargs, " ", MAX_CMDLINE_SIZE);
677 }
678
679 if (parameters)
680 strlcat(bootargs, parameters, MAX_CMDLINE_SIZE);
681
682 printf(" * Kernel command line: '%s'\n", bootargs);
683}
#define PHYSADDR(x)
Definition: cfe.h:14
void console_clrline()
Definition: console.c:100
#define NULL
Definition: def.h:47
void memicbi(void *addr, int len)
void memdcbst(void *addr, int len)
#define LINESIZE
Definition: elf.c:114
void kernel_reset_initrd(void)
Definition: elf.c:662
void elf_run(unsigned long entry, unsigned long devtree)
#define ELF_GET_RELOCATED_REAL(x)
Definition: elf.c:49
unsigned char elfldr_end[]
Definition: elf.c:61
#define ELF_ARGV_BEGIN
Definition: elf.c:46
#define MAX_CMDLINE_SIZE
Definition: elf.c:28
char * argv_GetFilepath(const char *argv)
Definition: elf.c:284
#define ELF_GET_RELOCATED(x)
Definition: elf.c:47
char * argv_GetFilename(const char *argv)
Definition: elf.c:268
int kernel_prepare_initrd(void *start, size_t size)
Definition: elf.c:632
int elf_runFromMemory(void *addr, int size)
Definition: elf.c:398
void kernel_build_cmdline(const char *parameters, const char *root)
Definition: elf.c:670
int elf_runFromDisk(char *filename)
Definition: elf.c:465
void elf_call_real(uint64_t function,...)
#define elf_debug_printf(...)
Definition: elf.c:55
#define ELF_CODE_MAX_SIZE
Definition: elf.c:38
void elf_setArgcArgv(int argc, char *argv[])
Definition: elf.c:316
volatile unsigned long elf_secondary_hold_addr
void kernel_relocate_initrd(void *start, size_t size)
Definition: elf.c:648
volatile unsigned long elf_secondary_count
#define ELF_CODE_RELOC_START
Definition: elf.c:37
#define ELF_TEMP_BEGIN
Definition: elf.c:41
void shutdown_drivers()
unsigned char pagetable_end[]
Definition: elf.c:61
#define ELF_DEVTREE_START
Definition: elf.c:26
#define INITRD_RELOC_START
Definition: elf.c:30
#define ELF_DEVTREE_MAX_SIZE
Definition: elf.c:27
#define ELF_MAX_SIZE
Definition: elf.c:42
#define ELF_DATA_RELOC_START
Definition: elf.c:45
char * argv_GetDevice(const char *argv)
Definition: elf.c:300
void elf_hold_thread()
int elf_runWithDeviceTree(void *elf_addr, int elf_size, void *dt_addr, int dt_size)
Definition: elf.c:488
#define INITRD_MAX_SIZE
Definition: elf.c:31
unsigned char elfldr_start[]
#define PT_DYNAMIC
Definition: elf_abi.h:118
#define ELFMAG0
Definition: elf_abi.h:45
#define ELFMAG3
Definition: elf_abi.h:48
#define EI_CLASS
Definition: elf_abi.h:42
#define ELFCLASS32
Definition: elf_abi.h:51
#define ELFMAG1
Definition: elf_abi.h:46
#define PT_NOTE
Definition: elf_abi.h:119
#define PT_LOAD
Definition: elf_abi.h:117
#define ELFMAG2
Definition: elf_abi.h:47
#define SHT_STRTAB
Definition: elf_abi.h:107
int fdt_path_offset(const void *fdt, const char *path)
Definition: fdt_ro.c:157
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
Definition: fdt_rw.c:172
int fdt_pack(void *fdt)
Definition: fdt_rw.c:453
int fdt_open_into(const void *fdt, void *buf, int bufsize)
Definition: fdt_rw.c:389
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len)
Definition: fdt_rw.c:274
u32 size
Definition: iso9660.c:558
u32 uint32_t
Definition: libfdt_env.h:11
u64 uint64_t
Definition: libfdt_env.h:12
u8 uint8_t
Definition: libfdt_env.h:9
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
Definition: mf-runtime.h:34
int close(int fileDesc)
Definition: newlib.c:829
int stat(const char *file, struct stat *st)
Definition: newlib.c:643
int read(int fileDesc, void *ptr, size_t len)
Definition: newlib.c:559
int open(const char *file, int flags, int mode)
Definition: newlib.c:522
Elf32_Word p_paddr
Definition: elf_abi.h:97
Elf32_Word p_type
Definition: elf_abi.h:94
Elf32_Word p_filesz
Definition: elf_abi.h:98
Elf32_Word p_offset
Definition: elf_abi.h:95
Elf32_Word p_memsz
Definition: elf_abi.h:99
Elf32_Off sh_offset
Definition: elf_abi.h:85
Elf32_Word sh_type
Definition: elf_abi.h:82
Definition: xetypes.h:76
int magic
Definition: xetypes.h:77
char ** argv
Definition: xetypes.h:79
int argc
Definition: xetypes.h:78
Definition: elf_abi.h:59
Elf32_Off e_phoff
Definition: elf_abi.h:65
Elf32_Off e_shoff
Definition: elf_abi.h:66
Elf32_Half e_shstrndx
Definition: elf_abi.h:73
Elf32_Addr e_entry
Definition: elf_abi.h:64
Elf32_Half e_phnum
Definition: elf_abi.h:70
unsigned char e_ident[EI_NIDENT]
Definition: elf_abi.h:60
void udelay(int u)
Definition: time.c:12
int xenon_run_thread_task(int thread, void *stack, void *task)
Definition: xenon_power.c:208
void xenon_thread_startup(void)
Definition: xenon_power.c:263
int xenon_get_speed()
Definition: xenon_power.c:202
#define XENON_SPEED_1_3
Definition: xenon_power.h:11
#define XENON_SPEED_1_2
Definition: xenon_power.h:12
#define XENON_SPEED_3_2
Definition: xenon_power.h:13
#define XENON_SPEED_FULL
Definition: xenon_power.h:14
u8 c
Definition: xenos_edid.h:7
u8 str[13]
Definition: xenos_edid.h:0
uint64_t u64
64bit unsigned integer
Definition: xetypes.h:15
#define ARGV_MAGIC
Definition: xetypes.h:84
uint32_t u32
32bit unsigned integer
Definition: xetypes.h:14