|
|
1.1 ! root 1: /* ! 2: * Creation Date: <2004/08/28 18:38:22 greg> ! 3: * Time-stamp: <2004/08/28 18:38:22 greg> ! 4: * ! 5: * <main.c> ! 6: * ! 7: * Copyright (C) 2004 Greg Watson ! 8: * ! 9: * Based on MOL specific code which is ! 10: * Copyright (C) 2002, 2003, 2004 Samuel Rydh ([email protected]) ! 11: * ! 12: * This program is free software; you can redistribute it and/or ! 13: * modify it under the terms of the GNU General Public License ! 14: * as published by the Free Software Foundation ! 15: * ! 16: */ ! 17: ! 18: ! 19: #include "config.h" ! 20: #include "libopenbios/bindings.h" ! 21: #include "libopenbios/elfload.h" ! 22: #include "arch/common/nvram.h" ! 23: #include "libc/diskio.h" ! 24: #include "libc/vsprintf.h" ! 25: #include "pearpc/pearpc.h" ! 26: #include "libopenbios/ofmem.h" ! 27: ! 28: static void ! 29: transfer_control_to_elf( unsigned long entry ) ! 30: { ! 31: extern void call_elf( unsigned long entry ); ! 32: printk("Starting ELF image at 0x%08lX\n", entry); ! 33: call_elf( 0x400000 ); ! 34: //call_elf( entry ); ! 35: ! 36: fatal_error("call_elf returned unexpectedly\n"); ! 37: } ! 38: ! 39: static int ! 40: load_elf_rom( unsigned long *entry, int fd ) ! 41: { ! 42: int i, lszz_offs, elf_offs; ! 43: char buf[128], *addr; ! 44: Elf_ehdr ehdr; ! 45: Elf_phdr *phdr; ! 46: size_t s; ! 47: ! 48: printk("Loading '%s'\n", get_file_path(fd)); ! 49: ! 50: /* the ELF-image (usually) starts at offset 0x4000 */ ! 51: if( (elf_offs=find_elf(fd)) < 0 ) { ! 52: printk("----> %s is not an ELF image\n", buf ); ! 53: exit(1); ! 54: } ! 55: if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) ! 56: fatal_error("elf_readhdrs failed\n"); ! 57: ! 58: *entry = ehdr.e_entry; ! 59: ! 60: /* load segments. Compressed ROM-image assumed to be located immediately ! 61: * after the last segment */ ! 62: lszz_offs = elf_offs; ! 63: for( i=0; i<ehdr.e_phnum; i++ ) { ! 64: /* p_memsz, p_flags */ ! 65: s = MIN( phdr[i].p_filesz, phdr[i].p_memsz ); ! 66: seek_io( fd, elf_offs + phdr[i].p_offset ); ! 67: ! 68: /* printk("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n", ! 69: phdr[i].p_filesz, phdr[i].p_memsz, phdr[i].p_offset, ! 70: phdr[i].p_vaddr ); */ ! 71: ! 72: if( phdr[i].p_vaddr != phdr[i].p_paddr ) ! 73: printk("WARNING: ELF segment virtual addr != physical addr\n"); ! 74: lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz ); ! 75: if( !s ) ! 76: continue; ! 77: if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) ! 78: fatal_error("Claim failed!\n"); ! 79: ! 80: addr = (char*)phdr[i].p_vaddr; ! 81: if( read_io(fd, addr, s) != s ) ! 82: fatal_error("read failed\n"); ! 83: ! 84: #if 0 ! 85: /* patch CODE segment */ ! 86: if( *entry >= phdr[i].p_vaddr && *entry < phdr[i].p_vaddr + s ) { ! 87: patch_newworld_rom( (char*)phdr[i].p_vaddr, s ); ! 88: newworld_timer_hack( (char*)phdr[i].p_vaddr, s ); ! 89: } ! 90: #endif ! 91: flush_icache_range( addr, addr+s ); ! 92: ! 93: /*printk("ELF ROM-section loaded at %08lX (size %08lX)\n", ! 94: (unsigned long)phdr[i].p_vaddr, (unsigned long)phdr[i].p_memsz );*/ ! 95: } ! 96: free( phdr ); ! 97: return lszz_offs; ! 98: } ! 99: ! 100: ! 101: static void ! 102: encode_bootpath( const char *spec, const char *args ) ! 103: { ! 104: phandle_t chosen_ph = find_dev("/chosen"); ! 105: set_property( chosen_ph, "bootpath", spec, strlen(spec)+1 ); ! 106: set_property( chosen_ph, "bootargs", args, strlen(args)+1 ); ! 107: } ! 108: ! 109: /************************************************************************/ ! 110: /* pearpc booting */ ! 111: /************************************************************************/ ! 112: ! 113: static void ! 114: pearpc_startup( void ) ! 115: { ! 116: const char *paths[] = { "hd:0,\\zImage.chrp", NULL }; ! 117: const char *args[] = { "root=/dev/hda2 console=ttyS0,115200", NULL }; ! 118: unsigned long entry; ! 119: int i, fd; ! 120: ! 121: for( i=0; paths[i]; i++ ) { ! 122: if( (fd=open_io(paths[i])) == -1 ) ! 123: continue; ! 124: (void) load_elf_rom( &entry, fd ); ! 125: close_io( fd ); ! 126: encode_bootpath( paths[i], args[i] ); ! 127: ! 128: update_nvram(); ! 129: transfer_control_to_elf( entry ); ! 130: /* won't come here */ ! 131: } ! 132: printk("*** Boot failure! No secondary bootloader specified ***\n"); ! 133: } ! 134: ! 135: ! 136: /************************************************************************/ ! 137: /* entry */ ! 138: /************************************************************************/ ! 139: ! 140: void ! 141: boot( void ) ! 142: { ! 143: fword("update-chosen"); ! 144: pearpc_startup(); ! 145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.