26#define ELF_DEVTREE_START ((void *)0x85FE0000)
27#define ELF_DEVTREE_MAX_SIZE 0x00010000
28#define MAX_CMDLINE_SIZE 255
30#define INITRD_RELOC_START ((void *)0x86000000)
31#define INITRD_MAX_SIZE (32 * 1024 * 1024)
36#define ELF_CODE_STACK_END ((void *)0x87F80000)
37#define ELF_CODE_RELOC_START ((void *)0x87F80000)
38#define ELF_CODE_MAX_SIZE 0x00080000
41#define ELF_TEMP_BEGIN ((void *)0x88000000)
42#define ELF_MAX_SIZE 0x03000000
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)
58extern void elf_run(
unsigned long entry,
unsigned long devtree);
67static size_t initrd_size = 0;
69static char _filename[256] = {0};
70static char _filepath[256] = {0};
71static char _device[256] = {0};
73static inline __attribute__((always_inline))
void elf_putch(
unsigned char c) {
74 while (!((*(
volatile uint32_t *)(0xea001000 + 0x18)) & 0x02000000))
76 *(
volatile uint32_t *)(0xea001000 + 0x14) = (
c << 24) & 0xFF000000;
79static inline __attribute__((always_inline))
void elf_puts(
unsigned char *s) {
85elf_int2hex(
unsigned long long n,
unsigned char w,
unsigned char *
str) {
91 for (i = 0; i < w; ++i) {
92 d = (n >> (i << 2)) & 0x0f;
93 *--
str = (d <= 9) ? d + 48 : d + 55;
97static inline __attribute__((always_inline))
void elf_memset(
unsigned char *dst,
104elf_memcpy(
unsigned char *dst,
const unsigned char *src,
int l) {
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");
119elf_sync_before_exec(
unsigned char *dst,
int l) {
120 dst = (
unsigned char *)((
unsigned long)dst & (~(
LINESIZE - 1)));
133elf_smc_send_message(
const unsigned char *msg) {
134 while ((read32(0xEA001000 + 0x84) & 4) == 0)
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);
145static inline __attribute__((always_inline))
void elf_smc_set_led(
int override,
148 elf_memset(buf, 0, 16);
154 elf_smc_send_message(buf);
159 __attribute__((section(
".elfldr"), used, noreturn, flatten, optimize(
"O2")))
160 elf_prepare_run_s2(
void *self,
uint32_t entry,
int mem_size) {
162 volatile void*
volatile zero = 0x0;
166 elf_sync_before_exec(zero, mem_size);
175 void *new_argv = (
void*)(0x00000008 + entry);
177 elf_sync_before_exec(new_argv,
sizeof(
struct __argv));
193 __attribute__((section(
".elfldr"), used, noreturn, flatten, optimize(
"O2")))
208 for (i = 0; i < ehdr->
e_phnum; ++i) {
210 elf_smc_set_led(1, (i << 4) & 0xF0);
231 elf_smc_set_led(1, 0x0F);
237 elf_smc_set_led(1, 0x87);
246 elf_prepare_run_s2(
NULL, 0, 0);
259 tmp = strrchr(argv,
'/');
264 strcpy(_filename, tmp + 1);
275 tmp = strrchr(argv,
'/');
280 strncpy(_filepath, argv, tmp - argv);
291 tmp = strrchr(argv,
':');
296 strncpy(_device, argv, tmp - argv);
306 memset(&args, 0,
sizeof(
struct __argv));
312 char *position = args.
argv + (
sizeof(
char *) *
argc);
315 for (i = 0; i <
argc; i++) {
316 strcpy(position,
argv[i]);
317 args.
argv[i] = position;
318 position += strlen(
argv[i]);
321 strcpy(position,
"\0");
330static int elf_VerifyHeaders(
void *addr,
int size) {
334 unsigned char *strtab = 0;
338 printf(
"ELF: Magic incorrect\n");
343 printf(
"ELF: Not a 32-bit file!\n Did you forget to convert it?\n");
352 strtab = (
unsigned char *)(addr + shdr->
sh_offset);
355 for (
int i = 0; i < ehdr->
e_phnum; i++) {
358 printf(
"ELF: Program header %d exceeds file size! (0x%.8X > 0x%.8X)\n",
369 volatile uint32_t *elf_secondary_count_ptr =
373 if (elf_VerifyHeaders(addr,
size) != 0) {
374 printf(
" * Elf headers invalid, abort!\n", addr);
379 printf(
" * Elf is too large, abort! (size = 0x%.8X)\n",
size);
384 printf(
" * Internal error: elfldr code is too large! (size = 0x%.8X)\n",
389 printf(
" * Executing @ 0x%.8X size 0x%.8X...\n", addr,
size);
400 printf(
" - Waiting for secondary threads...\n");
405 *elf_secondary_count_ptr = 0;
408 for (i = 1; i < 6; ++i) {
412 while (*elf_secondary_count_ptr < i) {
422 printf(
" - elf_prepare_run\n");
430 elf_prepare_run(
NULL, 0);
435 int f =
open(filename, O_RDONLY);
443 int size = s.st_size;
444 void *buf = malloc(
size);
462 printf(
"[ELF loader] Device tree too big (> %d bytes) !\n",
470 printf(
" ! fdt_open_into() failed\n");
476 printf(
" ! /chosen node not found in devtree\n");
482 strlen(bootargs) + 1);
484 printf(
" ! couldn't set chosen.bootargs property\n");
489 if (initrd_start && initrd_size) {
497 printf(
"couldn't set chosen.linux,initrd-start property\n");
505 printf(
"couldn't set chosen.linux,initrd-end property\n");
510 printf(
"couldn't add reservation for the initrd\n");
517 printf(
" ! /memory node not found in devtree\n");
529 printf(
" ! fdt_pack() failed\n");
534 printf(
" * Device tree prepared\n");
543 printf(
" ! Initrd bigger than INITRD_MAX_SIZE (32 MB), Aborting!\n");
547 if (initrd_start !=
NULL)
552 memcpy(initrd_start, start,
size);
558 printf(
" * Relocating initrd...\n");
567 printf(
"Initrd at %p/0x%lx: %ld bytes (%ldKiB)\n", initrd_start,
568 (
u32)
PHYSADDR((
u32)initrd_start), initrd_size, initrd_size / 1024);
572 if (initrd_start !=
NULL)
591 printf(
"Kernel command line: '%s'\n", bootargs);
void memicbi(void *addr, int len)
void memdcbst(void *addr, int len)
void kernel_reset_initrd(void)
void elf_run(unsigned long entry, unsigned long devtree)
#define ELF_GET_RELOCATED_REAL(x)
unsigned char elfldr_end[]
char * argv_GetFilepath(const char *argv)
#define ELF_GET_RELOCATED(x)
char * argv_GetFilename(const char *argv)
int kernel_prepare_initrd(void *start, size_t size)
int elf_runFromMemory(void *addr, int size)
void kernel_build_cmdline(const char *parameters, const char *root)
int elf_runFromDisk(char *filename)
void elf_call_real(uint64_t function,...)
#define ELF_CODE_MAX_SIZE
void elf_setArgcArgv(int argc, char *argv[])
volatile unsigned long elf_secondary_hold_addr
void kernel_relocate_initrd(void *start, size_t size)
volatile unsigned long elf_secondary_count
#define ELF_CODE_RELOC_START
unsigned char pagetable_end[]
#define ELF_DEVTREE_START
#define INITRD_RELOC_START
#define ELF_DEVTREE_MAX_SIZE
#define ELF_DATA_RELOC_START
char * argv_GetDevice(const char *argv)
int elf_runWithDeviceTree(void *elf_addr, int elf_size, void *dt_addr, int dt_size)
unsigned char elfldr_start[]
int fdt_path_offset(const void *fdt, const char *path)
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
int fdt_open_into(const void *fdt, void *buf, int bufsize)
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len)
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
int stat(const char *file, struct stat *st)
int read(int fileDesc, void *ptr, size_t len)
int open(const char *file, int flags, int mode)
unsigned char e_ident[EI_NIDENT]
int xenon_run_thread_task(int thread, void *stack, void *task)
void xenon_thread_startup(void)
uint64_t u64
64bit unsigned integer
uint32_t u32
32bit unsigned integer