#define LIBSTAND 1
#endif
+#ifdef BOOT2
+#include "boot2.h"
+#else
#include <sys/param.h>
-
#include <stddef.h>
#include <stdint.h>
+#endif
#ifdef TESTING
#include <sys/fcntl.h>
#else /* BOOT2 */
-struct dmadat {
- char secbuf[DEV_BSIZE];
+struct hammer_dmadat {
+ struct boot2_dmadat boot2;
char buf[HAMMER_BUFSIZE];
};
-static struct dmadat *dmadat;
+#define fsdmadat ((struct hammer_dmadat *)boot2_dmadat)
struct hfs {
hammer_off_t root;
static void *
hread(struct hfs *hfs, hammer_off_t off)
{
- char *buf = dmadat->buf;
+ char *buf = fsdmadat->buf;
hammer_off_t boff = off & ~HAMMER_BUFMASK64;
boff &= HAMMER_OFF_LONG_MASK;
struct hfs hfs;
static int
-hammerinit(void)
+boot2_hammer_init(void)
{
- if (dsk_meta)
- return (0);
+ hammer_volume_ondisk_t volhead;
- hammer_volume_ondisk_t volhead = hread(&hfs, HAMMER_ZONE_ENCODE(1, 0));
+ volhead = hread(&hfs, HAMMER_ZONE_ENCODE(1, 0));
if (volhead == NULL)
return (-1);
if (volhead->vol_signature != HAMMER_FSBUF_VOLUME)
return (-1);
hfs.root = volhead->vol0_btree_root;
hfs.buf_beg = volhead->vol_buf_beg;
- dsk_meta++;
return (0);
}
-static ino_t
-lookup(const char *path)
+static boot2_ino_t
+boot2_hammer_lookup(const char *path)
{
- hammerinit();
-
ino_t ino = hlookup(&hfs, path);
if (ino == -1)
}
static ssize_t
-fsread(ino_t ino, void *buf, size_t len)
+boot2_hammer_read(boot2_ino_t ino, void *buf, size_t len)
{
- hammerinit();
-
ssize_t rlen = hreadf(&hfs, ino, fs_off, len, buf);
if (rlen != -1)
fs_off += rlen;
return (rlen);
}
+
+const struct boot2_fsapi boot2_hammer_api = {
+ .fsinit = boot2_hammer_init,
+ .fslookup = boot2_hammer_lookup,
+ .fsread = boot2_hammer_read
+};
+
#endif
#ifndef BOOT2
--- /dev/null
+/*
+ * Copyright (c) 2009 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ *
+ * 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. Neither the name of The DragonFly Project 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDERS 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.
+ */
+/*
+ * boot2 encapsulated ABI. The boot2 standalone code provides these functions
+ * to the boot2 add-on modules (ufsread.c and hammerread.c).
+ */
+
+#ifndef _BOOT_COMMON_BOOT2_H_
+#define _BOOT_COMMON_BOOT2_H_
+
+
+#include <sys/param.h>
+#include <sys/dtype.h>
+#include <sys/dirent.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <machine/bootinfo.h>
+#include <machine/elf.h>
+
+/*
+ * We only need a 32 bit ino_t for UFS-only boot code. We have to squeeze
+ * space usage, else we'd just use 64 bits across the board.
+ */
+#if defined(HAMMERFS)
+typedef uint64_t boot2_ino_t;
+#else
+typedef uint32_t boot2_ino_t;
+#endif
+
+struct boot2_fsapi {
+ int (*fsinit)(void);
+ boot2_ino_t (*fslookup)(const char *);
+ ssize_t (*fsread)(boot2_ino_t, void *, size_t);
+};
+
+struct boot2_dmadat {
+ char secbuf[DEV_BSIZE];
+ /* extended by *fsread() modules */
+};
+
+extern uint32_t fs_off;
+extern int ls;
+extern int dsk_meta;
+extern struct boot2_dmadat *boot2_dmadat;
+
+extern int dskread(void *, unsigned, unsigned);
+extern void printf(const char *,...);
+extern void putchar(int);
+extern int strcmp(const char *s1, const char *s2);
+extern void memcpy(void *d, const void *s, int len);
+
+#ifdef UFS
+extern const struct boot2_fsapi boot2_ufs_api;
+#endif
+#ifdef HAMMERFS
+extern const struct boot2_fsapi boot2_hammer_api;
+#endif
+
+#endif
typedef int64_t ufs2_daddr_t;
typedef int64_t ufs_lbn_t;
typedef int64_t ufs_time_t;
+typedef uint32_t ufs_ino_t;
/* File permissions. */
#define IEXEC 0000100 /* Executable. */
* $DragonFly: src/sys/boot/common/ufsread.c,v 1.5 2008/09/13 11:46:28 corecode Exp $
*/
+#ifdef BOOT2
+#include "boot2.h"
+#else
+#include <sys/param.h>
+#endif
+#include <sys/dtype.h>
+#include <sys/dirent.h>
+#include <machine/bootinfo.h>
+#include <machine/elf.h>
#include <vfs/ufs/dir.h>
#include "dinode.h"
#include "fs.h"
+
#ifdef __i386__
/* XXX: Revert to old (broken for over 1.5Tb filesystems) version of cgbase
(see sys/ufs/ffs/fs.h rev 1.39) so that i386 boot loader (boot2) can
#define FS_TO_VBO(fs, fsb, off) ((off) & VBLKMASK)
/* Buffers that must not span a 64k boundary. */
-struct dmadat {
+struct ufs_dmadat {
+ struct boot2_dmadat boot2;
char blkbuf[VBLKSIZE]; /* filesystem blocks */
char indbuf[VBLKSIZE]; /* indir blocks */
char sbbuf[SBLOCKSIZE]; /* superblock */
- char secbuf[DEV_BSIZE]; /* for MBR/disklabel */
};
-static struct dmadat *dmadat;
-static ino_t lookup(const char *);
-static ssize_t fsread(ino_t, void *, size_t);
+#define fsdmadat ((struct ufs_dmadat *)boot2_dmadat)
+
+static boot2_ino_t boot2_ufs_lookup(const char *);
+static ssize_t boot2_ufs_read(boot2_ino_t, void *, size_t);
+static int boot2_ufs_init(void);
+
+const struct boot2_fsapi boot2_ufs_api = {
+ .fsinit = boot2_ufs_init,
+ .fslookup = boot2_ufs_lookup,
+ .fsread = boot2_ufs_read
+};
static __inline__ int
-fsfind(const char *name, ino_t * ino)
+fsfind(const char *name, ufs_ino_t *ino)
{
char buf[DEV_BSIZE];
struct direct *d;
ssize_t n;
fs_off = 0;
- while ((n = fsread(*ino, buf, DEV_BSIZE)) > 0)
+ while ((n = boot2_ufs_read(*ino, buf, DEV_BSIZE)) > 0)
for (s = buf; s < buf + DEV_BSIZE;) {
d = (void *)s;
if (ls)
return 0;
}
-static ino_t
-lookup(const char *path)
+static boot2_ino_t
+boot2_ufs_lookup(const char *path)
{
char name[MAXNAMLEN + 1];
const char *s;
- ino_t ino;
+ ufs_ino_t ino;
ssize_t n;
int dt;
#define DIP(field) fs->fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field
#endif
+static ufs_ino_t inomap;
+static ufs2_daddr_t blkmap, indmap;
+
+static int
+boot2_ufs_init(void)
+{
+ struct fs *fs;
+ size_t n;
+
+ fs = (struct fs *)fsdmadat->sbbuf;
+
+ for (n = 0; sblock_try[n] != -1; n++) {
+ if (dskread(fs, sblock_try[n] / DEV_BSIZE,
+ SBLOCKSIZE / DEV_BSIZE)) {
+ return -1;
+ }
+ if ((
+#if defined(UFS1_ONLY)
+ fs->fs_magic == FS_UFS1_MAGIC
+#elif defined(UFS2_ONLY)
+ (fs->fs_magic == FS_UFS2_MAGIC &&
+ fs->fs_sblockloc == sblock_try[n])
+#else
+ fs->fs_magic == FS_UFS1_MAGIC ||
+ (fs->fs_magic == FS_UFS2_MAGIC &&
+ fs->fs_sblockloc == sblock_try[n])
+#endif
+ ) &&
+ fs->fs_bsize <= MAXBSIZE &&
+ fs->fs_bsize >= sizeof(struct fs))
+ break;
+ }
+ if (sblock_try[n] == -1)
+ return -1;
+ return 0;
+}
+
static ssize_t
-fsread(ino_t inode, void *buf, size_t nbyte)
+boot2_ufs_read(boot2_ino_t boot2_inode, void *buf, size_t nbyte)
{
#ifndef UFS2_ONLY
static struct ufs1_dinode dp1;
#ifndef UFS1_ONLY
static struct ufs2_dinode dp2;
#endif
- static ino_t inomap;
+ ufs_ino_t ufs_inode = (ufs_ino_t)boot2_inode;
char *blkbuf;
void *indbuf;
struct fs *fs;
size_t n, nb, size, off, vboff;
ufs_lbn_t lbn;
ufs2_daddr_t addr, vbaddr;
- static ufs2_daddr_t blkmap, indmap;
u_int u;
+ blkbuf = fsdmadat->blkbuf;
+ indbuf = fsdmadat->indbuf;
+ fs = (struct fs *)fsdmadat->sbbuf;
- blkbuf = dmadat->blkbuf;
- indbuf = dmadat->indbuf;
- fs = (struct fs *)dmadat->sbbuf;
- if (!dsk_meta) {
- inomap = 0;
- for (n = 0; sblock_try[n] != -1; n++) {
- if (dskread(fs, sblock_try[n] / DEV_BSIZE,
- SBLOCKSIZE / DEV_BSIZE))
- return -1;
- if ((
-#if defined(UFS1_ONLY)
- fs->fs_magic == FS_UFS1_MAGIC
-#elif defined(UFS2_ONLY)
- (fs->fs_magic == FS_UFS2_MAGIC &&
- fs->fs_sblockloc == sblock_try[n])
-#else
- fs->fs_magic == FS_UFS1_MAGIC ||
- (fs->fs_magic == FS_UFS2_MAGIC &&
- fs->fs_sblockloc == sblock_try[n])
-#endif
- ) &&
- fs->fs_bsize <= MAXBSIZE &&
- fs->fs_bsize >= sizeof(struct fs))
- break;
- }
- if (sblock_try[n] == -1) {
- printf("Not ufs\n");
- return -1;
- }
- dsk_meta++;
- }
- if (!inode)
+ if (!ufs_inode)
return 0;
- if (inomap != inode) {
+ if (inomap != ufs_inode) {
n = IPERVBLK(fs);
- if (dskread(blkbuf, INO_TO_VBA(fs, n, inode), DBPERVBLK))
+ if (dskread(blkbuf, INO_TO_VBA(fs, n, ufs_inode), DBPERVBLK))
return -1;
- n = INO_TO_VBO(n, inode);
+ n = INO_TO_VBO(n, ufs_inode);
#if defined(UFS1_ONLY)
dp1 = ((struct ufs1_dinode *)blkbuf)[n];
#elif defined(UFS2_ONLY)
else
dp2 = ((struct ufs2_dinode *)blkbuf)[n];
#endif
- inomap = inode;
+ inomap = ufs_inode;
fs_off = 0;
blkmap = indmap = 0;
}
NXLDFLAGS=
.PATH: ${.CURDIR}/..
+.PATH: ${.CURDIR}/../../common
+.PATH: ${.CURDIR}/../../../../lib/libstand
# A value of 0x80 enables LBA support.
B1FLAGS= 0x80
-I${.CURDIR}/../btx/lib -I. \
-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
- -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
- -D__BOOT2_HACK
+ -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings
# Tell gcc that it shouldn't do fancy optimizations for newer processors.
# Otherwise it winds up creating larger code and we won't be able to fit boot2.
CFLAGS+= -fno-stack-protector
.endif
+# boot2 area in 32 bit disklabel is 16 sectors (8K)
+#
+# boot2 area in 64 bit disklabel is 64 sectors (32K).
+# However, the boot1 btx loader puts boot2 at a physical address
+# of MEM_BTX_USR+BOOT2_VORIGIN which is typically 0xC000, so we
+# cannot make boot2 any larger then 16KB or we overflow the segment.
+#
NSECT_32?= 16
-NSECT_64?= 18
+NSECT_64?= 30
LDFLAGS=-nostdlib -static -N --gc-sections
all: boot
_ts= $s
.if ${_ts} == "_64"
_ADDCFLAGS$s+= -DDISKLABEL64
-_ADDCFLAGS$s+= -DHAMMERFS
+_ADDCFLAGS$s+= -DHAMMERFS -DUFS
+_ADDOBJS$s+= hammerread$s.o ufsread$s.o
.else
-_ADDCFLAGS$s+= -DUFS1_ONLY
+_ADDCFLAGS$s+= -DUFS -DUFS1_ONLY
+_ADDOBJS$s+= ufsread$s.o
.endif
all: boot1$s boot2$s
boot2$s.bin: boot2$s.out
objcopy -S -O binary boot2$s.out ${.TARGET}
-boot2$s.out: boot2$s.o sio.o
+boot2$s.out: boot2$s.o sio.o ${_ADDOBJS$s}
${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} \
${BTX}/lib/crt0.o ${.ALLSRC}
boot2$s.o: boot2$s.h
CLEANFILES+= boot1$s boot1$s.out boot1$s.o \
- boot2$s boot2$s.ldr boot2$s.bin boot2$s.ld boot2$s.out boot2$s.o boot2$s.h boot2$s.s
+ boot2$s boot2$s.ldr boot2$s.bin \
+ boot2$s.ld boot2$s.out boot2$s.o boot2$s.h boot2$s.s \
+ ${_ADDOBJS$s}
+
+hammerread$s.o: hammerread.c
+ ${CC} ${CFLAGS} ${_ADDCFLAGS$s} ${.ALLSRC} -o ${.TARGET} -c
+
+ufsread$s.o: ufsread.c
+ ${CC} ${CFLAGS} ${_ADDCFLAGS$s} ${.ALLSRC} -o ${.TARGET} -c
.endfor
//
// Ok, we have a slice and drive in %dx now, so use that to locate and load
// boot2. %si references the start of the slice we are looking for, so go
-// ahead and load up the first 16 sectors (boot1 + boot2) from that.
+// ahead and load up the first N sectors (boot1 + boot2) from that.
+//
+// N is 16 for boot1 in a disklabel32 and up to 32 in a disklabel64. The
+// disklabel64 can hold up to 64 sectors but MEM_BTX_USR+BOOT2_VORIGIN
+// will overflow the segment if we use more then 32 sectors.
//
// When we read it in, we conveniently use BOOT2_LOAD_BUF (0x8c00) as our
// transfer buffer. Thus, boot1 ends up at 0x8c00, and boot2 starts at
* $FreeBSD: src/sys/boot/i386/boot2/boot2.c,v 1.64 2003/08/25 23:28:31 obrien Exp $
* $DragonFly: src/sys/boot/pc32/boot2/boot2.c,v 1.18 2008/09/13 11:45:45 corecode Exp $
*/
-#ifdef HAMMERFS
-#undef __BOOT2_HACK
-#endif
#include <sys/param.h>
#ifdef DISKLABEL64
#else
#include "boot2_32.h"
#endif
-
+#include "boot2.h"
#include "lib.h"
#include "../bootasm.h"
unsigned start;
int init;
} dsk;
+
static char cmd[512];
static char kname[1024];
-static uint32_t opts;
+static uint32_t opts = RBF_VIDEO;
static struct bootinfo bootinfo;
-static int ls, dsk_meta;
-static uint32_t fs_off;
+/*
+ * boot2 encapsulated ABI elements provided to *fsread.c
+ *
+ * NOTE: boot2_dmadat is extended by per-filesystem APIs
+ */
+uint32_t fs_off;
+int ls;
+struct boot2_dmadat *boot2_dmadat;
void exit(int);
static void load(void);
static int parse(void);
-static int xfsread(ino_t, void *, size_t);
-static int dskread(void *, unsigned, unsigned);
-static void printf(const char *,...);
-static void putchar(int);
+static int dskprobe(void);
+static int xfsread(boot2_ino_t, void *, size_t);
static uint32_t memsize(void);
static int drvread(void *, unsigned, unsigned);
static int keyhit(unsigned);
static int xgetc(int);
static int getc(int);
-static void
+void
memcpy(void *d, const void *s, int len)
{
char *dd = d;
#endif
}
-static inline int
+int
strcmp(const char *s1, const char *s2)
{
- for (; *s1 == *s2 && *s1; s1++, s2++);
- return (unsigned char)*s1 - (unsigned char)*s2;
+ for (; *s1 == *s2 && *s1; s1++, s2++)
+ ;
+ return ((int)((unsigned char)*s1 - (unsigned char)*s2));
}
-#if HAMMERFS
-#include "hammerread.c"
-#else
-#include "ufsread.c"
+#if defined(UFS) && defined(HAMMERFS)
+
+const struct boot2_fsapi *fsapi;
+
+#elif defined(UFS)
+
+#define fsapi (&boot2_ufs_api)
+
+#elif defined(HAMMERFS)
+
+#define fsapi (&boot2_hammer_api)
+
#endif
static int
-xfsread(ino_t inode, void *buf, size_t nbyte)
+xfsread(boot2_ino_t inode, void *buf, size_t nbyte)
{
- if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
+ if ((size_t)fsapi->fsread(inode, buf, nbyte) != nbyte) {
printf(INVALID_S, "format");
return -1;
}
main(void)
{
int autoboot;
- ino_t ino;
+ boot2_ino_t ino;
- dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
+ boot2_dmadat =
+ (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
v86.ctl = V86_FLAGS;
dsk.drive = *(uint8_t *)PTOV(MEM_BTX_USR_ARG);
dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
bootinfo.bi_extmem = memsize();
bootinfo.bi_memsizes_valid++;
- /* Process configuration file */
-
autoboot = 1;
- if ((ino = lookup(PATH_CONFIG)))
- fsread(ino, cmd, sizeof(cmd));
+ /*
+ * Probe the default disk and process the configuration file if
+ * successful.
+ */
+ if (dskprobe() == 0) {
+ if ((ino = fsapi->fslookup(PATH_CONFIG)))
+ fsapi->fsread(ino, cmd, sizeof(cmd));
+ }
+ /*
+ * Parse config file if present. parse() will re-probe if necessary.
+ */
if (cmd[0]) {
printf("%s: %s", PATH_CONFIG, cmd);
if (parse())
Elf32_Phdr ep[2];
Elf32_Shdr es[2];
caddr_t p;
- ino_t ino;
+ boot2_ino_t ino;
uint32_t addr, x;
int fmt, i, j;
- if (!(ino = lookup(kname))) {
+ if (!(ino = fsapi->fslookup(kname))) {
if (!ls)
printf("No %s\n", kname);
return;
}
static int
-parse()
+parse(void)
{
char *arg = cmd;
char *p, *q;
drv = dsk.unit;
dsk.drive = (dsk.type <= TYPE_MAXHARD
? DRV_HARD : 0) + drv;
- dsk_meta = 0;
}
if ((i = p - arg - !*(p - 1))) {
if ((size_t)i >= sizeof(kname))
}
arg = p;
}
- return 0;
+ return dskprobe();
}
static int
-dskread(void *buf, unsigned lba, unsigned nblk)
+dskprobe(void)
{
struct dos_partition *dp;
#ifdef DISKLABEL64
char *sec;
unsigned sl, i;
- if (!dsk_meta) {
- sec = dmadat->secbuf;
- dsk.start = 0;
- if (drvread(sec, DOSBBSECTOR, 1))
- return -1;
- dp = (void *)(sec + DOSPARTOFF);
- sl = dsk.slice;
- if (sl < BASE_SLICE) {
- for (i = 0; i < NDOSPART; i++)
- if (dp[i].dp_typ == DOSPTYP_386BSD &&
- (dp[i].dp_flag & 0x80 || sl < BASE_SLICE)) {
- sl = BASE_SLICE + i;
- if (dp[i].dp_flag & 0x80 ||
- dsk.slice == COMPATIBILITY_SLICE)
- break;
- }
- if (dsk.slice == WHOLE_DISK_SLICE)
- dsk.slice = sl;
- }
- if (sl != WHOLE_DISK_SLICE) {
- if (sl != COMPATIBILITY_SLICE)
- dp += sl - BASE_SLICE;
- if (dp->dp_typ != DOSPTYP_386BSD) {
- printf(INVALID_S, "slice");
- return -1;
+ /*
+ * Probe slice table
+ */
+ sec = boot2_dmadat->secbuf;
+ dsk.start = 0;
+ if (drvread(sec, DOSBBSECTOR, 1))
+ return -1;
+ dp = (void *)(sec + DOSPARTOFF);
+ sl = dsk.slice;
+ if (sl < BASE_SLICE) {
+ for (i = 0; i < NDOSPART; i++)
+ if (dp[i].dp_typ == DOSPTYP_386BSD &&
+ (dp[i].dp_flag & 0x80 || sl < BASE_SLICE)) {
+ sl = BASE_SLICE + i;
+ if (dp[i].dp_flag & 0x80 ||
+ dsk.slice == COMPATIBILITY_SLICE)
+ break;
}
- dsk.start = dp->dp_start;
+ if (dsk.slice == WHOLE_DISK_SLICE)
+ dsk.slice = sl;
+ }
+ if (sl != WHOLE_DISK_SLICE) {
+ if (sl != COMPATIBILITY_SLICE)
+ dp += sl - BASE_SLICE;
+ if (dp->dp_typ != DOSPTYP_386BSD) {
+ printf(INVALID_S, "slice");
+ return -1;
}
+ dsk.start = dp->dp_start;
+ }
+
+ /*
+ * Probe label and partition table
+ */
#ifdef DISKLABEL64
- if (drvread(sec, dsk.start, (sizeof(struct disklabel64) + 511) / 512))
- return -1;
- d = (void *)sec;
- if (d->d_magic != DISKMAGIC64) {
- printf(INVALID_S, "label");
+ if (drvread(sec, dsk.start, (sizeof(struct disklabel64) + 511) / 512))
+ return -1;
+ d = (void *)sec;
+ if (d->d_magic != DISKMAGIC64) {
+ printf(INVALID_S, "label");
+ return -1;
+ } else {
+ if (dsk.part >= d->d_npartitions || d->d_partitions[dsk.part].p_bsize == 0) {
+ printf(INVALID_S, "partition");
return -1;
- } else {
- if (dsk.part >= d->d_npartitions || d->d_partitions[dsk.part].p_bsize == 0) {
- printf(INVALID_S, "partition");
- return -1;
- }
- dsk.start += d->d_partitions[dsk.part].p_boffset / 512;
}
+ dsk.start += d->d_partitions[dsk.part].p_boffset / 512;
+ }
#else
- if (drvread(sec, dsk.start + LABELSECTOR32, 1))
- return -1;
- d = (void *)(sec + LABELOFFSET32);
- if (d->d_magic != DISKMAGIC32 || d->d_magic2 != DISKMAGIC32) {
- if (dsk.part != RAW_PART) {
- printf(INVALID_S, "label");
- return -1;
- }
- } else {
- if (!dsk.init) {
- if (d->d_type == DTYPE_SCSI)
- dsk.type = TYPE_DA;
- dsk.init++;
- }
- if (dsk.part >= d->d_npartitions ||
- !d->d_partitions[dsk.part].p_size) {
- printf(INVALID_S, "partition");
- return -1;
- }
- dsk.start += d->d_partitions[dsk.part].p_offset;
- dsk.start -= d->d_partitions[RAW_PART].p_offset;
+ if (drvread(sec, dsk.start + LABELSECTOR32, 1))
+ return -1;
+ d = (void *)(sec + LABELOFFSET32);
+ if (d->d_magic != DISKMAGIC32 || d->d_magic2 != DISKMAGIC32) {
+ if (dsk.part != RAW_PART) {
+ printf(INVALID_S, "label");
+ return -1;
+ }
+ } else {
+ if (!dsk.init) {
+ if (d->d_type == DTYPE_SCSI)
+ dsk.type = TYPE_DA;
+ dsk.init++;
}
+ if (dsk.part >= d->d_npartitions ||
+ !d->d_partitions[dsk.part].p_size) {
+ printf(INVALID_S, "partition");
+ return -1;
+ }
+ dsk.start += d->d_partitions[dsk.part].p_offset;
+ dsk.start -= d->d_partitions[RAW_PART].p_offset;
+ }
#endif
+ /*
+ * Probe filesystem
+ */
+#if defined(UFS) && defined(HAMMERFS)
+ if (boot2_hammer_api.fsinit() == 0) {
+ fsapi = &boot2_hammer_api;
+ } else if (boot2_ufs_api.fsinit() == 0) {
+ fsapi = &boot2_ufs_api;
+ } else {
+ printf("fs probe failed\n");
+ fsapi = &boot2_ufs_api;
+ return -1;
}
+ return 0;
+#else
+ return fsapi->fsinit();
+#endif
+}
+
+
+/*
+ * Read from the probed disk. We have established the slice and partition
+ * base sector.
+ */
+int
+dskread(void *buf, unsigned lba, unsigned nblk)
+{
return drvread(buf, dsk.start + lba, nblk);
}
-static void
+/*
+ * boot encapsulated ABI
+ */
+void
printf(const char *fmt,...)
{
va_list ap;
putchar(c);
}
va_end(ap);
- return;
}
-static void
+/*
+ * boot encapsulated ABI
+ */
+void
putchar(int c)
{
if (c == '\n')
xputc(c);
}
-static int
+/*
+ * boot encapsulated ABI
+ */
+int
drvread(void *buf, unsigned lba, unsigned nblk)
{
static unsigned c = 0x2d5c7c2f; /* twiddle */
/*
* This is the origin of boot2.bin relative to the BTX user address space
* (e.g. physical address would be MEM_BTX_USR+BOOT2_VORIGIN).
+ *
+ * The physical origin is typically around 0xC000 and limits the size of
+ * boot2 to 16K, otherwise the loader will overflow the segment in v86 mode.
*/
-#define BOOT2_VORIGIN 0x4000
+#define BOOT2_VORIGIN 0x2000
/*
* NOTE: BOOT0_ORIGIN is extracted from this file and used in boot0/Makefile
typedef __int64_t id_t; /* general id, can hold gid/pid/uid_t */
typedef __uint32_t in_addr_t; /* base type for internet address */
typedef __uint16_t in_port_t;
-#ifdef __BOOT2_HACK
-typedef __uint32_t ino_t; /* inode number */
-#else
typedef __uint64_t ino_t; /* inode number */
-#endif
typedef long key_t; /* IPC key (for Sys V IPC) */
typedef __uint16_t mode_t; /* permissions */
typedef __uint32_t nlink_t; /* link count */