/*-
* Copyright (c) 1998 Robert Nordier
* All rights reserved.
*
* Redistribution and use in source and binary forms are freely
* permitted provided that the above copyright notice and this
* paragraph and the following disclaimer are duplicated in all
* such forms.
*
* This software is provided "AS IS" and without any express or
* implied warranties, including, without limitation, the implied
* warranties of merchantability and fitness for a particular
* purpose.
*/
#include <stand.h>
#include <multiboot.h>
#include <machine/bootinfo.h>
#include <stdarg.h>
#include <stddef.h>
#include <a.out.h>
#include "bootstrap.h"
#include "libi386.h"
#include <btxv86.h>
#include "lib.h"
#include "rbx.h"
#include "cons.h"
#include "bootargs.h"
#include "disk.h"
#include "part.h"
#include "paths.h"
#include "libzfs.h"
#define TYPE_AD 0
/*
* Fake multiboot header to provide versioning and to pass
* partition start LBA. Partition is either GPT partition or
* VTOC slice.
*/
extern const struct multiboot_header mb_header;
extern uint64_t start_sector;
};
extern vm_offset_t high_heap_base;
static char *heap_top;
static char *heap_bottom;
static void i386_zfs_probe(void);
void exit(int);
static void load(void);
static int parse_cmd(void);
&biosdisk,
&zfs_dev,
};
};
/*
* probe arguments for partition iterator (see below)
*/
struct probe_args {
int fd;
char *devname;
};
/*
* simple wrapper around read() to avoid using device specific
* strategy() directly.
*/
static int
{
return (0);
return (EIO);
}
/*
* scan partition entries to find boot partition starting at start_sector.
* in case of MBR partition type PART_SOLARIS2, read VTOC and recurse.
*/
static int
const struct ptable_entry *part)
{
int ret = 0;
return (ret);
}
if (ret) {
return (ret);
}
}
}
return (ret);
}
/*
* open partition table on disk and scan partition entries to find
* boot partition starting at start_sector (recorded by installboot).
*/
static int
{
int ret;
return (ENXIO);
}
if (ret == 0)
if (ret == 0) {
}
}
return (ret);
}
int
main(void)
{
bios_getmem();
if (high_heap_size > 0) {
} else {
heap_bottom = (char *)
}
/*
* Initialise the block cache. Set the upper limit.
*/
/*
* dont init zfs yet, need to run through probe_disk(), then init
* zfs with probing boot device by name first.
*/
/*
* detect partition from boot disk and start_sector
*/
if (!ret)
printf("start sector %llu does not match any partition on device: %s\n",
/*
* check for zfs on boot partition, we need to make sure this is
* the first registered pool.
*/
/*
* zfs_fmtdev() can be called only after dv_init
*/
/* set up proper device name string for ZFS */
}
/* now make sure we have bdev on all cases */
/* Process configuration file */
auto_boot = 1;
if (fd == -1)
if (fd != -1) {
}
if (*cmd) {
/*
* Note that parse_cmd() is destructive to cmd[] and we also want
* to honor RBX_QUIET option that could be present in cmd[].
*/
if (parse_cmd())
auto_boot = 0;
/* Do not process this command twice */
*cmd = 0;
}
/*
* Try to exec stage 3 boot loader. If interrupted by a keypress,
* or in case of failure, switch off auto boot.
*/
if (!keyhit(3)) {
load();
auto_boot = 0;
}
}
/* Present the user with the boot2 prompt. */
for (;;) {
}
sio_flush();
putchar('\n');
auto_boot = 0;
if (parse_cmd())
putchar('\a');
else
load();
}
}
/* XXX - Needed for btxld to link the boot2 binary; do not remove. */
void
exit(int x)
{
}
static void
load(void)
{
union {
} hdr;
caddr_t p;
return;
}
return;
}
fmt = 0;
fmt = 1;
else {
return;
}
if (fmt == 0) {
return;
}
return;
}
return;
}
return;
}
x = *(uint32_t *)p;
p += sizeof(int);
x -= sizeof(int);
return;
}
p += x;
}
} else {
return;
}
j++;
}
for (i = 0; i < 2; i++) {
return;
}
}
SEEK_SET);
return;
}
for (i = 0; i < 2; i++) {
return;
}
}
}
}
zfsargs);
} else
}
static int
{
char *root;
return (1);
return (1);
}
/* we should have new device descriptor, free old and replace it. */
part = 0xff;
else
}
return (0);
}
static void
{
int fd;
struct dirent *d;
if (fd < 0)
return;
pager_open();
if (pager_output(line))
break;
}
pager_close();
}
static int
parse_cmd(void)
{
char *ep, *p, *q;
const char *cp;
int c, i, j;
while ((c = *arg++)) {
if (c == ' ' || c == '\t' || c == '\n')
continue;
ep = p;
if (*p)
*p++ = 0;
if (c == '-') {
while ((c = *arg++)) {
if (c == 'P') {
cp = "yes";
} else {
cp = "no";
}
continue;
} else if (c == 'S') {
j = 0;
j = j * 10 + i;
if (j > 0 && i == -'0') {
comspeed = j;
break;
}
/* Fall through to error below ('S' not in optstr[]). */
}
for (i = 0; c != optstr[i]; i++)
if (i == NOPT - 1)
return -1;
}
}
} if (c == '?') {
printf("\n");
return -1;
} else {
arg--;
/*
* Report pool status if the comment is 'status'. Lets
* hope no-one wants to load /status as a kernel.
*/
pager_open();
if (pager_output(line))
break;
break;
} else {
if (pager_output(line))
break;
}
}
pager_close();
return -1;
}
/*
* If there is a colon, switch pools.
*/
else
if (q) {
*q++ = '\0';
if (mount_root(arg) != 0)
return -1;
arg = q;
}
return -1;
}
}
arg = p;
}
return 0;
}
static void
i386_zfs_probe(void)
{
int unit;
/*
* Open all the disks we can find and see if we can reconstruct
* ZFS pools from them. We start from boot device to get boot pool_guid.
*/
if (pool_guid) {
}
break;
}
}