|
|
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 "briq/briq.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: /* briq booting */
111: /************************************************************************/
112:
113: static void
114: briq_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: briq_startup();
145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.