199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 2008 John Hay
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Robert Nordier
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
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 * 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#define DL_SLICE 2 /* Use only slices (DOS partitions) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define DL_SLICEPART 3 /* Use slices and partitions */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void load(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int parse(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int dskread(void *, unsigned, unsigned);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int drvread(void *, unsigned, unsigned);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void fixup_boot_drv(caddr_t, int, int, int);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic inline int
199767f8919635c4928607450d9e0abb932109ceToomas Soomexfsread(ufs_ino_t inode, void *buf, size_t nbyte)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((size_t)fsread(inode, buf, nbyte) != nbyte)
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic inline void
199767f8919635c4928607450d9e0abb932109ceToomas Soome switch (c) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '\177':
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("FreeBSD ARM (%s) boot2 v%d.%d\n", bt, 0, 4);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Process configuration file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Do not process this command twice */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Present the user with the boot2 prompt. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome (OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0))
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (j = i = 0; i < eh.e_phnum && j < 2; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < 2; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("Entry point %x for %s\n", addr, kname);
199767f8919635c4928607450d9e0abb932109ceToomas Soome fixup_boot_drv(staddr, klen, bootslice, bootpart);
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((void(*)(int))addr)(RB_BOOTINFO /* XXX | (opts & RBX_MASK) */);
199767f8919635c4928607450d9e0abb932109ceToomas Soome while ((c = *arg++)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (c == '-') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome while ((c = *arg++)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; c != optstr[i]; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* look for ad0s1a:... | ad0s1:... */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* XXX Should also handle disk. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* look for ad0a:... */
199767f8919635c4928607450d9e0abb932109ceToomas Soome arg[1] == 'd' && arg[2] == '0' && arg[4] == ':') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * dskread() will try to handle the disk layouts that are typically
199767f8919635c4928607450d9e0abb932109ceToomas Soome * encountered.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - raw or "Dangerously Dedicated" mode. No real slice table, just the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * default one that is included with bsdlabel -B. Typically this is
199767f8919635c4928607450d9e0abb932109ceToomas Soome * used with ROOTDEVNAME=\"ufs:ad0a\".
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - slice only. Only a slice table is installed with no bsd label or
199767f8919635c4928607450d9e0abb932109ceToomas Soome * bsd partition table. This is typically used with
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ROOTDEVNAME=\"ufs:ad0s1\".
199767f8919635c4928607450d9e0abb932109ceToomas Soome * - slice + bsd label + partition table. This is typically done with
199767f8919635c4928607450d9e0abb932109ceToomas Soome * with fdisk + bsdlabel and is used with ROOTDEVNAME=\"ufs:ad0s1a\".
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < NDOSPART; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("Found an active fbsd slice. (%d)\n", i + 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Although dp_start is aligned within the disk
199767f8919635c4928607450d9e0abb932109ceToomas Soome * partition structure, DOSPARTOFF is 446, which
199767f8919635c4928607450d9e0abb932109ceToomas Soome * is only word (2) aligned, not longword (4)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * aligned. Cope by using memcpy to fetch the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * start of this partition.
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((d->d_magic == DISKMAGIC && d->d_magic2 == DISKMAGIC) ||
199767f8919635c4928607450d9e0abb932109ceToomas Soome dsk_start += swap32(d->d_partitions[bootpart].p_offset);
199767f8919635c4928607450d9e0abb932109ceToomas Soome dsk_start -= swap32(d->d_partitions[RAW_PART].p_offset);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((disk_layout == DL_UNKNOWN) && (bootslice == 0))
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("bootslice %d, bootpart %d, dsk_start %u\n", bootslice,
199767f8919635c4928607450d9e0abb932109ceToomas Soome static unsigned c = 0x2d5c7c2f;
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 Soomefixup_boot_drv(caddr_t addr, int klen, int bs, int bp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n",
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* append slice */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* append partition */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*p == 's') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* fix slice */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*p == 'a')
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Could not locate \"%s\" to fix kernel boot device, "