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 0x03000000
43
44// ELF file relocation address.
45#define ELF_DATA_RELOC_START ((void *)0x8B000000)
46#define ELF_ARGV_BEGIN ((void *)0x8E000000)
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 1
52
53extern void shutdown_drivers();
54
55// section start/end, defined by the compiler
56extern unsigned char elfldr_start[], elfldr_end[], pagetable_end[];
57extern void elf_call_real(uint64_t function, ...);
58extern void elf_run(unsigned long entry, unsigned long devtree);
59extern void elf_hold_thread();
60
61extern volatile unsigned long elf_secondary_hold_addr;
62extern volatile unsigned long elf_secondary_count;
63
64static char bootargs[MAX_CMDLINE_SIZE];
65
66static uint8_t *initrd_start = NULL;
67static size_t initrd_size = 0;
68
69static char _filename[256] = {0};
70static char _filepath[256] = {0};
71static char _device[256] = {0};
72
73static inline __attribute__((always_inline)) void elf_putch(unsigned char c) {
74 while (!((*(volatile uint32_t *)(0xea001000 + 0x18)) & 0x02000000))
75 ;
76 *(volatile uint32_t *)(0xea001000 + 0x14) = (c << 24) & 0xFF000000;
77}
78
79static inline __attribute__((always_inline)) void elf_puts(unsigned char *s) {
80 while (*s)
81 elf_putch(*s++);
82}
83
84static inline __attribute__((always_inline)) void
85elf_int2hex(unsigned long long n, unsigned char w, unsigned char *str) {
86 unsigned char i, d;
87
88 str += w;
89 *str = 0;
90
91 for (i = 0; i < w; ++i) {
92 d = (n >> (i << 2)) & 0x0f;
93 *--str = (d <= 9) ? d + 48 : d + 55;
94 };
95}
96
97static inline __attribute__((always_inline)) void elf_memset(unsigned char *dst,
98 int v, int l) {
99 while (l--)
100 *dst++ = v;
101}
102
103static inline __attribute__((always_inline)) void
104elf_memcpy(unsigned char *dst, const unsigned char *src, int l) {
105 while (l--)
106 *dst++ = *src++;
107}
108
109#define LINESIZE 128
110static inline __attribute__((always_inline)) void
111elf_sync(volatile void *addr) {
112 asm volatile("dcbst 0, %0" : : "b"(addr));
113 asm volatile("sync");
114 asm volatile("icbi 0, %0" : : "b"(addr));
115 asm volatile("isync");
116}
117
118static inline __attribute__((always_inline)) void
119elf_sync_before_exec(unsigned char *dst, int l) {
120 dst = (unsigned char *)((unsigned long)dst & (~(LINESIZE - 1)));
121
122 l += (LINESIZE - 1);
123 l &= ~(LINESIZE - 1);
124
125 while (l > 0) {
126 elf_sync(dst);
127 dst += LINESIZE;
128 l -= LINESIZE;
129 }
130}
131
132static inline __attribute__((always_inline)) void
133elf_smc_send_message(const unsigned char *msg) {
134 while ((read32(0xEA001000 + 0x84) & 4) == 0)
135 ;
136
137 write32(0xEA001000 + 0x84, 4);
138 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 0));
139 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 4));
140 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 8));
141 write32n(0xEA001000 + 0x80, *(uint32_t *)(msg + 12));
142 write32(0xEA001000 + 0x84, 0);
143}
144
145static inline __attribute__((always_inline)) void elf_smc_set_led(int override,
146 int value) {
147 uint8_t buf[16];
148 elf_memset(buf, 0, 16);
149
150 buf[0] = 0x99;
151 buf[1] = override;
152 buf[2] = value;
153
154 elf_smc_send_message(buf);
155}
156
157// Stage 2 of prepare run: This function is called in real-mode.
158static void
159 __attribute__((section(".elfldr"), used, noreturn, flatten, optimize("O2")))
160 elf_prepare_run_s2(void *self, uint32_t entry, int mem_size) {
161 // GCC is allowed to optimize away writes to 0, so do a stupid trick.
162 volatile void* volatile zero = 0x0;
163
164 // Final copy, and synchronize icache. This is the point of no return.
165 elf_memcpy(zero, (void*)((uint64_t)ELF_TEMP_BEGIN & 0x1FFFFFFF), mem_size);
166 elf_sync_before_exec(zero, mem_size);
167
168 // Send secondary threads into the elf.
169 *(volatile unsigned long *)(ELF_GET_RELOCATED_REAL(
170 &elf_secondary_hold_addr)) = entry + 0x60;
171
172 // load the argv struct (if this isn't the kernel)
173 if (entry != 0) {
174 // disable argument for linux
175 void *new_argv = (void*)(0x00000008 + entry);
176 elf_memcpy(new_argv, (void*)((uint64_t)ELF_ARGV_BEGIN & 0x1FFFFFFF), sizeof(struct __argv));
177 elf_sync_before_exec(new_argv, sizeof(struct __argv));
178 }
179
180 // call elf_run() in elf_run.S
181 void (*call)(unsigned long, unsigned long) = ELF_GET_RELOCATED_REAL(elf_run);
182 call(entry, ((uint64_t)ELF_DEVTREE_START) & 0x1fffffff);
183
184 // This should never be reached.
185 for (;;)
186 ;
187}
188
189// optimize("O2") is required to prevent call to _savegpr, which would fail due
190// to the relocation
191// This function is RELOCATED! You CANNOT call regular functions from here!
192static void
193 __attribute__((section(".elfldr"), used, noreturn, flatten, optimize("O2")))
194 elf_prepare_run(void *addr, uint32_t size) {
195 Elf32_Ehdr *ehdr;
196 Elf32_Shdr *shdr;
197 Elf32_Phdr *phdr;
198 int i;
199
200 int mem_size = 0;
201 uint32_t pagetable_size = (uint32_t)pagetable_end & 0x1FFFFFFF;
202
203 ehdr = (Elf32_Ehdr *)addr;
204 shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
205 (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
206 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
207
208 for (i = 0; i < ehdr->e_phnum; ++i) {
209#if ELF_DEBUG
210 elf_smc_set_led(1, (i << 4) & 0xF0); // flash green LEDs
211#endif
212
213 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff + (i * sizeof(Elf32_Phdr)));
214
215 // Track the high address (even for pages we don't load)
216 if (phdr->p_paddr + phdr->p_memsz > mem_size) {
217 mem_size = phdr->p_paddr + phdr->p_memsz;
218 }
219
220 if (phdr->p_type == PT_LOAD || phdr->p_type == PT_DYNAMIC ||
221 phdr->p_type == PT_NOTE) {
222 // Zero then copy into our temporary memory...
223 elf_memset(ELF_TEMP_BEGIN + phdr->p_paddr, 0, phdr->p_memsz);
224 elf_memcpy(ELF_TEMP_BEGIN + phdr->p_paddr, addr + phdr->p_offset,
225 phdr->p_filesz);
226 }
227 }
228
229 if (mem_size == 0) {
230 // Uh-oh, no loading occurred. We're boned.
231 elf_smc_set_led(1, 0x0F);
232 while (1)
233 ;
234 }
235
236#if ELF_DEBUG
237 elf_smc_set_led(1, 0x87); // 1 green 3 red
238#endif
239
240 void (*call_real)(void *, uint32_t, int) = ELF_GET_RELOCATED(elf_call_real);
241 call_real(ELF_GET_RELOCATED_REAL(elf_prepare_run_s2), ehdr->e_entry,
242 mem_size);
243
244 // Call these just so they aren't optimized out (this isn't reached).
246 elf_prepare_run_s2(NULL, 0, 0);
247
248 // This should never be reached.
249 for (;;)
250 ;
251}
252
253char *argv_GetFilename(const char *argv) {
254 char *tmp;
255
256 if (argv == NULL)
257 return NULL;
258
259 tmp = strrchr(argv, '/');
260
261 if (tmp == NULL)
262 return NULL;
263
264 strcpy(_filename, tmp + 1);
265
266 return _filename;
267}
268
269char *argv_GetFilepath(const char *argv) {
270 char *tmp;
271
272 if (argv == NULL)
273 return NULL;
274
275 tmp = strrchr(argv, '/');
276
277 if (tmp == NULL)
278 return NULL;
279
280 strncpy(_filepath, argv, tmp - argv);
281
282 return _filepath;
283}
284
285char *argv_GetDevice(const char *argv) {
286 char *tmp;
287
288 if (argv == NULL)
289 return NULL;
290
291 tmp = strrchr(argv, ':');
292
293 if (tmp == NULL)
294 return NULL;
295
296 strncpy(_device, argv, tmp - argv);
297
298 return _device;
299}
300
301void elf_setArgcArgv(int argc, char *argv[]) {
302 int i;
303
304 // create argv struct and initialize it
305 struct __argv args;
306 memset(&args, 0, sizeof(struct __argv));
307 args.magic = ARGV_MAGIC;
308 args.argc = argc;
309
310 // set the start of the argv array
311 args.argv = (char *)ELF_ARGV_BEGIN + sizeof(struct __argv);
312 char *position = args.argv + (sizeof(char *) * argc);
313
314 // copy all the argument strings
315 for (i = 0; i < argc; i++) {
316 strcpy(position, argv[i]);
317 args.argv[i] = position;
318 position += strlen(argv[i]);
319
320 // be sure its null terminated
321 strcpy(position, "\0");
322 position++;
323 }
324
325 // move the struct to its final position
326 memmove(ELF_ARGV_BEGIN, &args, sizeof(args));
327 elf_sync_before_exec(ELF_ARGV_BEGIN, sizeof(args) + position);
328}
329
330static int elf_VerifyHeaders(void *addr, int size) {
331 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
332 Elf32_Shdr *shdr;
333 Elf32_Phdr *phdr;
334 unsigned char *strtab = 0;
335
336 if (ehdr->e_ident[0] != ELFMAG0 || ehdr->e_ident[1] != ELFMAG1 ||
337 ehdr->e_ident[2] != ELFMAG2 || ehdr->e_ident[3] != ELFMAG3) {
338 printf("ELF: Magic incorrect\n");
339 return -1;
340 }
341
342 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
343 printf("ELF: Not a 32-bit file!\n Did you forget to convert it?\n");
344 return -1;
345 }
346
347 shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
348 (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
349 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
350
351 if (shdr->sh_type == SHT_STRTAB) {
352 strtab = (unsigned char *)(addr + shdr->sh_offset);
353 }
354
355 for (int i = 0; i < ehdr->e_phnum; i++) {
356 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff + (i * sizeof(Elf32_Phdr)));
357 if (phdr->p_offset + phdr->p_filesz > size) {
358 printf("ELF: Program header %d exceeds file size! (0x%.8X > 0x%.8X)\n",
359 phdr->p_offset + phdr->p_filesz, size);
360 return -1;
361 }
362 }
363
364 return 0;
365}
366
367int elf_runFromMemory(void *addr, int size) {
368 uint64_t start_time;
369 volatile uint32_t *elf_secondary_count_ptr =
371 int i;
372
373 if (elf_VerifyHeaders(addr, size) != 0) {
374 printf(" * Elf headers invalid, abort!\n", addr);
375 return -1;
376 }
377
378 if (size >= ELF_MAX_SIZE) {
379 printf(" * Elf is too large, abort! (size = 0x%.8X)\n", size);
380 return -1;
381 }
382
384 printf(" * Internal error: elfldr code is too large! (size = 0x%.8X)\n",
386 return -1;
387 }
388
389 printf(" * Executing @ 0x%.8X size 0x%.8X...\n", addr, size);
391
392 // relocate our code
395
396 // relocate elf data
397 memcpy(ELF_DATA_RELOC_START, addr, size);
398
399#if ELF_DEBUG
400 printf(" - Waiting for secondary threads...\n");
401#endif
402
403 // get all threads to be on hold in the relocated zone
404 // TODO: timeout and reset
405 *elf_secondary_count_ptr = 0;
407 printf(" - ");
408 for (i = 1; i < 6; ++i) {
410 ;
411
412 while (*elf_secondary_count_ptr < i) {
413 udelay(100);
414 }
415
417 printf(" - %d", i);
418 }
419 printf("\n");
420
421#if ELF_DEBUG
422 printf(" - elf_prepare_run\n");
423#endif
424
425 // call elf_prepare_run()
426 void (*call)(void *, uint32_t) = ELF_GET_RELOCATED(elf_prepare_run);
428
429 // never called, make sure the function survives linking
430 elf_prepare_run(NULL, 0);
431 return 0;
432}
433
434int elf_runFromDisk(char *filename) {
435 int f = open(filename, O_RDONLY);
436 if (f < 0) {
437 return f;
438 }
439
440 struct stat s;
441 stat(filename, &s);
442
443 int size = s.st_size;
444 void *buf = malloc(size);
445
446 int r = read(f, buf, size);
447 if (r < 0) {
448 close(f);
449 return r;
450 }
451
452 elf_runFromMemory(buf, r);
453
454 return 0;
455}
456
457int elf_runWithDeviceTree(void *elf_addr, int elf_size, void *dt_addr,
458 int dt_size) {
459 int res, node;
460
461 if (dt_size > ELF_DEVTREE_MAX_SIZE) {
462 printf("[ELF loader] Device tree too big (> %d bytes) !\n",
464 return -1;
465 }
467
469 if (res < 0) {
470 printf(" ! fdt_open_into() failed\n");
471 return res;
472 }
473
474 node = fdt_path_offset(ELF_DEVTREE_START, "/chosen");
475 if (node < 0) {
476 printf(" ! /chosen node not found in devtree\n");
477 return node;
478 }
479
480 if (bootargs[0]) {
481 res = fdt_setprop(ELF_DEVTREE_START, node, "bootargs", bootargs,
482 strlen(bootargs) + 1);
483 if (res < 0) {
484 printf(" ! couldn't set chosen.bootargs property\n");
485 return res;
486 }
487 }
488
489 if (initrd_start && initrd_size) {
490 kernel_relocate_initrd(initrd_start, initrd_size);
491
492 u64 start, end;
493 start = (u32)PHYSADDR((u32)initrd_start);
494 res = fdt_setprop(ELF_DEVTREE_START, node, "linux,initrd-start", &start,
495 sizeof(start));
496 if (res < 0) {
497 printf("couldn't set chosen.linux,initrd-start property\n");
498 return res;
499 }
500
501 end = (u32)PHYSADDR(((u32)initrd_start + (u32)initrd_size));
502 res = fdt_setprop(ELF_DEVTREE_START, node, "linux,initrd-end", &end,
503 sizeof(end));
504 if (res < 0) {
505 printf("couldn't set chosen.linux,initrd-end property\n");
506 return res;
507 }
508 res = fdt_add_mem_rsv(ELF_DEVTREE_START, start, initrd_size);
509 if (res < 0) {
510 printf("couldn't add reservation for the initrd\n");
511 return res;
512 }
513 }
514
515 node = fdt_path_offset(ELF_DEVTREE_START, "/memory");
516 if (node < 0) {
517 printf(" ! /memory node not found in devtree\n");
518 return node;
519 }
520 /*
521 res = fdt_add_mem_rsv(ELF_DEVTREE_START, (uint64_t)ELF_DEVTREE_START,
522 ELF_DEVTREE_MAX_SIZE); if (res < 0){ printf("couldn't add reservation for
523 the devtree\n"); return;
524 }
525 */
526
528 if (res < 0) {
529 printf(" ! fdt_pack() failed\n");
530 return res;
531 }
532
534 printf(" * Device tree prepared\n");
535
536 elf_runFromMemory(elf_addr, elf_size);
537
538 return -1; // If this point is reached, elf execution failed
539}
540
541int kernel_prepare_initrd(void *start, size_t size) {
542 if (size > INITRD_MAX_SIZE) {
543 printf(" ! Initrd bigger than INITRD_MAX_SIZE (32 MB), Aborting!\n");
544 return -1;
545 }
546
547 if (initrd_start != NULL)
548 free(initrd_start);
549
550 initrd_start = (uint8_t *)malloc(size);
551
552 memcpy(initrd_start, start, size);
553 initrd_size = size;
554 return 0;
555}
556
557void kernel_relocate_initrd(void *start, size_t size) {
558 printf(" * Relocating initrd...\n");
559
561 memcpy(INITRD_RELOC_START, start, size);
563
564 initrd_start = INITRD_RELOC_START;
565 initrd_size = size;
566
567 printf("Initrd at %p/0x%lx: %ld bytes (%ldKiB)\n", initrd_start,
568 (u32)PHYSADDR((u32)initrd_start), initrd_size, initrd_size / 1024);
569}
570
572 if (initrd_start != NULL)
573 free(initrd_start);
574
575 initrd_start = NULL;
576 initrd_size = 0;
577}
578
579void kernel_build_cmdline(const char *parameters, const char *root) {
580 bootargs[0] = 0;
581
582 if (root) {
583 strlcat(bootargs, "root=", MAX_CMDLINE_SIZE);
584 strlcat(bootargs, root, MAX_CMDLINE_SIZE);
585 strlcat(bootargs, " ", MAX_CMDLINE_SIZE);
586 }
587
588 if (parameters)
589 strlcat(bootargs, parameters, MAX_CMDLINE_SIZE);
590
591 printf("Kernel command line: '%s'\n", bootargs);
592}
#define PHYSADDR(x)
Definition: cfe.h:14
void console_clrline()
Definition: console.c:94
#define NULL
Definition: def.h:47
void memicbi(void *addr, int len)
void memdcbst(void *addr, int len)
#define LINESIZE
Definition: elf.c:109
void kernel_reset_initrd(void)
Definition: elf.c:571
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:56
#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:269
#define ELF_GET_RELOCATED(x)
Definition: elf.c:47
char * argv_GetFilename(const char *argv)
Definition: elf.c:253
int kernel_prepare_initrd(void *start, size_t size)
Definition: elf.c:541
int elf_runFromMemory(void *addr, int size)
Definition: elf.c:367
void kernel_build_cmdline(const char *parameters, const char *root)
Definition: elf.c:579
int elf_runFromDisk(char *filename)
Definition: elf.c:434
void elf_call_real(uint64_t function,...)
#define ELF_CODE_MAX_SIZE
Definition: elf.c:38
void elf_setArgcArgv(int argc, char *argv[])
Definition: elf.c:301
volatile unsigned long elf_secondary_hold_addr
void kernel_relocate_initrd(void *start, size_t size)
Definition: elf.c:557
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:56
#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:285
void elf_hold_thread()
int elf_runWithDeviceTree(void *elf_addr, int elf_size, void *dt_addr, int dt_size)
Definition: elf.c:457
#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:537
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
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