NetBSD/sys/arch/x68k/sdboot/bootufs.c

648 lines
14 KiB
C
Raw Normal View History

1996-05-05 16:17:14 +04:00
/* $NetBSD: bootufs.c,v 1.1 1996/05/05 12:17:15 oki Exp $ */
1996-05-05 16:17:03 +04:00
/*-
* Copyright (c) 1993, 1994 Takumi Nakamura.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Takumi Nakamura.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/***************************************************************
*
* file: bootufs.c
*
* author: chapuni(GBA02750@niftyserve.or.jp)
*
* <EFBFBD><EFBFBD><EFBFBD>ͤˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: UNIX C PROGRAMMING (NUTSHELL)
* (¯<EFBFBD>˸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˾;
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD>Ƥߤ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD>ufs <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD>/sys/lib/libsa <EFBFBD>Τ<EFBFBD><EFBFBD>Τ<EFBFBD>
* <EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϥ<EFBFBD><EFBFBD>ʤΤǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҤȤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ä<EFBFBD> FD DRIVER <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϥ<EFBFBD><EFBFBD>ʤΤǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
*/
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <sys/time.h>
#include <ufs/ufs/quota.h>
#include <ufs/ffs/fs.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/dir.h>
#include <a.out.h>
#include "sdboot.h"
#include "../x68k/iodevice.h"
#define alloca __builtin_alloca
#define memcpy __builtin_memcpy
static inline void
bcopy (s, d, len)
const char *s;
char *d;
long len;
{
while (len--)
*d++ = *s++;
}
static inline int
strcmp (a, b)
const char *a;
const char *b;
{
while (*a && *b && *a == *b)
a++, b++;
return (*a != *b);
}
static inline int
memcmp (a, b, n)
const char *a;
const char *b;
int n;
{
while (*a == *b && --n)
a++, b++;
return (*a != *b);
}
static inline void
memset(p, v, len)
void *p;
long v;
long len;
{
while (len--)
*(char *)p++ = v;
}
/* for debug */
#ifdef DEBUG
extern int printf __P((const char *, ...));
#endif
#define IODEVbase ((volatile struct IODEVICE *)PHYS_IODEV)
union {
struct fs superblk; /* <20>ۥ<EFBFBD><DBA5><EFBFBD><EFBFBD><EFBFBD> */
unsigned char buf[SBSIZE]; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>碌 */
} superblk_buf;
#define sblock superblk_buf.superblk
/***************************************************************
*
* <EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD>򤿤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Хåե<EFBFBD>
*
*/
#define N_VMUNIX 24
struct {
ino_t ino; /* inode */
char name[60];
} vmunix_dirent[N_VMUNIX];
char *lowram;
/***************************************************************
*
* <EFBFBD>֥<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD>Ϣ³<EFBFBD>ɤߤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߤ
* length = 0 <EFBFBD>ΤȤ<EFBFBD><EFBFBD>ϡ<EFBFBD>ñ<EFBFBD>˥Хåե<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥʤ
*
*/
void *s_buf;
int s_pos;
size_t s_len;
int
raw_read_queue(buf, pos, len)
void *buf;
int pos;
size_t len;
{
int r = 0;
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD>ʤ<EFBFBD> */
if (s_len == 0) {
s_buf = buf;
s_pos = pos;
s_len = len;
return r;
}
/* <20><><EFBFBD>Υ<EFBFBD><CEA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ³<CFA2><C2B3><EFBFBD>Ƥ<EFBFBD><C6A4><EFBFBD><EFBFBD>Ȥ<EFBFBD> */
if (len > 0 && s_pos + btodb(s_len) == pos) {
s_len += len;
return r;
}
/* <20><><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD>ί<EFBFBD>äƤ<C3A4><C6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Τ<EFBFBD><CEA4>ɤ<EFBFBD> */
r = RAW_READ(s_buf, s_pos, s_len);
s_buf = buf;
s_pos = pos;
s_len = len;
return r;
}
/***************************************************************
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>֥<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤߤ<EFBFBD><EFBFBD><EFBFBD>
*
*/
void
get_superblk()
{
RAW_READ(&superblk_buf.buf, dbtob(SBLOCK), SBSIZE);
#ifdef DEBUG
printf("fs_magic=%08lx\n", sblock.fs_magic);
printf("fs_ipg=%08lx\n", sblock.fs_ipg);
printf("fs_ncg=%08lx\n", sblock.fs_ncg);
printf("fs_bsize=%08lx\n", sblock.fs_bsize);
printf("fs_fsize=%08lx\n", sblock.fs_fsize);
printf("INOPB=%08lx\n", INOPB(&sblock));
#endif
}
/***************************************************************
*
* inode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>äƤ<EFBFBD><EFBFBD><EFBFBD>
*
*/
int
get_inode(ino, pino)
ino_t ino;
struct dinode *pino;
{
struct dinode *buf = alloca(sblock.fs_bsize);
RAW_READ(buf,
dbtob(fsbtodb(&sblock, ino_to_fsba(&sblock, ino))),
sblock.fs_bsize);
*pino = buf[ino_to_fsbo(&sblock, ino)];
#ifdef DEBUG
printf("%d)permission=%06ho\n", ino, pino->di_mode);
printf("%d)nlink=%4d\n", ino, pino->di_nlink);
printf("%d)uid=%4d\n", ino, pino->di_uid);
printf("%d)gid=%4d\n", ino, pino->di_gid);
printf("%d)size=%ld\n", ino, pino->di_size);
#endif
return 0;
}
/***************************************************************
*
* inode <EFBFBD>λؤ<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֥<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>äƤ<EFBFBD><EFBFBD><EFBFBD>
*
* NutShell <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Υѥ<EFBFBD><EFBFBD><EFBFBD>
*
* buf <EFBFBD>ˤϥǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ<EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>ɥ<EFBFBD>򥻥åȤ<EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƥۤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Х֥<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
*/
int
read_indirect(blkno, level, buf, count)
ino_t blkno;
int level;
void **buf;
int count;
{
daddr_t idblk[MAXBSIZE / sizeof(daddr_t)];
int i;
RAW_READ(idblk,
dbtob(fsbtodb(&sblock, blkno)),
sblock.fs_bsize);
for (i = 0; i < NINDIR(&sblock) && count > 0; i++) {
if (level) {
/* <20><><EFBFBD><EFBFBD><EFBFBD>˴<EFBFBD><CBB4>ܥ֥<DCA5><D6A5>å<EFBFBD><C3A5><EFBFBD><EFBFBD>ɤޤ<C9A4><DEA4><EFBFBD> */
count = read_indirect(idblk[i], level - 1, buf, count);
} else {
/* <20>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ<EFBFBD> */
#ifdef DEBUG
printf("%d%4d\n", level, idblk[i]);
#endif
raw_read_queue(*buf,
dbtob(fsbtodb(&sblock, idblk[i])),
sblock.fs_bsize);
*buf += sblock.fs_bsize;
count -= sblock.fs_bsize;
}
}
return count;
}
/*
* <EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ANSI C <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥʤ<EFBFBD><EFBFBD><EFBFBD>ư<EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD>(?)
*/
void
read_blocks(struct dinode *dp, void *buf, int count)
{
int i;
if (dp->di_size < count)
count = dp->di_size;
s_len = 0;
/* direct block <20><><EFBFBD>ɤ<EFBFBD> */
for (i = 0; i < NDADDR && count > 0; i++) {
#ifdef DEBUG
printf(" %4d\n", dp->di_db[i]);
#endif
raw_read_queue(buf,
dbtob(fsbtodb(&sblock, dp->di_db[i])),
sblock.fs_bsize);
buf += sblock.fs_bsize;
count -= sblock.fs_bsize;
}
/* indirect block <20><><EFBFBD>ɤ<EFBFBD> */
for (i = 0; i < NIADDR && count > 0; i++) {
count = read_indirect(dp->di_ib[i], i, &buf, count);
}
/* <20>Хåե<C3A5><D5A5>Υե<CEA5><D5A5>å<EFBFBD><C3A5><EFBFBD> */
raw_read_queue(NULL, 0, 0);
}
/***************************************************************
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>줿<EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> inode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
*/
ino_t
search_file(dirino, filename)
ino_t dirino; /* <20>ǥ<EFBFBD><C7A5><EFBFBD>ȥ<EFBFBD><C8A5>ΰ<EFBFBD><CEB0><EFBFBD> */
const char *filename; /* <20>ե<EFBFBD><D5A5><EFBFBD><EFBFBD><EFBFBD>̾ */
{
void *dirp;
struct dinode dinode;
struct direct *dir;
get_inode(dirino, &dinode);
dirp = alloca((dinode.di_size + MAXBSIZE - 1) & -MAXBSIZE);
read_blocks(&dinode, dirp, dinode.di_size);
while (dir = dirp, dir->d_ino != 0) {
if (!strcmp(dir->d_name, filename))
return dir->d_ino;
dirp += dir->d_reclen;
}
return 0;
}
/***************************************************************
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>줿<EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>
*
*/
unsigned
load(buf, dirino, filename)
void *buf; /* <20>ɤ߹<C9A4><DFB9><EFBFBD><EFBFBD><EFBFBD> */
ino_t dirino; /* <20><><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD> inode <20>ֹ<EFBFBD> */
const char *filename; /* <20>ե<EFBFBD><D5A5><EFBFBD><EFBFBD><EFBFBD>̾ */
{
struct dinode dinode;
get_inode(search_file(dirino, filename), &dinode);
read_blocks(&dinode, buf, dinode.di_size);
return dinode.di_size;
}
/***************************************************************
*
* for test
*
* <EFBFBD><EFBFBD><EFBFBD>ΤȤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vmunix <EFBFBD>ϥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܥ<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD>󥯤ϵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ū<EFBFBD>ˤϤɤ<EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
*/
void
debug_print(s)
unsigned char *s;
{
unsigned c;
while ((c = *s++)) {
if (c >= 0x80)
c = JISSFT((0x0100 * c + *s++) & 0x7F7F);
B_PUTC(c);
}
}
void
debug_print_hex(x, l)
unsigned x; /* ɽ<><C9BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
int l; /* ɽ<><C9BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
{
if (l >= 0) {
debug_print_hex(x >> 4, l - 1);
x &= 0x0F;
if (x > 9)
x += 7;
B_PUTC('0' + x);
}
}
/***************************************************************
*
* vmunix.* netbsd.* <EFBFBD>Υ<EFBFBD>Ȥ<EFBFBD><EFBFBD>Ĥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD>
*
*/
void
pickup_list(dirino)
ino_t dirino;
{
void *dirp;
struct dinode dinode;
struct direct *dir;
int n = 0;
get_inode(dirino, &dinode);
dirp = alloca((dinode.di_size + MAXBSIZE - 1) & -MAXBSIZE);
read_blocks(&dinode, dirp, dinode.di_size);
while (dir = dirp, dir->d_ino != 0) {
if (!memcmp(dir->d_name, "vmunix", 6)
|| !memcmp(dir->d_name, "netbsd", 6)) {
vmunix_dirent[n].ino = dir->d_ino;
memcpy(vmunix_dirent[n].name, dir->d_name, 60);
if (++n >= N_VMUNIX)
return;
}
dirp += dir->d_reclen;
}
while (n < N_VMUNIX)
vmunix_dirent[n++].ino = 0;
}
/***************************************************************
*
* vmunix_dirent[] <EFBFBD>Υ<EFBFBD><EFBFBD><EFBFBD>ɤ<EFBFBD>ɽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
*/
void
print_list(n, active, bootflags)
int n;
int active;
unsigned bootflags;
{
if (!vmunix_dirent[n].ino)
return;
B_LOCATE(0, 4 + n);
B_PRINT(active && (bootflags & RB_SINGLE)
? "SINGLE "
: " ");
debug_print_hex(vmunix_dirent[n].ino, 8);
B_PRINT(" ");
if (active)
B_COLOR(0x0F);
B_PRINT(vmunix_dirent[n].name);
B_COLOR(0x03);
}
/***************************************************************
*
* <EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD>٤Ƥ<EFBFBD> IPL <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥϡ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>֥<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ž<EFBFBD><EFBFBD><EFBFBD>פ<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤǤϡ<EFBFBD>
* x68k IOCS <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߤ<EFBFBD><EFBFBD>ޥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤǤ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>פǤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
*/
volatile void
bootufs()
{
unsigned long bootflags;
unsigned long esym;
int i;
char *addr;
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0x100000 <20><><EFBFBD><EFBFBD>¸<EFBFBD>ߤ<EFBFBD><DFA4>Ƥ<EFBFBD><C6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
extern struct exec header;
extern char image[];
#if 0
/* for debug; <20><>ư<EFBFBD><C6B0><EFBFBD>Υ<CEA5><ECA5B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>äƤ<C3A4><C6A4><EFBFBD> */
extern long tmpbuf[16];
#endif
extern long ID;
unsigned short SFT;
/* <20><><EFBFBD><EFBFBD><EFBFBD>ϥ<EFBFBD><CFA5>ԡ<EFBFBD><D4A1><EFBFBD> */
struct exec localheader;
/* MPU <20><><EFBFBD><EFBFBD><EFBFBD>å<EFBFBD> */
#if 0
sys_stat = SYS_STAT(0);
if ((sys_stat & 255) == 0 ||
(getcpu() != 4 && !(sys_stat & (1 << 14)))) {
debug_print("MMU <20><><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD>ᡢNetBSD <20><><EFBFBD><EFBFBD>ư<EFBFBD>Ǥ<EFBFBD><C7A4>ޤ<EFBFBD><DEA4><EFBFBD><EFBFBD><EFBFBD>\r\n");
debug_print("<EFBFBD><EFBFBD>åȤ<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\r\n");
for(;;);
}
#endif
debug_print("\r\n");
/* bootflags <20>򥻥å<F2A5BBA5> */
bootflags = RB_AUTOBOOT;
/* <20><><EFBFBD>եȥ<D5A5><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD><C6A4><EFBFBD><EFBFBD><EFBFBD> */
SFT = B_SFTSNS();
if (SFT & 0x01)
bootflags |= RB_SINGLE;
#if 0
/* for debug; <20><EFBFBD><ECA5B8><EFBFBD><EFBFBD><EFBFBD>ξ<EFBFBD><CEBE>֤<EFBFBD><D6A4>ץ<EFBFBD><D7A5><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4><EFBFBD> */
for (i = 0; i < 16; i++) {
debug_print_hex(tmpbuf[i], 8);
debug_print("\r\n");
}
#endif
/* vmunix <20><><EFBFBD>ɤ߹<C9A4><DFB9><EFBFBD><EFBFBD>Ǥ<EFBFBD><C7A4><EFBFBD> */
get_superblk();
if (sblock.fs_magic != FS_MAGIC) {
debug_print("sdboot: bogus super block;"
" <20><EFBFBD>ȥե<C8A5><D5A5><EFBFBD><EFBFBD><EFBFBD><EBA5B7><EFBFBD>ƥब<C6A5><E0A4AC><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD><C6A4>ޤ<EFBFBD><DEA4><EFBFBD>\r\n");
debug_print("<EFBFBD><EFBFBD>åȤ<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\r\n");
for (;;);
}
if (bootflags == RB_AUTOBOOT) {
debug_print("loading netbsd...");
esym = load(&header, ROOTINO, "netbsd");
SFT = B_SFTSNS();
if (SFT & 0x0001)
bootflags |= RB_SINGLE;
}
if (bootflags != RB_AUTOBOOT) {
int x = 0;
struct dinode dinode;
B_CLR_ST(2);
debug_print("....<2E>ɤΥ<C9A4><CEA5><EFBFBD><EFBFBD>ͥ<EFBFBD><CDA5><EFBFBD><EFBFBD>ɤ߹<C9A4><DFB9>ߤޤ<DFA4><DEA4><EFBFBD><EFBFBD><EFBFBD>\r\n"
"SHIFT <20><> RB_SINGLE <20><><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>\r\n");
/* <20><EFBFBD>ȥǥ<C8A5><C7A5><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϥ<EFBFBD><CFA4><EFBFBD> */
pickup_list(ROOTINO);
/* ɽ<><C9BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
for (i = 0; i < N_VMUNIX; i++) {
if (!memcmp(vmunix_dirent[i].name, "netbsd", 7)) {
print_list(x, 0, bootflags);
x = i;
}
print_list(i, i == x, bootflags);
}
while (B_SFTSNS() & 0x0001);
/* <20><><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD>פ<EFBFBD><D7A4><EFBFBD> */
for (;;) {
switch ((B_KEYINP() >> 8) & 0xFF) {
case 0x3C: /* UP */
if (x > 0) {
print_list(--x, 1, bootflags);
print_list(x + 1, 0, bootflags);
}
break;
case 0x3E: /* DOWN */
if (x < N_VMUNIX - 1
&& vmunix_dirent[x + 1].ino) {
print_list(++x, 1, bootflags);
print_list(x - 1, 0, bootflags);
}
break;
case 0x70: /* SHIFT */
bootflags ^= RB_SINGLE;
print_list(x, 1, bootflags);
break;
case 0x1D: /* CR */
case 0x4E: /* ENTER */
goto exit_loop;
}
}
exit_loop:
B_CLR_ST(2);
B_PRINT("loading ");
B_PRINT(vmunix_dirent[x].name);
B_PRINT("...");
get_inode(vmunix_dirent[x].ino, &dinode);
read_blocks(&dinode, &header, dinode.di_size);
esym = dinode.di_size;
}
debug_print("done.\r\n");
/* <20>֤Ҥ餬<D2A4>ʡפǡ<D7A4>ddb <20>򵯤<EFBFBD><F2B5AFA4><EFBFBD> */
SFT = B_SFTSNS();
if (SFT & 0x2000)
bootflags |= RB_KDB;
/* esym == 32 + tsize + dsize + ssize + strsize */
/* <20>إå<D8A5><C3A5>򥳥ԡ<F2A5B3A5><D4A1><EFBFBD><EFBFBD><EFBFBD> */
localheader = header;
#define x localheader
esym -= sizeof(header) + localheader.a_text + localheader.a_data;
/* esym == ssize + strsize */
/* <20><><EFBFBD>Τ򥳥<CEA4><F2A5B3A5><EFBFBD> load <20><><EFBFBD><EFBFBD> */
if (N_GETMID(localheader) == MID_M68K
&& N_GETMAGIC(localheader) == NMAGIC) {
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶ػߤǤ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥ<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD>
*/
asm volatile ("oriw #0x0700,sr");
addr = lowram;
memcpy(addr, image, x.a_text);
addr += (x.a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1);
memcpy(addr, image + x.a_text, x.a_data);
addr += x.a_data;
memset(addr, 0x00, x.a_bss);
addr += x.a_bss;
/*ssym = addr;*/
bcopy(&x.a_syms, addr, sizeof(x.a_syms));
addr += sizeof(x.a_syms);
bcopy(image + x.a_text + x.a_data, addr, x.a_syms);
addr += x.a_syms;
i = *(int *)(image + x.a_text + x.a_data + x.a_syms);
bcopy(image + x.a_text + x.a_data + x.a_syms, addr, sizeof(int));
if (i) {
i -= sizeof(int);
addr += sizeof(int);
bcopy(image + x.a_text + x.a_data + x.a_syms + sizeof(int), addr, i);
addr += i;
}
#define round_to_size(x) \
(((int)(x) + sizeof(int) - 1) & ~(sizeof(int) - 1))
esym = (unsigned long)round_to_size(addr - lowram);
#undef round_to_size
memset(esym, 0, 0x003e8000 - (int)esym /* XXX */);
IODEVbase->io_mfp.iera = 0;
IODEVbase->io_mfp.ierb = 0;
IODEVbase->io_mfp.rsr = 0;
/* IODEVbase->io_sysport.keyctrl = 0;*/
/* <20>¹<EFBFBD> */
asm volatile ("movl %0,d6" : : "g" (MAKEBOOTDEV(4, 0, 0, ID & 7, 0)) : "d6");
asm volatile ("movl %0,d7" : : "g" (bootflags) : "d7");
/* <20><><EFBFBD>ޤ<EFBFBD> */
(*(void volatile (*)(long, long, long))localheader.a_entry)
(0, *(long *)0xED0008, esym);
} else {
debug_print("sdboot: improper file format: <20>¹<EFBFBD><C2B9>Բ<EFBFBD>ǽ<EFBFBD>Ǥ<EFBFBD><C7A4><EFBFBD>\r\n");
debug_print("<EFBFBD><EFBFBD>åȤ<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\r\n");
for (;;);
}
}
/* eof */