199767f8919635c4928607450d9e0abb932109ceToomas Soome/*-
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 2008 John Hay
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 2006 M Warner Losh <imp@freebsd.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Robert Nordier
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms are freely
199767f8919635c4928607450d9e0abb932109ceToomas Soome * permitted provided that the above copyright notice and this
199767f8919635c4928607450d9e0abb932109ceToomas Soome * paragraph and the following disclaimer are duplicated in all
199767f8919635c4928607450d9e0abb932109ceToomas Soome * such forms.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This software is provided "AS IS" and without any express or
199767f8919635c4928607450d9e0abb932109ceToomas Soome * implied warranties, including, without limitation, the implied
199767f8919635c4928607450d9e0abb932109ceToomas Soome * warranties of merchantability and fitness for a particular
199767f8919635c4928607450d9e0abb932109ceToomas Soome * purpose.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/cdefs.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome__FBSDID("$FreeBSD$");
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/param.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/disklabel.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/diskmbr.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/dirent.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/reboot.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <machine/elf.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <stdarg.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "lib.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "board.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "paths.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "rbx.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#undef PATH_KERNEL
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define PATH_KERNEL "/boot/kernel/kernel.gz.tramp"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeextern uint32_t _end;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define NOPT 6
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const char optstr[NOPT] = "agnrsv";
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const unsigned char bootflags[NOPT] = {
199767f8919635c4928607450d9e0abb932109ceToomas Soome RBX_ASKNAME,
199767f8919635c4928607450d9e0abb932109ceToomas Soome RBX_GDB,
199767f8919635c4928607450d9e0abb932109ceToomas Soome RBX_NOINTR,
199767f8919635c4928607450d9e0abb932109ceToomas Soome RBX_DFLTROOT,
199767f8919635c4928607450d9e0abb932109ceToomas Soome RBX_SINGLE,
199767f8919635c4928607450d9e0abb932109ceToomas Soome RBX_VERBOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome};
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeunsigned board_id; /* board type to pass to kernel, if set by board_* code */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeunsigned dsk_start;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char cmd[512];
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char kname[1024];
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic uint32_t opts;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic uint8_t dsk_meta;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint main(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void load(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int parse(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int dskread(void *, unsigned, unsigned);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef FIXUP_BOOT_DRV
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void fixup_boot_drv(caddr_t, int, int, int);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define UFS_SMALL_CGBASE
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "ufsread.c"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef DEBUG
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define DPRINTF(fmt, ...)
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic inline int
199767f8919635c4928607450d9e0abb932109ceToomas Soomexfsread(ufs_ino_t inode, void *buf, size_t nbyte)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((size_t)fsread(inode, buf, nbyte) != nbyte)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic inline void
199767f8919635c4928607450d9e0abb932109ceToomas Soomegetstr(int c)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *s;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome s = cmd;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (c == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome c = getc(10000);
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (;;) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome switch (c) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 0:
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '\177':
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '\b':
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (s > cmd) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome s--;
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("\b \b");
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '\n':
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '\r':
199767f8919635c4928607450d9e0abb932109ceToomas Soome *s = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome default:
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (s - cmd < sizeof(cmd) - 1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome *s++ = c;
199767f8919635c4928607450d9e0abb932109ceToomas Soome xputchar(c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome c = getc(10000);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint
199767f8919635c4928607450d9e0abb932109ceToomas Soomemain(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int autoboot, c = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome ufs_ino_t ino;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome dmadat = (void *)(0x20000000 + (16 << 20));
199767f8919635c4928607450d9e0abb932109ceToomas Soome board_init();
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome autoboot = 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Process configuration file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((ino = lookup(PATH_CONFIG)) ||
199767f8919635c4928607450d9e0abb932109ceToomas Soome (ino = lookup(PATH_DOTCONFIG)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome fsread(ino, cmd, sizeof(cmd));
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*cmd) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (parse())
199767f8919635c4928607450d9e0abb932109ceToomas Soome autoboot = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("%s: %s\n", PATH_CONFIG, cmd);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Do not process this command twice */
199767f8919635c4928607450d9e0abb932109ceToomas Soome *cmd = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*kname == '\0')
199767f8919635c4928607450d9e0abb932109ceToomas Soome strcpy(kname, PATH_KERNEL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Present the user with the boot2 prompt. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (;;) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("\nDefault: %s\nboot: ", kname);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!autoboot ||
199767f8919635c4928607450d9e0abb932109ceToomas Soome (OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0))
199767f8919635c4928607450d9e0abb932109ceToomas Soome getstr(c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome xputchar('\n');
199767f8919635c4928607450d9e0abb932109ceToomas Soome autoboot = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome c = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (parse())
199767f8919635c4928607450d9e0abb932109ceToomas Soome xputchar('\a');
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome load();
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomeload(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome Elf32_Ehdr eh;
199767f8919635c4928607450d9e0abb932109ceToomas Soome static Elf32_Phdr ep[2];
199767f8919635c4928607450d9e0abb932109ceToomas Soome caddr_t p;
199767f8919635c4928607450d9e0abb932109ceToomas Soome ufs_ino_t ino;
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint32_t addr;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int i, j;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef FIXUP_BOOT_DRV
199767f8919635c4928607450d9e0abb932109ceToomas Soome caddr_t staddr;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int klen;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome staddr = (caddr_t)0xffffffff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome klen = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!(ino = lookup(kname))) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!ls)
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("No %s\n", kname);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (xfsread(ino, &eh, sizeof(eh)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!IS_ELF(eh)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Invalid %s\n", "format");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome fs_off = eh.e_phoff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (j = i = 0; i < eh.e_phnum && j < 2; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (xfsread(ino, ep + j, sizeof(ep[0])))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ep[j].p_type == PT_LOAD)
199767f8919635c4928607450d9e0abb932109ceToomas Soome j++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < 2; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome p = (caddr_t)ep[i].p_paddr;
199767f8919635c4928607450d9e0abb932109ceToomas Soome fs_off = ep[i].p_offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef FIXUP_BOOT_DRV
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (staddr == (caddr_t)0xffffffff)
199767f8919635c4928607450d9e0abb932109ceToomas Soome staddr = p;
199767f8919635c4928607450d9e0abb932109ceToomas Soome klen += ep[i].p_filesz;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (xfsread(ino, p, ep[i].p_filesz))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome addr = eh.e_entry;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef FIXUP_BOOT_DRV
199767f8919635c4928607450d9e0abb932109ceToomas Soome fixup_boot_drv(staddr, klen, bootslice, bootpart);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((void(*)(int, int, int, int))addr)(opts & RBX_MASK, board_id, 0, 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomeparse()
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *arg = cmd;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *ep, *p;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int c, i;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome while ((c = *arg++)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (c == ' ' || c == '\t' || c == '\n')
199767f8919635c4928607450d9e0abb932109ceToomas Soome continue;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
199767f8919635c4928607450d9e0abb932109ceToomas Soome ep = p;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*p)
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p++ = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (c == '-') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome while ((c = *arg++)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; c != optstr[i]; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (i == NOPT - 1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome opts ^= OPT_SET(bootflags[i]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome arg--;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((i = ep - arg)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((size_t)i >= sizeof(kname))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome memcpy(kname, arg, i + 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome arg = p;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomedskread(void *buf, unsigned lba, unsigned nblk)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome struct dos_partition *dp;
199767f8919635c4928607450d9e0abb932109ceToomas Soome struct disklabel *d;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *sec;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int i;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!dsk_meta) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome sec = dmadat->secbuf;
199767f8919635c4928607450d9e0abb932109ceToomas Soome dsk_start = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (drvread(sec, DOSBBSECTOR, 1))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome dp = (void *)(sec + DOSPARTOFF);
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < NDOSPART; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (dp[i].dp_typ == DOSPTYP_386BSD)
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (i == NDOSPART)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Although dp_start is aligned within the disk
199767f8919635c4928607450d9e0abb932109ceToomas Soome * partition structure, DOSPARTOFF is 446, which is
199767f8919635c4928607450d9e0abb932109ceToomas Soome * only word (2) aligned, not longword (4) aligned.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Cope by using memcpy to fetch the start of this
199767f8919635c4928607450d9e0abb932109ceToomas Soome * partition.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome memcpy(&dsk_start, &dp[1].dp_start, 4);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (drvread(sec, dsk_start + LABELSECTOR, 1))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome d = (void *)(sec + LABELOFFSET);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Invalid %s\n", "label");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!d->d_partitions[0].p_size) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Invalid %s\n", "partition");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome dsk_start += d->d_partitions[0].p_offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome dsk_start -= d->d_partitions[RAW_PART].p_offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome dsk_meta++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome return drvread(buf, dsk_start + lba, nblk);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef FIXUP_BOOT_DRV
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel
199767f8919635c4928607450d9e0abb932109ceToomas Soome * and change it to what was specified on the comandline or /boot.conf
199767f8919635c4928607450d9e0abb932109ceToomas Soome * file or to what was encountered on the disk. It will try to handle 3
199767f8919635c4928607450d9e0abb932109ceToomas Soome * different disk layouts, raw (dangerously dedicated), slice only and
199767f8919635c4928607450d9e0abb932109ceToomas Soome * slice + partition. It will look for the following strings in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * kernel, but if it is one of the first three, the string in the kernel
199767f8919635c4928607450d9e0abb932109ceToomas Soome * must use the correct form to match the actual disk layout:
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - ufs:ad0a
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - ufs:ad0s1
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - ufs:ad0s1a
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - ufs:ROOTDEVNAME
199767f8919635c4928607450d9e0abb932109ceToomas Soome * In the case of the first three strings, only the "a" at the end and
199767f8919635c4928607450d9e0abb932109ceToomas Soome * the "1" after the "s" will be modified, if they exist. The string
199767f8919635c4928607450d9e0abb932109ceToomas Soome * length will not be changed. In the case of the last string, the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * whole string will be built up and nul, '\0' terminated.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomefixup_boot_drv(caddr_t addr, int klen, int bs, int bp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome const u_int8_t op[] = "ufs:ROOTDEVNAME";
199767f8919635c4928607450d9e0abb932109ceToomas Soome const u_int8_t op2[] = "ufs:ad0";
199767f8919635c4928607450d9e0abb932109ceToomas Soome u_int8_t *p, *ps;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n",
199767f8919635c4928607450d9e0abb932109ceToomas Soome (int)addr, klen, bs, bp);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (bs > 4)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (bp > 7)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome ps = memmem(addr, klen, op, sizeof(op));
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ps != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome p = ps + 4; /* past ufs: */
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("Found it at 0x%x\n", (int)ps);
199767f8919635c4928607450d9e0abb932109ceToomas Soome p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */
199767f8919635c4928607450d9e0abb932109ceToomas Soome p += 3;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (bs > 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* append slice */
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p++ = 's';
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p++ = bs + '0';
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (disk_layout != DL_SLICE) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* append partition */
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p++ = bp + 'a';
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p = '\0';
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome ps = memmem(addr, klen, op2, sizeof(op2) - 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ps != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome p = ps + sizeof(op2) - 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("Found it at 0x%x\n", (int)ps);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*p == 's') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* fix slice */
199767f8919635c4928607450d9e0abb932109ceToomas Soome p++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p++ = bs + '0';
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*p == 'a')
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p = bp + 'a';
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ps == NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Could not locate \"%s\" to fix kernel boot device, "
199767f8919635c4928607450d9e0abb932109ceToomas Soome "check ROOTDEVNAME is set\n", op);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("Changed boot device to %s\n", ps);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif