1 /* $NetBSD: bootxx.c,v 1.4 2008/04/28 20:23:18 martin Exp $ */
4 * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 #include <lib/libsa/stand.h>
34 #include <lib/libkern/libkern.h>
37 #include <sys/types.h>
38 #include <sys/param.h>
41 #include <sys/exec_ecoff.h>
42 #include <sys/exec_elf.h>
44 #include <machine/sector.h>
45 #include <machine/sbd.h>
49 #define FILHSZ (sizeof(struct ecoff_filehdr))
50 #define SCNHSZ (sizeof(struct ecoff_scnhdr))
51 #define N_TXTOFF(f, a) \
53 ((FILHSZ +(f)->f_opthdr +(f)->f_nscns * SCNHSZ + 7) & ~7) : \
54 ((FILHSZ +(f)->f_opthdr +(f)->f_nscns * SCNHSZ + 15) & ~15))
57 int loader(const char *, uint32_t *);
58 int load_elf(uint8_t *, uint32_t *);
59 int load_coff(uint8_t *, uint32_t *);
60 int dk_read(int, int, void *);
62 const char *errmsg
[] = {
63 [BERR_PDINFO
] = "No PDINFO",
64 [BERR_RDVTOC
] = "VTOC read error",
65 [BERR_VTOC
] = "VTOC bad magic",
66 [BERR_NOBFS
] = "No BFS partition",
67 [BERR_RDINODE
] = "I-node read error",
68 [BERR_NOROOT
] = "No root",
69 [BERR_RDDIRENT
] = "Dirent read error",
70 [BERR_NOFILE
] = "No such a file",
71 [BERR_RDFILE
] = "File read error",
72 [BERR_FILEMAGIC
] = "Bad file magic",
73 [BERR_AOUTHDR
] = "Not a OMAGIC",
74 [BERR_ELFHDR
] = "Not a ELF",
75 [BERR_TARHDR
] = "Read tar file",
76 [BERR_TARMAGIC
] = "Bad tar magic",
79 const char *boottab
[] = {
80 "boot", /* NetBSD (bfs,ustarfs) */
81 "iopboot", /* EWS-UX (bfs) */
85 int __dk_unit
, __dk_type
, __spb
;
86 bool (*fd_position
)(uint32_t, uint32_t *, int *);
91 char msg
[] = "[+++] NetBSD/ews4800mips >> ";
100 boot_device(&__dk_type
, &__dk_unit
, &fd_format
);
101 msg
[1] = __dk_type
+ '0';
102 msg
[2] = __dk_unit
+ '0';
103 msg
[3] = FS_SIGNATURE
;
104 for (i
= 0; msg
[i
] != 0; i
++)
105 ROM_PUTC(32 + i
* 12, 536, msg
[i
]);
107 if (__dk_type
== NVSRAM_BOOTDEV_FLOPPYDISK
) {
108 fd_position
= blk_to_2d_position
;
109 if (fd_format
== FD_FORMAT_2D
) {
110 fd_position
= blk_to_2d_position
;
111 __spb
= 2; /* 256bytes/sector */
113 fd_position
= blk_to_2hd_position
;
114 __dk_unit
|= 0x1000000; /* | 2HD flag */
120 sector_init("/dev/rsd1p", DEV_BSIZE
);
121 sector_read(SDBOOT_PDINFOADDR
, PDINFO_SECTOR
);
124 for (boot
= boottab
; *boot
; boot
++) {
125 if ((err
= loader(*boot
, &entry
)) == 0) {
127 ROM_PUTC(0, 0, '\n');
128 ROM_PUTC(0, 0, '\r');
131 printf("entry=%p\n", (void *)entry
);
138 for (i
= 0; p
[i
] != 0; i
++)
139 ROM_PUTC(600 + i
* 12, 536, p
[i
]);
141 DPRINTF("***ERROR *** %s\n", p
);
146 while (/*CONSTCOND*/1)
156 loader(const char *fname
, uint32_t *entry
)
164 for (i
= 0; fname
[i
] != 0; i
++)
165 ROM_PUTC(380 + i
* 12, 536, fname
[i
]);
167 printf("%s\n", fname
);
170 if ((err
= fileread(fname
, &sz
)) != 0)
173 DPRINTF("%s found. %d bytes.\n", fname
, sz
);
175 mag
= *(uint16_t *)SDBOOT_SCRATCHADDR
;
177 return load_elf((uint8_t *)SDBOOT_SCRATCHADDR
, entry
);
178 else if (mag
== ECOFF_MAGIC_MIPSEB
)
179 return load_coff((uint8_t *)SDBOOT_SCRATCHADDR
, entry
);
181 return BERR_FILEMAGIC
;
185 load_elf(uint8_t *buf
, uint32_t *entry
)
187 Elf32_Ehdr
*e
= (void *)buf
;
190 if (e
->e_ident
[EI_MAG2
] != 'L' || e
->e_ident
[EI_MAG3
] != 'F' ||
191 e
->e_ident
[EI_CLASS
] != ELFCLASS32
||
192 e
->e_ident
[EI_DATA
] != ELFDATA2MSB
||
193 e
->e_type
!= ET_EXEC
||
194 e
->e_machine
!= EM_MIPS
)
197 BASSERT(e
->e_phentsize
== sizeof(Elf32_Phdr
));
198 p
= (void *)(buf
+ e
->e_phoff
);
200 memcpy((void *)p
->p_vaddr
, buf
+ p
->p_offset
, p
->p_filesz
);
202 memcpy((void *)p
->p_vaddr
, buf
+ p
->p_offset
, p
->p_filesz
);
204 DPRINTF("ELF entry point 0x%08x\n", e
->e_entry
);
205 DPRINTF("[text] 0x%08x 0x%x %dbyte.\n", p
->p_vaddr
, p
->p_offset
,
208 DPRINTF("[data] 0x%08x 0x%x %dbyte.\n", p
->p_vaddr
, p
->p_offset
,
217 load_coff(uint8_t *p
, uint32_t *entry
)
219 struct ecoff_exechdr
*eh
= (void *)p
;
220 struct ecoff_aouthdr
*a
= &eh
->a
;
221 struct ecoff_filehdr
*f
= &eh
->f
;
223 if (a
->magic
!= ECOFF_OMAGIC
)
227 DPRINTF("file offset = 0x%x\n", N_TXTOFF(f
, a
));
229 memcpy((void *)a
->text_start
, p
, a
->tsize
);
230 memcpy((void *)a
->data_start
, p
+ a
->tsize
, a
->dsize
);
232 DPRINTF("COFF entry point 0x%08lx\n", a
->entry
);
233 DPRINTF("[text] 0x%08lx %ld byte.\n", a
->text_start
, a
->tsize
);
234 DPRINTF("[data] 0x%08lx %ld byte.\n", a
->data_start
, a
->dsize
);
243 dk_read(int sector
, int count
, void *buf
)
250 if (__dk_type
== NVSRAM_BOOTDEV_HARDDISK
) { /* DISK */
251 if ((ROM_DK_READ(__dk_unit
, sector
, count
, p
) & 0x7f) != 0)
255 fd_position(sector
, &pos
, &cnt
);
258 if ((ROM_FD_READ(__dk_unit
, pos
, cnt
* __spb
, p
)
267 sector_read_n(buf
, sector
, count
);