2 * Mach Operating System
3 * Copyright (c) 1992, 1991 Carnegie Mellon University
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
26 * from: Mach, Revision 2.2 92/04/04 11:36:34 rpd
27 * $FreeBSD: src/sys/boot/pc98/boot2/sys.c,v 1.2.2.1 2003/01/13 08:52:53 nyan Exp $
28 * $DragonFly: src/sys/boot/pc98/boot2/Attic/sys.c,v 1.2 2003/06/17 04:28:18 dillon Exp $
32 * Ported to PC-9801 by Yoshio Kimura
36 #include <sys/dirent.h>
37 #include <sys/reboot.h>
40 /* #define BUFSIZE 4096 */
41 #define BUFSIZE MAXBSIZE
42 static char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
45 static char biosdrivedigit;
48 #define MAPBUFSIZE BUFSIZE
49 static char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
51 static char mapbuf[MAPBUFSIZE];
57 #define STARTBYTE 8192 /* Where on the media the kernel starts */
60 static int block_map(int file_block);
61 static int find(char *path);
64 xread(char *addr, int size)
71 pcpy(buf, addr, count);
79 read(char *buffer, int count)
85 while (count > 0 && poff < inode.i_size) {
87 off = blkoff(fs_copy, poff);
88 logno = lblkno(fs_copy, poff);
89 cnt2 = size = blksize(fs_copy, &inode, logno);
90 bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
91 if ( (!off) && (size <= count)) {
92 devread(buffer, bnum2, cnt2);
97 devread(iobuf, bnum2, cnt2);
98 bcopy(iobuf+off, buffer, size);
107 read(char *buffer, int count)
109 int cnt, bnum, off, size;
111 off = STARTBYTE + poff;
114 /* Read any unaligned bit at the front */
120 devread(iobuf, off >> 9, 512);
121 bcopy(iobuf+cnt, buffer, size);
126 size = count & (~511);
127 if (size && (off & (~511))) {
128 devread(buffer, off >> 9, size);
134 devread(iobuf, off >> 9, 512);
135 bcopy(iobuf, buffer, count);
144 int block, off, loc, ino = ROOTINO;
148 list_only = (path[0] == '?' && path[1] == '\0');
150 devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
151 bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
152 (void *)&inode.i_din,
153 sizeof (struct dinode));
158 if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
160 for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
164 if (loc >= inode.i_size) {
172 if (!(off = blkoff(fs, loc))) {
173 block = lblkno(fs, loc);
174 devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
175 blksize(fs, &inode, block));
177 dp = (struct dirent *)(iobuf + off);
179 if (dp->d_fileno && list_only)
180 printf("%s ", dp->d_name);
181 } while (!dp->d_fileno || strcmp(path, dp->d_name));
189 block_map(int file_block)
192 if (file_block < NDADDR)
193 return(inode.i_db[file_block]);
194 if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
195 devread(mapbuf, bnum, fs->fs_bsize);
198 return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
205 char **devp, *name0 = name, *cp = name0;
206 int biosdrive, dosdev_copy, ret;
208 /*******************************************************\
209 * If bracket given look for preceding device name *
210 \*******************************************************/
211 while (*cp && *cp!='(')
220 * Look for a BIOS drive number (a leading digit followed
223 biosdrivedigit = '\0';
224 if (*(name0 + 1) == ':' && *name0 >= '0' && *name0 <= '9') {
225 biosdrivedigit = *name0;
231 for (devp = devs; *devp; devp++)
232 if (name0[0] == (*devp)[0] &&
233 name0[1] == (*devp)[1])
237 printf("Unknown device\n");
242 /*******************************************************\
243 * Look inside brackets for unit number, and partition *
244 \*******************************************************/
246 * Allow any valid digit as the unit number, as the BIOS
247 * will complain if the unit number is out of range.
248 * Restricting the range here prevents the possibilty of using
249 * BIOSes that support more than 2 units.
250 * XXX Bad values may cause strange errors, need to check if
251 * what happens when a value out of range is supplied.
253 if (*cp >= '0' && *cp <= '9')
255 if (!*cp || (*cp == ',' && !*++cp))
257 if (*cp >= 'a' && *cp <= 'p')
259 while (*cp && *cp++!=')') ;
263 biosdrive = biosdrivedigit - '0';
264 if (biosdrivedigit == '\0') {
266 biosdrive = dosdev & 0x0f;
273 biosdrive += BOOT_HD_BIAS;
280 dosdev_copy = biosdrive | 0xA0; /* SCSI HD or MO */
284 dosdev_copy = biosdrive | 0x80;
289 case 2: /* 1200KB fd */
290 dosdev_copy = (maj << 3) | unit | 0x80;
293 dosdev_copy = biosdrive;
297 case 6: /* 1440KB fd */
298 dosdev_copy = (maj << 3) | unit;
302 printf("Unknown device\n");
305 dosdev = dosdev_copy;
307 /* XXX this is useful, but misplaced. */
308 printf("dosdev= %x, biosdrive = %d, unit = %d, maj = %d\n",
309 dosdev_copy, biosdrive, unit, maj);
312 /***********************************************\
313 * Now we know the disk unit and part, *
314 * Load disk info, (open the device) *
315 \***********************************************/
320 /***********************************************\
321 * Load Filesystem info (mount the device) *
322 \***********************************************/
323 devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
324 /***********************************************\
325 * Find the actual FILE on the mounted device *
326 \***********************************************/