diff options
author | Luiz Souza <luiz@netgate.com> | 2018-04-30 20:35:14 -0300 |
---|---|---|
committer | Luiz Souza <luiz@netgate.com> | 2018-04-30 20:35:14 -0300 |
commit | f15466802c06eecb466e862c800e8c8b0c799597 (patch) | |
tree | a5d2aed81ed753abc34f13b835296d8ec9b3e20e /stand | |
parent | 8d882f60e34a4ffa79ce70fbe5e65485e0ad9a54 (diff) | |
parent | 4aefbd6952cff7b80d06d8f0d3805e1453ad9ec1 (diff) | |
download | FreeBSD-src-f15466802c06eecb466e862c800e8c8b0c799597.zip FreeBSD-src-f15466802c06eecb466e862c800e8c8b0c799597.tar.gz |
Merge remote-tracking branch 'origin/stable/11' into devel-11
Diffstat (limited to 'stand')
186 files changed, 4860 insertions, 5796 deletions
diff --git a/stand/Makefile b/stand/Makefile index 5234189..f13be3e 100644 --- a/stand/Makefile +++ b/stand/Makefile @@ -2,19 +2,41 @@ .include <src.opts.mk> -SUBDIR+= libsa -.if ${MK_FORTH} != "no" -# Build the add-in FORTH interpreter. -SUBDIR+= ficl -SUBDIR+= forth +# For amd64 we have to build 32 and 64 bit versions of things. For +# others we don't. LIB32LIST is a list of libraries, which if +# included, need to be built 32-bit as well. +.if ${MACHINE_ARCH} == "amd64" +LIB32LIST=libsa ficl zfs .endif -SUBDIR+= man +S.yes+= libsa + +S.${MK_FORTH}+= ficl +S.${MK_FORTH}+= forth +S.${MK_FDT}+= fdt +S.${MK_LOADER_OFW}+= ofw +S.${MK_ZFS}+= zfs +S.yes+= defaults +S.yes+= man + +S.${MK_LOADER_GELI}+= geli .include <bsd.arch.inc.mk> +S.${MK_EFI}+= efi +S.${MK_LOADER_UBOOT}+= uboot + .if exists(${.CURDIR}/${MACHINE}/.) -SUBDIR+= ${MACHINE} +S.yes+= ${MACHINE} +.endif + +# Build the actual subdir list from S.yes, adding in the 32-bit +# variant if necessary. +.for _x in ${S.yes} +SUBDIR+=${_x} +.if defined(LIB32LIST) && ${LIB32LIST:M${_x}} +SUBDIR+=${_x}32 .endif +.endfor .include <bsd.subdir.mk> diff --git a/stand/Makefile.amd64 b/stand/Makefile.amd64 index 6e8c967..b2b918e 100644 --- a/stand/Makefile.amd64 +++ b/stand/Makefile.amd64 @@ -1,18 +1,4 @@ # $FreeBSD$ -SUBDIR+= libsa32 -.if ${MK_ZFS} != "no" -SUBDIR+= zfs zfs32 -.endif -.if ${MK_FORTH} != "no" -SUBDIR+= ficl32 -.endif - -SUBDIR+= efi -SUBDIR+= userboot - -.if ${MK_LOADER_GELI} == "yes" -SUBDIR+= geli -.endif - -SUBDIR+= i386 +S.yes+= userboot +S.yes+= i386 diff --git a/stand/Makefile.arm b/stand/Makefile.arm deleted file mode 100644 index 387b77b..0000000 --- a/stand/Makefile.arm +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.if ${MK_FDT} != "no" -SUBDIR+= fdt -.endif -.if ${MK_ZFS} != "no" -SUBDIR+= zfs -.endif - -SUBDIR+= efi uboot diff --git a/stand/Makefile.arm64 b/stand/Makefile.arm64 deleted file mode 100644 index bf0fd39..0000000 --- a/stand/Makefile.arm64 +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.if ${MK_FDT} != "no" -SUBDIR+= fdt -.endif -.if ${MK_ZFS} != "no" -SUBDIR+= zfs -.endif - -SUBDIR+= efi diff --git a/stand/Makefile.i386 b/stand/Makefile.i386 deleted file mode 100644 index 9664974..0000000 --- a/stand/Makefile.i386 +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.if ${MK_LOADER_GELI} == "yes" -SUBDIR+= geli -.endif -.if ${MK_ZFS} != "no" -SUBDIR+= zfs -.endif - -SUBDIR+= efi diff --git a/stand/Makefile.mips b/stand/Makefile.mips deleted file mode 100644 index 46fc574..0000000 --- a/stand/Makefile.mips +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ - -.if ${MK_FDT} != "no" -SUBDIR+= fdt -.endif - -SUBDIR+= uboot diff --git a/stand/Makefile.pc98 b/stand/Makefile.pc98 index 8468399..6462e454 100644 --- a/stand/Makefile.pc98 +++ b/stand/Makefile.pc98 @@ -1,3 +1,4 @@ # $FreeBSD$ -SUBDIR+= libstand32 +# Need an empty file here so Makefile.i386 isn't used (which contains options +# that don't work on pc98). diff --git a/stand/Makefile.powerpc b/stand/Makefile.powerpc deleted file mode 100644 index b7660f4..0000000 --- a/stand/Makefile.powerpc +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -.if ${MK_FDT} != "no" -SUBDIR+= fdt -.endif - -SUBDIR+= ofw -SUBDIR+= uboot diff --git a/stand/Makefile.sparc64 b/stand/Makefile.sparc64 deleted file mode 100644 index 40b42e9..0000000 --- a/stand/Makefile.sparc64 +++ /dev/null @@ -1,6 +0,0 @@ -# $FreeBSD$ - -SUBDIR+= ofw -.if ${MK_ZFS} != "no" -SUBDIR+= zfs -.endif diff --git a/stand/arm/Makefile b/stand/arm/Makefile index 1d12d98..7ff21ab 100644 --- a/stand/arm/Makefile +++ b/stand/arm/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +NO_OBJ=t + SUBDIR= uboot .include <bsd.subdir.mk> diff --git a/stand/arm/loader/loader.conf b/stand/arm/loader/loader.conf deleted file mode 100644 index dd2a23a..0000000 --- a/stand/arm/loader/loader.conf +++ /dev/null @@ -1,13 +0,0 @@ -# This is defaults/loader.conf for ARM, containing defaults for loader(8). -# Do not modify the contents of this file, instead put your customizations -# into /boot/loader.conf or /boot/loader.conf.local -# $FreeBSD$ - -autoboot_delay=10 -bootfile="kernel" # Kernel name (possibly absolute path) -kernel="kernel" # /boot sub-directory containing kernel and modules -loader_conf_files="/boot/loader.conf /boot/loader.conf.local" -module_path="/boot/kernel;/boot/modules;/boot/dtb;/boot/overlays" -nextboot_conf="/boot/nextboot.conf" -nextboot_enable="NO" -verbose_loading="NO" diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h index 2808117..7d9b9b4 100644 --- a/stand/common/bootstrap.h +++ b/stand/common/bootstrap.h @@ -150,7 +150,7 @@ void pnp_addident(struct pnpinfo *pi, char *ident); struct pnpinfo *pnp_allocinfo(void); void pnp_freeinfo(struct pnpinfo *pi); void pnp_addinfo(struct pnpinfo *pi); -char *pnp_eisaformat(u_int8_t *data); +char *pnp_eisaformat(uint8_t *data); /* * < 0 - No ISA in system @@ -168,7 +168,7 @@ extern int isapnp_readport; struct file_metadata { size_t md_size; - u_int16_t md_type; + uint16_t md_type; struct file_metadata *md_next; char md_data[1]; /* data are immediately appended */ }; @@ -210,7 +210,7 @@ struct preloaded_file struct file_format { /* Load function must return EFTYPE if it can't handle the module supplied */ - int (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result); + int (* l_load)(char *filename, uint64_t dest, struct preloaded_file **result); /* Only a loader that will load a kernel (first module) should have an exec handler */ int (* l_exec)(struct preloaded_file *mp); }; @@ -239,20 +239,20 @@ void file_removemetadata(struct preloaded_file *fp); #define ELF_RELOC_RELA 2 /* Relocation offset for some architectures */ -extern u_int64_t __elfN(relocation_offset); +extern uint64_t __elfN(relocation_offset); struct elf_file; typedef Elf_Addr (symaddr_fn)(struct elf_file *ef, Elf_Size symidx); -int __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result); -int __elfN(obj_loadfile)(char *filename, u_int64_t dest, +int __elfN(loadfile)(char *filename, uint64_t dest, struct preloaded_file **result); +int __elfN(obj_loadfile)(char *filename, uint64_t dest, struct preloaded_file **result); int __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata, int reltype, Elf_Addr relbase, Elf_Addr dataaddr, void *data, size_t len); -int __elfN(loadfile_raw)(char *filename, u_int64_t dest, +int __elfN(loadfile_raw)(char *filename, uint64_t dest, struct preloaded_file **result, int multiboot); -int __elfN(load_modmetadata)(struct preloaded_file *fp, u_int64_t dest); +int __elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest); #endif /* @@ -330,10 +330,8 @@ void dev_cleanup(void); time_t time(time_t *tloc); -#ifndef CTASSERT /* Allow lint to override */ -#define CTASSERT(x) _CTASSERT(x, __LINE__) -#define _CTASSERT(x, y) __CTASSERT(x, y) -#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] +#ifndef CTASSERT +#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") #endif #endif /* !_BOOTSTRAP_H_ */ diff --git a/stand/common/disk.c b/stand/common/disk.c index 4cb57d4..31e5957 100644 --- a/stand/common/disk.c +++ b/stand/common/disk.c @@ -86,7 +86,7 @@ ptblread(void *d, void *buf, size_t blocks, uint64_t offset) struct open_disk *od; dev = (struct disk_devdesc *)d; - od = (struct open_disk *)dev->d_opendata; + od = (struct open_disk *)dev->dd.d_opendata; /* * The strategy function assumes the offset is in units of 512 byte @@ -98,7 +98,7 @@ ptblread(void *d, void *buf, size_t blocks, uint64_t offset) * As the GPT backup partition is located at the end of the disk, * to avoid reading past disk end, flag bcache not to use RA. */ - return (dev->d_dev->dv_strategy(dev, F_READ | F_NORA, offset, + return (dev->dd.d_dev->dv_strategy(dev, F_READ | F_NORA, offset, blocks * od->sectorsize, (char *)buf, NULL)); } @@ -114,7 +114,7 @@ ptable_print(void *arg, const char *pname, const struct ptable_entry *part) int res; pa = (struct print_args *)arg; - od = (struct open_disk *)pa->dev->d_opendata; + od = (struct open_disk *)pa->dev->dd.d_opendata; sprintf(line, " %s%s: %s", pa->prefix, pname, parttype2str(part->type)); if (pa->verbose) @@ -127,8 +127,8 @@ ptable_print(void *arg, const char *pname, const struct ptable_entry *part) res = 0; if (part->type == PART_FREEBSD) { /* Open slice with BSD label */ - dev.d_dev = pa->dev->d_dev; - dev.d_unit = pa->dev->d_unit; + dev.dd.d_dev = pa->dev->dd.d_dev; + dev.dd.d_unit = pa->dev->dd.d_unit; dev.d_slice = part->index; dev.d_partition = -1; if (disk_open(&dev, part->end - part->start + 1, @@ -158,7 +158,7 @@ disk_print(struct disk_devdesc *dev, char *prefix, int verbose) struct print_args pa; /* Disk should be opened */ - od = (struct open_disk *)dev->d_opendata; + od = (struct open_disk *)dev->dd.d_opendata; pa.dev = dev; pa.prefix = prefix; pa.verbose = verbose; @@ -171,8 +171,8 @@ disk_read(struct disk_devdesc *dev, void *buf, uint64_t offset, u_int blocks) struct open_disk *od; int ret; - od = (struct open_disk *)dev->d_opendata; - ret = dev->d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset, + od = (struct open_disk *)dev->dd.d_opendata; + ret = dev->dd.d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset, blocks * od->sectorsize, buf, NULL); return (ret); @@ -184,8 +184,8 @@ disk_write(struct disk_devdesc *dev, void *buf, uint64_t offset, u_int blocks) struct open_disk *od; int ret; - od = (struct open_disk *)dev->d_opendata; - ret = dev->d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset, + od = (struct open_disk *)dev->dd.d_opendata; + ret = dev->dd.d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset, blocks * od->sectorsize, buf, NULL); return (ret); @@ -194,7 +194,7 @@ disk_write(struct disk_devdesc *dev, void *buf, uint64_t offset, u_int blocks) int disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *data) { - struct open_disk *od = dev->d_opendata; + struct open_disk *od = dev->dd.d_opendata; if (od == NULL) return (ENOTTY); @@ -238,7 +238,7 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize) DEBUG("no memory"); return (ENOMEM); } - dev->d_opendata = od; + dev->dd.d_opendata = od; od->entrysize = 0; od->mediasize = mediasize; od->sectorsize = sectorsize; @@ -270,6 +270,9 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize) dev->d_offset = part.start; od->entrysize = part.end - part.start + 1; } + } else if (ptable_gettype(od->table) == PTABLE_ISO9660) { + dev->d_offset = 0; + od->entrysize = mediasize; } else if (slice >= 0) { /* Try to get information about partition */ if (slice == 0) @@ -348,7 +351,7 @@ disk_close(struct disk_devdesc *dev) { struct open_disk *od; - od = (struct open_disk *)dev->d_opendata; + od = (struct open_disk *)dev->dd.d_opendata; DEBUG("%s closed => %p", disk_fmtdev(dev), od); ptable_close(od->table); free(od); @@ -361,7 +364,7 @@ disk_fmtdev(struct disk_devdesc *dev) static char buf[128]; char *cp; - cp = buf + sprintf(buf, "%s%d", dev->d_dev->dv_name, dev->d_unit); + cp = buf + sprintf(buf, "%s%d", dev->dd.d_dev->dv_name, dev->dd.d_unit); if (dev->d_slice >= 0) { #ifdef LOADER_GPT_SUPPORT if (dev->d_partition == 255) { @@ -423,7 +426,7 @@ disk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path) if (*cp != '\0' && *cp != ':') return (EINVAL); - dev->d_unit = unit; + dev->dd.d_unit = unit; dev->d_slice = slice; dev->d_partition = partition; if (path != NULL) diff --git a/stand/common/disk.h b/stand/common/disk.h index 51e1498..8396c27 100644 --- a/stand/common/disk.h +++ b/stand/common/disk.h @@ -81,12 +81,9 @@ #ifndef _DISK_H #define _DISK_H -struct disk_devdesc -{ - struct devsw *d_dev; - int d_type; - int d_unit; - void *d_opendata; +/* Note: Must match the 'struct devdesc' in stand.h */ +struct disk_devdesc { + struct devdesc dd; int d_slice; int d_partition; uint64_t d_offset; diff --git a/stand/common/isapnp.c b/stand/common/isapnp.c index 5867600..16eb0b9 100644 --- a/stand/common/isapnp.c +++ b/stand/common/isapnp.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); static void isapnp_write(int d, int r); static void isapnp_send_Initiation_LFSR(void); -static int isapnp_get_serial(u_int8_t *p); +static int isapnp_get_serial(uint8_t *p); static int isapnp_isolation_protocol(void); static void isapnp_enumerate(void); @@ -90,7 +90,7 @@ isapnp_send_Initiation_LFSR(void) * Get the device's serial number. Returns 1 if the serial is valid. */ static int -isapnp_get_serial(u_int8_t *data) +isapnp_get_serial(uint8_t *data) { int i, bit, valid = 0, sum = 0x6a; @@ -123,7 +123,7 @@ isapnp_get_serial(u_int8_t *data) * Returns nonzero if the device fails to report */ static int -isapnp_get_resource_info(u_int8_t *buffer, int len) +isapnp_get_resource_info(uint8_t *buffer, int len) { int i, j; u_char temp; @@ -229,7 +229,7 @@ isapnp_isolation_protocol(void) { int csn; struct pnpinfo *pi; - u_int8_t cardid[_PNP_ID_LEN]; + uint8_t cardid[_PNP_ID_LEN]; int ndevs; isapnp_send_Initiation_LFSR(); diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c index 89c0733..695eec6 100644 --- a/stand/common/load_elf.c +++ b/stand/common/load_elf.c @@ -52,29 +52,31 @@ __FBSDID("$FreeBSD$"); #endif typedef struct elf_file { - Elf_Phdr *ph; - Elf_Ehdr *ehdr; - Elf_Sym *symtab; - Elf_Hashelt *hashtab; - Elf_Hashelt nbuckets; - Elf_Hashelt nchains; - Elf_Hashelt *buckets; - Elf_Hashelt *chains; - Elf_Rel *rel; - size_t relsz; - Elf_Rela *rela; - size_t relasz; - char *strtab; - size_t strsz; - int fd; - caddr_t firstpage; - size_t firstlen; - int kernel; - u_int64_t off; + Elf_Phdr *ph; + Elf_Ehdr *ehdr; + Elf_Sym *symtab; + Elf_Hashelt *hashtab; + Elf_Hashelt nbuckets; + Elf_Hashelt nchains; + Elf_Hashelt *buckets; + Elf_Hashelt *chains; + Elf_Rel *rel; + size_t relsz; + Elf_Rela *rela; + size_t relasz; + char *strtab; + size_t strsz; + int fd; + caddr_t firstpage; + size_t firstlen; + int kernel; + uint64_t off; } *elf_file_t; -static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef, u_int64_t loadaddr); -static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef, const char* name, Elf_Sym* sym); +static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef, + uint64_t loadaddr); +static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef, + const char* name, Elf_Sym* sym); static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, Elf_Addr p, void *val, size_t len); static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef, @@ -85,7 +87,7 @@ static char *fake_modname(const char *name); const char *__elfN(kerneltype) = "elf kernel"; const char *__elfN(moduletype) = "elf module"; -u_int64_t __elfN(relocation_offset) = 0; +uint64_t __elfN(relocation_offset) = 0; extern void elf_wrong_field_size(void); #define CONVERT_FIELD(b, f, e) \ @@ -198,11 +200,11 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef) { ssize_t bytes_read; Elf_Ehdr *ehdr; - int err; + int err; /* - * Open the image, read and validate the ELF header - */ + * Open the image, read and validate the ELF header + */ if (filename == NULL) /* can't handle nameless */ return (EFTYPE); if ((ef->fd = open(filename, O_RDONLY)) == -1) @@ -237,7 +239,8 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef) if (err) goto error; - if (ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */ + if (ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) { + /* Machine ? */ err = EFTYPE; goto error; } @@ -262,145 +265,153 @@ error: * will be saved in (result). */ int -__elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result) +__elfN(loadfile)(char *filename, uint64_t dest, struct preloaded_file **result) { return (__elfN(loadfile_raw)(filename, dest, result, 0)); } int -__elfN(loadfile_raw)(char *filename, u_int64_t dest, +__elfN(loadfile_raw)(char *filename, uint64_t dest, struct preloaded_file **result, int multiboot) { - struct preloaded_file *fp, *kfp; - struct elf_file ef; - Elf_Ehdr *ehdr; - int err; + struct preloaded_file *fp, *kfp; + struct elf_file ef; + Elf_Ehdr *ehdr; + int err; - fp = NULL; - bzero(&ef, sizeof(struct elf_file)); - ef.fd = -1; + fp = NULL; + bzero(&ef, sizeof(struct elf_file)); + ef.fd = -1; - err = __elfN(load_elf_header)(filename, &ef); - if (err != 0) - return (err); + err = __elfN(load_elf_header)(filename, &ef); + if (err != 0) + return (err); - ehdr = ef.ehdr; + ehdr = ef.ehdr; - /* - * Check to see what sort of module we are. - */ - kfp = file_findfile(NULL, __elfN(kerneltype)); + /* + * Check to see what sort of module we are. + */ + kfp = file_findfile(NULL, __elfN(kerneltype)); #ifdef __powerpc__ - /* - * Kernels can be ET_DYN, so just assume the first loaded object is the - * kernel. This assumption will be checked later. - */ - if (kfp == NULL) - ef.kernel = 1; -#endif - if (ef.kernel || ehdr->e_type == ET_EXEC) { - /* Looks like a kernel */ - if (kfp != NULL) { - printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n"); - err = EPERM; - goto oerr; - } - /* - * Calculate destination address based on kernel entrypoint. - * - * For ARM, the destination address is independent of any values in the - * elf header (an ARM kernel can be loaded at any 2MB boundary), so we - * leave dest set to the value calculated by archsw.arch_loadaddr() and - * passed in to this function. + /* + * Kernels can be ET_DYN, so just assume the first loaded object is the + * kernel. This assumption will be checked later. */ + if (kfp == NULL) + ef.kernel = 1; +#endif + if (ef.kernel || ehdr->e_type == ET_EXEC) { + /* Looks like a kernel */ + if (kfp != NULL) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) + "_loadfile: kernel already loaded\n"); + err = EPERM; + goto oerr; + } + /* + * Calculate destination address based on kernel entrypoint. + * + * For ARM, the destination address is independent of any values + * in the elf header (an ARM kernel can be loaded at any 2MB + * boundary), so we leave dest set to the value calculated by + * archsw.arch_loadaddr() and passed in to this function. + */ #ifndef __arm__ - if (ehdr->e_type == ET_EXEC) - dest = (ehdr->e_entry & ~PAGE_MASK); + if (ehdr->e_type == ET_EXEC) + dest = (ehdr->e_entry & ~PAGE_MASK); #endif - if ((ehdr->e_entry & ~PAGE_MASK) == 0) { - printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n"); - err = EPERM; - goto oerr; - } - ef.kernel = 1; + if ((ehdr->e_entry & ~PAGE_MASK) == 0) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) + "_loadfile: not a kernel (maybe static binary?)\n"); + err = EPERM; + goto oerr; + } + ef.kernel = 1; - } else if (ehdr->e_type == ET_DYN) { - /* Looks like a kld module */ - if (multiboot != 0) { - printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module as multiboot\n"); - err = EPERM; + } else if (ehdr->e_type == ET_DYN) { + /* Looks like a kld module */ + if (multiboot != 0) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) + "_loadfile: can't load module as multiboot\n"); + err = EPERM; + goto oerr; + } + if (kfp == NULL) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) + "_loadfile: can't load module before kernel\n"); + err = EPERM; + goto oerr; + } + if (strcmp(__elfN(kerneltype), kfp->f_type)) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) + "_loadfile: can't load module with kernel type '%s'\n", + kfp->f_type); + err = EPERM; + goto oerr; + } + /* Looks OK, got ahead */ + ef.kernel = 0; + + } else { + err = EFTYPE; goto oerr; } - if (kfp == NULL) { - printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module before kernel\n"); - err = EPERM; - goto oerr; - } - if (strcmp(__elfN(kerneltype), kfp->f_type)) { - printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); - err = EPERM; - goto oerr; + + if (archsw.arch_loadaddr != NULL) + dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest); + else + dest = roundup(dest, PAGE_SIZE); + + /* + * Ok, we think we should handle this. + */ + fp = file_alloc(); + if (fp == NULL) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) + "_loadfile: cannot allocate module info\n"); + err = EPERM; + goto out; } - /* Looks OK, got ahead */ - ef.kernel = 0; - - } else { - err = EFTYPE; - goto oerr; - } - - if (archsw.arch_loadaddr != NULL) - dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest); - else - dest = roundup(dest, PAGE_SIZE); - - /* - * Ok, we think we should handle this. - */ - fp = file_alloc(); - if (fp == NULL) { - printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: cannot allocate module info\n"); - err = EPERM; - goto out; - } - if (ef.kernel == 1 && multiboot == 0) - setenv("kernelname", filename, 1); - fp->f_name = strdup(filename); - if (multiboot == 0) - fp->f_type = strdup(ef.kernel ? - __elfN(kerneltype) : __elfN(moduletype)); - else - fp->f_type = strdup("elf multiboot kernel"); + if (ef.kernel == 1 && multiboot == 0) + setenv("kernelname", filename, 1); + fp->f_name = strdup(filename); + if (multiboot == 0) + fp->f_type = strdup(ef.kernel ? + __elfN(kerneltype) : __elfN(moduletype)); + else + fp->f_type = strdup("elf multiboot kernel"); #ifdef ELF_VERBOSE - if (ef.kernel) - printf("%s entry at 0x%jx\n", filename, (uintmax_t)ehdr->e_entry); + if (ef.kernel) + printf("%s entry at 0x%jx\n", filename, + (uintmax_t)ehdr->e_entry); #else - printf("%s ", filename); + printf("%s ", filename); #endif - fp->f_size = __elfN(loadimage)(fp, &ef, dest); - if (fp->f_size == 0 || fp->f_addr == 0) - goto ioerr; - - /* save exec header as metadata */ - file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr); - - /* Load OK, return module pointer */ - *result = (struct preloaded_file *)fp; - err = 0; - goto out; - - ioerr: - err = EIO; - oerr: - file_discard(fp); - out: - if (ef.firstpage) - free(ef.firstpage); - if (ef.fd != -1) - close(ef.fd); - return(err); + fp->f_size = __elfN(loadimage)(fp, &ef, dest); + if (fp->f_size == 0 || fp->f_addr == 0) + goto ioerr; + + /* save exec header as metadata */ + file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr); + + /* Load OK, return module pointer */ + *result = (struct preloaded_file *)fp; + err = 0; + goto out; + +ioerr: + err = EIO; +oerr: + file_discard(fp); +out: + if (ef.firstpage) + free(ef.firstpage); + if (ef.fd != -1) + close(ef.fd); + return (err); } /* @@ -408,410 +419,433 @@ __elfN(loadfile_raw)(char *filename, u_int64_t dest, * the Elf header, load the image at (off) */ static int -__elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) +__elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off) { - int i; - u_int j; - Elf_Ehdr *ehdr; - Elf_Phdr *phdr, *php; - Elf_Shdr *shdr; - char *shstr; - int ret; - vm_offset_t firstaddr; - vm_offset_t lastaddr; - size_t chunk; - ssize_t result; - Elf_Addr ssym, esym; - Elf_Dyn *dp; - Elf_Addr adp; - Elf_Addr ctors; - int ndp; - int symstrindex; - int symtabindex; - Elf_Size size; - u_int fpcopy; - Elf_Sym sym; - Elf_Addr p_start, p_end; - - dp = NULL; - shdr = NULL; - ret = 0; - firstaddr = lastaddr = 0; - ehdr = ef->ehdr; - if (ehdr->e_type == ET_EXEC) { + int i; + u_int j; + Elf_Ehdr *ehdr; + Elf_Phdr *phdr, *php; + Elf_Shdr *shdr; + char *shstr; + int ret; + vm_offset_t firstaddr; + vm_offset_t lastaddr; + size_t chunk; + ssize_t result; + Elf_Addr ssym, esym; + Elf_Dyn *dp; + Elf_Addr adp; + Elf_Addr ctors; + int ndp; + int symstrindex; + int symtabindex; + Elf_Size size; + u_int fpcopy; + Elf_Sym sym; + Elf_Addr p_start, p_end; + + dp = NULL; + shdr = NULL; + ret = 0; + firstaddr = lastaddr = 0; + ehdr = ef->ehdr; + if (ehdr->e_type == ET_EXEC) { #if defined(__i386__) || defined(__amd64__) #if __ELF_WORD_SIZE == 64 - off = - (off & 0xffffffffff000000ull);/* x86_64 relocates after locore */ + /* x86_64 relocates after locore */ + off = - (off & 0xffffffffff000000ull); #else - off = - (off & 0xff000000u); /* i386 relocates after locore */ + /* i386 relocates after locore */ + off = - (off & 0xff000000u); #endif #elif defined(__powerpc__) - /* - * On the purely virtual memory machines like e500, the kernel is - * linked against its final VA range, which is most often not - * available at the loader stage, but only after kernel initializes - * and completes its VM settings. In such cases we cannot use p_vaddr - * field directly to load ELF segments, but put them at some - * 'load-time' locations. - */ - if (off & 0xf0000000u) { - off = -(off & 0xf0000000u); - /* - * XXX the physical load address should not be hardcoded. Note - * that the Book-E kernel assumes that it's loaded at a 16MB - * boundary for now... - */ - off += 0x01000000; - ehdr->e_entry += off; + /* + * On the purely virtual memory machines like e500, the kernel + * is linked against its final VA range, which is most often + * not available at the loader stage, but only after kernel + * initializes and completes its VM settings. In such cases we + * cannot use p_vaddr field directly to load ELF segments, but + * put them at some 'load-time' locations. + */ + if (off & 0xf0000000u) { + off = -(off & 0xf0000000u); + /* + * XXX the physical load address should not be + * hardcoded. Note that the Book-E kernel assumes that + * it's loaded at a 16MB boundary for now... + */ + off += 0x01000000; + ehdr->e_entry += off; #ifdef ELF_VERBOSE - printf("Converted entry 0x%08x\n", ehdr->e_entry); + printf("Converted entry 0x%08x\n", ehdr->e_entry); #endif - } else - off = 0; + } else + off = 0; #elif defined(__arm__) && !defined(EFI) - /* - * The elf headers in arm kernels specify virtual addresses in all - * header fields, even the ones that should be physical addresses. - * We assume the entry point is in the first page, and masking the page - * offset will leave us with the virtual address the kernel was linked - * at. We subtract that from the load offset, making 'off' into the - * value which, when added to a virtual address in an elf header, - * translates it to a physical address. We do the va->pa conversion on - * the entry point address in the header now, so that later we can - * launch the kernel by just jumping to that address. - * - * When booting from UEFI the copyin and copyout functions handle - * adjusting the location relative to the first virtual address. - * Because of this there is no need to adjust the offset or entry - * point address as these will both be handled by the efi code. - */ - off -= ehdr->e_entry & ~PAGE_MASK; - ehdr->e_entry += off; + /* + * The elf headers in arm kernels specify virtual addresses in + * all header fields, even the ones that should be physical + * addresses. We assume the entry point is in the first page, + * and masking the page offset will leave us with the virtual + * address the kernel was linked at. We subtract that from the + * load offset, making 'off' into the value which, when added + * to a virtual address in an elf header, translates it to a + * physical address. We do the va->pa conversion on the entry + * point address in the header now, so that later we can launch + * the kernel by just jumping to that address. + * + * When booting from UEFI the copyin and copyout functions + * handle adjusting the location relative to the first virtual + * address. Because of this there is no need to adjust the + * offset or entry point address as these will both be handled + * by the efi code. + */ + off -= ehdr->e_entry & ~PAGE_MASK; + ehdr->e_entry += off; #ifdef ELF_VERBOSE - printf("ehdr->e_entry 0x%08x, va<->pa off %llx\n", ehdr->e_entry, off); + printf("ehdr->e_entry 0x%08x, va<->pa off %llx\n", + ehdr->e_entry, off); #endif #else - off = 0; /* other archs use direct mapped kernels */ + off = 0; /* other archs use direct mapped kernels */ #endif - } - ef->off = off; + } + ef->off = off; - if (ef->kernel) - __elfN(relocation_offset) = off; + if (ef->kernel) + __elfN(relocation_offset) = off; - if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) { - printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: program header not within first page\n"); - goto out; - } - phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); + if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) + "_loadimage: program header not within first page\n"); + goto out; + } + phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); - for (i = 0; i < ehdr->e_phnum; i++) { - if (elf_program_header_convert(ehdr, phdr)) - continue; + for (i = 0; i < ehdr->e_phnum; i++) { + if (elf_program_header_convert(ehdr, phdr)) + continue; - /* We want to load PT_LOAD segments only.. */ - if (phdr[i].p_type != PT_LOAD) - continue; + /* We want to load PT_LOAD segments only.. */ + if (phdr[i].p_type != PT_LOAD) + continue; #ifdef ELF_VERBOSE - printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx", - (long)phdr[i].p_filesz, (long)phdr[i].p_offset, - (long)(phdr[i].p_vaddr + off), - (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1)); + printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx", + (long)phdr[i].p_filesz, (long)phdr[i].p_offset, + (long)(phdr[i].p_vaddr + off), + (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1)); #else - if ((phdr[i].p_flags & PF_W) == 0) { - printf("text=0x%lx ", (long)phdr[i].p_filesz); - } else { - printf("data=0x%lx", (long)phdr[i].p_filesz); - if (phdr[i].p_filesz < phdr[i].p_memsz) - printf("+0x%lx", (long)(phdr[i].p_memsz -phdr[i].p_filesz)); - printf(" "); - } + if ((phdr[i].p_flags & PF_W) == 0) { + printf("text=0x%lx ", (long)phdr[i].p_filesz); + } else { + printf("data=0x%lx", (long)phdr[i].p_filesz); + if (phdr[i].p_filesz < phdr[i].p_memsz) + printf("+0x%lx", (long)(phdr[i].p_memsz - + phdr[i].p_filesz)); + printf(" "); + } #endif - fpcopy = 0; - if (ef->firstlen > phdr[i].p_offset) { - fpcopy = ef->firstlen - phdr[i].p_offset; - archsw.arch_copyin(ef->firstpage + phdr[i].p_offset, - phdr[i].p_vaddr + off, fpcopy); - } - if (phdr[i].p_filesz > fpcopy) { - if (kern_pread(ef->fd, phdr[i].p_vaddr + off + fpcopy, - phdr[i].p_filesz - fpcopy, phdr[i].p_offset + fpcopy) != 0) { - printf("\nelf" __XSTRING(__ELF_WORD_SIZE) - "_loadimage: read failed\n"); - goto out; - } - } - /* clear space from oversized segments; eg: bss */ - if (phdr[i].p_filesz < phdr[i].p_memsz) { + fpcopy = 0; + if (ef->firstlen > phdr[i].p_offset) { + fpcopy = ef->firstlen - phdr[i].p_offset; + archsw.arch_copyin(ef->firstpage + phdr[i].p_offset, + phdr[i].p_vaddr + off, fpcopy); + } + if (phdr[i].p_filesz > fpcopy) { + if (kern_pread(ef->fd, phdr[i].p_vaddr + off + fpcopy, + phdr[i].p_filesz - fpcopy, + phdr[i].p_offset + fpcopy) != 0) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) + "_loadimage: read failed\n"); + goto out; + } + } + /* clear space from oversized segments; eg: bss */ + if (phdr[i].p_filesz < phdr[i].p_memsz) { #ifdef ELF_VERBOSE - printf(" (bss: 0x%lx-0x%lx)", - (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz), - (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1)); + printf(" (bss: 0x%lx-0x%lx)", + (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz), + (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz -1)); #endif - kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz, - phdr[i].p_memsz - phdr[i].p_filesz); - } + kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz, + phdr[i].p_memsz - phdr[i].p_filesz); + } #ifdef ELF_VERBOSE - printf("\n"); + printf("\n"); #endif - if (archsw.arch_loadseg != NULL) - archsw.arch_loadseg(ehdr, phdr + i, off); - - if (firstaddr == 0 || firstaddr > (phdr[i].p_vaddr + off)) - firstaddr = phdr[i].p_vaddr + off; - if (lastaddr == 0 || lastaddr < (phdr[i].p_vaddr + off + phdr[i].p_memsz)) - lastaddr = phdr[i].p_vaddr + off + phdr[i].p_memsz; - } - lastaddr = roundup(lastaddr, sizeof(long)); - - /* - * Get the section headers. We need this for finding the .ctors - * section as well as for loading any symbols. Both may be hard - * to do if reading from a .gz file as it involves seeking. I - * think the rule is going to have to be that you must strip a - * file to remove symbols before gzipping it. - */ - chunk = (size_t)ehdr->e_shnum * (size_t)ehdr->e_shentsize; - if (chunk == 0 || ehdr->e_shoff == 0) - goto nosyms; - shdr = alloc_pread(ef->fd, ehdr->e_shoff, chunk); - if (shdr == NULL) { - printf("\nelf" __XSTRING(__ELF_WORD_SIZE) - "_loadimage: failed to read section headers"); - goto nosyms; - } - - for (i = 0; i < ehdr->e_shnum; i++) - elf_section_header_convert(ehdr, &shdr[i]); - - file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr); - - /* - * Read the section string table and look for the .ctors section. - * We need to tell the kernel where it is so that it can call the - * ctors. - */ - chunk = shdr[ehdr->e_shstrndx].sh_size; - if (chunk) { - shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset, chunk); - if (shstr) { - for (i = 0; i < ehdr->e_shnum; i++) { - if (strcmp(shstr + shdr[i].sh_name, ".ctors") != 0) - continue; - ctors = shdr[i].sh_addr; - file_addmetadata(fp, MODINFOMD_CTORS_ADDR, sizeof(ctors), - &ctors); - size = shdr[i].sh_size; - file_addmetadata(fp, MODINFOMD_CTORS_SIZE, sizeof(size), - &size); - break; - } - free(shstr); + if (archsw.arch_loadseg != NULL) + archsw.arch_loadseg(ehdr, phdr + i, off); + + if (firstaddr == 0 || firstaddr > (phdr[i].p_vaddr + off)) + firstaddr = phdr[i].p_vaddr + off; + if (lastaddr == 0 || lastaddr < + (phdr[i].p_vaddr + off + phdr[i].p_memsz)) + lastaddr = phdr[i].p_vaddr + off + phdr[i].p_memsz; + } + lastaddr = roundup(lastaddr, sizeof(long)); + + /* + * Get the section headers. We need this for finding the .ctors + * section as well as for loading any symbols. Both may be hard + * to do if reading from a .gz file as it involves seeking. I + * think the rule is going to have to be that you must strip a + * file to remove symbols before gzipping it. + */ + chunk = (size_t)ehdr->e_shnum * (size_t)ehdr->e_shentsize; + if (chunk == 0 || ehdr->e_shoff == 0) + goto nosyms; + shdr = alloc_pread(ef->fd, ehdr->e_shoff, chunk); + if (shdr == NULL) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) + "_loadimage: failed to read section headers"); + goto nosyms; } - } - - /* - * Now load any symbols. - */ - symtabindex = -1; - symstrindex = -1; - for (i = 0; i < ehdr->e_shnum; i++) { - if (shdr[i].sh_type != SHT_SYMTAB) - continue; - for (j = 0; j < ehdr->e_phnum; j++) { - if (phdr[j].p_type != PT_LOAD) - continue; - if (shdr[i].sh_offset >= phdr[j].p_offset && - (shdr[i].sh_offset + shdr[i].sh_size <= - phdr[j].p_offset + phdr[j].p_filesz)) { - shdr[i].sh_offset = 0; - shdr[i].sh_size = 0; - break; - } + + for (i = 0; i < ehdr->e_shnum; i++) + elf_section_header_convert(ehdr, &shdr[i]); + + file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr); + + /* + * Read the section string table and look for the .ctors section. + * We need to tell the kernel where it is so that it can call the + * ctors. + */ + chunk = shdr[ehdr->e_shstrndx].sh_size; + if (chunk) { + shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset, + chunk); + if (shstr) { + for (i = 0; i < ehdr->e_shnum; i++) { + if (strcmp(shstr + shdr[i].sh_name, + ".ctors") != 0) + continue; + ctors = shdr[i].sh_addr; + file_addmetadata(fp, MODINFOMD_CTORS_ADDR, + sizeof(ctors), &ctors); + size = shdr[i].sh_size; + file_addmetadata(fp, MODINFOMD_CTORS_SIZE, + sizeof(size), &size); + break; + } + free(shstr); + } } - if (shdr[i].sh_offset == 0 || shdr[i].sh_size == 0) - continue; /* alread loaded in a PT_LOAD above */ - /* Save it for loading below */ - symtabindex = i; - symstrindex = shdr[i].sh_link; - } - if (symtabindex < 0 || symstrindex < 0) - goto nosyms; - - /* Ok, committed to a load. */ + + /* + * Now load any symbols. + */ + symtabindex = -1; + symstrindex = -1; + for (i = 0; i < ehdr->e_shnum; i++) { + if (shdr[i].sh_type != SHT_SYMTAB) + continue; + for (j = 0; j < ehdr->e_phnum; j++) { + if (phdr[j].p_type != PT_LOAD) + continue; + if (shdr[i].sh_offset >= phdr[j].p_offset && + (shdr[i].sh_offset + shdr[i].sh_size <= + phdr[j].p_offset + phdr[j].p_filesz)) { + shdr[i].sh_offset = 0; + shdr[i].sh_size = 0; + break; + } + } + if (shdr[i].sh_offset == 0 || shdr[i].sh_size == 0) + continue; /* alread loaded in a PT_LOAD above */ + /* Save it for loading below */ + symtabindex = i; + symstrindex = shdr[i].sh_link; + } + if (symtabindex < 0 || symstrindex < 0) + goto nosyms; + + /* Ok, committed to a load. */ #ifndef ELF_VERBOSE - printf("syms=["); + printf("syms=["); #endif - ssym = lastaddr; - for (i = symtabindex; i >= 0; i = symstrindex) { + ssym = lastaddr; + for (i = symtabindex; i >= 0; i = symstrindex) { #ifdef ELF_VERBOSE - char *secname; - - switch(shdr[i].sh_type) { - case SHT_SYMTAB: /* Symbol table */ - secname = "symtab"; - break; - case SHT_STRTAB: /* String table */ - secname = "strtab"; - break; - default: - secname = "WHOA!!"; - break; - } + char *secname; + + switch(shdr[i].sh_type) { + case SHT_SYMTAB: /* Symbol table */ + secname = "symtab"; + break; + case SHT_STRTAB: /* String table */ + secname = "strtab"; + break; + default: + secname = "WHOA!!"; + break; + } #endif - size = shdr[i].sh_size; + size = shdr[i].sh_size; #if defined(__powerpc__) #if __ELF_WORD_SIZE == 64 - size = htobe64(size); + size = htobe64(size); #else - size = htobe32(size); + size = htobe32(size); #endif #endif - archsw.arch_copyin(&size, lastaddr, sizeof(size)); - lastaddr += sizeof(size); + archsw.arch_copyin(&size, lastaddr, sizeof(size)); + lastaddr += sizeof(size); #ifdef ELF_VERBOSE - printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname, - (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset, - (uintmax_t)lastaddr, (uintmax_t)(lastaddr + shdr[i].sh_size)); + printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname, + (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset, + (uintmax_t)lastaddr, + (uintmax_t)(lastaddr + shdr[i].sh_size)); #else - if (i == symstrindex) - printf("+"); - printf("0x%lx+0x%lx", (long)sizeof(size), (long)size); + if (i == symstrindex) + printf("+"); + printf("0x%lx+0x%lx", (long)sizeof(size), (long)size); #endif - if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) { - printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not seek for symbols - skipped!"); - lastaddr = ssym; - ssym = 0; - goto nosyms; - } - result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size); - if (result < 0 || (size_t)result != shdr[i].sh_size) { - printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not read symbols - skipped! (%ju != %ju)", (uintmax_t)result, - (uintmax_t)shdr[i].sh_size); - lastaddr = ssym; - ssym = 0; - goto nosyms; + if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) + "_loadimage: could not seek for symbols - skipped!"); + lastaddr = ssym; + ssym = 0; + goto nosyms; + } + result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size); + if (result < 0 || (size_t)result != shdr[i].sh_size) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) + "_loadimage: could not read symbols - skipped! " + "(%ju != %ju)", (uintmax_t)result, + (uintmax_t)shdr[i].sh_size); + lastaddr = ssym; + ssym = 0; + goto nosyms; + } + /* Reset offsets relative to ssym */ + lastaddr += shdr[i].sh_size; + lastaddr = roundup(lastaddr, sizeof(size)); + if (i == symtabindex) + symtabindex = -1; + else if (i == symstrindex) + symstrindex = -1; } - /* Reset offsets relative to ssym */ - lastaddr += shdr[i].sh_size; - lastaddr = roundup(lastaddr, sizeof(size)); - if (i == symtabindex) - symtabindex = -1; - else if (i == symstrindex) - symstrindex = -1; - } - esym = lastaddr; + esym = lastaddr; #ifndef ELF_VERBOSE - printf("]"); + printf("]"); #endif #if defined(__powerpc__) /* On PowerPC we always need to provide BE data to the kernel */ #if __ELF_WORD_SIZE == 64 - ssym = htobe64((uint64_t)ssym); - esym = htobe64((uint64_t)esym); + ssym = htobe64((uint64_t)ssym); + esym = htobe64((uint64_t)esym); #else - ssym = htobe32((uint32_t)ssym); - esym = htobe32((uint32_t)esym); + ssym = htobe32((uint32_t)ssym); + esym = htobe32((uint32_t)esym); #endif #endif - file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym); - file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym); + file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym); + file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym); nosyms: - printf("\n"); - - ret = lastaddr - firstaddr; - fp->f_addr = firstaddr; - - php = NULL; - for (i = 0; i < ehdr->e_phnum; i++) { - if (phdr[i].p_type == PT_DYNAMIC) { - php = phdr + i; - adp = php->p_vaddr; - file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp), &adp); - break; + printf("\n"); + + ret = lastaddr - firstaddr; + fp->f_addr = firstaddr; + + php = NULL; + for (i = 0; i < ehdr->e_phnum; i++) { + if (phdr[i].p_type == PT_DYNAMIC) { + php = phdr + i; + adp = php->p_vaddr; + file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp), + &adp); + break; + } } - } - if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */ - goto out; + if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */ + goto out; - ndp = php->p_filesz / sizeof(Elf_Dyn); - if (ndp == 0) - goto out; - dp = malloc(php->p_filesz); - if (dp == NULL) - goto out; - archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz); - - ef->strsz = 0; - for (i = 0; i < ndp; i++) { - if (dp[i].d_tag == 0) - break; - switch (dp[i].d_tag) { - case DT_HASH: - ef->hashtab = (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off); - break; - case DT_STRTAB: - ef->strtab = (char *)(uintptr_t)(dp[i].d_un.d_ptr + off); - break; - case DT_STRSZ: - ef->strsz = dp[i].d_un.d_val; - break; - case DT_SYMTAB: - ef->symtab = (Elf_Sym*)(uintptr_t)(dp[i].d_un.d_ptr + off); - break; - case DT_REL: - ef->rel = (Elf_Rel *)(uintptr_t)(dp[i].d_un.d_ptr + off); - break; - case DT_RELSZ: - ef->relsz = dp[i].d_un.d_val; - break; - case DT_RELA: - ef->rela = (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off); - break; - case DT_RELASZ: - ef->relasz = dp[i].d_un.d_val; - break; - default: - break; + ndp = php->p_filesz / sizeof(Elf_Dyn); + if (ndp == 0) + goto out; + dp = malloc(php->p_filesz); + if (dp == NULL) + goto out; + archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz); + + ef->strsz = 0; + for (i = 0; i < ndp; i++) { + if (dp[i].d_tag == 0) + break; + switch (dp[i].d_tag) { + case DT_HASH: + ef->hashtab = + (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; + case DT_STRTAB: + ef->strtab = + (char *)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; + case DT_STRSZ: + ef->strsz = dp[i].d_un.d_val; + break; + case DT_SYMTAB: + ef->symtab = + (Elf_Sym *)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; + case DT_REL: + ef->rel = + (Elf_Rel *)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; + case DT_RELSZ: + ef->relsz = dp[i].d_un.d_val; + break; + case DT_RELA: + ef->rela = + (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; + case DT_RELASZ: + ef->relasz = dp[i].d_un.d_val; + break; + default: + break; + } } - } - if (ef->hashtab == NULL || ef->symtab == NULL || - ef->strtab == NULL || ef->strsz == 0) - goto out; - COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets)); - COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains)); - ef->buckets = ef->hashtab + 2; - ef->chains = ef->buckets + ef->nbuckets; + if (ef->hashtab == NULL || ef->symtab == NULL || + ef->strtab == NULL || ef->strsz == 0) + goto out; + COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets)); + COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains)); + ef->buckets = ef->hashtab + 2; + ef->chains = ef->buckets + ef->nbuckets; - if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0) - return 0; - p_start = sym.st_value + ef->off; - if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0) - return ENOENT; - p_end = sym.st_value + ef->off; + if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", + &sym) != 0) + return 0; + p_start = sym.st_value + ef->off; + if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", + &sym) != 0) + return ENOENT; + p_end = sym.st_value + ef->off; - if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0) - goto out; + if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0) + goto out; - if (ef->kernel) /* kernel must not depend on anything */ - goto out; + if (ef->kernel) /* kernel must not depend on anything */ + goto out; out: - if (dp) - free(dp); - if (shdr) - free(shdr); - return ret; + if (dp) + free(dp); + if (shdr) + free(shdr); + return ret; } static char invalid_name[] = "bad"; @@ -819,51 +853,51 @@ static char invalid_name[] = "bad"; char * fake_modname(const char *name) { - const char *sp, *ep; - char *fp; - size_t len; - - sp = strrchr(name, '/'); - if (sp) - sp++; - else - sp = name; - ep = strrchr(name, '.'); - if (ep) { - if (ep == name) { - sp = invalid_name; - ep = invalid_name + sizeof(invalid_name) - 1; - } - } else - ep = name + strlen(name); - len = ep - sp; - fp = malloc(len + 1); - if (fp == NULL) - return NULL; - memcpy(fp, sp, len); - fp[len] = '\0'; - return fp; + const char *sp, *ep; + char *fp; + size_t len; + + sp = strrchr(name, '/'); + if (sp) + sp++; + else + sp = name; + ep = strrchr(name, '.'); + if (ep) { + if (ep == name) { + sp = invalid_name; + ep = invalid_name + sizeof(invalid_name) - 1; + } + } else + ep = name + strlen(name); + len = ep - sp; + fp = malloc(len + 1); + if (fp == NULL) + return NULL; + memcpy(fp, sp, len); + fp[len] = '\0'; + return fp; } #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 struct mod_metadata64 { - int md_version; /* structure version MDTV_* */ + int md_version; /* structure version MDTV_* */ int md_type; /* type of entry MDT_* */ - u_int64_t md_data; /* specific data */ - u_int64_t md_cval; /* common string label */ + uint64_t md_data; /* specific data */ + uint64_t md_cval; /* common string label */ }; #endif #if defined(__amd64__) && __ELF_WORD_SIZE == 32 struct mod_metadata32 { - int md_version; /* structure version MDTV_* */ + int md_version; /* structure version MDTV_* */ int md_type; /* type of entry MDT_* */ - u_int32_t md_data; /* specific data */ - u_int32_t md_cval; /* common string label */ + uint32_t md_data; /* specific data */ + uint32_t md_cval; /* common string label */ }; #endif int -__elfN(load_modmetadata)(struct preloaded_file *fp, u_int64_t dest) +__elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest) { struct elf_file ef; int err, i, j; @@ -981,149 +1015,153 @@ int __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef, Elf_Addr p_start, Elf_Addr p_end) { - struct mod_metadata md; + struct mod_metadata md; #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 - struct mod_metadata64 md64; + struct mod_metadata64 md64; #elif defined(__amd64__) && __ELF_WORD_SIZE == 32 - struct mod_metadata32 md32; + struct mod_metadata32 md32; #endif - struct mod_depend *mdepend; - struct mod_version mver; - char *s; - int error, modcnt, minfolen; - Elf_Addr v, p; - - modcnt = 0; - p = p_start; - while (p < p_end) { - COPYOUT(p, &v, sizeof(v)); - error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v)); - if (error == EOPNOTSUPP) - v += ef->off; - else if (error != 0) - return (error); + struct mod_depend *mdepend; + struct mod_version mver; + char *s; + int error, modcnt, minfolen; + Elf_Addr v, p; + + modcnt = 0; + p = p_start; + while (p < p_end) { + COPYOUT(p, &v, sizeof(v)); + error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v)); + if (error == EOPNOTSUPP) + v += ef->off; + else if (error != 0) + return (error); #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 - COPYOUT(v, &md64, sizeof(md64)); - error = __elfN(reloc_ptr)(fp, ef, v, &md64, sizeof(md64)); - if (error == EOPNOTSUPP) { - md64.md_cval += ef->off; - md64.md_data += ef->off; - } else if (error != 0) - return (error); - md.md_version = md64.md_version; - md.md_type = md64.md_type; - md.md_cval = (const char *)(uintptr_t)md64.md_cval; - md.md_data = (void *)(uintptr_t)md64.md_data; + COPYOUT(v, &md64, sizeof(md64)); + error = __elfN(reloc_ptr)(fp, ef, v, &md64, sizeof(md64)); + if (error == EOPNOTSUPP) { + md64.md_cval += ef->off; + md64.md_data += ef->off; + } else if (error != 0) + return (error); + md.md_version = md64.md_version; + md.md_type = md64.md_type; + md.md_cval = (const char *)(uintptr_t)md64.md_cval; + md.md_data = (void *)(uintptr_t)md64.md_data; #elif defined(__amd64__) && __ELF_WORD_SIZE == 32 - COPYOUT(v, &md32, sizeof(md32)); - error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32)); - if (error == EOPNOTSUPP) { - md32.md_cval += ef->off; - md32.md_data += ef->off; - } else if (error != 0) - return (error); - md.md_version = md32.md_version; - md.md_type = md32.md_type; - md.md_cval = (const char *)(uintptr_t)md32.md_cval; - md.md_data = (void *)(uintptr_t)md32.md_data; + COPYOUT(v, &md32, sizeof(md32)); + error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32)); + if (error == EOPNOTSUPP) { + md32.md_cval += ef->off; + md32.md_data += ef->off; + } else if (error != 0) + return (error); + md.md_version = md32.md_version; + md.md_type = md32.md_type; + md.md_cval = (const char *)(uintptr_t)md32.md_cval; + md.md_data = (void *)(uintptr_t)md32.md_data; #else - COPYOUT(v, &md, sizeof(md)); - error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md)); - if (error == EOPNOTSUPP) { - md.md_cval += ef->off; - md.md_data = (void *)((uintptr_t)md.md_data + (uintptr_t)ef->off); - } else if (error != 0) - return (error); + COPYOUT(v, &md, sizeof(md)); + error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md)); + if (error == EOPNOTSUPP) { + md.md_cval += ef->off; + md.md_data = (void *)((uintptr_t)md.md_data + + (uintptr_t)ef->off); + } else if (error != 0) + return (error); #endif - p += sizeof(Elf_Addr); - switch(md.md_type) { - case MDT_DEPEND: - if (ef->kernel) /* kernel must not depend on anything */ - break; - s = strdupout((vm_offset_t)md.md_cval); - minfolen = sizeof(*mdepend) + strlen(s) + 1; - mdepend = malloc(minfolen); - if (mdepend == NULL) - return ENOMEM; - COPYOUT((vm_offset_t)md.md_data, mdepend, sizeof(*mdepend)); - strcpy((char*)(mdepend + 1), s); - free(s); - file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, mdepend); - free(mdepend); - break; - case MDT_VERSION: - s = strdupout((vm_offset_t)md.md_cval); - COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver)); - file_addmodule(fp, s, mver.mv_version, NULL); - free(s); - modcnt++; - break; + p += sizeof(Elf_Addr); + switch(md.md_type) { + case MDT_DEPEND: + if (ef->kernel) /* kernel must not depend on anything */ + break; + s = strdupout((vm_offset_t)md.md_cval); + minfolen = sizeof(*mdepend) + strlen(s) + 1; + mdepend = malloc(minfolen); + if (mdepend == NULL) + return ENOMEM; + COPYOUT((vm_offset_t)md.md_data, mdepend, + sizeof(*mdepend)); + strcpy((char*)(mdepend + 1), s); + free(s); + file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, + mdepend); + free(mdepend); + break; + case MDT_VERSION: + s = strdupout((vm_offset_t)md.md_cval); + COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver)); + file_addmodule(fp, s, mver.mv_version, NULL); + free(s); + modcnt++; + break; + } + } + if (modcnt == 0) { + s = fake_modname(fp->f_name); + file_addmodule(fp, s, 1, NULL); + free(s); } - } - if (modcnt == 0) { - s = fake_modname(fp->f_name); - file_addmodule(fp, s, 1, NULL); - free(s); - } - return 0; + return 0; } static unsigned long elf_hash(const char *name) { - const unsigned char *p = (const unsigned char *) name; - unsigned long h = 0; - unsigned long g; - - while (*p != '\0') { - h = (h << 4) + *p++; - if ((g = h & 0xf0000000) != 0) - h ^= g >> 24; - h &= ~g; - } - return h; + const unsigned char *p = (const unsigned char *) name; + unsigned long h = 0; + unsigned long g; + + while (*p != '\0') { + h = (h << 4) + *p++; + if ((g = h & 0xf0000000) != 0) + h ^= g >> 24; + h &= ~g; + } + return h; } -static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) "_lookup_symbol: corrupt symbol table\n"; +static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) + "_lookup_symbol: corrupt symbol table\n"; int -__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef, const char* name, - Elf_Sym *symp) +__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef, + const char* name, Elf_Sym *symp) { - Elf_Hashelt symnum; - Elf_Sym sym; - char *strp; - unsigned long hash; - - hash = elf_hash(name); - COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum)); - - while (symnum != STN_UNDEF) { - if (symnum >= ef->nchains) { - printf(__elfN(bad_symtable)); - return ENOENT; - } + Elf_Hashelt symnum; + Elf_Sym sym; + char *strp; + unsigned long hash; + + hash = elf_hash(name); + COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum)); + + while (symnum != STN_UNDEF) { + if (symnum >= ef->nchains) { + printf(__elfN(bad_symtable)); + return ENOENT; + } - COPYOUT(ef->symtab + symnum, &sym, sizeof(sym)); - if (sym.st_name == 0) { - printf(__elfN(bad_symtable)); - return ENOENT; - } + COPYOUT(ef->symtab + symnum, &sym, sizeof(sym)); + if (sym.st_name == 0) { + printf(__elfN(bad_symtable)); + return ENOENT; + } - strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name)); - if (strcmp(name, strp) == 0) { - free(strp); - if (sym.st_shndx != SHN_UNDEF || - (sym.st_value != 0 && - ELF_ST_TYPE(sym.st_info) == STT_FUNC)) { - *symp = sym; - return 0; - } - return ENOENT; + strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name)); + if (strcmp(name, strp) == 0) { + free(strp); + if (sym.st_shndx != SHN_UNDEF || + (sym.st_value != 0 && + ELF_ST_TYPE(sym.st_info) == STT_FUNC)) { + *symp = sym; + return 0; + } + return ENOENT; + } + free(strp); + COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum)); } - free(strp); - COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum)); - } - return ENOENT; + return ENOENT; } /* diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c index 57df57a..3ff6e5f 100644 --- a/stand/common/load_elf_obj.c +++ b/stand/common/load_elf_obj.c @@ -63,7 +63,7 @@ typedef struct elf_file { } *elf_file_t; static int __elfN(obj_loadimage)(struct preloaded_file *mp, elf_file_t ef, - u_int64_t loadaddr); + uint64_t loadaddr); static int __elfN(obj_lookup_set)(struct preloaded_file *mp, elf_file_t ef, const char *name, Elf_Addr *startp, Elf_Addr *stopp, int *countp); static int __elfN(obj_reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, @@ -81,7 +81,7 @@ const char *__elfN(obj_moduletype) = "elf obj module"; * will be saved in (result). */ int -__elfN(obj_loadfile)(char *filename, u_int64_t dest, +__elfN(obj_loadfile)(char *filename, uint64_t dest, struct preloaded_file **result) { struct preloaded_file *fp, *kfp; @@ -186,7 +186,7 @@ out: * the Elf header, load the image at (off) */ static int -__elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) +__elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off) { Elf_Ehdr *hdr; Elf_Shdr *shdr, *cshdr, *lshdr; @@ -224,6 +224,8 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) #if defined(__i386__) || defined(__amd64__) case SHT_X86_64_UNWIND: #endif + if ((shdr[i].sh_flags & SHF_ALLOC) == 0) + break; lastaddr = roundup(lastaddr, shdr[i].sh_addralign); shdr[i].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[i].sh_size; @@ -280,6 +282,8 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) switch (shdr[i].sh_type) { case SHT_REL: case SHT_RELA: + if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) + break; lastaddr = roundup(lastaddr, shdr[i].sh_addralign); shdr[i].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[i].sh_size; @@ -345,8 +349,8 @@ out: struct mod_metadata64 { int md_version; /* structure version MDTV_* */ int md_type; /* type of entry MDT_* */ - u_int64_t md_data; /* specific data */ - u_int64_t md_cval; /* common string label */ + uint64_t md_data; /* specific data */ + uint64_t md_cval; /* common string label */ }; #endif diff --git a/stand/powerpc/ofw/metadata.c b/stand/common/metadata.c index 25d51f8..16f8c58 100644 --- a/stand/powerpc/ofw/metadata.c +++ b/stand/common/metadata.c @@ -34,12 +34,66 @@ __FBSDID("$FreeBSD$"); #include <sys/reboot.h> #include <sys/linker.h> #include <sys/boot.h> +#if defined(LOADER_FDT_SUPPORT) #include <fdt_platform.h> +#endif +#ifdef __arm__ +#include <machine/elf.h> +#endif #include <machine/metadata.h> #include "bootstrap.h" +#if defined(__sparc64__) +#include <openfirm.h> + +extern struct tlb_entry *dtlb_store; +extern struct tlb_entry *itlb_store; + +extern int dtlb_slot; +extern int itlb_slot; + +static int +md_bootserial(void) +{ + char buf[64]; + ihandle_t inst; + phandle_t input; + phandle_t node; + phandle_t output; + + if ((node = OF_finddevice("/options")) == -1) + return(-1); + if (OF_getprop(node, "input-device", buf, sizeof(buf)) == -1) + return(-1); + input = OF_finddevice(buf); + if (OF_getprop(node, "output-device", buf, sizeof(buf)) == -1) + return(-1); + output = OF_finddevice(buf); + if (input == -1 || output == -1 || + OF_getproplen(input, "keyboard") >= 0) { + if ((node = OF_finddevice("/chosen")) == -1) + return(-1); + if (OF_getprop(node, "stdin", &inst, sizeof(inst)) == -1) + return(-1); + if ((input = OF_instance_to_package(inst)) == -1) + return(-1); + if (OF_getprop(node, "stdout", &inst, sizeof(inst)) == -1) + return(-1); + if ((output = OF_instance_to_package(inst)) == -1) + return(-1); + } + if (input != output) + return(-1); + if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) + return(-1); + if (strcmp(buf, "serial") != 0) + return(-1); + return(0); +} +#endif + int md_getboothowto(char *kargs) { @@ -47,7 +101,7 @@ md_getboothowto(char *kargs) int howto; int active; int i; - + /* Parse kargs */ howto = 0; if (kargs != NULL) { @@ -98,14 +152,20 @@ md_getboothowto(char *kargs) cp++; } } + /* get equivalents from the environment */ for (i = 0; howto_names[i].ev != NULL; i++) if (getenv(howto_names[i].ev) != NULL) howto |= howto_names[i].mask; +#if defined(__sparc64__) + if (md_bootserial() != -1) + howto |= RB_SERIAL; +#else if (!strcmp(getenv("console"), "comconsole")) howto |= RB_SERIAL; if (!strcmp(getenv("console"), "nullconsole")) howto |= RB_MUTE; +#endif return(howto); } @@ -114,11 +174,11 @@ md_getboothowto(char *kargs) * Each variable is formatted as <name>=<value>, with a single nul * separating each variable, and a double nul terminating the environment. */ -vm_offset_t +static vm_offset_t md_copyenv(vm_offset_t addr) { struct env_var *ep; - + /* traverse the environment */ for (ep = environ; ep != NULL; ep = ep->ev_next) { archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name)); @@ -157,7 +217,7 @@ md_copyenv(vm_offset_t addr) static int align; #define COPY32(v, a, c) { \ - u_int32_t x = (v); \ + uint32_t x = (v); \ if (c) \ archsw.arch_copyin(&x, a, sizeof(x)); \ a += sizeof(x); \ @@ -199,12 +259,13 @@ static int align; COPY32(0, a, c); \ } -vm_offset_t +static vm_offset_t md_copymodules(vm_offset_t addr, int kern64) { struct preloaded_file *fp; struct file_metadata *md; uint64_t scratch64; + uint32_t scratch32; int c; c = addr != 0; @@ -221,7 +282,11 @@ md_copymodules(vm_offset_t addr, int kern64) scratch64 = fp->f_size; MOD_SIZE(addr, scratch64, c); } else { - MOD_ADDR(addr, fp->f_addr, c); + scratch32 = fp->f_addr; +#ifdef __arm__ + scratch32 -= __elfN(relocation_offset); +#endif + MOD_ADDR(addr, scratch32, c); MOD_SIZE(addr, fp->f_size, c); } for (md = fp->f_metadata; md != NULL; md = md->md_next) { @@ -235,7 +300,7 @@ md_copymodules(vm_offset_t addr, int kern64) } /* - * Load the information expected by a powerpc kernel. + * Load the information expected by a kernel. * * - The 'boothowto' argument is constructed * - The 'bootdev' argument is constructed @@ -251,49 +316,72 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) vm_offset_t kernend; vm_offset_t addr; vm_offset_t envp; +#if defined(LOADER_FDT_SUPPORT) vm_offset_t fdtp; +#endif vm_offset_t size; uint64_t scratch64; char *rootdevname; int howto; +#ifdef __arm__ + vm_offset_t vaddr; + int i; + + /* + * These metadata addreses must be converted for kernel after + * relocation. + */ + uint32_t mdt[] = { + MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND, + MODINFOMD_ENVP, +#if defined(LOADER_FDT_SUPPORT) + MODINFOMD_DTBP +#endif + }; +#endif align = kern64 ? 8 : 4; howto = md_getboothowto(args); - /* - * Allow the environment variable 'rootdev' to override the supplied device - * This should perhaps go to MI code and/or have $rootdev tested/set by - * MI code before launching the kernel. + /* + * Allow the environment variable 'rootdev' to override the supplied + * device. This should perhaps go to MI code and/or have $rootdev + * tested/set by MI code before launching the kernel. */ rootdevname = getenv("rootdev"); if (rootdevname == NULL) - rootdevname = getenv("currdev"); + rootdevname = getenv("currdev"); /* Try reading the /etc/fstab file to select the root device */ getrootmount(rootdevname); - /* find the last module in the chain */ + /* Find the last module in the chain */ addr = 0; for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { if (addr < (xp->f_addr + xp->f_size)) addr = xp->f_addr + xp->f_size; } - /* pad to a page boundary */ + /* Pad to a page boundary */ addr = roundup(addr, PAGE_SIZE); - /* copy our environment */ + /* Copy our environment */ envp = addr; addr = md_copyenv(addr); - /* pad to a page boundary */ + /* Pad to a page boundary */ addr = roundup(addr, PAGE_SIZE); +#if defined(LOADER_FDT_SUPPORT) /* Copy out FDT */ - *dtb = fdtp = 0; - if (getenv("usefdt") != NULL) { - size = fdt_copy(addr); - *dtb = fdtp = addr; - addr = roundup(addr + size, PAGE_SIZE); + fdtp = 0; +#if defined(__powerpc__) + if (getenv("usefdt") != NULL) +#endif + { + size = fdt_copy(addr); + fdtp = addr; + addr = roundup(addr + size, PAGE_SIZE); } +#endif kernend = 0; kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel"); @@ -305,19 +393,35 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) if (kern64) { scratch64 = envp; file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64); - if (fdtp != 0) { +#if defined(LOADER_FDT_SUPPORT) + if (fdtp != 0) { scratch64 = fdtp; file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch64, &scratch64); - } + } +#endif scratch64 = kernend; - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64); + file_addmetadata(kfp, MODINFOMD_KERNEND, + sizeof scratch64, &scratch64); } else { file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); - if (fdtp != 0) +#if defined(LOADER_FDT_SUPPORT) + if (fdtp != 0) file_addmetadata(kfp, MODINFOMD_DTBP, sizeof fdtp, &fdtp); +#endif file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); } +#if defined(__sparc64__) + file_addmetadata(kfp, MODINFOMD_DTLB_SLOTS, + sizeof dtlb_slot, &dtlb_slot); + file_addmetadata(kfp, MODINFOMD_ITLB_SLOTS, + sizeof itlb_slot, &itlb_slot); + file_addmetadata(kfp, MODINFOMD_DTLB, + dtlb_slot * sizeof(*dtlb_store), dtlb_store); + file_addmetadata(kfp, MODINFOMD_ITLB, + itlb_slot * sizeof(*itlb_store), itlb_store); +#endif + *modulep = addr; size = md_copymodules(0, kern64); kernend = roundup(addr + size, PAGE_SIZE); @@ -329,8 +433,29 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) } else { bcopy(&kernend, md->md_data, sizeof kernend); } - + +#ifdef __arm__ + /* Convert addresses to the final VA */ + *modulep -= __elfN(relocation_offset); + + /* Do relocation fixup on metadata of each module. */ + for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { + for (i = 0; i < nitems(mdt); i++) { + md = file_findmetadata(xp, mdt[i]); + if (md) { + bcopy(md->md_data, &vaddr, sizeof vaddr); + vaddr -= __elfN(relocation_offset); + bcopy(&vaddr, md->md_data, sizeof vaddr); + } + } + } +#endif + (void)md_copymodules(addr, kern64); +#if defined(LOADER_FDT_SUPPORT) + if (dtb != NULL) + *dtb = fdtp; +#endif return(0); } @@ -341,9 +466,10 @@ md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb) return (md_load_dual(args, modulep, dtb, 0)); } +#if defined(__mips__) || defined(__powerpc__) int md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb) { return (md_load_dual(args, modulep, dtb, 1)); } - +#endif diff --git a/stand/common/misc.c b/stand/common/misc.c index 4c0273f..2ad9afa 100644 --- a/stand/common/misc.c +++ b/stand/common/misc.c @@ -185,7 +185,7 @@ hexdump(caddr_t region, size_t len) for (x = 0; x < 16; x++) { if ((line + x) < (region + len)) { - emit("%02x ", *(u_int8_t *)(line + x)); + emit("%02x ", *(uint8_t *)(line + x)); } else { emit("-- "); } @@ -195,7 +195,7 @@ hexdump(caddr_t region, size_t len) emit(" |"); for (x = 0; x < 16; x++) { if ((line + x) < (region + len)) { - c = *(u_int8_t *)(line + x); + c = *(uint8_t *)(line + x); if ((c < ' ') || (c > '~')) /* !isprint(c) */ c = '.'; emit("%c", c); diff --git a/stand/common/part.c b/stand/common/part.c index cdb1e00..9a59453 100644 --- a/stand/common/part.c +++ b/stand/common/part.c @@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$"); #include <sys/queue.h> #include <sys/vtoc.h> +#include <fs/cd9660/iso.h> + #include <crc32.h> #include <part.h> #include <uuid.h> @@ -97,6 +99,7 @@ static struct parttypes { { PART_LINUX, "Linux" }, { PART_LINUX_SWAP, "Linux swap" }, { PART_DOS, "DOS/Windows" }, + { PART_ISO9660, "ISO9660" }, }; const char * @@ -603,6 +606,45 @@ out: } #endif /* LOADER_VTOC8_SUPPORT */ +#define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / table->sectorsize) + +static struct ptable * +ptable_iso9660read(struct ptable *table, void *dev, diskread_t dread) +{ + uint8_t *buf; + struct iso_primary_descriptor *vd; + struct pentry *entry; + + buf = malloc(table->sectorsize); + if (buf == NULL) + return (table); + + if (dread(dev, buf, 1, cdb2devb(16)) != 0) { + DEBUG("read failed"); + ptable_close(table); + table = NULL; + goto out; + } + vd = (struct iso_primary_descriptor *)buf; + if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0) + goto out; + + entry = malloc(sizeof(*entry)); + if (entry == NULL) + goto out; + entry->part.start = 0; + entry->part.end = table->sectors; + entry->part.type = PART_ISO9660; + entry->part.index = 0; + STAILQ_INSERT_TAIL(&table->entries, entry, entry); + + table->type = PTABLE_ISO9660; + +out: + free(buf); + return (table); +} + struct ptable * ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, diskread_t *dread) @@ -634,6 +676,11 @@ ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, table->type = PTABLE_NONE; STAILQ_INIT(&table->entries); + if (ptable_iso9660read(table, dev, dread) != NULL) { + if (table->type == PTABLE_ISO9660) + goto out; + } + #ifdef LOADER_VTOC8_SUPPORT if (be16dec(buf + offsetof(struct vtoc8, magic)) == VTOC_MAGIC) { if (ptable_vtoc8read(table, dev, dread) == NULL) { diff --git a/stand/common/part.h b/stand/common/part.h index 19bd670..3eac476 100644 --- a/stand/common/part.h +++ b/stand/common/part.h @@ -36,7 +36,8 @@ enum ptable_type { PTABLE_BSD, PTABLE_MBR, PTABLE_GPT, - PTABLE_VTOC8 + PTABLE_VTOC8, + PTABLE_ISO9660 }; enum partition_type { @@ -52,6 +53,7 @@ enum partition_type { PART_LINUX, PART_LINUX_SWAP, PART_DOS, + PART_ISO9660 }; struct ptable_entry { diff --git a/stand/common/pnp.c b/stand/common/pnp.c index 31a0de9..4759c44 100644 --- a/stand/common/pnp.c +++ b/stand/common/pnp.c @@ -169,7 +169,7 @@ pnp_addinfo(struct pnpinfo *pi) * where 'AAA' is the EISA vendor ID, II is the product ID and RR the revision ID. */ char * -pnp_eisaformat(u_int8_t *data) +pnp_eisaformat(uint8_t *data) { static char idbuf[8]; const char hextoascii[] = "0123456789abcdef"; diff --git a/stand/common/zfs_cmd.c b/stand/common/zfs_cmd.c new file mode 100644 index 0000000..ae5a4b1 --- /dev/null +++ b/stand/common/zfs_cmd.c @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2018 Warner Losh <imp@freebd.org> + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * MD bootstrap main() and assorted miscellaneous + * commands. + */ + +#include <stand.h> +#include <stddef.h> +#include <sys/disk.h> +#include <sys/reboot.h> + +#include "bootstrap.h" + +#ifdef LOADER_ZFS_SUPPORT +#include "../zfs/libzfs.h" +#endif + +COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset", + command_lszfs); + +static int +command_lszfs(int argc, char *argv[]) +{ + int err; + + if (argc != 2) { + command_errmsg = "a single dataset must be supplied"; + return (CMD_ERROR); + } + + err = zfs_list(argv[1]); + if (err != 0) { + command_errmsg = strerror(err); + return (CMD_ERROR); + } + return (CMD_OK); +} + +COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments", + command_reloadbe); + +static int +command_reloadbe(int argc, char *argv[]) +{ + int err; + char *root; + + if (argc > 2) { + command_errmsg = "wrong number of arguments"; + return (CMD_ERROR); + } + + if (argc == 2) { + err = zfs_bootenv(argv[1]); + } else { + root = getenv("zfs_be_root"); + if (root == NULL) { + /* There does not appear to be a ZFS pool here, exit without error */ + return (CMD_OK); + } + err = zfs_bootenv(root); + } + + if (err != 0) { + command_errmsg = strerror(err); + return (CMD_ERROR); + } + + return (CMD_OK); +} + +uint64_t +ldi_get_size(void *priv) +{ + int fd = (uintptr_t) priv; + uint64_t size; + + ioctl(fd, DIOCGMEDIASIZE, &size); + return (size); +} diff --git a/stand/defaults/Makefile b/stand/defaults/Makefile new file mode 100644 index 0000000..131034d --- /dev/null +++ b/stand/defaults/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.include <bsd.init.mk> + +FILES+= loader.conf +MAN+= loader.conf.5 + +FILESDIR_loader.conf= /boot/defaults + +.include <bsd.prog.mk> diff --git a/stand/defaults/loader.conf b/stand/defaults/loader.conf new file mode 100644 index 0000000..0b13dc7 --- /dev/null +++ b/stand/defaults/loader.conf @@ -0,0 +1,160 @@ +# This is loader.conf - a file full of useful variables that you can +# set to change the default load behavior of your system. You should +# not edit this file! Put any overrides into one of the +# loader_conf_files instead and you will be able to update these +# defaults later without spamming your local configuration information. +# +# All arguments must be in double quotes. +# +# $FreeBSD$ + +### Basic configuration options ############################ +exec="echo Loading /boot/defaults/loader.conf" + +kernel="kernel" # /boot sub-directory containing kernel and modules +bootfile="kernel" # Kernel name (possibly absolute path) +kernel_options="" # Flags to be passed to the kernel +loader_conf_files="/boot/device.hints /boot/loader.conf /boot/loader.conf.local" +nextboot_conf="/boot/nextboot.conf" +nextboot_enable="NO" +verbose_loading="NO" # Set to YES for verbose loader output + +### Splash screen configuration ############################ +splash_bmp_load="NO" # Set this to YES for bmp splash screen! +splash_pcx_load="NO" # Set this to YES for pcx splash screen! +splash_txt_load="NO" # Set this to YES for TheDraw splash screen! +vesa_load="NO" # Set this to YES to load the vesa module +bitmap_load="NO" # Set this to YES if you want splash screen! +bitmap_name="splash.bmp" # Set this to the name of the file +bitmap_type="splash_image_data" # and place it on the module_path + +### Screen saver modules ################################### +# This is best done in rc.conf +screensave_load="NO" # Set to YES to load a screensaver module +screensave_name="green_saver" # Set to the name of the screensaver module + +### Random number generator configuration ################## +# See rc.conf(5). The entropy_boot_file config variable must agree with the +# settings below. +entropy_cache_load="YES" # Set this to NO to disable loading + # entropy at boot time +entropy_cache_name="/boot/entropy" # Set this to the name of the file +entropy_cache_type="boot_entropy_cache" # Required for the kernel to find + # the boot-time entropy cache. This + # must not change value even if the + # _name above does change! + +### RAM Blacklist configuration ############################ +ram_blacklist_load="NO" # Set this to YES to load a file + # containing a list of addresses to + # exclude from the running system. +ram_blacklist_name="/boot/blacklist.txt" # Set this to the name of the file +ram_blacklist_type="ram_blacklist" # Required for the kernel to find + # the blacklist module + +### ACPI settings ########################################## +acpi_dsdt_load="NO" # DSDT Overriding +acpi_dsdt_type="acpi_dsdt" # Don't change this +acpi_dsdt_name="/boot/acpi_dsdt.aml" + # Override DSDT in BIOS by this file +acpi_video_load="NO" # Load the ACPI video extension driver + +### Initial memory disk settings ########################### +#mdroot_load="YES" # The "mdroot" prefix is arbitrary. +#mdroot_type="md_image" # Create md(4) disk at boot. +#mdroot_name="/boot/root.img" # Path to a file containing the image. +#rootdev="ufs:/dev/md0" # Set the root filesystem to md(4) device. + +### Loader settings ######################################## +#loader_delay="3" # Delay in seconds before loading anything. + # Default is unset and disabled (no delay). +#autoboot_delay="10" # Delay in seconds before autobooting, + # -1 for no user interrupts, NO to disable +#password="" # Prevent changes to boot options +#bootlock_password="" # Prevent booting (see check-password.4th(8)) +#geom_eli_passphrase_prompt="NO" # Prompt for geli(8) passphrase to mount root +bootenv_autolist="YES" # Auto populate the list of ZFS Boot Environments +#beastie_disable="NO" # Turn the beastie boot menu on and off +#kernels="kernel kernel.old" # Kernels to display in the boot menu +#loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none +#comconsole_speed="9600" # Set the current serial console speed +#console="vidconsole" # A comma separated list of console(s) +#currdev="disk1s1a" # Set the current device +module_path="/boot/modules;/boot/dtb;/boot/dtb/overlays" # Set the module search path +#prompt="\\${interpret}" # Set the command prompt +#root_disk_unit="0" # Force the root disk unit number +#rootdev="disk1s1a" # Set the root filesystem +#dumpdev="disk1s1b" # Set a dump device early in the boot process +#tftp.blksize="1428" # Set the RFC 2348 TFTP block size. + # If the TFTP server does not support RFC 2348, + # the block size is set to 512. Valid: (8,9007) +#twiddle_divisor="1" # >1 means slow down the progress indicator. + +### Kernel settings ######################################## +# The following boot_ variables are enabled by setting them to any value. +# Their presence in the kernel environment (see kenv(1)) has the same +# effect as setting the given boot flag (see boot(8)). +#boot_askname="" # -a: Prompt the user for the name of the root device +#boot_cdrom="" # -C: Attempt to mount root file system from CD-ROM +#boot_ddb="" # -d: Instructs the kernel to start in the DDB debugger +#boot_dfltroot="" # -r: Use the statically configured root file system +#boot_gdb="" # -g: Selects gdb-remote mode for the kernel debugger +#boot_multicons="" # -D: Use multiple consoles +#boot_mute="" # -m: Mute the console +#boot_pause="" # -p: Pause after each line during device probing +#boot_serial="" # -h: Use serial console +#boot_single="" # -s: Start system in single-user mode +#boot_verbose="" # -v: Causes extra debugging information to be printed +#init_path="/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init" + # Sets the list of init candidates +#init_shell="/bin/sh" # The shell binary used by init(8). +#init_script="" # Initial script to run by init(8) before chrooting. +#init_chroot="" # Directory for init(8) to chroot into. + +### Kernel tunables ######################################## +#hw.physmem="1G" # Limit physical memory. See loader(8) +#kern.dfldsiz="" # Set the initial data size limit +#kern.dflssiz="" # Set the initial stack size limit +#kern.hz="100" # Set the kernel interval timer rate +#kern.maxbcache="" # Set the max buffer cache KVA storage +#kern.maxdsiz="" # Set the max data size +#kern.maxfiles="" # Set the sys. wide open files limit +#kern.maxproc="" # Set the maximum # of processes +#kern.maxssiz="" # Set the max stack size +#kern.maxswzone="" # Set the max swmeta KVA storage +#kern.maxtsiz="" # Set the max text size +#kern.maxusers="32" # Set size of various static tables +#kern.msgbufsize="65536" # Set size of kernel message buffer +#kern.nbuf="" # Set the number of buffer headers +#kern.ncallout="" # Set the maximum # of timer events +#kern.ngroups="1023" # Set the maximum # of supplemental groups +#kern.sgrowsiz="" # Set the amount to grow stack +#kern.cam.boot_delay="10000" # Delay (in ms) of root mount for CAM bus + # registration, useful for USB sticks as root +#kern.cam.scsi_delay="2000" # Delay (in ms) before probing SCSI +#kern.ipc.maxsockets="" # Set the maximum number of sockets available +#kern.ipc.nmbclusters="" # Set the number of mbuf clusters +#kern.ipc.nsfbufs="" # Set the number of sendfile(2) bufs +#net.inet.tcp.tcbhashsize="" # Set the value of TCBHASHSIZE +#vfs.root.mountfrom="" # Specify root partition +#vm.kmem_size="" # Sets the size of kernel memory (bytes) +#debug.kdb.break_to_debugger="0" # Allow console to break into debugger. +#debug.ktr.cpumask="0xf" # Bitmask of CPUs to enable KTR on +#debug.ktr.mask="0x1200" # Bitmask of KTR events to enable +#debug.ktr.verbose="1" # Enable console dump of KTR events + +### Module loading syntax example ########################## +#module_load="YES" # loads module "module" +#module_name="realname" # uses "realname" instead of "module" +#module_type="type" # passes "-t type" to load +#module_flags="flags" # passes "flags" to the module +#module_before="cmd" # executes "cmd" before loading the module +#module_after="cmd" # executes "cmd" after loading the module +#module_error="cmd" # executes "cmd" if load fails + +### pfSense specific default values ########################## +loader_color="NO" +loader_logo="pfSensebw" +loader_brand="pfSense" +hw.usb.no_pf="1" +net.isr.maxthreads="-1" diff --git a/stand/forth/loader.conf.5 b/stand/defaults/loader.conf.5 index 631250c..dc22cb4 100644 --- a/stand/forth/loader.conf.5 +++ b/stand/defaults/loader.conf.5 @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd January 6, 2016 +.Dd March 19, 2018 .Dt LOADER.CONF 5 .Os .Sh NAME @@ -39,18 +39,6 @@ it, and additional modules to be loaded; and generally set all variables described in .Xr loader 8 . .Pp -The file -.Pa /boot/loader.rc -must contain the following two lines for -.Nm -to be automatically processed: -.Pp -.Dl include /boot/loader.4th -.Dl start -.Pp -If no -.Pa /boot/loader.rc -exists at installworld time, one with the above lines will be installed. .Sh SYNTAX Though .Nm Ns 's @@ -261,7 +249,6 @@ be displayed. If set to .Dq YES , the beastie boot menu will be skipped. -The beastie boot menu is always skipped if running non-x86 hardware. .It Va loader_logo Pq Dq Li orbbw Selects a desired logo in the beastie boot menu. Possible values are: @@ -290,20 +277,31 @@ See the entropy entries in The name of the very early boot-time entropy cache file. .El +.Sh OTHER SETTINGS +Other settings that may be used in +.Nm +that have no default value: +.Bl -tag -width bootfile -offset indent +.It Va fdt_overlays +Specifies a comma-delimited list of FDT overlays to apply. +.Pa /boot/dtb/overlays +is created by default for overlays to be placed in. +.It Va kernels_autodetect +If set to +.Dq YES , +attempt to auto-detect kernels installed in +.Pa /boot . +This is an option specific to the Lua-based loader. +It is not available in the default Forth-based loader. +.El .Sh FILES .Bl -tag -width /boot/defaults/loader.conf -compact .It Pa /boot/defaults/loader.conf default settings -- do not change this file. -.It Pa /boot/loader.4th -defines the commands used by loader to read and process -.Nm . .It Pa /boot/loader.conf user defined settings. .It Pa /boot/loader.conf.local machine-specific settings for sites with a common loader.conf. -.It Pa /boot/loader.rc -contains the instructions to automatically process -.Nm . .El .Sh SEE ALSO .Xr rc.conf 5 , diff --git a/stand/defs.mk b/stand/defs.mk index 3b646c6..7ca6d66 100644 --- a/stand/defs.mk +++ b/stand/defs.mk @@ -49,6 +49,9 @@ CFLAGS+= -I${BOOTOBJ}/libsa .endif CFLAGS+= -I${SASRC} -D_STANDALONE CFLAGS+= -I${SYSDIR} +# Spike the floating point interfaces +CFLAGS+= -Ddouble=jagged-little-pill -Dfloat=floaty-mcfloatface + # GELI Support, with backward compat hooks (mostly) .if defined(HAVE_GELI) @@ -99,8 +102,10 @@ SSP_CFLAGS= # currently has no /boot/loader, but may soon. CFLAGS+= -ffreestanding ${CFLAGS_NO_SIMD} .if ${MACHINE_CPUARCH} == "aarch64" -CFLAGS+= -mgeneral-regs-only -.elif ${MACHINE_CPUARCH} != "riscv" +CFLAGS+= -mgeneral-regs-only -fPIC +.elif ${MACHINE_CPUARCH} == "riscv" +CFLAGS+= -march=rv64imac -mabi=lp64 +.else CFLAGS+= -msoft-float .endif @@ -108,7 +113,9 @@ CFLAGS+= -msoft-float CFLAGS+= -march=i386 CFLAGS.gcc+= -mpreferred-stack-boundary=2 .endif - +.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 0 +CFLAGS+= -fPIC -mno-red-zone +.endif .if ${MACHINE_CPUARCH} == "arm" # Do not generate movt/movw, because the relocation fixup for them does not @@ -120,6 +127,7 @@ CFLAGS.clang+= -mllvm -arm-use-movt=0 CFLAGS.clang+= -mno-movt .endif CFLAGS.clang+= -mfpu=none +CFLAGS+= -fPIC .endif # The boot loader build uses dd status=none, where possible, for reproducible @@ -129,6 +137,10 @@ CFLAGS.clang+= -mfpu=none DD_NOSTATUS!=(dd status=none count=0 2> /dev/null && echo status=none) || true DD=dd ${DD_NOSTATUS} +.if ${MACHINE_CPUARCH} == "mips" +CFLAGS+= -G0 -fno-pic -mno-abicalls +.endif + .if ${MK_LOADER_FORCE_LE} != "no" .if ${MACHINE_ARCH} == "powerpc64" CFLAGS+= -mlittle-endian @@ -138,6 +150,9 @@ CFLAGS+= -mlittle-endian # Make sure we use the machine link we're about to create CFLAGS+=-I. +all: ${PROG} + +.if !defined(NO_OBJ) _ILINKS=machine .if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64" _ILINKS+=${MACHINE_CPUARCH} @@ -147,8 +162,6 @@ _ILINKS+=x86 .endif CLEANFILES+=${_ILINKS} -all: ${PROG} - beforedepend: ${_ILINKS} beforebuild: ${_ILINKS} @@ -157,7 +170,7 @@ beforebuild: ${_ILINKS} .for _link in ${_ILINKS} .if !exists(${.OBJDIR}/${_link}) ${OBJS}: ${_link} -.endif +.endif # _link exists .endfor .NOPATH: ${_ILINKS} @@ -176,5 +189,5 @@ ${_ILINKS}: path=`(cd $$path && /bin/pwd)` ; \ ${ECHO} ${.TARGET:T} "->" $$path ; \ ln -fhs $$path ${.TARGET:T} - +.endif # !NO_OBJ .endif # __BOOT_DEFS_MK__ diff --git a/stand/efi/Makefile b/stand/efi/Makefile index e3b22de..4f8dc65 100644 --- a/stand/efi/Makefile +++ b/stand/efi/Makefile @@ -1,22 +1,15 @@ # $FreeBSD$ +NO_OBJ=t + .include <bsd.init.mk> # In-tree GCC does not support __attribute__((ms_abi)), but gcc newer # than 4.5 supports it. .if ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 40500 -.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" -.if ${MK_FDT} != "no" -SUBDIR+= fdt -.endif -.endif - -.if ${MACHINE_CPUARCH} == "aarch64" || \ - ${MACHINE_CPUARCH} == "amd64" || \ - ${MACHINE_CPUARCH} == "arm" -SUBDIR+= libefi loader boot1 -.endif +SUBDIR.${MK_FDT}+= fdt +SUBDIR.yes+= libefi loader boot1 .endif # ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 40500 diff --git a/stand/efi/boot1/boot1.c b/stand/efi/boot1/boot1.c index 35f3332d..c6c921e 100644 --- a/stand/efi/boot1/boot1.c +++ b/stand/efi/boot1/boot1.c @@ -54,8 +54,6 @@ static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL; static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL; static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL; static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; -static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID; -static EFI_GUID GlobalBootVarGUID = UEFI_BOOT_VAR_GUID; /* * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures @@ -80,42 +78,6 @@ Free(void *buf, const char *file __unused, int line __unused) (void)BS->FreePool(buf); } -static EFI_STATUS -efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len) -{ - size_t ul; - CHAR16 *uv; - UINT32 attr; - UINTN dl; - EFI_STATUS rv; - - uv = NULL; - if (utf8_to_ucs2(v, &uv, &ul) != 0) - return (EFI_OUT_OF_RESOURCES); - dl = *len; - rv = RS->GetVariable(uv, g, &attr, &dl, data); - if (rv == EFI_SUCCESS) - *len = dl; - free(uv); - return (rv); -} - -static EFI_STATUS -efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr) -{ - CHAR16 *var = NULL; - size_t len; - EFI_STATUS rv; - - if (utf8_to_ucs2(varname, &var, &len) != 0) - return (EFI_OUT_OF_RESOURCES); - rv = RS->SetVariable(var, &FreeBSDBootVarGUID, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - (ucs2len(valstr) + 1) * sizeof(efi_char), valstr); - free(var); - return (rv); -} - /* * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match, * FALSE otherwise. @@ -505,15 +467,18 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) boot_current = 0; sz = sizeof(boot_current); - efi_getenv(&GlobalBootVarGUID, "BootCurrent", &boot_current, &sz); - printf(" BootCurrent: %04x\n", boot_current); - - sz = sizeof(boot_order); - efi_getenv(&GlobalBootVarGUID, "BootOrder", &boot_order, &sz); - printf(" BootOrder:"); - for (i = 0; i < sz / sizeof(boot_order[0]); i++) - printf(" %04x", boot_order[i]); - printf("\n"); + if (efi_global_getenv("BootCurrent", &boot_current, &sz) == EFI_SUCCESS) { + printf(" BootCurrent: %04x\n", boot_current); + + sz = sizeof(boot_order); + if (efi_global_getenv("BootOrder", &boot_order, &sz) == EFI_SUCCESS) { + printf(" BootOrder:"); + for (i = 0; i < sz / sizeof(boot_order[0]); i++) + printf(" %04x%s", boot_order[i], + boot_order[i] == boot_current ? "[*]" : ""); + printf("\n"); + } + } #ifdef TEST_FAILURE /* diff --git a/stand/efi/boot1/fat-amd64.tmpl.xz b/stand/efi/boot1/fat-amd64.tmpl.xz Binary files differindex fb5f94e..fe68cd8 100644 --- a/stand/efi/boot1/fat-amd64.tmpl.xz +++ b/stand/efi/boot1/fat-amd64.tmpl.xz diff --git a/stand/efi/boot1/fat-arm.tmpl.xz b/stand/efi/boot1/fat-arm.tmpl.xz Binary files differindex bb253fc..d8fea41 100644 --- a/stand/efi/boot1/fat-arm.tmpl.xz +++ b/stand/efi/boot1/fat-arm.tmpl.xz diff --git a/stand/efi/boot1/fat-arm64.tmpl.xz b/stand/efi/boot1/fat-arm64.tmpl.xz Binary files differindex 15df643..9e9fea2 100644 --- a/stand/efi/boot1/fat-arm64.tmpl.xz +++ b/stand/efi/boot1/fat-arm64.tmpl.xz diff --git a/stand/efi/boot1/fat-i386.tmpl.xz b/stand/efi/boot1/fat-i386.tmpl.xz Binary files differindex 2cde337..d576a7b 100644 --- a/stand/efi/boot1/fat-i386.tmpl.xz +++ b/stand/efi/boot1/fat-i386.tmpl.xz diff --git a/stand/efi/boot1/generate-fat.sh b/stand/efi/boot1/generate-fat.sh index f6bda6f..a4389f9 100755 --- a/stand/efi/boot1/generate-fat.sh +++ b/stand/efi/boot1/generate-fat.sh @@ -42,7 +42,7 @@ while read ARCH FILENAME; do dd if=/dev/zero of=$OUTPUT_FILE bs=512 count=$FAT_SIZE DEVICE=`mdconfig -a -f $OUTPUT_FILE` - newfs_msdos -F 12 -L EFI $DEVICE + newfs_msdos -F 12 -L EFISYS $DEVICE mkdir stub mount -t msdosfs /dev/$DEVICE stub diff --git a/stand/efi/boot1/ufs_module.c b/stand/efi/boot1/ufs_module.c index 4a8016f..76c15e4 100644 --- a/stand/efi/boot1/ufs_module.c +++ b/stand/efi/boot1/ufs_module.c @@ -44,7 +44,7 @@ static dev_info_t *devinfo; static dev_info_t *devices; static int -dskread(void *buf, u_int64_t lba, int nblk) +dskread(void *buf, uint64_t lba, int nblk) { int size; EFI_STATUS status; diff --git a/stand/efi/include/efi.h b/stand/efi/include/efi.h index 9164ec9..a91e881 100644 --- a/stand/efi/include/efi.h +++ b/stand/efi/include/efi.h @@ -59,7 +59,5 @@ Revision History */ #define FREEBSD_BOOT_VAR_GUID \ { 0xCFEE69AD, 0xA0DE, 0x47A9, {0x93, 0xA8, 0xF6, 0x31, 0x06, 0xF8, 0xAE, 0x99} } -#define UEFI_BOOT_VAR_GUID \ - { 0x8be4df61, 0x93ca, 0x11d2, {0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c} } #endif diff --git a/stand/efi/include/efidevp.h b/stand/efi/include/efidevp.h index cda6b41..862f7ac 100644 --- a/stand/efi/include/efidevp.h +++ b/stand/efi/include/efidevp.h @@ -31,6 +31,8 @@ Revision History // Device Path structures - Section C // +#pragma pack(1) + typedef struct _EFI_DEVICE_PATH { UINT8 Type; UINT8 SubType; @@ -451,4 +453,6 @@ typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL { EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText; } EFI_DEVICE_PATH_TO_TEXT_PROTOCOL; +#pragma pack() + #endif diff --git a/stand/efi/include/efilib.h b/stand/efi/include/efilib.h index 8721bc5..91a7e95f 100644 --- a/stand/efi/include/efilib.h +++ b/stand/efi/include/efilib.h @@ -59,10 +59,13 @@ typedef struct pdinfo uint32_t pd_unit; /* unit number */ uint32_t pd_open; /* reference counter */ void *pd_bcache; /* buffer cache data */ + struct pdinfo *pd_parent; /* Linked items (eg partitions) */ + struct devsw *pd_devsw; /* Back pointer to devsw */ } pdinfo_t; pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev); pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev); +pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h); void *efi_get_table(EFI_GUID *tbl); @@ -106,4 +109,18 @@ int wcscmp(CHAR16 *, CHAR16 *); void cpy8to16(const char *, CHAR16 *, size_t); void cpy16to8(const CHAR16 *, char *, size_t); +/* + * Routines for interacting with EFI's env vars in a more unix-like + * way than the standard APIs. In addition, convenience routines for + * the loader setting / getting FreeBSD specific variables. + */ + +EFI_STATUS efi_freebsd_getenv(const char *v, void *data, __size_t *len); +EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, __size_t *len); +EFI_STATUS efi_global_getenv(const char *v, void *data, __size_t *len); +EFI_STATUS efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr); + +/* efipart.c */ +int efipart_inithandles(void); + #endif /* _LOADER_EFILIB_H */ diff --git a/stand/efi/include/efizfs.h b/stand/efi/include/efizfs.h index 1fd034f..607c08f 100644 --- a/stand/efi/include/efizfs.h +++ b/stand/efi/include/efizfs.h @@ -48,6 +48,7 @@ extern void efi_zfs_probe(void); extern zfsinfo_list_t *efizfs_get_zfsinfo_list(void); extern bool efi_zfs_is_preferred(EFI_HANDLE *h); extern EFI_HANDLE efizfs_get_handle_by_guid(uint64_t); +extern bool efizfs_get_guid_by_handle(EFI_HANDLE, uint64_t *); #endif diff --git a/stand/efi/libefi/Makefile b/stand/efi/libefi/Makefile index c88eb4d..f45f3a7 100644 --- a/stand/efi/libefi/Makefile +++ b/stand/efi/libefi/Makefile @@ -5,8 +5,21 @@ LIB= efi WARNS?= 2 -SRCS= delay.c devpath.c efi_console.c efichar.c efinet.c efipart.c env.c errno.c \ - handles.c wchar.c libefi.c efi_driver_utils.c efizfs.c devicename.c +SRCS= delay.c \ + devicename.c \ + devpath.c \ + efi_console.c \ + efi_driver_utils.c \ + efichar.c \ + efienv.c \ + efinet.c \ + efipart.c \ + efizfs.c \ + env.c \ + errno.c \ + handles.c \ + libefi.c \ + wchar.c .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" SRCS+= time.c diff --git a/stand/efi/libefi/devicename.c b/stand/efi/libefi/devicename.c index 52e4799..e5d11a1 100644 --- a/stand/efi/libefi/devicename.c +++ b/stand/efi/libefi/devicename.c @@ -161,7 +161,6 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) } idev->d_dev = dv; - idev->d_type = dv->dv_type; if (dev != NULL) *dev = idev; @@ -180,7 +179,7 @@ efi_fmtdev(void *vdev) struct devdesc *dev = (struct devdesc *)vdev; static char buf[SPECNAMELEN + 1]; - switch(dev->d_type) { + switch(dev->d_dev->dv_type) { case DEVT_NONE: strcpy(buf, "(no device)"); break; diff --git a/stand/efi/libefi/efi_console.c b/stand/efi/libefi/efi_console.c index 450ed46..5c519ac 100644 --- a/stand/efi/libefi/efi_console.c +++ b/stand/efi/libefi/efi_console.c @@ -383,6 +383,13 @@ efi_term_emu(int c) fg_c = bg_c; bg_c = t; break; + case 22: /* normal intensity */ + fg_c &= ~0x8; + break; + case 24: /* not underline */ + case 25: /* not blinking */ + bg_c &= ~0x8; + break; case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: fg_c = ansi_col[args[i] - 30]; diff --git a/stand/pc98/libpc98/time.c b/stand/efi/libefi/efienv.c index 5d832bb..1ee6bee 100644 --- a/stand/pc98/libpc98/time.c +++ b/stand/efi/libefi/efienv.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2018 Netflix, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,71 +28,60 @@ __FBSDID("$FreeBSD$"); #include <stand.h> -#include <btxv86.h> -#include <machine/cpufunc.h> -#include "bootstrap.h" -#include "libi386.h" +#include <efi.h> +#include <efichar.h> +#include <efilib.h> -static int bios_seconds(void); +static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID; +static EFI_GUID GlobalBootVarGUID = EFI_GLOBAL_VARIABLE; -/* - * Return the BIOS time-of-day value. - * - * XXX uses undocumented BCD support from libstand. - */ -static int -bios_seconds(void) +EFI_STATUS +efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len) { - int hr, minute, sec; - unsigned char bios_time[6]; - - v86.ctl = 0; - v86.addr = 0x1c; /* int 0x1c, function 0 */ - v86.eax = 0x0000; - v86.es = VTOPSEG(bios_time); - v86.ebx = VTOPOFF(bios_time); - v86int(); + size_t ul; + CHAR16 *uv; + UINT32 attr; + UINTN dl; + EFI_STATUS rv; - hr = bcd2bin(bios_time[3]); - minute = bcd2bin(bios_time[4]); - sec = bcd2bin(bios_time[5]); - - return (hr * 3600 + minute * 60 + sec); + uv = NULL; + if (utf8_to_ucs2(v, &uv, &ul) != 0) + return (EFI_OUT_OF_RESOURCES); + dl = *len; + rv = RS->GetVariable(uv, g, &attr, &dl, data); + if (rv == EFI_SUCCESS) + *len = dl; + free(uv); + return (rv); } -/* - * Return the time in seconds since the beginning of the day. - */ -time_t -time(time_t *t) +EFI_STATUS +efi_global_getenv(const char *v, void *data, size_t *len) { - static time_t lasttime; - time_t now; - now = bios_seconds(); + return (efi_getenv(&GlobalBootVarGUID, v, data, len)); +} - if (now < lasttime) - now += 24 * 3600; - lasttime = now; - - if (t != NULL) - *t = now; - return(now); +EFI_STATUS +efi_freebsd_getenv(const char *v, void *data, size_t *len) +{ + + return (efi_getenv(&FreeBSDBootVarGUID, v, data, len)); } -/* - * Use the BIOS Wait function to pause for (period) microseconds. - * - * Resolution of this function is variable, but typically around - * 1ms. - */ -void -delay(int period) +EFI_STATUS +efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr) { - int i; + CHAR16 *var = NULL; + size_t len; + EFI_STATUS rv; - period = (period + 500) / 1000; - for( ; period != 0 ; period--) - for(i=800;i != 0; i--) - outb(0x5f,0); /* wait 600ns */ + if (utf8_to_ucs2(varname, &var, &len) != 0) + return (EFI_OUT_OF_RESOURCES); + rv = RS->SetVariable(var, &FreeBSDBootVarGUID, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + (ucs2len(valstr) + 1) * sizeof(efi_char), valstr); + free(var); + return (rv); } + diff --git a/stand/efi/libefi/efinet.c b/stand/efi/libefi/efinet.c index cdb63c9..8a3e418 100644 --- a/stand/efi/libefi/efinet.c +++ b/stand/efi/libefi/efinet.c @@ -225,11 +225,9 @@ efinet_init(struct iodesc *desc, void *machdep_hint) EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; status = net->ReceiveFilters(net, mask, 0, FALSE, 0, NULL); - if (status != EFI_SUCCESS) { + if (status != EFI_SUCCESS) printf("net%d: cannot set rx. filters (status=%lu)\n", nif->nif_unit, EFI_ERROR_CODE(status)); - return; - } #ifdef EFINET_DEBUG dump_mode(net->Mode); diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c index e0dfa87..2b21099 100644 --- a/stand/efi/libefi/efipart.c +++ b/stand/efi/libefi/efipart.c @@ -119,6 +119,7 @@ efiblk_get_pdinfo_list(struct devsw *dev) return (NULL); } +/* XXX this gets called way way too often, investigate */ pdinfo_t * efiblk_get_pdinfo(struct devdesc *dev) { @@ -136,6 +137,40 @@ efiblk_get_pdinfo(struct devdesc *dev) return (pd); } +static bool +same_handle(pdinfo_t *pd, EFI_HANDLE h) +{ + + return (pd->pd_handle == h || pd->pd_alias == h); +} + +pdinfo_t * +efiblk_get_pdinfo_by_handle(EFI_HANDLE h) +{ + pdinfo_t *dp, *pp; + + /* + * Check hard disks, then cd, then floppy + */ + STAILQ_FOREACH(dp, &hdinfo, pd_link) { + if (same_handle(dp, h)) + return (dp); + STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { + if (same_handle(pp, h)) + return (pp); + } + } + STAILQ_FOREACH(dp, &cdinfo, pd_link) { + if (same_handle(dp, h)) + return (dp); + } + STAILQ_FOREACH(dp, &fdinfo, pd_link) { + if (same_handle(dp, h)) + return (dp); + } + return (NULL); +} + static int efiblk_pdinfo_count(pdinfo_list_t *pdi) { @@ -148,7 +183,7 @@ efiblk_pdinfo_count(pdinfo_list_t *pdi) return (i); } -static int +int efipart_inithandles(void) { UINTN sz; @@ -176,6 +211,10 @@ efipart_inithandles(void) efipart_handles = hin; efipart_nhandles = sz; +#ifdef EFIPART_DEBUG + printf("%s: Got %d BLOCK IO MEDIA handle(s)\n", __func__, + efipart_nhandles); +#endif return (0); } @@ -290,6 +329,8 @@ efipart_fdinfo_add(EFI_HANDLE handle, uint32_t uid, EFI_DEVICE_PATH *devpath) fd->pd_unit = uid; fd->pd_handle = handle; fd->pd_devpath = devpath; + fd->pd_parent = NULL; + fd->pd_devsw = &efipart_fddev; STAILQ_INSERT_TAIL(&fdinfo, fd, pd_link); return (0); } @@ -319,11 +360,7 @@ efipart_updatefd(void) static int efipart_initfd(void) { - int rv; - rv = efipart_inithandles(); - if (rv != 0) - return (rv); STAILQ_INIT(&fdinfo); efipart_updatefd(); @@ -364,6 +401,8 @@ efipart_cdinfo_add(EFI_HANDLE handle, EFI_HANDLE alias, cd->pd_unit = unit; cd->pd_alias = alias; cd->pd_devpath = devpath; + cd->pd_parent = NULL; + cd->pd_devsw = &efipart_cddev; STAILQ_INSERT_TAIL(&cdinfo, cd, pd_link); return (0); } @@ -439,11 +478,7 @@ efipart_updatecd(void) static int efipart_initcd(void) { - int rv; - rv = efipart_inithandles(); - if (rv != 0) - return (rv); STAILQ_INIT(&cdinfo); efipart_updatecd(); @@ -493,6 +528,8 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle) pd->pd_handle = part_handle; pd->pd_unit = node->PartitionNumber; pd->pd_devpath = part_devpath; + pd->pd_parent = hd; + pd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link); return (0); } @@ -509,6 +546,8 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle) hd->pd_handle = disk_handle; hd->pd_unit = unit; hd->pd_devpath = disk_devpath; + hd->pd_parent = NULL; + hd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link); if (part_devpath == NULL) @@ -525,6 +564,8 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle) pd->pd_handle = part_handle; pd->pd_unit = node->PartitionNumber; pd->pd_devpath = part_devpath; + pd->pd_parent = hd; + pd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link); return (0); @@ -583,6 +624,8 @@ efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle) pd->pd_handle = disk_handle; pd->pd_unit = unit; pd->pd_devpath = devpath; + pd->pd_parent = NULL; + pd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&hdinfo, pd, pd_link); free(pathname); return (0); @@ -613,6 +656,8 @@ efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle) pd->pd_handle = disk_handle; pd->pd_unit = unit; pd->pd_devpath = devpath; + pd->pd_parent = last; + pd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&last->pd_part, pd, pd_link); free(pathname); return (0); @@ -685,11 +730,7 @@ efipart_updatehd(void) static int efipart_inithd(void) { - int rv; - rv = efipart_inithandles(); - if (rv != 0) - return (rv); STAILQ_INIT(&hdinfo); efipart_updatehd(); @@ -752,11 +793,10 @@ efipart_print_common(struct devsw *dev, pdinfo_list_t *pdlist, int verbose) continue; pd->pd_blkio = blkio; - pd_dev.d_dev = dev; - pd_dev.d_unit = pd->pd_unit; + pd_dev.dd.d_dev = dev; + pd_dev.dd.d_unit = pd->pd_unit; pd_dev.d_slice = -1; pd_dev.d_partition = -1; - pd_dev.d_opendata = blkio; ret = disk_open(&pd_dev, blkio->Media->BlockSize * (blkio->Media->LastBlock + 1), blkio->Media->BlockSize); @@ -829,7 +869,7 @@ efipart_open(struct open_file *f, ...) if (pd->pd_bcache == NULL) pd->pd_bcache = bcache_allocate(); - if (dev->d_dev->dv_type == DEVT_DISK) { + if (dev->dd.d_dev->dv_type == DEVT_DISK) { int rc; rc = disk_open(dev, @@ -868,7 +908,7 @@ efipart_close(struct open_file *f) bcache_free(pd->pd_bcache); pd->pd_bcache = NULL; } - if (dev->d_dev->dv_type == DEVT_DISK) + if (dev->dd.d_dev->dv_type == DEVT_DISK) return (disk_close(dev)); return (0); } @@ -888,7 +928,7 @@ efipart_ioctl(struct open_file *f, u_long cmd, void *data) if (pd == NULL) return (EINVAL); - if (dev->d_dev->dv_type == DEVT_DISK) { + if (dev->dd.d_dev->dv_type == DEVT_DISK) { rc = disk_ioctl(dev, cmd, data); if (rc != ENOTTY) return (rc); @@ -975,7 +1015,7 @@ efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, bcd.dv_devdata = devdata; bcd.dv_cache = pd->pd_bcache; - if (dev->d_dev->dv_type == DEVT_DISK) { + if (dev->dd.d_dev->dv_type == DEVT_DISK) { daddr_t offset; offset = dev->d_offset * pd->pd_blkio->Media->BlockSize; @@ -1019,7 +1059,7 @@ efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size, * partition. */ disk_blocks = 0; - if (dev->d_dev->dv_type == DEVT_DISK) { + if (dev->dd.d_dev->dv_type == DEVT_DISK) { if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) { /* DIOCGMEDIASIZE does return bytes. */ disk_blocks /= blkio->Media->BlockSize; diff --git a/stand/efi/libefi/efizfs.c b/stand/efi/libefi/efizfs.c index 7c43476..2fb3128 100644 --- a/stand/efi/libefi/efizfs.c +++ b/stand/efi/libefi/efizfs.c @@ -29,8 +29,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/disk.h> -#include <stdint.h> +#include <stand.h> #ifdef EFI_ZFS_BOOT #include <libzfs.h> @@ -65,6 +64,22 @@ efizfs_get_handle_by_guid(uint64_t guid) return (NULL); } +bool +efizfs_get_guid_by_handle(EFI_HANDLE handle, uint64_t *guid) +{ + zfsinfo_t *zi; + + if (guid == NULL) + return (false); + STAILQ_FOREACH(zi, &zfsinfo, zi_link) { + if (zi->zi_handle == handle) { + *guid = zi->zi_pool_guid; + return (true); + } + } + return (false); +} + static void insert_zfs(EFI_HANDLE handle, uint64_t guid) { @@ -109,14 +124,4 @@ efi_zfs_probe(void) } } } - -uint64_t -ldi_get_size(void *priv) -{ - int fd = (uintptr_t) priv; - uint64_t size; - - ioctl(fd, DIOCGMEDIASIZE, &size); - return (size); -} #endif diff --git a/stand/efi/libefi/env.c b/stand/efi/libefi/env.c index 6b2d176..0008232 100644 --- a/stand/efi/libefi/env.c +++ b/stand/efi/libefi/env.c @@ -35,35 +35,6 @@ __FBSDID("$FreeBSD$"); #include <stdbool.h> #include "bootstrap.h" -/* - * Simple wrappers to the underlying UEFI functions. - * See http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES - * for details. - */ -EFI_STATUS -efi_get_next_variable_name(UINTN *variable_name_size, CHAR16 *variable_name, - EFI_GUID *vendor_guid) -{ - return (RS->GetNextVariableName(variable_name_size, variable_name, - vendor_guid)); -} - -EFI_STATUS -efi_get_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid, - UINT32 *attributes, UINTN *data_size, void *data) -{ - return (RS->GetVariable(variable_name, vendor_guid, attributes, - data_size, data)); -} - -EFI_STATUS -efi_set_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid, - UINT32 attributes, UINTN data_size, void *data) -{ - return (RS->SetVariable(variable_name, vendor_guid, attributes, - data_size, data)); -} - void efi_init_environment(void) { diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile index 57b5600..09181df 100644 --- a/stand/efi/loader/Makefile +++ b/stand/efi/loader/Makefile @@ -28,6 +28,7 @@ SRCS= autoload.c \ LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a CFLAGS+= -I${ZFSSRC} CFLAGS+= -DEFI_ZFS_BOOT +HAVE_ZFS= yes .endif .if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201 diff --git a/stand/efi/loader/arch/arm/exec.c b/stand/efi/loader/arch/arm/exec.c index 83d3f2b..2de99a0 100644 --- a/stand/efi/loader/arch/arm/exec.c +++ b/stand/efi/loader/arch/arm/exec.c @@ -47,7 +47,7 @@ extern vm_offset_t md_load(char *, vm_offset_t *); extern int bi_load(char *, vm_offset_t *, vm_offset_t *); static int -__elfN(arm_load)(char *filename, u_int64_t dest, +__elfN(arm_load)(char *filename, uint64_t dest, struct preloaded_file **result) { int r; diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c index ca06a61..4a41566 100644 --- a/stand/efi/loader/bootinfo.c +++ b/stand/efi/loader/bootinfo.c @@ -236,17 +236,48 @@ bi_copymodules(vm_offset_t addr) return(addr); } +static EFI_STATUS +efi_do_vmap(EFI_MEMORY_DESCRIPTOR *mm, UINTN sz, UINTN mmsz, UINT32 mmver) +{ + EFI_MEMORY_DESCRIPTOR *desc, *viter, *vmap; + EFI_STATUS ret; + int curr, ndesc, nset; + + nset = 0; + desc = mm; + ndesc = sz / mmsz; + vmap = malloc(sz); + if (vmap == NULL) + /* This isn't really an EFI error case, but pretend it is */ + return (EFI_OUT_OF_RESOURCES); + viter = vmap; + for (curr = 0; curr < ndesc; + curr++, desc = NextMemoryDescriptor(desc, mmsz)) { + if ((desc->Attribute & EFI_MEMORY_RUNTIME) != 0) { + ++nset; + desc->VirtualStart = desc->PhysicalStart; + *viter = *desc; + viter = NextMemoryDescriptor(viter, mmsz); + } + } + ret = RS->SetVirtualAddressMap(nset * mmsz, mmsz, mmver, vmap); + free(vmap); + return (ret); +} + static int bi_load_efi_data(struct preloaded_file *kfp) { EFI_MEMORY_DESCRIPTOR *mm; EFI_PHYSICAL_ADDRESS addr; EFI_STATUS status; + const char *efi_novmap; size_t efisz; UINTN efi_mapkey; UINTN mmsz, pages, retry, sz; UINT32 mmver; struct efi_map_header *efihdr; + bool do_vmap; #if defined(__amd64__) || defined(__aarch64__) struct efi_fb efifb; @@ -266,6 +297,11 @@ bi_load_efi_data(struct preloaded_file *kfp) } #endif + do_vmap = true; + efi_novmap = getenv("efi_disable_vmap"); + if (efi_novmap != NULL) + do_vmap = strcasecmp(efi_novmap, "YES") != 0; + efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; /* @@ -321,6 +357,13 @@ bi_load_efi_data(struct preloaded_file *kfp) } status = BS->ExitBootServices(IH, efi_mapkey); if (EFI_ERROR(status) == 0) { + /* + * This may be disabled by setting efi_disable_vmap in + * loader.conf(5). By default we will setup the virtual + * map entries. + */ + if (do_vmap) + efi_do_vmap(mm, sz, mmsz, mmver); efihdr->memory_size = sz; efihdr->descriptor_size = mmsz; efihdr->descriptor_version = mmver; diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index 9b5dfd8..09ac1e0 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -78,6 +78,15 @@ EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL; static EFI_LOADED_IMAGE *img; +/* + * Number of seconds to wait for a keystroke before exiting with failure + * in the event no currdev is found. -2 means always break, -1 means + * never break, 0 means poll once and then reboot, > 0 means wait for + * that many seconds. "fail_timeout" can be set in the environment as + * well. + */ +static int fail_timeout = 5; + #ifdef EFI_ZFS_BOOT bool efi_zfs_is_preferred(EFI_HANDLE *h) @@ -169,119 +178,183 @@ out: } static void -set_devdesc_currdev(struct devsw *dev, int unit) +set_currdev_devdesc(struct devdesc *currdev) +{ + const char *devname; + + devname = efi_fmtdev(currdev); + + printf("Setting currdev to %s\n", devname); + + env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, devname, env_noset, env_nounset); +} + +static void +set_currdev_devsw(struct devsw *dev, int unit) { struct devdesc currdev; - char *devname; currdev.d_dev = dev; - currdev.d_type = currdev.d_dev->dv_type; currdev.d_unit = unit; - currdev.d_opendata = NULL; + + set_currdev_devdesc(&currdev); +} + +static void +set_currdev_pdinfo(pdinfo_t *dp) +{ + + /* + * Disks are special: they have partitions. if the parent + * pointer is non-null, we're a partition not a full disk + * and we need to adjust currdev appropriately. + */ + if (dp->pd_devsw->dv_type == DEVT_DISK) { + struct disk_devdesc currdev; + + currdev.dd.d_dev = dp->pd_devsw; + if (dp->pd_parent == NULL) { + currdev.dd.d_unit = dp->pd_unit; + currdev.d_slice = -1; + currdev.d_partition = -1; + } else { + currdev.dd.d_unit = dp->pd_parent->pd_unit; + currdev.d_slice = dp->pd_unit; + currdev.d_partition = 255; /* Assumes GPT */ + } + set_currdev_devdesc((struct devdesc *)&currdev); + } else { + set_currdev_devsw(dp->pd_devsw, dp->pd_unit); + } +} + +static bool +sanity_check_currdev(void) +{ + struct stat st; + + return (stat("/boot/defaults/loader.conf", &st) == 0); +} + +#ifdef EFI_ZFS_BOOT +static bool +probe_zfs_currdev(uint64_t guid) +{ + char *devname; + struct zfs_devdesc currdev; + + currdev.dd.d_dev = &zfs_dev; + currdev.dd.d_unit = 0; + currdev.pool_guid = guid; + currdev.root_guid = 0; + set_currdev_devdesc((struct devdesc *)&currdev); devname = efi_fmtdev(&currdev); + init_zfs_bootenv(devname); - env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, - env_nounset); - env_setenv("loaddev", EV_VOLATILE, devname, env_noset, env_nounset); + return (sanity_check_currdev()); +} +#endif + +static bool +try_as_currdev(pdinfo_t *hd, pdinfo_t *pp) +{ + uint64_t guid; + +#ifdef EFI_ZFS_BOOT + /* + * If there's a zpool on this device, try it as a ZFS + * filesystem, which has somewhat different setup than all + * other types of fs due to imperfect loader integration. + * This all stems from ZFS being both a device (zpool) and + * a filesystem, plus the boot env feature. + */ + if (efizfs_get_guid_by_handle(pp->pd_handle, &guid)) + return (probe_zfs_currdev(guid)); +#endif + /* + * All other filesystems just need the pdinfo + * initialized in the standard way. + */ + set_currdev_pdinfo(pp); + return (sanity_check_currdev()); } static int find_currdev(EFI_LOADED_IMAGE *img) { - pdinfo_list_t *pdi_list; pdinfo_t *dp, *pp; EFI_DEVICE_PATH *devpath, *copy; EFI_HANDLE h; - char *devname; + CHAR16 *text; struct devsw *dev; int unit; uint64_t extra; #ifdef EFI_ZFS_BOOT - /* Did efi_zfs_probe() detect the boot pool? */ + /* + * Did efi_zfs_probe() detect the boot pool? If so, use the zpool + * it found, if it's sane. ZFS is the only thing that looks for + * disks and pools to boot. This may change in the future, however, + * if we allow specifying which pool to boot from via UEFI variables + * rather than the bootenv stuff that FreeBSD uses today. + */ if (pool_guid != 0) { - struct zfs_devdesc currdev; - - currdev.d_dev = &zfs_dev; - currdev.d_unit = 0; - currdev.d_type = currdev.d_dev->dv_type; - currdev.d_opendata = NULL; - currdev.pool_guid = pool_guid; - currdev.root_guid = 0; - devname = efi_fmtdev(&currdev); - - env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, - env_nounset); - env_setenv("loaddev", EV_VOLATILE, devname, env_noset, - env_nounset); - init_zfs_bootenv(devname); - return (0); - } -#endif /* EFI_ZFS_BOOT */ - - /* We have device lists for hd, cd, fd, walk them all. */ - pdi_list = efiblk_get_pdinfo_list(&efipart_hddev); - STAILQ_FOREACH(dp, pdi_list, pd_link) { - struct disk_devdesc currdev; - - currdev.d_dev = &efipart_hddev; - currdev.d_type = currdev.d_dev->dv_type; - currdev.d_unit = dp->pd_unit; - currdev.d_opendata = NULL; - currdev.d_slice = -1; - currdev.d_partition = -1; - - if (dp->pd_handle == img->DeviceHandle) { - devname = efi_fmtdev(&currdev); - - env_setenv("currdev", EV_VOLATILE, devname, - efi_setcurrdev, env_nounset); - env_setenv("loaddev", EV_VOLATILE, devname, - env_noset, env_nounset); + printf("Trying ZFS pool\n"); + if (probe_zfs_currdev(pool_guid)) return (0); - } - /* Assuming GPT partitioning. */ - STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { - if (pp->pd_handle == img->DeviceHandle) { - currdev.d_slice = pp->pd_unit; - currdev.d_partition = 255; - devname = efi_fmtdev(&currdev); - - env_setenv("currdev", EV_VOLATILE, devname, - efi_setcurrdev, env_nounset); - env_setenv("loaddev", EV_VOLATILE, devname, - env_noset, env_nounset); - return (0); - } - } } +#endif /* EFI_ZFS_BOOT */ - pdi_list = efiblk_get_pdinfo_list(&efipart_cddev); - STAILQ_FOREACH(dp, pdi_list, pd_link) { - if (dp->pd_handle == img->DeviceHandle || - dp->pd_alias == img->DeviceHandle) { - set_devdesc_currdev(&efipart_cddev, dp->pd_unit); - return (0); + /* + * Try to find the block device by its handle based on the + * image we're booting. If we can't find a sane partition, + * search all the other partitions of the disk. We do not + * search other disks because it's a violation of the UEFI + * boot protocol to do so. We fail and let UEFI go on to + * the next candidate. + */ + dp = efiblk_get_pdinfo_by_handle(img->DeviceHandle); + if (dp != NULL) { + text = efi_devpath_name(dp->pd_devpath); + if (text != NULL) { + printf("Trying ESP: %S\n", text); + efi_free_devpath_name(text); } - } - - pdi_list = efiblk_get_pdinfo_list(&efipart_fddev); - STAILQ_FOREACH(dp, pdi_list, pd_link) { - if (dp->pd_handle == img->DeviceHandle) { - set_devdesc_currdev(&efipart_fddev, dp->pd_unit); + set_currdev_pdinfo(dp); + if (sanity_check_currdev()) return (0); + if (dp->pd_parent != NULL) { + dp = dp->pd_parent; + STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { + text = efi_devpath_name(pp->pd_devpath); + if (text != NULL) { + printf("And now the part: %S\n", text); + efi_free_devpath_name(text); + } + /* + * Roll up the ZFS special case + * for those partitions that have + * zpools on them + */ + if (try_as_currdev(dp, pp)) + return (0); + } } + } else { + printf("Can't find device by handle\n"); } /* * Try the device handle from our loaded image first. If that * fails, use the device path from the loaded image and see if * any of the nodes in that path match one of the enumerated - * handles. + * handles. Currently, this handle list is only for netboot. */ if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &extra) == 0) { - set_devdesc_currdev(dev, unit); - return (0); + set_currdev_devsw(dev, unit); + if (sanity_check_currdev()) + return (0); } copy = NULL; @@ -295,8 +368,9 @@ find_currdev(EFI_LOADED_IMAGE *img) copy = NULL; if (efi_handle_lookup(h, &dev, &unit, &extra) == 0) { - set_devdesc_currdev(dev, unit); - return (0); + set_currdev_devsw(dev, unit); + if (sanity_check_currdev()) + return (0); } devpath = efi_lookup_devpath(h); @@ -310,6 +384,33 @@ find_currdev(EFI_LOADED_IMAGE *img) return (ENOENT); } +static bool +interactive_interrupt(const char *msg) +{ + time_t now, then, last; + + last = 0; + now = then = getsecs(); + printf("%s\n", msg); + if (fail_timeout == -2) /* Always break to OK */ + return (true); + if (fail_timeout == -1) /* Never break to OK */ + return (false); + do { + if (last != now) { + printf("press any key to interrupt reboot in %d seconds\r", + fail_timeout - (int)(now - then)); + last = now; + } + + /* XXX no pause or timeout wait for char */ + if (ischar()) + return (true); + now = getsecs(); + } while (now - then < fail_timeout); + return (false); +} + EFI_STATUS main(int argc, CHAR16 *argv[]) { @@ -318,6 +419,13 @@ main(int argc, CHAR16 *argv[]) int i, j, vargood, howto; UINTN k; int has_kbd; + char *s; + EFI_DEVICE_PATH *imgpath; + CHAR16 *text; + EFI_STATUS status; + UINT16 boot_current; + size_t sz; + UINT16 boot_order[100]; #if !defined(__arm__) char buf[40]; #endif @@ -356,12 +464,15 @@ main(int argc, CHAR16 *argv[]) /* * Parse the args to set the console settings, etc * boot1.efi passes these in, if it can read /boot.config or /boot/config - * or iPXE may be setup to pass these in. + * or iPXE may be setup to pass these in. Or the optional argument in the + * boot environment was used to pass these arguments in (in which case + * neither /boot.config nor /boot/config are consulted). * * Loop through the args, and for each one that contains an '=' that is * not the first character, add it to the environment. This allows * loader and kernel env vars to be passed on the command line. Convert - * args from UCS-2 to ASCII (16 to 8 bit) as they are copied. + * args from UCS-2 to ASCII (16 to 8 bit) as they are copied (though this + * method is flawed for non-ASCII characters). */ howto = 0; for (i = 1; i < argc; i++) { @@ -441,6 +552,10 @@ main(int argc, CHAR16 *argv[]) for (i = 0; howto_names[i].ev != NULL; i++) if (howto & howto_names[i].mask) setenv(howto_names[i].ev, "YES", 1); + + /* + * XXX we need fallback to this stuff after looking at the ConIn, ConOut and ConErr variables + */ if (howto & RB_MULTIPLE) { if (howto & RB_SERIAL) setenv("console", "comconsole efi" , 1); @@ -448,19 +563,27 @@ main(int argc, CHAR16 *argv[]) setenv("console", "efi comconsole" , 1); } else if (howto & RB_SERIAL) { setenv("console", "comconsole" , 1); - } + } else + setenv("console", "efi", 1); if (efi_copy_init()) { printf("failed to allocate staging area\n"); return (EFI_BUFFER_TOO_SMALL); } + if ((s = getenv("fail_timeout")) != NULL) + fail_timeout = strtol(s, NULL, 10); + /* - * March through the device switch probing for things. + * Scan the BLOCK IO MEDIA handles then + * march through the device switch probing for things. */ - for (i = 0; devsw[i] != NULL; i++) - if (devsw[i]->dv_init != NULL) - (devsw[i]->dv_init)(); + if ((i = efipart_inithandles()) == 0) { + for (i = 0; devsw[i] != NULL; i++) + if (devsw[i]->dv_init != NULL) + (devsw[i]->dv_init)(); + } else + printf("efipart_inithandles failed %d, expect failures", i); printf("Command line arguments:"); for (i = 0; i < argc; i++) @@ -475,6 +598,37 @@ main(int argc, CHAR16 *argv[]) printf("\n%s", bootprog_info); + /* Determine the devpath of our image so we can prefer it. */ + text = efi_devpath_name(img->FilePath); + if (text != NULL) { + printf(" Load Path: %S\n", text); + efi_setenv_freebsd_wcs("LoaderPath", text); + efi_free_devpath_name(text); + } + + status = BS->HandleProtocol(img->DeviceHandle, &devid, (void **)&imgpath); + if (status == EFI_SUCCESS) { + text = efi_devpath_name(imgpath); + if (text != NULL) { + printf(" Load Device: %S\n", text); + efi_setenv_freebsd_wcs("LoaderDev", text); + efi_free_devpath_name(text); + } + } + + boot_current = 0; + sz = sizeof(boot_current); + efi_global_getenv("BootCurrent", &boot_current, &sz); + printf(" BootCurrent: %04x\n", boot_current); + + sz = sizeof(boot_order); + efi_global_getenv("BootOrder", &boot_order, &sz); + printf(" BootOrder:"); + for (i = 0; i < sz / sizeof(boot_order[0]); i++) + printf(" %04x%s", boot_order[i], + boot_order[i] == boot_current ? "[*]" : ""); + printf("\n"); + /* * Disable the watchdog timer. By default the boot manager sets * the timer to 5 minutes before invoking a boot option. If we @@ -486,8 +640,16 @@ main(int argc, CHAR16 *argv[]) */ BS->SetWatchdogTimer(0, 0, 0, NULL); + /* + * Try and find a good currdev based on the image that was booted. + * It might be desirable here to have a short pause to allow falling + * through to the boot loader instead of returning instantly to follow + * the boot protocol and also allow an escape hatch for users wishing + * to try something different. + */ if (find_currdev(img) != 0) - return (EFI_NOT_FOUND); + if (!interactive_interrupt("Failed to find bootable partition")) + return (EFI_NOT_FOUND); efi_init_environment(); setenv("LINES", "24", 1); /* optional */ @@ -743,61 +905,6 @@ command_mode(int argc, char *argv[]) return (CMD_OK); } -#ifdef EFI_ZFS_BOOT -COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset", - command_lszfs); - -static int -command_lszfs(int argc, char *argv[]) -{ - int err; - - if (argc != 2) { - command_errmsg = "wrong number of arguments"; - return (CMD_ERROR); - } - - err = zfs_list(argv[1]); - if (err != 0) { - command_errmsg = strerror(err); - return (CMD_ERROR); - } - return (CMD_OK); -} - -COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments", - command_reloadbe); - -static int -command_reloadbe(int argc, char *argv[]) -{ - int err; - char *root; - - if (argc > 2) { - command_errmsg = "wrong number of arguments"; - return (CMD_ERROR); - } - - if (argc == 2) { - err = zfs_bootenv(argv[1]); - } else { - root = getenv("zfs_be_root"); - if (root == NULL) { - return (CMD_OK); - } - err = zfs_bootenv(root); - } - - if (err != 0) { - command_errmsg = strerror(err); - return (CMD_ERROR); - } - - return (CMD_OK); -} -#endif - #ifdef LOADER_FDT_SUPPORT extern int command_fdt_internal(int argc, char *argv[]); @@ -899,7 +1006,7 @@ command_chain(int argc, char *argv[]) struct disk_devdesc *d_dev; pdinfo_t *hd, *pd; - switch (dev->d_type) { + switch (dev->d_dev->dv_type) { #ifdef EFI_ZFS_BOOT case DEVT_ZFS: z_dev = (struct zfs_devdesc *)dev; diff --git a/stand/fdt/Makefile b/stand/fdt/Makefile index b4767ed..3eee143 100644 --- a/stand/fdt/Makefile +++ b/stand/fdt/Makefile @@ -17,5 +17,4 @@ CFLAGS+= -I${SYSDIR}/contrib/libfdt/ -I${LDRSRC} CFLAGS+= -Wformat -Wall -.include <bsd.stand.mk> .include <bsd.lib.mk> diff --git a/stand/ficl/Makefile b/stand/ficl/Makefile index 1e64ae0..3573085 100644 --- a/stand/ficl/Makefile +++ b/stand/ficl/Makefile @@ -12,9 +12,9 @@ BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ SRCS= ${BASE_SRCS} sysdep.c softcore.c CLEANFILES+= softcore.c testmain testmain.o -.include <bsd.stand.mk> .ifmake testmain -CFLAGS+= -DTESTMAIN -D_TESTMAIN +CFLAGS= -DTESTMAIN -D_TESTMAIN +CFLAGS+= -I${FICLSRC} -I${FICLSRC}/${FICL_CPUARCH} -I${LDRSRC} SRCS+= testmain.c PROG= testmain .include <bsd.prog.mk> diff --git a/stand/ficl/aarch64/sysdep.c b/stand/ficl/aarch64/sysdep.c index ad38660..43e7c3c 100644 --- a/stand/ficl/aarch64/sysdep.c +++ b/stand/ficl/aarch64/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/ficl/amd64/sysdep.c b/stand/ficl/amd64/sysdep.c index 5957b71..68661c4 100644 --- a/stand/ficl/amd64/sysdep.c +++ b/stand/ficl/amd64/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/ficl/arm/sysdep.c b/stand/ficl/arm/sysdep.c index ad38660..43e7c3c 100644 --- a/stand/ficl/arm/sysdep.c +++ b/stand/ficl/arm/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/ficl/i386/sysdep.c b/stand/ficl/i386/sysdep.c index ea594e6..685c45b 100644 --- a/stand/ficl/i386/sysdep.c +++ b/stand/ficl/i386/sysdep.c @@ -28,12 +28,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -41,7 +41,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; @@ -89,7 +89,7 @@ void ficlOutb(FICL_VM *pVM) { u_char c; - u_int32_t port; + uint32_t port; port=stackPopUNS(pVM->pStack); c=(u_char)stackPopINT(pVM->pStack); @@ -104,7 +104,7 @@ void ficlInb(FICL_VM *pVM) { u_char c; - u_int32_t port; + uint32_t port; port=stackPopUNS(pVM->pStack); c=inb(port); diff --git a/stand/ficl/mips/sysdep.c b/stand/ficl/mips/sysdep.c index ad38660..43e7c3c 100644 --- a/stand/ficl/mips/sysdep.c +++ b/stand/ficl/mips/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/ficl/mips64/sysdep.c b/stand/ficl/mips64/sysdep.c index ad38660..43e7c3c 100644 --- a/stand/ficl/mips64/sysdep.c +++ b/stand/ficl/mips64/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/ficl/powerpc/sysdep.c b/stand/ficl/powerpc/sysdep.c index ad38660..43e7c3c 100644 --- a/stand/ficl/powerpc/sysdep.c +++ b/stand/ficl/powerpc/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/ficl/riscv/sysdep.c b/stand/ficl/riscv/sysdep.c index ad38660..43e7c3c 100644 --- a/stand/ficl/riscv/sysdep.c +++ b/stand/ficl/riscv/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/ficl/sparc64/sysdep.c b/stand/ficl/sparc64/sysdep.c index ad38660..43e7c3c 100644 --- a/stand/ficl/sparc64/sysdep.c +++ b/stand/ficl/sparc64/sysdep.c @@ -25,12 +25,12 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { DPUNS q; - u_int64_t qx; + uint64_t qx; - qx = (u_int64_t)x * (u_int64_t) y; + qx = (uint64_t)x * (uint64_t) y; - q.hi = (u_int32_t)( qx >> 32 ); - q.lo = (u_int32_t)( qx & 0xFFFFFFFFL); + q.hi = (uint32_t)( qx >> 32 ); + q.lo = (uint32_t)( qx & 0xFFFFFFFFL); return q; } @@ -38,7 +38,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { UNSQR result; - u_int64_t qx, qh; + uint64_t qx, qh; qh = q.hi; qx = (qh << 32) | q.lo; diff --git a/stand/forth/Makefile b/stand/forth/Makefile index b175cc1..4b4d857 100644 --- a/stand/forth/Makefile +++ b/stand/forth/Makefile @@ -7,7 +7,6 @@ MAN+= beastie.4th.8 \ check-password.4th.8 \ color.4th.8 \ delay.4th.8 \ - loader.conf.5 \ loader.4th.8 \ menu.4th.8 \ menusets.4th.8 \ @@ -33,14 +32,13 @@ FILES+= screen.4th FILES+= shortcuts.4th FILES+= support.4th FILES+= version.4th -FILESDIR_loader.conf= /boot/defaults # pfSense FILES+= logo-pfSensebw.4th FILES+= brand-pfSense.4th # Allow machine specific loader.rc to be installed. -.for f in loader.rc menu.rc loader.conf +.for f in loader.rc menu.rc .if exists(${BOOTSRC}/${MACHINE:C/amd64/i386/}/loader/${f}) FILES+= ${BOOTSRC}/${MACHINE:C/amd64/i386/}/loader/${f} .else diff --git a/stand/forth/loader.conf b/stand/forth/loader.conf deleted file mode 100644 index c888c8b..0000000 --- a/stand/forth/loader.conf +++ /dev/null @@ -1,583 +0,0 @@ -# This is loader.conf - a file full of useful variables that you can -# set to change the default load behavior of your system. You should -# not edit this file! Put any overrides into one of the -# loader_conf_files instead and you will be able to update these -# defaults later without spamming your local configuration information. -# -# All arguments must be in double quotes. -# -# $FreeBSD$ - -############################################################## -### Basic configuration options ############################ -############################################################## - -exec="echo Loading /boot/defaults/loader.conf" - -kernel="kernel" # /boot sub-directory containing kernel and modules -bootfile="kernel" # Kernel name (possibly absolute path) -kernel_options="" # Flags to be passed to the kernel - -loader_conf_files="/boot/device.hints /boot/loader.conf /boot/loader.conf.local" -nextboot_conf="/boot/nextboot.conf" -nextboot_enable="NO" - -verbose_loading="NO" # Set to YES for verbose loader output - - -############################################################## -### Splash screen configuration ############################ -############################################################## - -splash_bmp_load="NO" # Set this to YES for bmp splash screen! -splash_pcx_load="NO" # Set this to YES for pcx splash screen! -splash_txt_load="NO" # Set this to YES for TheDraw splash screen! -vesa_load="NO" # Set this to YES to load the vesa module -bitmap_load="NO" # Set this to YES if you want splash screen! -bitmap_name="splash.bmp" # Set this to the name of the file -bitmap_type="splash_image_data" # and place it on the module_path - - -############################################################## -### Random number generator configuration ################## -############################################################## - -# See rc.conf(5). The entropy_boot_file config variable must agree with the -# settings below. - -entropy_cache_load="YES" # Set this to NO to disable loading - # entropy at boot time -entropy_cache_name="/boot/entropy" # Set this to the name of the file -entropy_cache_type="/boot/entropy" # Required for the kernel to find - # the boot-time entropy cache. This - # must not change value even if the - # _name above does change! - - -############################################################## -### RAM Blacklist configuration ############################ -############################################################## - -ram_blacklist_load="NO" # Set this to YES to load a file - # containing a list of addresses to - # exclude from the running system. -ram_blacklist_name="/boot/blacklist.txt" # Set this to the name of the file -ram_blacklist_type="ram_blacklist" # Required for the kernel to find - # the blacklist module - - -############################################################## -### Initial memory disk settings ########################### -############################################################## - -#mdroot_load="YES" # The "mdroot" prefix is arbitrary. -#mdroot_type="md_image" # Create md(4) disk at boot. -#mdroot_name="/boot/root.img" # Path to a file containing the image. -#rootdev="ufs:/dev/md0" # Set the root filesystem to md(4) device. - - -############################################################## -### Loader settings ######################################## -############################################################## - -#loader_delay="3" # Delay in seconds before loading anything. - # Default is unset and disabled (no delay). -#autoboot_delay="10" # Delay in seconds before autobooting, - # set to -1 if you don't want user to be - # allowed to interrupt autoboot process and - # escape to the loader prompt, set to - # "NO" to disable autobooting -#password="" # Prevent changes to boot options -#bootlock_password="" # Prevent booting (see check-password.4th(8)) -#geom_eli_passphrase_prompt="NO" # Prompt for geli(8) passphrase to mount root -bootenv_autolist="YES" # Auto populate the list of ZFS Boot Environments -#beastie_disable="NO" # Turn the beastie boot menu on and off -#kernels="kernel kernel.old" # Kernels to display in the boot menu -#loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none -#comconsole_speed="9600" # Set the current serial console speed -#console="vidconsole" # A comma separated list of console(s) -#currdev="disk1s1a" # Set the current device -module_path="/boot/modules;/boot/dtb" # Set the module search path -#prompt="\\${interpret}" # Set the command prompt -#root_disk_unit="0" # Force the root disk unit number -#rootdev="disk1s1a" # Set the root filesystem -#dumpdev="disk1s1b" # Set a dump device early in the boot process -#tftp.blksize="1428" # Set the RFC 2348 TFTP block size. - # If the TFTP server does not support RFC 2348, - # the block size is set to 512. If the value - # is out of range ( < 8 || > 9008 ) an error is - # returned. -#twiddle_divisor="1" # >1 means slow down the progress indicator. - - -############################################################## -### Kernel settings ######################################## -############################################################## - -# The following boot_ variables are enabled by setting them to any value. -# Their presence in the kernel environment (see kenv(1)) has the same -# effect as setting the given boot flag (see boot(8)). - -#boot_askname="" # -a: Prompt the user for the name of the root device -#boot_cdrom="" # -C: Attempt to mount root file system from CD-ROM -#boot_ddb="" # -d: Instructs the kernel to start in the DDB debugger -#boot_dfltroot="" # -r: Use the statically configured root file system -#boot_gdb="" # -g: Selects gdb-remote mode for the kernel debugger -#boot_multicons="" # -D: Use multiple consoles -#boot_mute="" # -m: Mute the console -#boot_pause="" # -p: Pause after each line during device probing -#boot_serial="" # -h: Use serial console -#boot_single="" # -s: Start system in single-user mode -#boot_verbose="" # -v: Causes extra debugging information to be printed -#init_path="/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init" - # Sets the list of init candidates -#init_shell="/bin/sh" # The shell binary used by init(8). -#init_script="" # Initial script to run by init(8) before chrooting. -#init_chroot="" # Directory for init(8) to chroot into. - - -############################################################## -### Kernel tunables ######################################## -############################################################## - -#hw.physmem="1G" # Limit physical memory. See loader(8) -#kern.dfldsiz="" # Set the initial data size limit -#kern.dflssiz="" # Set the initial stack size limit -#kern.hz="100" # Set the kernel interval timer rate -#kern.maxbcache="" # Set the max buffer cache KVA storage -#kern.maxdsiz="" # Set the max data size -#kern.maxfiles="" # Set the sys. wide open files limit -#kern.maxproc="" # Set the maximum # of processes -#kern.maxssiz="" # Set the max stack size -#kern.maxswzone="" # Set the max swmeta KVA storage -#kern.maxtsiz="" # Set the max text size -#kern.maxusers="32" # Set size of various static tables -#kern.msgbufsize="65536" # Set size of kernel message buffer -#kern.nbuf="" # Set the number of buffer headers -#kern.ncallout="" # Set the maximum # of timer events -#kern.ngroups="1023" # Set the maximum # of supplemental groups -#kern.sgrowsiz="" # Set the amount to grow stack -#kern.cam.boot_delay="10000" # Delay (in ms) of root mount for CAM bus - # registration, useful for USB sticks as root -#kern.cam.scsi_delay="2000" # Delay (in ms) before probing SCSI -#kern.ipc.maxsockets="" # Set the maximum number of sockets available -#kern.ipc.nmbclusters="" # Set the number of mbuf clusters -#kern.ipc.nsfbufs="" # Set the number of sendfile(2) bufs -#net.inet.tcp.tcbhashsize="" # Set the value of TCBHASHSIZE -#vfs.root.mountfrom="" # Specify root partition in a way the - # kernel understands -#vm.kmem_size="" # Sets the size of kernel memory (bytes) -#debug.kdb.break_to_debugger="0" # Allow console to break into debugger. -#debug.ktr.cpumask="0xf" # Bitmask of CPUs to enable KTR on -#debug.ktr.mask="0x1200" # Bitmask of KTR events to enable -#debug.ktr.verbose="1" # Enable console dump of KTR events -#net.graph.maxalloc="128" # Maximum number of queue items to allocate - - -############################################################## -### ATA modules ############################################ -############################################################## - -ataacard_load="NO" # ACARD -ataacerlabs_load="NO" # Acer Labs Inc. (ALI) -ataamd_load="NO" # American Micro Devices (AMD) -ataati_load="NO" # ATI -atacenatek_load="NO" # Cenatek -atacypress_load="NO" # Cypress -atacyrix_load="NO" # Cyrix -atahighpoint_load="NO" # HighPoint -ataintel_load="NO" # Intel -ataite_load="NO" # Integrated Technology Inc. (ITE) -atajmicron_load="NO" # JMicron -atamarvell_load="NO" # Marvell -atamicron_load="NO" # Micron -atanational_load="NO" # National -atanetcell_load="NO" # NetCell -atanvidia_load="NO" # nVidia -atapromise_load="NO" # Promise -ataserverworks_load="NO" # ServerWorks -atasiliconimage_load="NO" # Silicon Image Inc. (SiI) (formerly CMD) -atasis_load="NO" # Silicon Integrated Systems Corp.(SiS) -atavia_load="NO" # VIA Technologies Inc. - - -############################################################## -### Filesystem and related modules ######################### -############################################################## - -# Filesystems - -cd9660_load="NO" # ISO 9660 filesystem -fdescfs_load="NO" # Filedescriptors filesystem -linprocfs_load="NO" # Linux compatibility process filesystem -linsysfs_load="NO" # Linux compatibility system filesystem -msdosfs_load="NO" # FAT-12/16/32 -nfsclient_load="NO" # NFS client -nfsserver_load="NO" # NFS server -nullfs_load="NO" # Null filesystem -procfs_load="NO" # Process filesystem -unionfs_load="NO" # Union filesystem -zfs_load="NO" # ZFS - -# Related stuff - -geom_bde_load="NO" # Disk encryption driver (see gbde(4,8)) -geom_ccd_load="NO" # Concatenated disk driver (see ccd(4), - # ccdconfig(8)) -geom_concat_load="NO" # Concatenated disk driver (see gconcat(8)) -geom_eli_load="NO" # Disk encryption driver (see geli(8)) -geom_gate_load="NO" # Userland disk driver (see geom_gate(4), - # ggatec(8), ggated(8), ggatel(8)) -geom_journal_load="NO" # Journaled filesystem driver (see gjournal(8)) -geom_label_load="NO" # File system labels (see glabel(8)) -geom_md_load="NO" # Memory disk driver (vnode/swap/malloc) (see - # md(4), mdconfig(8)) -geom_mirror_load="NO" # RAID1 disk driver (see gmirror(8)) -geom_mountver_load="NO" # Mount verification disk driver -geom_nop_load="NO" # Transparent disk driver (see gnop(8)) -geom_raid3_load="NO" # RAID3 disk driver (see graid3(8)) -geom_shsec_load="NO" # Shared secret disk driver (see gshsec(8)) -geom_stripe_load="NO" # RAID0 disk driver (see gstripe(8)) -geom_uzip_load="NO" # Compressed disk images driver (see mkuzip(8)) -geom_vinum_load="NO" # Concatenated/mirror/raid driver (see vinum(4)) - - -############################################################## -### FireWire modules ####################################### -############################################################## - -firewire_load="NO" # IEEE1394 High-performance Serial Bus -fwe_load="NO" # Ethernet emulation driver for FireWire -fwip_load="NO" # IP over FireWire driver -fwohci_load="NO" # OHCI FireWire chipset device driver -sbp_load="NO" # SBP-2 Mass Storage Devices driver -sbp_targ_load="NO" # SBP-2 Target mode - - -############################################################## -### Screen saver modules ################################### -############################################################## - -# This is best done in rc.conf - -screensave_load="NO" # Set to YES to load a screensaver module -screensave_name="green_saver" # Set to the name of the screensaver module - - -############################################################## -### Emulation modules ###################################### -############################################################## - -cloudabi_load="NO" # Platform independent CloudABI support -cloudabi64_load="NO" # 64-bit CloudABI executables support -ibcs2_load="NO" # IBCS2 (SCO) emulation -ibcs2_coff_load="NO" -linux_load="NO" # Linux emulation -svr4_load="NO" # SystemV R4 emulation -streams_load="NO" # System V streams module - - -############################################################## -### Networking modules ##################################### -############################################################## - -if_disc_load="NO" # Discard device -if_ef_load="NO" # pseudo-device providing support for multiple - # ethernet frame types -if_epair_load="NO" # Virtual b-t-b Ethernet-like interface pair -if_gif_load="NO" # generic tunnel interface -if_gre_load="NO" # encapsulating network device -if_stf_load="NO" # 6to4 tunnel interface -if_tap_load="NO" # Ethernet tunnel software network interface -if_tun_load="NO" # Tunnel driver (user process ppp) -if_vlan_load="NO" # IEEE 802.1Q VLAN network interface -ipfw_load="NO" # Firewall -pf_load="NO" # packet filter - - -############################################################## -### Networking drivers ##################################### -############################################################## - -bridgestp_load="NO" # if_bridge(4) support -miibus_load="NO" # miibus support, needed for some drivers -carp_load="NO" # carp(4) protocol -if_ae_load="NO" # Attansic/Atheros L2 FastEthernet -if_age_load="NO" # Attansic/Atheros L1 Gigabit Ethernet -if_alc_load="NO" # Atheros AR8131/AR8132 Ethernet -if_ale_load="NO" # Atheros AR8121/AR8113/AR8114 Ethernet -if_an_load="NO" # Aironet 4500/4800 802.11 wireless NICs -if_ath_load="NO" # Atheros IEEE 802.11 wireless NICs -if_aue_load="NO" # ADMtek AN986 Pegasus USB Ethernet -if_axe_load="NO" # ASIX Electronics AX88172 USB Ethernet -if_bce_load="NO" # Broadcom NetXtreme II Gigabit Ethernet -if_bfe_load="NO" # Broadcom BCM4401 -if_bge_load="NO" # Broadcom BCM570x PCI Gigabit Ethernet -if_bnxt_load="NO" # Broadcom NetXtreme-C/NetXtreme-E -if_bridge_load="NO" # if_bridge(4) devices -if_bwi_load="NO" # Broadcom BCM53xx IEEE 802.11b/g wireness NICs -if_bwn_load="NO" # Broadcom BCM43xx IEEE 802.11 wireless NICs -if_bxe_load="NO" # Broadcom NetXtreme II 10Gb Ethernet -if_cas_load="NO" # Sun Cassini/Cassini+ and NS DP83065 Saturn -if_cm_load="NO" # SMC (90c26, 90c56, 90c66) -if_cs_load="NO" # Crystal Semiconductor CS8920 -if_cue_load="NO" # CATC USB-EL1210A USB Ethernet -if_cxgb_load="NO" # Chelsio T3 10 Gigabit Ethernet -if_cxgbe_load="NO" # Chelsio T4/T5/T6 1/10/25/40/100 Gigabit Ethernet -if_dc_load="NO" # DEC/Intel 21143 and various workalikes -if_de_load="NO" # DEC DC21x4x Ethernet -if_ed_load="NO" # National Semiconductor DS8390/WD83C690 - # Ethernet -if_em_load="NO" # Intel(R) PRO/1000 Gigabit Ethernet -if_en_load="NO" # Midway-based ATM interfaces -if_ep_load="NO" # 3Com Etherlink III (3c5x9) -if_et_load="NO" # Agere ET1310 10/100/Gigabit Ethernet -if_ex_load="NO" # Intel EtherExpress Pro/10 Ethernet -if_fatm_load="NO" # Fore PCA200E ATM -if_fe_load="NO" # Fujitsu MB86960A/MB86965A based Ethernet - # adapters -if_fxp_load="NO" # Intel EtherExpress PRO/100B (82557, 82558) -if_gem_load="NO" # Sun GEM/Sun ERI/Apple GMAC -if_hatm_load="NO" # Fore/Marconi HE155 and HE622 -if_hme_load="NO" # Sun Microelectronics STP2002-STQ Ethernet -if_ie_load="NO" # Intel 82586 -if_igb_load="NO" # Intel(R) PRO/1000 Gigabit Ethernet -if_ipw_load="NO" # Intel PRO/Wireless 2100 wireless -if_iwi_load="NO" # Intel PRO/Wireless 2200BG/2225BG/2915ABG - # wireless -if_iwn_load="NO" # Intel Wireless WiFi Link 802.11n wireless -if_ixgb_load="NO" # Intel PRO/10Gb Ethernet -if_ixgbe_load="NO" # Intel PRO/10Gb Ethernet PCI Express -if_ixl_load="NO" # Intel XL710 Ethernet 40Gb Base driver -if_ixlv_load="NO" # Intel XL710 Ethernet 40Gb VF driver -if_jme_load="NO" # JMicron JMC250 Gigabit/JMC260 Fast Ethernet -if_lagg_load="NO" # lagg(4) devices -if_le_load="NO" # AMD Am7900 LANCE and Am79C9xx PCnet -if_lge_load="NO" # Level 1 LXT1001 NetCellerator PCI Gigabit - # Ethernet -if_malo_load="NO" # Marvell Libertas 88W8335 802.11 wireless - # adapter -if_msk_load="NO" # Marvell/SysKonnect Yukon II Gigabit Ethernet -if_mxge_load="NO" # Myricom Myri10GE 10Gb Ethernet -if_my_load="NO" # Myson PCI Fast Ethernet -if_nfe_load="NO" # NVIDIA nForce MCP Networking Adapter -if_nge_load="NO" # National Semiconductor PCI Gigabit Ethernet -if_nxge_load="NO" # Neterion Xframe 10Gb Ethernet -if_patm_load="NO" # IDT77252 ATM -if_pcn_load="NO" # AMD PCnet PCI -if_ral_load="NO" # Ralink Technology wireless -if_re_load="NO" # RealTek 8139C+/8169/8169S/8110S -if_rl_load="NO" # RealTek 8129/8139 -if_rue_load="NO" # RealTek RTL8150 USB to Fast Ethernet -if_rum_load="NO" # Ralink Technology USB 802.11a/b/g wireless -if_run_load="NO" # Ralink Technology USB 802.11a/g/n wireless -if_sbni_load="NO" # Granch SBNI12 leased line adapters -if_sf_load="NO" # Adaptec Duralink PCI (AIC-6915 "starfire") -if_sge_load="NO" # Silicon Integrated Systems SiS 190/191 -if_sis_load="NO" # Silicon Integrated Systems SiS 900/7016 -if_sk_load="NO" # SysKonnect SK-984x series PCI Gigabit Ethernet -if_sn_load="NO" # SMC 91Cxx -if_ste_load="NO" # Sundance Technologies ST201 Fast Ethernet -if_stge_load="NO" # Sundance/Tamarack TC9021 Gigabit Ethernet -if_ti_load="NO" # Alteon Networks Tigon 1 and Tigon 2 -if_tl_load="NO" # Texas Instruments TNETE100 ("ThunderLAN") -if_tx_load="NO" # SMC 83c17x Fast Ethernet -if_txp_load="NO" # 3Com 3XP Typhoon/Sidewinder (3CR990) -if_vge_load="NO" # VIA VT6122 PCI Gigabit Ethernet -if_vte_load="NO" # DM&P Vortex86 RDC R6040 Fast Ethernet -if_uath_load="NO" # Atheros USB wireless for AR5005UG & AR5005UX -if_udav_load="NO" # Davicom DM9601 USB Ethernet -if_upgt_load="NO" # Conexant/Intersil PrismGT USB wireless -if_ural_load="NO" # Ralink Technology USB wireless -if_urtw_load="NO" # Realtek 8187L USB wireless -if_vr_load="NO" # VIA Rhine I and Rhine II -if_vx_load="NO" # 3Com 3C590 family -if_wb_load="NO" # Winbond W89C840F -if_wi_load="NO" # WaveLAN/IEEE 802.11 wireless NICs -if_wpi_load="NO" # Intel 3945ABG Wireless LAN IEEE 802.11 -if_xe_load="NO" # Xircom CreditCard PCMCIA -if_xl_load="NO" # 3Com Etherlink XL (3c900, 3c905, 3c905B) -sfxge_load="NO" # Solarflare 10Gb Ethernet adapter driver -utopia_load="NO" # ATM PHY driver - - -############################################################## -### Netgraph modules ####################################### -############################################################## - -ng_UI_load="NO" # UI netgraph node type -ng_async_load="NO" # asynchronous framing netgraph node type -ng_bpf_load="NO" # Berkeley packet filter netgraph node type -ng_bridge_load="NO" # Ethernet bridging netgraph node type -ng_cisco_load="NO" # Cisco HDLC protocol netgraph node type -ng_echo_load="NO" # Netgraph echo node type -ng_eiface_load="NO" # generic Ethernet interface netgraph node type -ng_etf_load="NO" # Ethertype filtering netgraph node type -ng_ether_load="NO" # Ethernet netgraph node type -ng_frame_relay_load="NO" # frame relay netgraph node type -ng_gif_load="NO" # generic tunnel interface netgraph node type -ng_gif_demux_load="NO" # demultiplexer for packets from ng_gif(4) nodes -ng_hole_load="NO" # Netgraph discard node type -ng_hub_load="NO" # packet distribution netgraph node type -ng_iface_load="NO" # interface Netgraph node type -ng_ip_input_load="NO" # netgraph IP input node type -ng_ksocket_load="NO" # kernel socket netgraph node type -ng_l2tp_load="NO" # L2TP protocol netgraph node type -ng_lmi_load="NO" # frame relay LMI protocol netgraph node type -ng_mppc_load="NO" # Microsoft MPPC/MPPE compression and - # encryption netgraph node type -ng_netflow_load="NO" # Cisco's NetFlow netgraph node type -ng_one2many_load="NO" # packet multiplexing netgraph node type -ng_ppp_load="NO" # PPP protocol netgraph node type -ng_pppoe_load="NO" # RFC 2516 PPPOE protocol netgraph node type -ng_pptpgre_load="NO" # PPTP GRE protocol netgraph node type -ng_rfc1490_load="NO" # RFC 1490 netgraph node type -ng_socket_load="NO" # Netgraph socket node type -ng_split_load="NO" # netgraph node to separate incoming and - # outgoing flows -ng_sppp_load="NO" # sppp netgraph node type -ng_tee_load="NO" # Netgraph ``tee'' node type -ng_tty_load="NO" # Netgraph node type that is also a line - # discipline -ng_vjc_load="NO" # Van Jacobsen compression netgraph node type -ng_vlan_load="NO" # IEEE 802.1Q VLAN tagging netgraph node type - - -############################################################## -### Sound modules ########################################## -############################################################## - -sound_load="NO" # Digital sound subsystem -snd_ad1816_load="NO" # ad1816 -snd_als4000_load="NO" # als4000 -snd_atiixp_load="NO" # atiixp -snd_cmi_load="NO" # cmi -snd_cs4281_load="NO" # cs4281 -snd_csa_load="NO" # csa -snd_ds1_load="NO" # ds1 -snd_emu10k1_load="NO" # Creative Sound Blaster Live -snd_emu10kx_load="NO" # Creative SoundBlaster Live! and Audigy -snd_envy24_load="NO" # VIA Envy24 -snd_envy24ht_load="NO" # VIA Envy24HT -snd_es137x_load="NO" # es137x -snd_ess_load="NO" # ess -snd_fm801_load="NO" # fm801 -snd_hda_load="NO" # Intel High Definition Audio (Controller) -snd_ich_load="NO" # Intel ICH -snd_maestro_load="NO" # Maestro -snd_maestro3_load="NO" # Maestro3 -snd_mss_load="NO" # Mss -snd_neomagic_load="NO" # Neomagic -snd_sb16_load="NO" # Sound Blaster 16 -snd_sb8_load="NO" # Sound Blaster Pro -snd_sbc_load="NO" # Sbc -snd_solo_load="NO" # Solo -snd_spicds_load="NO" # SPI codecs -snd_t4dwave_load="NO" # t4dwave -snd_via8233_load="NO" # via8233 -snd_via82c686_load="NO" # via82c686 -snd_vibes_load="NO" # vibes -snd_driver_load="NO" # All sound drivers - - -############################################################## -### USB modules ############################################ -############################################################## - -usb_load="NO" # USB subsystem -udbp_load="NO" # USB double bulk pipe host 2 host cables -ugen_load="NO" # USB generic device, if all else fails ... -ucycom_load="NO" # Cyprus USB serial adapters -ufm_load="NO" # Fm Radio -uhid_load="NO" # Human Interface Devices -ukbd_load="NO" # Keyboard -ulpt_load="NO" # Printer -ums_load="NO" # Mouse -umass_load="NO" # Mass Storage Devices -umct_load="NO" # Magic Control Technology USB-RS232 -umodem_load="NO" # Modems -uplcom_load="NO" # Prolific USB serial adapters -urio_load="NO" # Rio MP3 players -uvisor_load="NO" # PalmOS based PDAs -if_aue_load="NO" # ADMtek USB ethernet -if_axe_load="NO" # ASIX Electronics AX88172 USB ethernet -if_cdce_load="NO" # Ethernet over USB (CDC) -if_cue_load="NO" # CATC USB ethernet -if_kue_load="NO" # Kawasaki LSI USB ethernet -if_rae_load="NO" # Realtek RTL8150 USB adapter. -if_rum_load="NO" # Ralink USB 802.11 wireless adapter -if_uath_load="NO" # Atheros AR5523 wireless adapter -if_run_load="NO" # Ralink USB 802.11 wireless adapter -if_ural_load="NO" # Ralink RT2500USB 802.11 wireless adapter -if_zyd_load="NO" # ZyDAS ZD1211(B) USB 802.11 wireless adapter -snd_uaudio_load="NO" # USB audio - - -############################################################## -### Other modules ########################################## -############################################################## - -aio_load="NO" # Asynchronous I/O -bktr_load="NO" # Brooktree Bt848/Bt878 TV/Video Capture Card -ispfw_load="NO" # Qlogic ISP Firmware -agp_load="NO" # agp module -accf_data_load="NO" # Wait for data accept filter -accf_dns_load="NO" # Wait for full DNS request accept filter -accf_http_load="NO" # Wait for full HTTP request accept filter -ppi_load="NO" # Interface to ppbus parallel 'geek' port -pps_load="NO" # Pulse per second devices -puc_load="NO" # PCI "Universal" Communications driver -random_load="NO" # Random device -speaker_load="NO" # AT speaker module -coretemp_load="NO" # Intel Core CPU temperature monitor -vkbd_load="NO" # Virtual AT keyboard interface -vpd_load="NO" # Vital Product Data kernel interface -vpo_load="NO" # Parallel to SCSI interface driver -amdsmn_load="NO" # AMD Family 17h System Management Network -amdtemp_load="NO" # AMD K8/K10/K11 temperature monitor -tpm_load="NO" # Trusted Platform Module -wbwd_load="NO" # Winbond watchdog - - -############################################################## -### ACPI settings ########################################## -############################################################## - -acpi_dsdt_load="NO" # DSDT Overriding -acpi_dsdt_type="acpi_dsdt" # Don't change this -acpi_dsdt_name="/boot/acpi_dsdt.aml" - # Override DSDT in BIOS by this file -acpi_video_load="NO" # Load the ACPI video extension driver - - -############################################################## -### TrustedBSD MAC settings ################################ -############################################################## - -mac_biba_load="NO" # Biba MAC policy -mac_bsdextended_load="NO" # BSD/extended MAC policy -mac_ifoff="NO" # Interface silencing policy -mac_mls_load="NO" # MLS MAC policy -mac_none_load="NO" # Null MAC policy -mac_partition_load="NO" # Partition MAC policy -mac_seeotheruids_load="NO" # UID visbility MAC policy - - -############################################################## -### Module loading syntax example ########################## -############################################################## - -#module_load="YES" # loads module "module" -#module_name="realname" # uses "realname" instead of "module" -#module_type="type" # passes "-t type" to load -#module_flags="flags" # passes "flags" to the module -#module_before="cmd" # executes "cmd" before loading the module -#module_after="cmd" # executes "cmd" after loading the module -#module_error="cmd" # executes "cmd" if load fails - -# pfSense specific default values -loader_color="NO" -loader_logo="pfSensebw" -loader_brand="pfSense" -hw.usb.no_pf="1" -net.isr.maxthreads="-1" diff --git a/stand/geli/Makefile b/stand/geli/Makefile index 24faf12..fa77b19 100644 --- a/stand/geli/Makefile +++ b/stand/geli/Makefile @@ -34,5 +34,4 @@ SRCS+= geliboot_crypto.c g_eli_hmac.c g_eli_key.c g_eli_key_cache.c pkcs5v2.c .PATH: ${SYSDIR}/opencrypto SRCS+= xform_aes_xts.c -.include <bsd.stand.mk> .include <bsd.lib.mk> diff --git a/stand/i386/Makefile b/stand/i386/Makefile index 9a1663a..1deeef3 100644 --- a/stand/i386/Makefile +++ b/stand/i386/Makefile @@ -1,25 +1,23 @@ # $FreeBSD$ +NO_OBJ=t + .include <bsd.init.mk> -SUBDIR= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot \ - libi386 +SUBDIR.yes= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot \ + isoboot libi386 -.if ${MK_LOADER_FIREWIRE} == "yes" -SUBDIR+= libfirewire -.endif +SUBDIR.${MK_LOADER_FIREWIRE}+= libfirewire -SUBDIR+= loader +SUBDIR.yes+= loader # special boot programs, 'self-extracting boot2+loader' -SUBDIR+= pxeldr +SUBDIR.yes+= pxeldr .if ${MACHINE_CPUARCH} == "i386" -SUBDIR+= kgzldr +SUBDIR.yes+= kgzldr .endif -.if ${MK_ZFS} != "no" -SUBDIR+= zfsboot gptzfsboot zfsloader -.endif +SUBDIR.${MK_ZFS}+= zfsboot gptzfsboot zfsloader .include <bsd.subdir.mk> diff --git a/stand/i386/Makefile.inc b/stand/i386/Makefile.inc index 042ee1b..ef351fc 100644 --- a/stand/i386/Makefile.inc +++ b/stand/i386/Makefile.inc @@ -2,8 +2,13 @@ # # $FreeBSD$ +.sinclude <bsd.linker.mk> + LOADER_ADDRESS?=0x200000 LDFLAGS+= -nostdlib +.if defined(LINKER_TYPE) && ${LINKER_TYPE} == "lld" +LDFLAGS+= -Wl,--no-rosegment +.endif # BTX components BTXDIR= ${BOOTOBJ}/i386/btx diff --git a/stand/i386/boot2/boot2.c b/stand/i386/boot2/boot2.c index cc5d76f..898a8c2 100644 --- a/stand/i386/boot2/boot2.c +++ b/stand/i386/boot2/boot2.c @@ -72,33 +72,33 @@ extern uint32_t _end; static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ static const unsigned char flags[NOPT] = { - RBX_DUAL, - RBX_SERIAL, - RBX_ASKNAME, - RBX_CDROM, - RBX_CONFIG, - RBX_KDB, - RBX_GDB, - RBX_MUTE, - RBX_NOINTR, - RBX_PAUSE, - RBX_QUIET, - RBX_DFLTROOT, - RBX_SINGLE, - RBX_VERBOSE + RBX_DUAL, + RBX_SERIAL, + RBX_ASKNAME, + RBX_CDROM, + RBX_CONFIG, + RBX_KDB, + RBX_GDB, + RBX_MUTE, + RBX_NOINTR, + RBX_PAUSE, + RBX_QUIET, + RBX_DFLTROOT, + RBX_SINGLE, + RBX_VERBOSE }; static const char *const dev_nm[NDEV] = {"ad", "da", "fd"}; static const unsigned char dev_maj[NDEV] = {30, 4, 2}; static struct dsk { - unsigned drive; - unsigned type; - unsigned unit; - uint8_t slice; - uint8_t part; - unsigned start; - int init; + unsigned drive; + unsigned type; + unsigned unit; + uint8_t slice; + uint8_t part; + unsigned start; + int init; } dsk; static char cmd[512], cmddup[512], knamebuf[1024]; static const char *kname; @@ -126,18 +126,22 @@ static void memcpy(void *, const void *, int); static void memcpy(void *dst, const void *src, int len) { - const char *s = src; - char *d = dst; + const char *s; + char *d; - while (len--) - *d++ = *s++; + s = src; + d = dst; + + while (len--) + *d++ = *s++; } static inline 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 ((unsigned char)*s1 - (unsigned char)*s2); } #define UFS_SMALL_CGBASE @@ -146,501 +150,513 @@ strcmp(const char *s1, const char *s2) static int xfsread(ufs_ino_t inode, void *buf, size_t nbyte) { - if ((size_t)fsread(inode, buf, nbyte) != nbyte) { - printf("Invalid %s\n", "format"); - return -1; - } - return 0; + + if ((size_t)fsread(inode, buf, nbyte) != nbyte) { + printf("Invalid %s\n", "format"); + return (-1); + } + return (0); } static inline void getstr(void) { - char *s; - int c; - - s = cmd; - for (;;) { - switch (c = xgetc(0)) { - case 0: - break; - case '\177': - case '\b': - if (s > cmd) { - s--; - printf("\b \b"); - } - break; - case '\n': - case '\r': - *s = 0; - return; - default: - if (s - cmd < sizeof(cmd) - 1) - *s++ = c; - putchar(c); + char *s; + int c; + + s = cmd; + for (;;) { + switch (c = xgetc(0)) { + case 0: + break; + case '\177': + case '\b': + if (s > cmd) { + s--; + printf("\b \b"); + } + break; + case '\n': + case '\r': + *s = 0; + return; + default: + if (s - cmd < sizeof(cmd) - 1) + *s++ = c; + putchar(c); + } } - } } static inline void putc(int c) { - v86.addr = 0x10; - v86.eax = 0xe00 | (c & 0xff); - v86.ebx = 0x7; - v86int(); + + v86.addr = 0x10; + v86.eax = 0xe00 | (c & 0xff); + v86.ebx = 0x7; + v86int(); } int main(void) { - uint8_t autoboot; - ufs_ino_t ino; - size_t nbyte; - - dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); - v86.ctl = V86_FLAGS; - v86.efl = PSL_RESERVED_DEFAULT | PSL_I; - dsk.drive = *(uint8_t *)PTOV(ARGS); - dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD; - dsk.unit = dsk.drive & DRV_MASK; - dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1; - bootinfo.bi_version = BOOTINFO_VERSION; - bootinfo.bi_size = sizeof(bootinfo); - - /* Process configuration file */ - - autoboot = 1; - - if ((ino = lookup(PATH_CONFIG)) || - (ino = lookup(PATH_DOTCONFIG))) { - nbyte = fsread(ino, cmd, sizeof(cmd) - 1); - cmd[nbyte] = '\0'; - } - - if (*cmd) { - memcpy(cmddup, cmd, sizeof(cmd)); - if (parse()) - autoboot = 0; - if (!OPT_CHECK(RBX_QUIET)) - printf("%s: %s", PATH_CONFIG, cmddup); - /* 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, try to load a kernel directly instead. - */ - - if (!kname) { - kname = PATH_LOADER; - if (autoboot && !keyhit(3*SECOND)) { - load(); - kname = PATH_KERNEL; + uint8_t autoboot; + ufs_ino_t ino; + size_t nbyte; + + dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); + v86.ctl = V86_FLAGS; + v86.efl = PSL_RESERVED_DEFAULT | PSL_I; + dsk.drive = *(uint8_t *)PTOV(ARGS); + dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD; + dsk.unit = dsk.drive & DRV_MASK; + dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1; + bootinfo.bi_version = BOOTINFO_VERSION; + bootinfo.bi_size = sizeof(bootinfo); + + /* Process configuration file */ + + autoboot = 1; + + if ((ino = lookup(PATH_CONFIG)) || + (ino = lookup(PATH_DOTCONFIG))) { + nbyte = fsread(ino, cmd, sizeof(cmd) - 1); + cmd[nbyte] = '\0'; + } + + if (*cmd) { + memcpy(cmddup, cmd, sizeof(cmd)); + if (parse()) + autoboot = 0; + if (!OPT_CHECK(RBX_QUIET)) + printf("%s: %s", PATH_CONFIG, cmddup); + /* Do not process this command twice */ + *cmd = 0; } - } - /* Present the user with the boot2 prompt. */ + /* + * Try to exec stage 3 boot loader. If interrupted by a keypress, + * or in case of failure, try to load a kernel directly instead. + */ - for (;;) { - if (!autoboot || !OPT_CHECK(RBX_QUIET)) - printf("\nFreeBSD/x86 boot\n" - "Default: %u:%s(%u,%c)%s\n" - "boot: ", - dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit, - 'a' + dsk.part, kname); - if (DO_SIO) - sio_flush(); - if (!autoboot || keyhit(3*SECOND)) - getstr(); - else if (!autoboot || !OPT_CHECK(RBX_QUIET)) - putchar('\n'); - autoboot = 0; - if (parse()) - putchar('\a'); - else - load(); - } + if (!kname) { + kname = PATH_LOADER; + if (autoboot && !keyhit(3*SECOND)) { + load(); + kname = PATH_KERNEL; + } + } + + /* Present the user with the boot2 prompt. */ + + for (;;) { + if (!autoboot || !OPT_CHECK(RBX_QUIET)) + printf("\nFreeBSD/x86 boot\n" + "Default: %u:%s(%u,%c)%s\n" + "boot: ", + dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit, + 'a' + dsk.part, kname); + if (DO_SIO) + sio_flush(); + if (!autoboot || keyhit(3*SECOND)) + getstr(); + else if (!autoboot || !OPT_CHECK(RBX_QUIET)) + putchar('\n'); + autoboot = 0; + if (parse()) + 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 { - struct exec ex; - Elf32_Ehdr eh; - } hdr; - static Elf32_Phdr ep[2]; - static Elf32_Shdr es[2]; - caddr_t p; - ufs_ino_t ino; - uint32_t addr; - int k; - uint8_t i, j; - - if (!(ino = lookup(kname))) { - if (!ls) - printf("No %s\n", kname); - return; - } - if (xfsread(ino, &hdr, sizeof(hdr))) - return; - - if (N_GETMAGIC(hdr.ex) == ZMAGIC) { - addr = hdr.ex.a_entry & 0xffffff; - p = PTOV(addr); - fs_off = PAGE_SIZE; - if (xfsread(ino, p, hdr.ex.a_text)) - return; - p += roundup2(hdr.ex.a_text, PAGE_SIZE); - if (xfsread(ino, p, hdr.ex.a_data)) - return; - } else if (IS_ELF(hdr.eh)) { - fs_off = hdr.eh.e_phoff; - for (j = k = 0; k < hdr.eh.e_phnum && j < 2; k++) { - if (xfsread(ino, ep + j, sizeof(ep[0]))) + union { + struct exec ex; + Elf32_Ehdr eh; + } hdr; + static Elf32_Phdr ep[2]; + static Elf32_Shdr es[2]; + caddr_t p; + ufs_ino_t ino; + uint32_t addr; + int k; + uint8_t i, j; + + if (!(ino = lookup(kname))) { + if (!ls) + printf("No %s\n", kname); return; - if (ep[j].p_type == PT_LOAD) - j++; } - for (i = 0; i < 2; i++) { - p = PTOV(ep[i].p_paddr & 0xffffff); - fs_off = ep[i].p_offset; - if (xfsread(ino, p, ep[i].p_filesz)) + if (xfsread(ino, &hdr, sizeof(hdr))) return; - } - p += roundup2(ep[1].p_memsz, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { - fs_off = hdr.eh.e_shoff + sizeof(es[0]) * - (hdr.eh.e_shstrndx + 1); - if (xfsread(ino, &es, sizeof(es))) + + if (N_GETMAGIC(hdr.ex) == ZMAGIC) { + addr = hdr.ex.a_entry & 0xffffff; + p = PTOV(addr); + fs_off = PAGE_SIZE; + if (xfsread(ino, p, hdr.ex.a_text)) + return; + p += roundup2(hdr.ex.a_text, PAGE_SIZE); + if (xfsread(ino, p, hdr.ex.a_data)) + return; + } else if (IS_ELF(hdr.eh)) { + fs_off = hdr.eh.e_phoff; + for (j = k = 0; k < hdr.eh.e_phnum && j < 2; k++) { + if (xfsread(ino, ep + j, sizeof(ep[0]))) + return; + if (ep[j].p_type == PT_LOAD) + j++; + } + for (i = 0; i < 2; i++) { + p = PTOV(ep[i].p_paddr & 0xffffff); + fs_off = ep[i].p_offset; + if (xfsread(ino, p, ep[i].p_filesz)) + return; + } + p += roundup2(ep[1].p_memsz, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { + fs_off = hdr.eh.e_shoff + sizeof(es[0]) * + (hdr.eh.e_shstrndx + 1); + if (xfsread(ino, &es, sizeof(es))) + return; + for (i = 0; i < 2; i++) { + *(Elf32_Word *)p = es[i].sh_size; + p += sizeof(es[i].sh_size); + fs_off = es[i].sh_offset; + if (xfsread(ino, p, es[i].sh_size)) + return; + p += es[i].sh_size; + } + } + addr = hdr.eh.e_entry & 0xffffff; + bootinfo.bi_esymtab = VTOP(p); + } else { + printf("Invalid %s\n", "format"); return; - for (i = 0; i < 2; i++) { - *(Elf32_Word *)p = es[i].sh_size; - p += sizeof(es[i].sh_size); - fs_off = es[i].sh_offset; - if (xfsread(ino, p, es[i].sh_size)) - return; - p += es[i].sh_size; - } } - addr = hdr.eh.e_entry & 0xffffff; - bootinfo.bi_esymtab = VTOP(p); - } else { - printf("Invalid %s\n", "format"); - return; - } - bootinfo.bi_kernelname = VTOP(kname); - bootinfo.bi_bios_dev = dsk.drive; - __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), - MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part), - 0, 0, 0, VTOP(&bootinfo)); + bootinfo.bi_kernelname = VTOP(kname); + bootinfo.bi_bios_dev = dsk.drive; + __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), + MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part), + 0, 0, 0, VTOP(&bootinfo)); } static int parse() { - char *arg = cmd; - char *ep, *p, *q; - const char *cp; - unsigned int drv; - int c, i, j; - size_t k; - - while ((c = *arg++)) { - if (c == ' ' || c == '\t' || c == '\n') - continue; - for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); - ep = p; - if (*p) - *p++ = 0; - if (c == '-') { - while ((c = *arg++)) { - if (c == 'P') { - if (*(uint8_t *)PTOV(0x496) & 0x10) { - cp = "yes"; - } else { - opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); - cp = "no"; - } - printf("Keyboard: %s\n", cp); - continue; + char *arg, *ep, *p, *q; + const char *cp; + unsigned int drv; + int c, i, j; + size_t k; + + arg = cmd; + + while ((c = *arg++)) { + if (c == ' ' || c == '\t' || c == '\n') + continue; + for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; + if (*p) + *p++ = 0; + if (c == '-') { + while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= OPT_SET(RBX_DUAL) | + OPT_SET(RBX_SERIAL); + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; #if SERIAL - } else if (c == 'S') { - j = 0; - while ((unsigned int)(i = *arg++ - '0') <= 9) - j = j * 10 + i; - if (j > 0 && i == -'0') { - comspeed = j; - break; - } - /* Fall through to error below ('S' not in optstr[]). */ + } else if (c == 'S') { + j = 0; + while ((u_int)(i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* + * Fall through to error below + * ('S' not in optstr[]). + */ #endif - } - for (i = 0; c != optstr[i]; i++) - if (i == NOPT - 1) - return -1; - opts ^= OPT_SET(flags[i]); - } + } + for (i = 0; c != optstr[i]; i++) + if (i == NOPT - 1) + return (-1); + opts ^= OPT_SET(flags[i]); + } #if SERIAL - ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : - OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; - if (DO_SIO) { - if (sio_init(115200 / comspeed) != 0) - ioctrl &= ~IO_SERIAL; - } + ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : + OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; + if (DO_SIO) { + if (sio_init(115200 / comspeed) != 0) + ioctrl &= ~IO_SERIAL; + } #endif - } else { - for (q = arg--; *q && *q != '('; q++); - if (*q) { - drv = -1; - if (arg[1] == ':') { - drv = *arg - '0'; - if (drv > 9) - return (-1); - arg += 2; - } - if (q - arg != 2) - return -1; - for (i = 0; arg[0] != dev_nm[i][0] || - arg[1] != dev_nm[i][1]; i++) - if (i == NDEV - 1) - return -1; - dsk.type = i; - arg += 3; - dsk.unit = *arg - '0'; - if (arg[1] != ',' || dsk.unit > 9) - return -1; - arg += 2; - dsk.slice = WHOLE_DISK_SLICE; - if (arg[1] == ',') { - dsk.slice = *arg - '0' + 1; - if (dsk.slice > NDOSPART + 1) - return -1; - arg += 2; + } else { + for (q = arg--; *q && *q != '('; q++); + if (*q) { + drv = -1; + if (arg[1] == ':') { + drv = *arg - '0'; + if (drv > 9) + return (-1); + arg += 2; + } + if (q - arg != 2) + return (-1); + for (i = 0; arg[0] != dev_nm[i][0] || + arg[1] != dev_nm[i][1]; i++) + if (i == NDEV - 1) + return (-1); + dsk.type = i; + arg += 3; + dsk.unit = *arg - '0'; + if (arg[1] != ',' || dsk.unit > 9) + return (-1); + arg += 2; + dsk.slice = WHOLE_DISK_SLICE; + if (arg[1] == ',') { + dsk.slice = *arg - '0' + 1; + if (dsk.slice > NDOSPART + 1) + return (-1); + arg += 2; + } + if (arg[1] != ')') + return (-1); + dsk.part = *arg - 'a'; + if (dsk.part > 7) + return (-1); + arg += 2; + if (drv == -1) + drv = dsk.unit; + dsk.drive = (dsk.type <= TYPE_MAXHARD + ? DRV_HARD : 0) + drv; + dsk_meta = 0; + } + k = ep - arg; + if (k > 0) { + if (k >= sizeof(knamebuf)) + return (-1); + memcpy(knamebuf, arg, k + 1); + kname = knamebuf; + } } - if (arg[1] != ')') - return -1; - dsk.part = *arg - 'a'; - if (dsk.part > 7) - return (-1); - arg += 2; - if (drv == -1) - drv = dsk.unit; - dsk.drive = (dsk.type <= TYPE_MAXHARD - ? DRV_HARD : 0) + drv; - dsk_meta = 0; - } - k = ep - arg; - if (k > 0) { - if (k >= sizeof(knamebuf)) - return -1; - memcpy(knamebuf, arg, k + 1); - kname = knamebuf; - } + arg = p; } - arg = p; - } - return 0; + return (0); } static int dskread(void *buf, unsigned lba, unsigned nblk) { - struct dos_partition *dp; - struct disklabel *d; - char *sec; - unsigned i; - uint8_t sl; - const char *reason; - - 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; + struct dos_partition *dp; + struct disklabel *d; + char *sec; + unsigned i; + uint8_t sl; + const char *reason; + + 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) { + reason = "slice"; + goto error; + } + dsk.start = dp->dp_start; + } + if (drvread(sec, dsk.start + LABELSECTOR, 1)) + return (-1); + d = (void *)(sec + LABELOFFSET); + if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) { + if (dsk.part != RAW_PART) { + reason = "label"; + goto error; + } + } 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) { + reason = "partition"; + goto error; + } + dsk.start += d->d_partitions[dsk.part].p_offset; + dsk.start -= d->d_partitions[RAW_PART].p_offset; } - 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) { - reason = "slice"; - goto error; - } - dsk.start = dp->dp_start; - } - if (drvread(sec, dsk.start + LABELSECTOR, 1)) - return -1; - d = (void *)(sec + LABELOFFSET); - if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) { - if (dsk.part != RAW_PART) { - reason = "label"; - goto error; - } - } 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) { - reason = "partition"; - goto error; - } - dsk.start += d->d_partitions[dsk.part].p_offset; - dsk.start -= d->d_partitions[RAW_PART].p_offset; } - } - return drvread(buf, dsk.start + lba, nblk); + return (drvread(buf, dsk.start + lba, nblk)); error: - printf("Invalid %s\n", reason); - return -1; + printf("Invalid %s\n", reason); + return (-1); } static void printf(const char *fmt,...) { - va_list ap; - static char buf[10]; - char *s; - unsigned u; - int c; - - va_start(ap, fmt); - while ((c = *fmt++)) { - if (c == '%') { - c = *fmt++; - switch (c) { - case 'c': - putchar(va_arg(ap, int)); - continue; - case 's': - for (s = va_arg(ap, char *); *s; s++) - putchar(*s); - continue; - case 'u': - u = va_arg(ap, unsigned); - s = buf; - do - *s++ = '0' + u % 10U; - while (u /= 10U); - while (--s >= buf) - putchar(*s); - continue; - } + va_list ap; + static char buf[10]; + char *s; + unsigned u; + int c; + + va_start(ap, fmt); + while ((c = *fmt++)) { + if (c == '%') { + c = *fmt++; + switch (c) { + case 'c': + putchar(va_arg(ap, int)); + continue; + case 's': + for (s = va_arg(ap, char *); *s; s++) + putchar(*s); + continue; + case 'u': + u = va_arg(ap, unsigned); + s = buf; + do + *s++ = '0' + u % 10U; + while (u /= 10U); + while (--s >= buf) + putchar(*s); + continue; + } + } + putchar(c); } - putchar(c); - } - va_end(ap); - return; + va_end(ap); + return; } static void putchar(int c) { - if (c == '\n') - xputc('\r'); - xputc(c); + + if (c == '\n') + xputc('\r'); + xputc(c); } static int drvread(void *buf, unsigned lba, unsigned nblk) { - static unsigned c = 0x2d5c7c2f; - - if (!OPT_CHECK(RBX_QUIET)) { - xputc(c = c << 8 | c >> 24); - xputc('\b'); - } - v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; - v86.addr = XREADORG; /* call to xread in boot1 */ - v86.es = VTOPSEG(buf); - v86.eax = lba; - v86.ebx = VTOPOFF(buf); - v86.ecx = lba >> 16; - v86.edx = nblk << 8 | dsk.drive; - v86int(); - v86.ctl = V86_FLAGS; - if (V86_CY(v86.efl)) { - printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba); - return -1; - } - return 0; + static unsigned c = 0x2d5c7c2f; + + if (!OPT_CHECK(RBX_QUIET)) { + xputc(c = c << 8 | c >> 24); + xputc('\b'); + } + v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; + v86.addr = XREADORG; /* call to xread in boot1 */ + v86.es = VTOPSEG(buf); + v86.eax = lba; + v86.ebx = VTOPOFF(buf); + v86.ecx = lba >> 16; + v86.edx = nblk << 8 | dsk.drive; + v86int(); + v86.ctl = V86_FLAGS; + if (V86_CY(v86.efl)) { + printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba); + return (-1); + } + return (0); } static int keyhit(unsigned ticks) { - uint32_t t0, t1; - - if (OPT_CHECK(RBX_NOINTR)) - return 0; - t0 = 0; - for (;;) { - if (xgetc(1)) - return 1; - t1 = *(uint32_t *)PTOV(0x46c); - if (!t0) - t0 = t1; - if ((uint32_t)(t1 - t0) >= ticks) - return 0; - } + uint32_t t0, t1; + + if (OPT_CHECK(RBX_NOINTR)) + return (0); + t0 = 0; + for (;;) { + if (xgetc(1)) + return (1); + t1 = *(uint32_t *)PTOV(0x46c); + if (!t0) + t0 = t1; + if ((uint32_t)(t1 - t0) >= ticks) + return (0); + } } static int xputc(int c) { - if (DO_KBD) - putc(c); - if (DO_SIO) - sio_putc(c); - return c; + + if (DO_KBD) + putc(c); + if (DO_SIO) + sio_putc(c); + return (c); } static int getc(int fn) { - v86.addr = 0x16; - v86.eax = fn << 8; - v86int(); - return fn == 0 ? v86.eax & 0xff : !V86_ZR(v86.efl); + + v86.addr = 0x16; + v86.eax = fn << 8; + v86int(); + return (fn == 0 ? v86.eax & 0xff : !V86_ZR(v86.efl)); } static int xgetc(int fn) { - if (OPT_CHECK(RBX_NOINTR)) - return 0; - for (;;) { - if (DO_KBD && getc(1)) - return fn ? 1 : getc(0); - if (DO_SIO && sio_ischar()) - return fn ? 1 : sio_getc(); - if (fn) - return 0; - } + + if (OPT_CHECK(RBX_NOINTR)) + return (0); + for (;;) { + if (DO_KBD && getc(1)) + return (fn ? 1 : getc(0)); + if (DO_SIO && sio_ischar()) + return (fn ? 1 : sio_getc()); + if (fn) + return (0); + } } diff --git a/stand/i386/btx/lib/btxv86.h b/stand/i386/btx/lib/btxv86.h index f04ce5e..0dca768 100644 --- a/stand/i386/btx/lib/btxv86.h +++ b/stand/i386/btx/lib/btxv86.h @@ -58,13 +58,13 @@ void __v86int(void); #define v86 __v86 #define v86int __v86int -extern u_int32_t __base; -extern u_int32_t __args; +extern uint32_t __base; +extern uint32_t __args; #define PTOV(pa) ((caddr_t)(pa) - __base) #define VTOP(va) ((vm_offset_t)(va) + __base) -#define VTOPSEG(va) (u_int16_t)(VTOP((caddr_t)va) >> 4) -#define VTOPOFF(va) (u_int16_t)(VTOP((caddr_t)va) & 0xf) +#define VTOPSEG(va) (uint16_t)(VTOP((caddr_t)va) >> 4) +#define VTOPOFF(va) (uint16_t)(VTOP((caddr_t)va) & 0xf) #define V86_CY(x) ((x) & PSL_C) #define V86_ZR(x) ((x) & PSL_Z) diff --git a/stand/i386/gptboot/gptboot.c b/stand/i386/gptboot/gptboot.c index a9d54f4..9c2d9d1 100644 --- a/stand/i386/gptboot/gptboot.c +++ b/stand/i386/gptboot/gptboot.c @@ -132,87 +132,93 @@ xfsread(ufs_ino_t inode, void *buf, size_t nbyte) static void bios_getmem(void) { - uint64_t size; + uint64_t size; + + /* Parse system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = MEM_EXT; /* int 0x15 function 0xe820*/ + v86.eax = 0xe820; + v86.ecx = sizeof(struct bios_smap); + v86.edx = SMAP_SIG; + v86.es = VTOPSEG(&smap); + v86.edi = VTOPOFF(&smap); + v86int(); + if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) + break; + /* look for a low-memory segment that's large enough */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && + (smap.length >= (512 * 1024))) + bios_basemem = smap.length; + /* look for the first segment in 'extended' memory */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base == 0x100000)) { + bios_extmem = smap.length; + } - /* Parse system memory map */ - v86.ebx = 0; - do { - v86.ctl = V86_FLAGS; - v86.addr = MEM_EXT; /* int 0x15 function 0xe820*/ - v86.eax = 0xe820; - v86.ecx = sizeof(struct bios_smap); - v86.edx = SMAP_SIG; - v86.es = VTOPSEG(&smap); - v86.edi = VTOPOFF(&smap); - v86int(); - if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) - break; - /* look for a low-memory segment that's large enough */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && - (smap.length >= (512 * 1024))) - bios_basemem = smap.length; - /* look for the first segment in 'extended' memory */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) { - bios_extmem = smap.length; + /* + * Look for the largest segment in 'extended' memory beyond + * 1MB but below 4GB. + */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base > 0x100000) && (smap.base < 0x100000000ull)) { + size = smap.length; + + /* + * If this segment crosses the 4GB boundary, + * truncate it. + */ + if (smap.base + size > 0x100000000ull) + size = 0x100000000ull - smap.base; + + if (size > high_heap_size) { + high_heap_size = size; + high_heap_base = smap.base; + } + } + } while (v86.ebx != 0); + + /* Fall back to the old compatibility function for base memory */ + if (bios_basemem == 0) { + v86.ctl = 0; + v86.addr = 0x12; /* int 0x12 */ + v86int(); + + bios_basemem = (v86.eax & 0xffff) * 1024; } /* - * Look for the largest segment in 'extended' memory beyond - * 1MB but below 4GB. + * Fall back through several compatibility functions for extended + * memory */ - if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && - (smap.base < 0x100000000ull)) { - size = smap.length; - - /* - * If this segment crosses the 4GB boundary, truncate it. - */ - if (smap.base + size > 0x100000000ull) - size = 0x100000000ull - smap.base; - - if (size > high_heap_size) { - high_heap_size = size; - high_heap_base = smap.base; - } + if (bios_extmem == 0) { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe801*/ + v86.eax = 0xe801; + v86int(); + if (!(v86.efl & 1)) { + bios_extmem = ((v86.ecx & 0xffff) + + ((v86.edx & 0xffff) * 64)) * 1024; + } + } + if (bios_extmem == 0) { + v86.ctl = 0; + v86.addr = 0x15; /* int 0x15 function 0x88*/ + v86.eax = 0x8800; + v86int(); + bios_extmem = (v86.eax & 0xffff) * 1024; } - } while (v86.ebx != 0); - - /* Fall back to the old compatibility function for base memory */ - if (bios_basemem == 0) { - v86.ctl = 0; - v86.addr = 0x12; /* int 0x12 */ - v86int(); - - bios_basemem = (v86.eax & 0xffff) * 1024; - } - /* Fall back through several compatibility functions for extended memory */ - if (bios_extmem == 0) { - v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe801*/ - v86.eax = 0xe801; - v86int(); - if (!(v86.efl & 1)) { - bios_extmem = ((v86.ecx & 0xffff) + ((v86.edx & 0xffff) * 64)) * 1024; + /* + * If we have extended memory and did not find a suitable heap + * region in the SMAP, use the last 3MB of 'extended' memory as a + * high heap candidate. + */ + if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; } - } - if (bios_extmem == 0) { - v86.ctl = 0; - v86.addr = 0x15; /* int 0x15 function 0x88*/ - v86.eax = 0x8800; - v86int(); - bios_extmem = (v86.eax & 0xffff) * 1024; - } - - /* - * If we have extended memory and did not find a suitable heap - * region in the SMAP, use the last 3MB of 'extended' memory as a - * high heap candidate. - */ - if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { - high_heap_size = HEAP_MIN; - high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; - } } static int @@ -364,6 +370,7 @@ main(void) void exit(int x) { + while (1); __unreachable(); } @@ -371,207 +378,216 @@ exit(int x) static void load(void) { - union { - struct exec ex; - Elf32_Ehdr eh; - } hdr; - static Elf32_Phdr ep[2]; - static Elf32_Shdr es[2]; - caddr_t p; - ufs_ino_t ino; - uint32_t addr, x; - int fmt, i, j; - - if (!(ino = lookup(kname))) { - if (!ls) { - printf("%s: No %s on %u:%s(%up%u)\n", BOOTPROG, - kname, dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit, - dsk.part); - } - return; - } - if (xfsread(ino, &hdr, sizeof(hdr))) - return; - if (N_GETMAGIC(hdr.ex) == ZMAGIC) - fmt = 0; - else if (IS_ELF(hdr.eh)) - fmt = 1; - else { - printf("Invalid %s\n", "format"); - return; - } - if (fmt == 0) { - addr = hdr.ex.a_entry & 0xffffff; - p = PTOV(addr); - fs_off = PAGE_SIZE; - if (xfsread(ino, p, hdr.ex.a_text)) - return; - p += roundup2(hdr.ex.a_text, PAGE_SIZE); - if (xfsread(ino, p, hdr.ex.a_data)) - return; - p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); - p += sizeof(hdr.ex.a_syms); - if (hdr.ex.a_syms) { - if (xfsread(ino, p, hdr.ex.a_syms)) - return; - p += hdr.ex.a_syms; - if (xfsread(ino, p, sizeof(int))) - return; - x = *(uint32_t *)p; - p += sizeof(int); - x -= sizeof(int); - if (xfsread(ino, p, x)) + union { + struct exec ex; + Elf32_Ehdr eh; + } hdr; + static Elf32_Phdr ep[2]; + static Elf32_Shdr es[2]; + caddr_t p; + ufs_ino_t ino; + uint32_t addr, x; + int fmt, i, j; + + if (!(ino = lookup(kname))) { + if (!ls) { + printf("%s: No %s on %u:%s(%up%u)\n", BOOTPROG, + kname, dsk.drive & DRV_MASK, dev_nm[dsk.type], + dsk.unit, + dsk.part); + } return; - p += x; } - } else { - fs_off = hdr.eh.e_phoff; - for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { - if (xfsread(ino, ep + j, sizeof(ep[0]))) + if (xfsread(ino, &hdr, sizeof(hdr))) return; - if (ep[j].p_type == PT_LOAD) - j++; - } - for (i = 0; i < 2; i++) { - p = PTOV(ep[i].p_paddr & 0xffffff); - fs_off = ep[i].p_offset; - if (xfsread(ino, p, ep[i].p_filesz)) + if (N_GETMAGIC(hdr.ex) == ZMAGIC) + fmt = 0; + else if (IS_ELF(hdr.eh)) + fmt = 1; + else { + printf("Invalid %s\n", "format"); return; } - p += roundup2(ep[1].p_memsz, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { - fs_off = hdr.eh.e_shoff + sizeof(es[0]) * - (hdr.eh.e_shstrndx + 1); - if (xfsread(ino, &es, sizeof(es))) - return; - for (i = 0; i < 2; i++) { - memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size)); - p += sizeof(es[i].sh_size); - fs_off = es[i].sh_offset; - if (xfsread(ino, p, es[i].sh_size)) - return; - p += es[i].sh_size; - } + if (fmt == 0) { + addr = hdr.ex.a_entry & 0xffffff; + p = PTOV(addr); + fs_off = PAGE_SIZE; + if (xfsread(ino, p, hdr.ex.a_text)) + return; + p += roundup2(hdr.ex.a_text, PAGE_SIZE); + if (xfsread(ino, p, hdr.ex.a_data)) + return; + p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); + p += sizeof(hdr.ex.a_syms); + if (hdr.ex.a_syms) { + if (xfsread(ino, p, hdr.ex.a_syms)) + return; + p += hdr.ex.a_syms; + if (xfsread(ino, p, sizeof(int))) + return; + x = *(uint32_t *)p; + p += sizeof(int); + x -= sizeof(int); + if (xfsread(ino, p, x)) + return; + p += x; + } + } else { + fs_off = hdr.eh.e_phoff; + for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { + if (xfsread(ino, ep + j, sizeof(ep[0]))) + return; + if (ep[j].p_type == PT_LOAD) + j++; + } + for (i = 0; i < 2; i++) { + p = PTOV(ep[i].p_paddr & 0xffffff); + fs_off = ep[i].p_offset; + if (xfsread(ino, p, ep[i].p_filesz)) + return; + } + p += roundup2(ep[1].p_memsz, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { + fs_off = hdr.eh.e_shoff + sizeof(es[0]) * + (hdr.eh.e_shstrndx + 1); + if (xfsread(ino, &es, sizeof(es))) + return; + for (i = 0; i < 2; i++) { + memcpy(p, &es[i].sh_size, + sizeof(es[i].sh_size)); + p += sizeof(es[i].sh_size); + fs_off = es[i].sh_offset; + if (xfsread(ino, p, es[i].sh_size)) + return; + p += es[i].sh_size; + } + } + addr = hdr.eh.e_entry & 0xffffff; } - addr = hdr.eh.e_entry & 0xffffff; - } - bootinfo.bi_esymtab = VTOP(p); - bootinfo.bi_kernelname = VTOP(kname); - bootinfo.bi_bios_dev = dsk.drive; + bootinfo.bi_esymtab = VTOP(p); + bootinfo.bi_kernelname = VTOP(kname); + bootinfo.bi_bios_dev = dsk.drive; #ifdef LOADER_GELI_SUPPORT - geliargs.size = sizeof(geliargs); - explicit_bzero(gelipw, sizeof(gelipw)); - gelibuf = malloc(sizeof(struct keybuf) + (GELI_MAX_KEYS * sizeof(struct keybuf_ent))); - geli_fill_keybuf(gelibuf); - geliargs.notapw = '\0'; - geliargs.keybuf_sentinel = KEYBUF_SENTINEL; - geliargs.keybuf = gelibuf; + geliargs.size = sizeof(geliargs); + explicit_bzero(gelipw, sizeof(gelipw)); + gelibuf = malloc(sizeof(struct keybuf) + + (GELI_MAX_KEYS * sizeof(struct keybuf_ent))); + geli_fill_keybuf(gelibuf); + geliargs.notapw = '\0'; + geliargs.keybuf_sentinel = KEYBUF_SENTINEL; + geliargs.keybuf = gelibuf; #endif - __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), - MAKEBOOTDEV(dev_maj[dsk.type], dsk.part + 1, dsk.unit, 0xff), - KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo) + __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), + MAKEBOOTDEV(dev_maj[dsk.type], dsk.part + 1, dsk.unit, 0xff), + KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo) #ifdef LOADER_GELI_SUPPORT - , geliargs + , geliargs #endif - ); + ); } static int parse_cmds(char *cmdstr, int *dskupdated) { - char *arg = cmdstr; - char *ep, *p, *q; - const char *cp; - unsigned int drv; - int c, i, j; - - *dskupdated = 0; - while ((c = *arg++)) { - if (c == ' ' || c == '\t' || c == '\n') - continue; - for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); - ep = p; - if (*p) - *p++ = 0; - if (c == '-') { - while ((c = *arg++)) { - if (c == 'P') { - if (*(uint8_t *)PTOV(0x496) & 0x10) { - cp = "yes"; - } else { - opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); - cp = "no"; - } - printf("Keyboard: %s\n", cp); - continue; - } else if (c == 'S') { - j = 0; - while ((unsigned int)(i = *arg++ - '0') <= 9) - 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; - opts ^= OPT_SET(flags[i]); - } - ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : - OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; - if (ioctrl & IO_SERIAL) { - if (sio_init(115200 / comspeed) != 0) - ioctrl &= ~IO_SERIAL; - } - } else { - for (q = arg--; *q && *q != '('; q++); - if (*q) { - drv = -1; - if (arg[1] == ':') { - drv = *arg - '0'; - if (drv > 9) - return (-1); - arg += 2; + char *arg; + char *ep, *p, *q; + const char *cp; + unsigned int drv; + int c, i, j; + + arg = cmdstr; + *dskupdated = 0; + while ((c = *arg++)) { + if (c == ' ' || c == '\t' || c == '\n') + continue; + for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; + if (*p) + *p++ = 0; + if (c == '-') { + while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= OPT_SET(RBX_DUAL) | + OPT_SET(RBX_SERIAL); + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') + <= 9) + 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); + opts ^= OPT_SET(flags[i]); + } + ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : + OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; + if (ioctrl & IO_SERIAL) { + if (sio_init(115200 / comspeed) != 0) + ioctrl &= ~IO_SERIAL; + } + } else { + for (q = arg--; *q && *q != '('; q++); + if (*q) { + drv = -1; + if (arg[1] == ':') { + drv = *arg - '0'; + if (drv > 9) + return (-1); + arg += 2; + } + if (q - arg != 2) + return (-1); + for (i = 0; arg[0] != dev_nm[i][0] || + arg[1] != dev_nm[i][1]; i++) + if (i == NDEV - 1) + return (-1); + dsk.type = i; + arg += 3; + dsk.unit = *arg - '0'; + if (arg[1] != 'p' || dsk.unit > 9) + return (-1); + arg += 2; + dsk.part = *arg - '0'; + if (dsk.part < 1 || dsk.part > 9) + return (-1); + arg++; + if (arg[0] != ')') + return (-1); + arg++; + if (drv == -1) + drv = dsk.unit; + dsk.drive = (dsk.type <= TYPE_MAXHARD + ? DRV_HARD : 0) + drv; + *dskupdated = 1; + } + if ((i = ep - arg)) { + if ((size_t)i >= sizeof(kname)) + return (-1); + memcpy(kname, arg, i + 1); + } } - if (q - arg != 2) - return -1; - for (i = 0; arg[0] != dev_nm[i][0] || - arg[1] != dev_nm[i][1]; i++) - if (i == NDEV - 1) - return -1; - dsk.type = i; - arg += 3; - dsk.unit = *arg - '0'; - if (arg[1] != 'p' || dsk.unit > 9) - return -1; - arg += 2; - dsk.part = *arg - '0'; - if (dsk.part < 1 || dsk.part > 9) - return -1; - arg++; - if (arg[0] != ')') - return -1; - arg++; - if (drv == -1) - drv = dsk.unit; - dsk.drive = (dsk.type <= TYPE_MAXHARD - ? DRV_HARD : 0) + drv; - *dskupdated = 1; - } - if ((i = ep - arg)) { - if ((size_t)i >= sizeof(kname)) - return -1; - memcpy(kname, arg, i + 1); - } + arg = p; } - arg = p; - } - return 0; + return (0); } static int @@ -603,7 +619,9 @@ vdev_read(void *vdev __unused, void *priv, off_t off, void *buf, size_t bytes) char *p; daddr_t lba; unsigned int nb; - struct dsk *dskp = (struct dsk *) priv; + struct dsk *dskp; + + dskp = (struct dsk *)priv; if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1))) return (-1); diff --git a/stand/i386/isoboot/Makefile b/stand/i386/isoboot/Makefile new file mode 100644 index 0000000..744198d --- /dev/null +++ b/stand/i386/isoboot/Makefile @@ -0,0 +1,68 @@ +# $FreeBSD$ + +HAVE_GELI= yes + +.include <bsd.init.mk> + +.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \ + ${BOOTSRC}/i386/common ${SASRC} + +FILES= isoboot +MAN= isoboot.8 + +NM?= nm + +BOOT_COMCONSOLE_PORT?= 0x3f8 +BOOT_COMCONSOLE_SPEED?= 9600 +B2SIOFMT?= 0x3 + +REL1= 0x700 +ORG1= 0x7c00 +ORG2= 0x0 + +ISOBOOTSIZE?= 30720 + +CFLAGS+=-DBOOTPROG=\"isoboot\" \ + -O1 \ + -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ + -DSIOFMT=${B2SIOFMT} \ + -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ + -I${LDRSRC} \ + -I${BOOTSRC}/i386/common \ + -I${BOOTSRC}/i386/boot2 \ + -Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \ + -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ + -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ + -Winline -Wno-pointer-sign + +CFLAGS.gcc+= --param max-inline-insns-single=100 +CFLAGS.clang+= -Oz ${CLANG_OPT_SMALL} + +LD_FLAGS+=${LD_FLAGS_BIN} + +CLEANFILES+= isoboot + +isoboot: gptldr.bin isoboot.bin ${BTXKERN} + btxld -v -E ${ORG2} -f bin -b ${BTXKERN} -l gptldr.bin \ + -o ${.TARGET} isoboot.bin + @set -- `ls -l ${.TARGET}`; x=$$((${ISOBOOTSIZE}-$$5)); \ + echo "$$x bytes available"; test $$x -ge 0 + +CLEANFILES+= gptldr.bin gptldr.out gptldr.o + +gptldr.bin: gptldr.out + ${OBJCOPY} -S -O binary gptldr.out ${.TARGET} + +gptldr.out: gptldr.o + ${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} gptldr.o + +CLEANFILES+= isoboot.bin isoboot.out isoboot.o sio.o crc32.o drv.o \ + cons.o ${OPENCRYPTO_XTS} + +isoboot.bin: isoboot.out + ${OBJCOPY} -S -O binary isoboot.out ${.TARGET} + +isoboot.out: ${BTXCRT} isoboot.o sio.o crc32.o drv.o cons.o ${OPENCRYPTO_XTS} + ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSA32} + +.include <bsd.prog.mk> diff --git a/stand/i386/isoboot/isoboot.8 b/stand/i386/isoboot/isoboot.8 new file mode 100644 index 0000000..e6971313 --- /dev/null +++ b/stand/i386/isoboot/isoboot.8 @@ -0,0 +1,69 @@ +.\" Copyright (c) 2018 iXsystems, Inc. +.\" All rights reserved. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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. +.\" +.\" $FreeBSD$ +.\" +.Dd March 30, 2018 +.Dt ISOBOOT 8 +.Os +.Sh NAME +.Nm isoboot +.Nd Boot code for hybrid ISO/USB images on BIOS-based computers +.Sh DESCRIPTION +.Nm +is used on BIOS-based computers to boot from an ISO image that has +been written to a USB flash drive or other HDD-like device. +.Nm +is installed in a +.Cm freebsd-boot +partition with +.Xr mkimg 1 . +.Sh IMPLEMENTATION NOTES +The El Torito standard for bootable CDs provides a 32KB "System Area" +at the beginning of an image. +To create an image that is able to be booted by the BIOS as either a +CD-ROM ("ISO") and as a more HDD-like image (e.g. on a USB flash drive) +it is necessary to have both a standard El Torito boot catalog +containing a HDD-style partition table and boot code. +.Nm +is intended to be placed in a GPT partition to allow the system to find +the standard +.Fx +.Xr loader 8 +in the ISO filesystem later in the image. +.Sh BOOTING +.Nm +looks for an ISO filesystem image on the device it was booted from and +seeks to read either the primary +.Fx +.Xr loader 8 +or kernel from there. +.Sh SEE ALSO +.Xr mkimg 1 +.Sh HISTORY +.Nm +appeared in FreeBSD 12.0. +.Sh AUTHORS +This manual page written by +.An Benno Rice Aq benno@FreeBSD.org . diff --git a/stand/i386/isoboot/isoboot.c b/stand/i386/isoboot/isoboot.c new file mode 100644 index 0000000..0505db6 --- /dev/null +++ b/stand/i386/isoboot/isoboot.c @@ -0,0 +1,522 @@ +/*- + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/gpt.h> +#include <sys/dirent.h> +#include <sys/reboot.h> + +#include <machine/bootinfo.h> +#include <machine/elf.h> +#include <machine/pc/bios.h> +#include <machine/psl.h> + +#include <stdarg.h> + +#include <a.out.h> + +#include <btxv86.h> + +#include "stand.h" + +#include "bootargs.h" +#include "lib.h" +#include "rbx.h" +#include "drv.h" +#include "cons.h" +#include "gpt.h" +#include "paths.h" + +#define ARGS 0x900 +#define NOPT 14 +#define NDEV 3 +#define MEM_BASE 0x12 +#define MEM_EXT 0x15 + +#define DRV_HARD 0x80 +#define DRV_MASK 0x7f + +#define TYPE_AD 0 +#define TYPE_DA 1 +#define TYPE_MAXHARD TYPE_DA +#define TYPE_FD 2 + +extern uint32_t _end; + +static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ +static const unsigned char flags[NOPT] = { + RBX_DUAL, + RBX_SERIAL, + RBX_ASKNAME, + RBX_CDROM, + RBX_CONFIG, + RBX_KDB, + RBX_GDB, + RBX_MUTE, + RBX_NOINTR, + RBX_PAUSE, + RBX_QUIET, + RBX_DFLTROOT, + RBX_SINGLE, + RBX_VERBOSE +}; +uint32_t opts; + +static const char *const dev_nm[NDEV] = {"ad", "da", "fd"}; +static const unsigned char dev_maj[NDEV] = {30, 4, 2}; + +static struct dsk dsk; +static char kname[1024]; +static int comspeed = SIOSPD; +static struct bootinfo bootinfo; + +static vm_offset_t high_heap_base; +static uint32_t bios_basemem, bios_extmem, high_heap_size; + +static struct bios_smap smap; + +/* + * The minimum amount of memory to reserve in bios_extmem for the heap. + */ +#define HEAP_MIN (3 * 1024 * 1024) + +static char *heap_next; +static char *heap_end; + +int main(void); + +static void load(void); +static int parse_cmds(char *, int *); + +static uint8_t ls, dsk_meta; +static uint32_t fs_off; + +#include "cd9660read.c" + +static inline int +xfsread(uint64_t inode, void *buf, size_t nbyte) +{ + + if ((size_t)cd9660_fsread(inode, buf, nbyte) != nbyte) { + printf("Invalid %s\n", "format"); + return (-1); + } + return (0); +} + +static void +bios_getmem(void) +{ + uint64_t size; + + /* Parse system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = MEM_EXT; /* int 0x15 function 0xe820*/ + v86.eax = 0xe820; + v86.ecx = sizeof(struct bios_smap); + v86.edx = SMAP_SIG; + v86.es = VTOPSEG(&smap); + v86.edi = VTOPOFF(&smap); + v86int(); + if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) + break; + /* look for a low-memory segment that's large enough */ + if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && + (smap.length >= (512 * 1024))) + bios_basemem = smap.length; + /* look for the first segment in 'extended' memory */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base == 0x100000)) { + bios_extmem = smap.length; + } + + /* + * Look for the largest segment in 'extended' memory beyond + * 1MB but below 4GB. + */ + if ((smap.type == SMAP_TYPE_MEMORY) && + (smap.base > 0x100000) && (smap.base < 0x100000000ull)) { + size = smap.length; + + /* + * If this segment crosses the 4GB boundary, + * truncate it. + */ + if (smap.base + size > 0x100000000ull) + size = 0x100000000ull - smap.base; + + if (size > high_heap_size) { + high_heap_size = size; + high_heap_base = smap.base; + } + } + } while (v86.ebx != 0); + + /* Fall back to the old compatibility function for base memory */ + if (bios_basemem == 0) { + v86.ctl = 0; + v86.addr = 0x12; /* int 0x12 */ + v86int(); + + bios_basemem = (v86.eax & 0xffff) * 1024; + } + + /* + * Fall back through several compatibility functions for extended + * memory + */ + if (bios_extmem == 0) { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe801*/ + v86.eax = 0xe801; + v86int(); + if (!(v86.efl & 1)) { + bios_extmem = ((v86.ecx & 0xffff) + + ((v86.edx & 0xffff) * 64)) * 1024; + } + } + if (bios_extmem == 0) { + v86.ctl = 0; + v86.addr = 0x15; /* int 0x15 function 0x88*/ + v86.eax = 0x8800; + v86int(); + bios_extmem = (v86.eax & 0xffff) * 1024; + } + + /* + * If we have extended memory and did not find a suitable heap + * region in the SMAP, use the last 3MB of 'extended' memory as a + * high heap candidate. + */ + if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { + high_heap_size = HEAP_MIN; + high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; + } +} + +int +main(void) +{ + char cmd[512], cmdtmp[512]; + ssize_t sz; + int autoboot, dskupdated; + uint64_t ino; + + bios_getmem(); + + if (high_heap_size > 0) { + heap_end = PTOV(high_heap_base + high_heap_size); + heap_next = PTOV(high_heap_base); + } else { + heap_next = (char *) + (roundup2(__base + (int32_t)&_end, 0x10000) - __base); + heap_end = (char *)PTOV(bios_basemem); + } + setheap(heap_next, heap_end); + + v86.ctl = V86_FLAGS; + v86.efl = PSL_RESERVED_DEFAULT | PSL_I; + dsk.drive = *(uint8_t *)PTOV(ARGS); + dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD; + dsk.unit = dsk.drive & DRV_MASK; + dsk.part = -1; + dsk.start = 0; + bootinfo.bi_version = BOOTINFO_VERSION; + bootinfo.bi_size = sizeof(bootinfo); + bootinfo.bi_basemem = bios_basemem / 1024; + bootinfo.bi_extmem = bios_extmem / 1024; + bootinfo.bi_memsizes_valid++; + bootinfo.bi_bios_dev = dsk.drive; + + autoboot = 1; + *cmd = '\0'; + + for (;;) { + *kname = '\0'; + if ((ino = cd9660_lookup(PATH_CONFIG)) || + (ino = cd9660_lookup(PATH_DOTCONFIG))) { + sz = cd9660_fsread(ino, cmd, sizeof(cmd) - 1); + cmd[(sz < 0) ? 0 : sz] = '\0'; + } + if (*cmd != '\0') { + memcpy(cmdtmp, cmd, sizeof(cmdtmp)); + if (parse_cmds(cmdtmp, &dskupdated)) + break; + if (!OPT_CHECK(RBX_QUIET)) + printf("%s: %s", PATH_CONFIG, cmd); + *cmd = '\0'; + } + + if (autoboot && keyhit(3)) { + if (*kname == '\0') + memcpy(kname, PATH_LOADER, sizeof(PATH_LOADER)); + break; + } + autoboot = 0; + + /* + * Try to exec stage 3 boot loader. If interrupted by a + * keypress, or in case of failure, try to load a kernel + * directly instead. + */ + if (*kname != '\0') + load(); + memcpy(kname, PATH_LOADER, sizeof(PATH_LOADER)); + load(); + memcpy(kname, PATH_KERNEL, sizeof(PATH_KERNEL)); + load(); + dsk_meta = 0; + } + + /* Present the user with the boot2 prompt. */ + + for (;;) { + if (!OPT_CHECK(RBX_QUIET)) { + printf("\nFreeBSD/x86 boot\n" + "Default: %u:%s(%up%u)%s\n" + "boot: ", + dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit, + dsk.part, kname); + } + if (ioctrl & IO_SERIAL) + sio_flush(); + *cmd = '\0'; + if (keyhit(0)) + getstr(cmd, sizeof(cmd)); + else if (!OPT_CHECK(RBX_QUIET)) + putchar('\n'); + if (parse_cmds(cmd, &dskupdated)) { + putchar('\a'); + continue; + } + load(); + } + /* NOTREACHED */ +} + +/* Needed so btxld can link us properly; do not remove. */ +void +exit(int x) +{ + + while (1); + __unreachable(); +} + +static void +load(void) +{ + union { + struct exec ex; + Elf32_Ehdr eh; + } hdr; + static Elf32_Phdr ep[2]; + static Elf32_Shdr es[2]; + caddr_t p; + uint64_t ino; + uint32_t addr, x; + int fmt, i, j; + + if (!(ino = cd9660_lookup(kname))) { + if (!ls) { + printf("%s: No %s on %u:%s(%up%u)\n", BOOTPROG, + kname, dsk.drive & DRV_MASK, dev_nm[dsk.type], + dsk.unit, + dsk.part); + } + return; + } + if (xfsread(ino, &hdr, sizeof(hdr))) + return; + if (N_GETMAGIC(hdr.ex) == ZMAGIC) + fmt = 0; + else if (IS_ELF(hdr.eh)) + fmt = 1; + else { + printf("Invalid %s\n", "format"); + return; + } + if (fmt == 0) { + addr = hdr.ex.a_entry & 0xffffff; + p = PTOV(addr); + fs_off = PAGE_SIZE; + if (xfsread(ino, p, hdr.ex.a_text)) + return; + p += roundup2(hdr.ex.a_text, PAGE_SIZE); + if (xfsread(ino, p, hdr.ex.a_data)) + return; + p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); + p += sizeof(hdr.ex.a_syms); + if (hdr.ex.a_syms) { + if (xfsread(ino, p, hdr.ex.a_syms)) + return; + p += hdr.ex.a_syms; + if (xfsread(ino, p, sizeof(int))) + return; + x = *(uint32_t *)p; + p += sizeof(int); + x -= sizeof(int); + if (xfsread(ino, p, x)) + return; + p += x; + } + } else { + fs_off = hdr.eh.e_phoff; + for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { + if (xfsread(ino, ep + j, sizeof(ep[0]))) + return; + if (ep[j].p_type == PT_LOAD) + j++; + } + for (i = 0; i < 2; i++) { + p = PTOV(ep[i].p_paddr & 0xffffff); + fs_off = ep[i].p_offset; + if (xfsread(ino, p, ep[i].p_filesz)) + return; + } + p += roundup2(ep[1].p_memsz, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { + fs_off = hdr.eh.e_shoff + sizeof(es[0]) * + (hdr.eh.e_shstrndx + 1); + if (xfsread(ino, &es, sizeof(es))) + return; + for (i = 0; i < 2; i++) { + memcpy(p, &es[i].sh_size, + sizeof(es[i].sh_size)); + p += sizeof(es[i].sh_size); + fs_off = es[i].sh_offset; + if (xfsread(ino, p, es[i].sh_size)) + return; + p += es[i].sh_size; + } + } + addr = hdr.eh.e_entry & 0xffffff; + } + bootinfo.bi_esymtab = VTOP(p); + bootinfo.bi_kernelname = VTOP(kname); + bootinfo.bi_bios_dev = dsk.drive; + __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), + MAKEBOOTDEV(dev_maj[dsk.type], 0, dsk.unit, 0), + KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo)); +} + +static int +parse_cmds(char *cmdstr, int *dskupdated) +{ + char *arg; + char *ep, *p, *q; + const char *cp; + unsigned int drv; + int c, i, j; + + arg = cmdstr; + *dskupdated = 0; + while ((c = *arg++)) { + if (c == ' ' || c == '\t' || c == '\n') + continue; + for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; + if (*p) + *p++ = 0; + if (c == '-') { + while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= OPT_SET(RBX_DUAL) | + OPT_SET(RBX_SERIAL); + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') + <= 9) + 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); + opts ^= OPT_SET(flags[i]); + } + ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : + OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; + if (ioctrl & IO_SERIAL) { + if (sio_init(115200 / comspeed) != 0) + ioctrl &= ~IO_SERIAL; + } + } else { + for (q = arg--; *q && *q != '('; q++); + if (*q) { + drv = -1; + if (arg[1] == ':') { + drv = *arg - '0'; + if (drv > 9) + return (-1); + arg += 2; + } + if (q - arg != 2) + return (-1); + for (i = 0; arg[0] != dev_nm[i][0] || + arg[1] != dev_nm[i][1]; i++) + if (i == NDEV - 1) + return (-1); + dsk.type = i; + arg += 3; + dsk.unit = *arg - '0'; + if (arg[1] != 'p' || dsk.unit > 9) + return (-1); + arg += 2; + dsk.part = *arg - '0'; + if (dsk.part < 1 || dsk.part > 9) + return (-1); + arg++; + if (arg[0] != ')') + return (-1); + arg++; + if (drv == -1) + drv = dsk.unit; + dsk.drive = (dsk.type <= TYPE_MAXHARD + ? DRV_HARD : 0) + drv; + *dskupdated = 1; + } + if ((i = ep - arg)) { + if ((size_t)i >= sizeof(kname)) + return (-1); + memcpy(kname, arg, i + 1); + } + } + arg = p; + } + return (0); +} diff --git a/stand/i386/libfirewire/firewire.c b/stand/i386/libfirewire/firewire.c index e0b0bf9..f961f2b 100644 --- a/stand/i386/libfirewire/firewire.c +++ b/stand/i386/libfirewire/firewire.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <bootstrap.h> #include <btxv86.h> #include <libi386.h> +#include <dev/firewire/firewire.h> #include "fwohci.h" #include <dev/dcons/dcons.h> diff --git a/stand/i386/libfirewire/fwohci.c b/stand/i386/libfirewire/fwohci.c index 567abcf..85e6173 100644 --- a/stand/i386/libfirewire/fwohci.c +++ b/stand/i386/libfirewire/fwohci.c @@ -39,8 +39,9 @@ #include <btxv86.h> #include <bootstrap.h> +#include <dev/firewire/firewire.h> #include "fwohci.h" -#include "fwohcireg.h" +#include <dev/firewire/fwohcireg.h> #include <dev/firewire/firewire_phy.h> static uint32_t fwphy_wrdata ( struct fwohci_softc *, uint32_t, uint32_t); @@ -63,12 +64,6 @@ char *linkspeed[] = { "S1600", "S3200", "undef", "undef" }; -#define FW_EUI64_BYTE(eui, x) \ - ((((x)<4)? \ - ((eui)->hi >> (8*(3-(x)))): \ - ((eui)->lo >> (8*(7-(x)))) \ - ) & 0xff) - /* * Communication with PHY device */ diff --git a/stand/i386/libfirewire/fwohci.h b/stand/i386/libfirewire/fwohci.h index 4a93220..3c1d290 100644 --- a/stand/i386/libfirewire/fwohci.h +++ b/stand/i386/libfirewire/fwohci.h @@ -37,10 +37,6 @@ #define MAX_OHCI 5 #define CROMSIZE 0x400 -struct fw_eui64 { - uint32_t hi, lo; -}; - struct fwohci_softc { uint32_t locator; uint32_t devid; diff --git a/stand/i386/libfirewire/fwohcireg.h b/stand/i386/libfirewire/fwohcireg.h deleted file mode 100644 index d57870c..0000000 --- a/stand/i386/libfirewire/fwohcireg.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (c) 2003 Hidetoshi Shimokawa - * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa - * All rights reserved. - * - * 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. All advertising materials mentioning features or use of this software - * must display the acknowledgement as bellow: - * - * This product includes software developed by K. Kobayashi and H. Shimokawa - * - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD$ - * - */ -#define PCI_CBMEM PCIR_BAR(0) - -#define FW_VENDORID_NATSEMI 0x100B -#define FW_VENDORID_NEC 0x1033 -#define FW_VENDORID_SIS 0x1039 -#define FW_VENDORID_TI 0x104c -#define FW_VENDORID_SONY 0x104d -#define FW_VENDORID_VIA 0x1106 -#define FW_VENDORID_RICOH 0x1180 -#define FW_VENDORID_APPLE 0x106b -#define FW_VENDORID_LUCENT 0x11c1 -#define FW_VENDORID_INTEL 0x8086 -#define FW_VENDORID_ADAPTEC 0x9004 - -#define FW_DEVICE_CS4210 (0x000f << 16) -#define FW_DEVICE_UPD861 (0x0063 << 16) -#define FW_DEVICE_UPD871 (0x00ce << 16) -#define FW_DEVICE_UPD72870 (0x00cd << 16) -#define FW_DEVICE_UPD72873 (0x00e7 << 16) -#define FW_DEVICE_UPD72874 (0x00f2 << 16) -#define FW_DEVICE_TITSB22 (0x8009 << 16) -#define FW_DEVICE_TITSB23 (0x8019 << 16) -#define FW_DEVICE_TITSB26 (0x8020 << 16) -#define FW_DEVICE_TITSB43 (0x8021 << 16) -#define FW_DEVICE_TITSB43A (0x8023 << 16) -#define FW_DEVICE_TITSB43AB23 (0x8024 << 16) -#define FW_DEVICE_TITSB82AA2 (0x8025 << 16) -#define FW_DEVICE_TITSB43AB21 (0x8026 << 16) -#define FW_DEVICE_TIPCI4410A (0x8017 << 16) -#define FW_DEVICE_TIPCI4450 (0x8011 << 16) -#define FW_DEVICE_TIPCI4451 (0x8027 << 16) -#define FW_DEVICE_CXD1947 (0x8009 << 16) -#define FW_DEVICE_CXD3222 (0x8039 << 16) -#define FW_DEVICE_VT6306 (0x3044 << 16) -#define FW_DEVICE_R5C551 (0x0551 << 16) -#define FW_DEVICE_R5C552 (0x0552 << 16) -#define FW_DEVICE_PANGEA (0x0030 << 16) -#define FW_DEVICE_UNINORTH (0x0031 << 16) -#define FW_DEVICE_AIC5800 (0x5800 << 16) -#define FW_DEVICE_FW322 (0x5811 << 16) -#define FW_DEVICE_7007 (0x7007 << 16) -#define FW_DEVICE_82372FB (0x7605 << 16) - -#define PCI_INTERFACE_OHCI 0x10 - -#define FW_OHCI_BASE_REG 0x10 - -#define OHCI_DMA_ITCH 0x20 -#define OHCI_DMA_IRCH 0x20 - -#define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH) - - -typedef uint32_t fwohcireg_t; - -/* for PCI */ -#if BYTE_ORDER == BIG_ENDIAN -#define FWOHCI_DMA_WRITE(x, y) ((x) = htole32(y)) -#define FWOHCI_DMA_READ(x) le32toh(x) -#define FWOHCI_DMA_SET(x, y) ((x) |= htole32(y)) -#define FWOHCI_DMA_CLEAR(x, y) ((x) &= htole32(~(y))) -#else -#define FWOHCI_DMA_WRITE(x, y) ((x) = (y)) -#define FWOHCI_DMA_READ(x) (x) -#define FWOHCI_DMA_SET(x, y) ((x) |= (y)) -#define FWOHCI_DMA_CLEAR(x, y) ((x) &= ~(y)) -#endif - -struct fwohcidb { - union { - struct { - uint32_t cmd; - uint32_t addr; - uint32_t depend; - uint32_t res; - } desc; - uint32_t immed[4]; - } db; -#define OHCI_STATUS_SHIFT 16 -#define OHCI_COUNT_MASK 0xffff -#define OHCI_OUTPUT_MORE (0 << 28) -#define OHCI_OUTPUT_LAST (1 << 28) -#define OHCI_INPUT_MORE (2 << 28) -#define OHCI_INPUT_LAST (3 << 28) -#define OHCI_STORE_QUAD (4 << 28) -#define OHCI_LOAD_QUAD (5 << 28) -#define OHCI_NOP (6 << 28) -#define OHCI_STOP (7 << 28) -#define OHCI_STORE (8 << 28) -#define OHCI_CMD_MASK (0xf << 28) - -#define OHCI_UPDATE (1 << 27) - -#define OHCI_KEY_ST0 (0 << 24) -#define OHCI_KEY_ST1 (1 << 24) -#define OHCI_KEY_ST2 (2 << 24) -#define OHCI_KEY_ST3 (3 << 24) -#define OHCI_KEY_REGS (5 << 24) -#define OHCI_KEY_SYS (6 << 24) -#define OHCI_KEY_DEVICE (7 << 24) -#define OHCI_KEY_MASK (7 << 24) - -#define OHCI_INTERRUPT_NEVER (0 << 20) -#define OHCI_INTERRUPT_TRUE (1 << 20) -#define OHCI_INTERRUPT_FALSE (2 << 20) -#define OHCI_INTERRUPT_ALWAYS (3 << 20) - -#define OHCI_BRANCH_NEVER (0 << 18) -#define OHCI_BRANCH_TRUE (1 << 18) -#define OHCI_BRANCH_FALSE (2 << 18) -#define OHCI_BRANCH_ALWAYS (3 << 18) -#define OHCI_BRANCH_MASK (3 << 18) - -#define OHCI_WAIT_NEVER (0 << 16) -#define OHCI_WAIT_TRUE (1 << 16) -#define OHCI_WAIT_FALSE (2 << 16) -#define OHCI_WAIT_ALWAYS (3 << 16) -}; - -#define OHCI_SPD_S100 0x4 -#define OHCI_SPD_S200 0x1 -#define OHCI_SPD_S400 0x2 - - -#define FWOHCIEV_NOSTAT 0 -#define FWOHCIEV_LONGP 2 -#define FWOHCIEV_MISSACK 3 -#define FWOHCIEV_UNDRRUN 4 -#define FWOHCIEV_OVRRUN 5 -#define FWOHCIEV_DESCERR 6 -#define FWOHCIEV_DTRDERR 7 -#define FWOHCIEV_DTWRERR 8 -#define FWOHCIEV_BUSRST 9 -#define FWOHCIEV_TIMEOUT 0xa -#define FWOHCIEV_TCODERR 0xb -#define FWOHCIEV_UNKNOWN 0xe -#define FWOHCIEV_FLUSHED 0xf -#define FWOHCIEV_ACKCOMPL 0x11 -#define FWOHCIEV_ACKPEND 0x12 -#define FWOHCIEV_ACKBSX 0x14 -#define FWOHCIEV_ACKBSA 0x15 -#define FWOHCIEV_ACKBSB 0x16 -#define FWOHCIEV_ACKTARD 0x1b -#define FWOHCIEV_ACKDERR 0x1d -#define FWOHCIEV_ACKTERR 0x1e - -#define FWOHCIEV_MASK 0x1f - -struct ohci_dma{ - fwohcireg_t cntl; - -#define OHCI_CNTL_CYCMATCH_S (0x1 << 31) - -#define OHCI_CNTL_BUFFIL (0x1 << 31) -#define OHCI_CNTL_ISOHDR (0x1 << 30) -#define OHCI_CNTL_CYCMATCH_R (0x1 << 29) -#define OHCI_CNTL_MULTICH (0x1 << 28) - -#define OHCI_CNTL_DMA_RUN (0x1 << 15) -#define OHCI_CNTL_DMA_WAKE (0x1 << 12) -#define OHCI_CNTL_DMA_DEAD (0x1 << 11) -#define OHCI_CNTL_DMA_ACTIVE (0x1 << 10) -#define OHCI_CNTL_DMA_BT (0x1 << 8) -#define OHCI_CNTL_DMA_BAD (0x1 << 7) -#define OHCI_CNTL_DMA_STAT (0xff) - - fwohcireg_t cntl_clr; - fwohcireg_t dummy0; - fwohcireg_t cmd; - fwohcireg_t match; - fwohcireg_t dummy1; - fwohcireg_t dummy2; - fwohcireg_t dummy3; -}; - -struct ohci_itdma{ - fwohcireg_t cntl; - fwohcireg_t cntl_clr; - fwohcireg_t dummy0; - fwohcireg_t cmd; -}; - -struct ohci_registers { - fwohcireg_t ver; /* Version No. 0x0 */ - fwohcireg_t guid; /* GUID_ROM No. 0x4 */ - fwohcireg_t retry; /* AT retries 0x8 */ -#define FWOHCI_RETRY 0x8 - fwohcireg_t csr_data; /* CSR data 0xc */ - fwohcireg_t csr_cmp; /* CSR compare 0x10 */ - fwohcireg_t csr_cntl; /* CSR compare 0x14 */ - fwohcireg_t rom_hdr; /* config ROM ptr. 0x18 */ - fwohcireg_t bus_id; /* BUS_ID 0x1c */ - fwohcireg_t bus_opt; /* BUS option 0x20 */ -#define FWOHCIGUID_H 0x24 -#define FWOHCIGUID_L 0x28 - fwohcireg_t guid_hi; /* GUID hi 0x24 */ - fwohcireg_t guid_lo; /* GUID lo 0x28 */ - fwohcireg_t dummy0[2]; /* dummy 0x2c-0x30 */ - fwohcireg_t config_rom; /* config ROM map 0x34 */ - fwohcireg_t post_wr_lo; /* post write addr lo 0x38 */ - fwohcireg_t post_wr_hi; /* post write addr hi 0x3c */ - fwohcireg_t vendor; /* vendor ID 0x40 */ - fwohcireg_t dummy1[3]; /* dummy 0x44-0x4c */ - fwohcireg_t hcc_cntl_set; /* HCC control set 0x50 */ - fwohcireg_t hcc_cntl_clr; /* HCC control clr 0x54 */ -#define OHCI_HCC_BIBIV (1U << 31) /* BIBimage Valid */ -#define OHCI_HCC_BIGEND (1 << 30) /* noByteSwapData */ -#define OHCI_HCC_PRPHY (1 << 23) /* programPhyEnable */ -#define OHCI_HCC_PHYEN (1 << 22) /* aPhyEnhanceEnable */ -#define OHCI_HCC_LPS (1 << 19) /* LPS */ -#define OHCI_HCC_POSTWR (1 << 18) /* postedWriteEnable */ -#define OHCI_HCC_LINKEN (1 << 17) /* linkEnable */ -#define OHCI_HCC_RESET (1 << 16) /* softReset */ - fwohcireg_t dummy2[2]; /* dummy 0x58-0x5c */ - fwohcireg_t dummy3[1]; /* dummy 0x60 */ - fwohcireg_t sid_buf; /* self id buffer 0x64 */ - fwohcireg_t sid_cnt; /* self id count 0x68 */ - fwohcireg_t dummy4[1]; /* dummy 0x6c */ - fwohcireg_t ir_mask_hi_set; /* ir mask hi set 0x70 */ - fwohcireg_t ir_mask_hi_clr; /* ir mask hi set 0x74 */ - fwohcireg_t ir_mask_lo_set; /* ir mask hi set 0x78 */ - fwohcireg_t ir_mask_lo_clr; /* ir mask hi set 0x7c */ -#define FWOHCI_INTSTAT 0x80 -#define FWOHCI_INTSTATCLR 0x84 -#define FWOHCI_INTMASK 0x88 -#define FWOHCI_INTMASKCLR 0x8c - fwohcireg_t int_stat; /* 0x80 */ - fwohcireg_t int_clear; /* 0x84 */ - fwohcireg_t int_mask; /* 0x88 */ - fwohcireg_t int_mask_clear; /* 0x8c */ - fwohcireg_t it_int_stat; /* 0x90 */ - fwohcireg_t it_int_clear; /* 0x94 */ - fwohcireg_t it_int_mask; /* 0x98 */ - fwohcireg_t it_mask_clear; /* 0x9c */ - fwohcireg_t ir_int_stat; /* 0xa0 */ - fwohcireg_t ir_int_clear; /* 0xa4 */ - fwohcireg_t ir_int_mask; /* 0xa8 */ - fwohcireg_t ir_mask_clear; /* 0xac */ - fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */ - fwohcireg_t fairness; /* fairness control 0xdc */ - fwohcireg_t link_cntl; /* Chip control 0xe0*/ - fwohcireg_t link_cntl_clr; /* Chip control clear 0xe4*/ -#define FWOHCI_NODEID 0xe8 - fwohcireg_t node; /* Node ID 0xe8 */ -#define OHCI_NODE_VALID (1U << 31) -#define OHCI_NODE_ROOT (1 << 30) - -#define OHCI_ASYSRCBUS 1 - - fwohcireg_t phy_access; /* PHY cntl 0xec */ -#define PHYDEV_RDDONE (1<<31) -#define PHYDEV_RDCMD (1<<15) -#define PHYDEV_WRCMD (1<<14) -#define PHYDEV_REGADDR 8 -#define PHYDEV_WRDATA 0 -#define PHYDEV_RDADDR 24 -#define PHYDEV_RDDATA 16 - - fwohcireg_t cycle_timer; /* Cycle Timer 0xf0 */ - fwohcireg_t dummy6[3]; /* dummy 0xf4-fc */ - fwohcireg_t areq_hi; /* Async req. filter hi 0x100 */ - fwohcireg_t areq_hi_clr; /* Async req. filter hi 0x104 */ - fwohcireg_t areq_lo; /* Async req. filter lo 0x108 */ - fwohcireg_t areq_lo_clr; /* Async req. filter lo 0x10c */ - fwohcireg_t preq_hi; /* Async req. filter hi 0x110 */ - fwohcireg_t preq_hi_clr; /* Async req. filter hi 0x114 */ - fwohcireg_t preq_lo; /* Async req. filter lo 0x118 */ - fwohcireg_t preq_lo_clr; /* Async req. filter lo 0x11c */ - - fwohcireg_t pys_upper; /* Physical Upper bound 0x120 */ - - fwohcireg_t dummy7[23]; /* dummy 0x124-0x17c */ - - /* 0x180, 0x184, 0x188, 0x18c */ - /* 0x190, 0x194, 0x198, 0x19c */ - /* 0x1a0, 0x1a4, 0x1a8, 0x1ac */ - /* 0x1b0, 0x1b4, 0x1b8, 0x1bc */ - /* 0x1c0, 0x1c4, 0x1c8, 0x1cc */ - /* 0x1d0, 0x1d4, 0x1d8, 0x1dc */ - /* 0x1e0, 0x1e4, 0x1e8, 0x1ec */ - /* 0x1f0, 0x1f4, 0x1f8, 0x1fc */ - struct ohci_dma dma_ch[0x4]; - - /* 0x200, 0x204, 0x208, 0x20c */ - /* 0x210, 0x204, 0x208, 0x20c */ - struct ohci_itdma dma_itch[0x20]; - - /* 0x400, 0x404, 0x408, 0x40c */ - /* 0x410, 0x404, 0x408, 0x40c */ - struct ohci_dma dma_irch[0x20]; -}; - -#define OHCI_CNTL_CYCSRC (0x1 << 22) -#define OHCI_CNTL_CYCMTR (0x1 << 21) -#define OHCI_CNTL_CYCTIMER (0x1 << 20) -#define OHCI_CNTL_PHYPKT (0x1 << 10) -#define OHCI_CNTL_SID (0x1 << 9) - -#define OHCI_INT_DMA_ATRQ (0x1 << 0) -#define OHCI_INT_DMA_ATRS (0x1 << 1) -#define OHCI_INT_DMA_ARRQ (0x1 << 2) -#define OHCI_INT_DMA_ARRS (0x1 << 3) -#define OHCI_INT_DMA_PRRQ (0x1 << 4) -#define OHCI_INT_DMA_PRRS (0x1 << 5) -#define OHCI_INT_DMA_IT (0x1 << 6) -#define OHCI_INT_DMA_IR (0x1 << 7) -#define OHCI_INT_PW_ERR (0x1 << 8) -#define OHCI_INT_LR_ERR (0x1 << 9) - -#define OHCI_INT_PHY_SID (0x1 << 16) -#define OHCI_INT_PHY_BUS_R (0x1 << 17) - -#define OHCI_INT_REG_FAIL (0x1 << 18) - -#define OHCI_INT_PHY_INT (0x1 << 19) -#define OHCI_INT_CYC_START (0x1 << 20) -#define OHCI_INT_CYC_64SECOND (0x1 << 21) -#define OHCI_INT_CYC_LOST (0x1 << 22) -#define OHCI_INT_CYC_ERR (0x1 << 23) - -#define OHCI_INT_ERR (0x1 << 24) -#define OHCI_INT_CYC_LONG (0x1 << 25) -#define OHCI_INT_PHY_REG (0x1 << 26) - -#define OHCI_INT_EN (0x1 << 31) - -#define IP_CHANNELS 0x0234 -#define FWOHCI_MAXREC 2048 - -#define OHCI_ISORA 0x02 -#define OHCI_ISORB 0x04 - -#define FWOHCITCODE_PHY 0xe diff --git a/stand/i386/libi386/biosacpi.c b/stand/i386/libi386/biosacpi.c index 8167fca..236c3fc 100644 --- a/stand/i386/libi386/biosacpi.c +++ b/stand/i386/libi386/biosacpi.c @@ -122,7 +122,7 @@ static ACPI_TABLE_RSDP * biosacpi_search_rsdp(char *base, int length) { ACPI_TABLE_RSDP *rsdp; - u_int8_t *cp, sum; + uint8_t *cp, sum; int ofs, idx; /* search on 16-byte boundaries */ @@ -131,7 +131,7 @@ biosacpi_search_rsdp(char *base, int length) /* compare signature, validate checksum */ if (!strncmp(rsdp->Signature, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP))) { - cp = (u_int8_t *)rsdp; + cp = (uint8_t *)rsdp; sum = 0; for (idx = 0; idx < RSDP_CHECKSUM_LENGTH; idx++) sum += *(cp + idx); diff --git a/stand/i386/libi386/bioscd.c b/stand/i386/libi386/bioscd.c index 2e8fc3b..a451f16 100644 --- a/stand/i386/libi386/bioscd.c +++ b/stand/i386/libi386/bioscd.c @@ -90,7 +90,7 @@ static struct bcinfo { } bcinfo [MAXBCDEV]; static int nbcinfo = 0; -#define BC(dev) (bcinfo[(dev)->d_unit]) +#define BC(dev) (bcinfo[(dev)->dd.d_unit]) static int bc_read(int unit, daddr_t dblk, int blks, caddr_t dest); static int bc_init(void); @@ -211,7 +211,7 @@ bc_open(struct open_file *f, ...) va_start(ap, f); dev = va_arg(ap, struct i386_devdesc *); va_end(ap); - if (dev->d_unit >= nbcinfo) { + if (dev->dd.d_unit >= nbcinfo) { DEBUG("attempt to open nonexistent disk"); return(ENXIO); } @@ -271,7 +271,7 @@ bc_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, if ((rw & F_MASK) != F_READ) return(EROFS); dev = (struct i386_devdesc *)devdata; - unit = dev->d_unit; + unit = dev->dd.d_unit; blks = size / BIOSCD_SECSIZE; if (dblk % (BIOSCD_SECSIZE / DEV_BSIZE) != 0) return (EINVAL); @@ -427,7 +427,7 @@ bc_getdev(struct i386_devdesc *dev) int major; int rootdev; - unit = dev->d_unit; + unit = dev->dd.d_unit; biosdev = bc_unit2bios(unit); DEBUG("unit %d BIOS device %d", unit, biosdev); if (biosdev == -1) /* not a BIOS device */ diff --git a/stand/i386/libi386/biosdisk.c b/stand/i386/libi386/biosdisk.c index 2644514..eb1f688 100644 --- a/stand/i386/libi386/biosdisk.c +++ b/stand/i386/libi386/biosdisk.c @@ -120,7 +120,9 @@ static struct bdinfo } bdinfo [MAXBDDEV]; static int nbdinfo = 0; -#define BD(dev) (bdinfo[(dev)->d_unit]) +#define BD(dev) (bdinfo[(dev)->dd.d_unit]) + +static void bd_io_workaround(struct disk_devdesc *dev); static int bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest); @@ -349,8 +351,8 @@ bd_print(int verbose) bdinfo[i].bd_sectorsize); if ((ret = pager_output(line)) != 0) break; - dev.d_dev = &biosdisk; - dev.d_unit = i; + dev.dd.d_dev = &biosdisk; + dev.dd.d_unit = i; dev.d_slice = -1; dev.d_partition = -1; if (disk_open(&dev, @@ -389,7 +391,7 @@ bd_open(struct open_file *f, ...) dev = va_arg(ap, struct disk_devdesc *); va_end(ap); - if (dev->d_unit < 0 || dev->d_unit >= nbdinfo) + if (dev->dd.d_unit < 0 || dev->dd.d_unit >= nbdinfo) return (EIO); BD(dev).bd_open++; if (BD(dev).bd_bcache == NULL) @@ -402,10 +404,8 @@ bd_open(struct open_file *f, ...) * During bd_probe() we tested if the mulitplication of bd_sectors * would overflow so it should be safe to perform here. */ - disk.d_dev = dev->d_dev; - disk.d_type = dev->d_type; - disk.d_unit = dev->d_unit; - disk.d_opendata = NULL; + disk.dd.d_dev = dev->dd.d_dev; + disk.dd.d_unit = dev->dd.d_unit; disk.d_slice = -1; disk.d_partition = -1; disk.d_offset = 0; @@ -431,7 +431,7 @@ bd_open(struct open_file *f, ...) return (err); /* if we already know there is no GELI, skip the rest */ - if (geli_status[dev->d_unit][dev->d_slice] != ISGELI_UNKNOWN) + if (geli_status[dev->dd.d_unit][dev->d_slice] != ISGELI_UNKNOWN) return (err); struct dsk dskp; @@ -440,9 +440,9 @@ bd_open(struct open_file *f, ...) struct pentry *entry; int geli_part = 0; - dskp.drive = bd_unit2bios(dev->d_unit); - dskp.type = dev->d_type; - dskp.unit = dev->d_unit; + dskp.drive = bd_unit2bios(dev->dd.d_unit); + dskp.type = dev->dd.d_dev->dv_type; + dskp.unit = dev->dd.d_unit; dskp.slice = dev->d_slice; dskp.part = dev->d_partition; dskp.start = dev->d_offset; @@ -466,13 +466,13 @@ bd_open(struct open_file *f, ...) dskp.slice = entry->part.index; dskp.start = entry->part.start; if (is_geli(&dskp) == 0) { - geli_status[dev->d_unit][dskp.slice] = ISGELI_YES; + geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_YES; return (0); } if (geli_taste(bios_read, &dskp, entry->part.end - entry->part.start) == 0) { if (geli_havekey(&dskp) == 0) { - geli_status[dev->d_unit][dskp.slice] = ISGELI_YES; + geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_YES; geli_part++; continue; } @@ -486,18 +486,18 @@ bd_open(struct open_file *f, ...) &dskp) == 0) { setenv("kern.geom.eli.passphrase", gelipw, 1); bzero(gelipw, sizeof(gelipw)); - geli_status[dev->d_unit][dskp.slice] = ISGELI_YES; + geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_YES; geli_part++; continue; } } else - geli_status[dev->d_unit][dskp.slice] = ISGELI_NO; + geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_NO; } /* none of the partitions on this disk have GELI */ if (geli_part == 0) { /* found no GELI */ - geli_status[dev->d_unit][dev->d_slice] = ISGELI_NO; + geli_status[dev->dd.d_unit][dev->d_slice] = ISGELI_NO; } #endif /* LOADER_GELI_SUPPORT */ @@ -726,6 +726,15 @@ bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, return (0); } +static void +bd_io_workaround(struct disk_devdesc *dev) +{ + uint8_t buf[8 * 1024]; + + bd_edd_io(dev, 0xffffffff, 1, (caddr_t)buf, 0); +} + + static int bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int write) { @@ -739,6 +748,17 @@ bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int write) resid = blks; p = dest; + /* + * Workaround for a problem with some HP ProLiant BIOS failing to work out + * the boot disk after installation. hrs and kuriyama discovered this + * problem with an HP ProLiant DL320e Gen 8 with a 3TB HDD, and discovered + * that an int13h call seems to cause a buffer overrun in the bios. The + * problem is alleviated by doing an extra read before the buggy read. It + * is not immediately known whether other models are similarly affected. + */ + if (dblk >= 0x100000000) + bd_io_workaround(dev); + /* Decide whether we have to bounce */ if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 && (VTOP(dest) >> 16) != (VTOP(dest + @@ -834,10 +854,10 @@ bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) char *tmpbuf; /* if we already know there is no GELI, skip the rest */ - if (geli_status[dev->d_unit][dev->d_slice] != ISGELI_YES) + if (geli_status[dev->dd.d_unit][dev->d_slice] != ISGELI_YES) return (bd_io(dev, dblk, blks, dest, 0)); - if (geli_status[dev->d_unit][dev->d_slice] == ISGELI_YES) { + if (geli_status[dev->dd.d_unit][dev->d_slice] == ISGELI_YES) { /* * Align reads to DEV_GELIBOOT_BSIZE bytes because partial * sectors cannot be decrypted. Round the requested LBA down to @@ -871,9 +891,9 @@ bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) if (err) return (err); - dskp.drive = bd_unit2bios(dev->d_unit); - dskp.type = dev->d_type; - dskp.unit = dev->d_unit; + dskp.drive = bd_unit2bios(dev->dd.d_unit); + dskp.type = dev->dd.d_dev->dv_type; + dskp.unit = dev->dd.d_unit; dskp.slice = dev->d_slice; dskp.part = dev->d_partition; dskp.start = dev->d_offset; @@ -918,7 +938,7 @@ bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) * disk. And, incidentally, what is returned is not the geometry as * such but the highest valid cylinder, head, and sector numbers. */ -u_int32_t +uint32_t bd_getbigeom(int bunit) { @@ -950,8 +970,8 @@ bd_getdev(struct i386_devdesc *d) int i, unit; dev = (struct disk_devdesc *)d; - biosdev = bd_unit2bios(dev->d_unit); - DEBUG("unit %d BIOS device %d", dev->d_unit, biosdev); + biosdev = bd_unit2bios(dev->dd.d_unit); + DEBUG("unit %d BIOS device %d", dev->dd.d_unit, biosdev); if (biosdev == -1) /* not a BIOS device */ return(-1); if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize, @@ -962,7 +982,7 @@ bd_getdev(struct i386_devdesc *d) if (biosdev < 0x80) { /* floppy (or emulated floppy) or ATAPI device */ - if (bdinfo[dev->d_unit].bd_type == DT_ATAPI) { + if (bdinfo[dev->dd.d_unit].bd_type == DT_ATAPI) { /* is an ATAPI disk */ major = WFDMAJOR; } else { @@ -996,9 +1016,8 @@ bios_read(void *vdev __unused, void *xpriv, off_t off, void *buf, size_t bytes) struct disk_devdesc dev; struct dsk *priv = xpriv; - dev.d_dev = &biosdisk; - dev.d_type = priv->type; - dev.d_unit = priv->unit; + dev.dd.d_dev = &biosdisk; + dev.dd.d_unit = priv->unit; dev.d_slice = priv->slice; dev.d_partition = priv->part; dev.d_offset = priv->start; diff --git a/stand/i386/libi386/biospnp.c b/stand/i386/libi386/biospnp.c index 30e55fc..6cd381b 100644 --- a/stand/i386/libi386/biospnp.c +++ b/stand/i386/libi386/biospnp.c @@ -49,49 +49,49 @@ struct pnphandler biospnphandler = struct pnp_ICstructure { - u_int8_t pnp_signature[4]; - u_int8_t pnp_version; - u_int8_t pnp_length; - u_int16_t pnp_BIOScontrol; - u_int8_t pnp_checksum; - u_int32_t pnp_eventflag; - u_int16_t pnp_rmip; - u_int16_t pnp_rmcs; - u_int16_t pnp_pmip; - u_int32_t pnp_pmcs; - u_int8_t pnp_OEMdev[4]; - u_int16_t pnp_rmds; - u_int32_t pnp_pmds; + uint8_t pnp_signature[4]; + uint8_t pnp_version; + uint8_t pnp_length; + uint16_t pnp_BIOScontrol; + uint8_t pnp_checksum; + uint32_t pnp_eventflag; + uint16_t pnp_rmip; + uint16_t pnp_rmcs; + uint16_t pnp_pmip; + uint32_t pnp_pmcs; + uint8_t pnp_OEMdev[4]; + uint16_t pnp_rmds; + uint32_t pnp_pmds; } __packed; struct pnp_devNode { - u_int16_t dn_size; - u_int8_t dn_handle; - u_int8_t dn_id[4]; - u_int8_t dn_type[3]; - u_int16_t dn_attrib; - u_int8_t dn_data[1]; + uint16_t dn_size; + uint8_t dn_handle; + uint8_t dn_id[4]; + uint8_t dn_type[3]; + uint16_t dn_attrib; + uint8_t dn_data[1]; } __packed; struct pnp_isaConfiguration { - u_int8_t ic_revision; - u_int8_t ic_nCSN; - u_int16_t ic_rdport; - u_int16_t ic_reserved; + uint8_t ic_revision; + uint8_t ic_nCSN; + uint16_t ic_rdport; + uint16_t ic_reserved; } __packed; static struct pnp_ICstructure *pnp_Icheck = NULL; -static u_int16_t pnp_NumNodes; -static u_int16_t pnp_NodeSize; +static uint16_t pnp_NumNodes; +static uint16_t pnp_NodeSize; static void biospnp_scanresdata(struct pnpinfo *pi, struct pnp_devNode *dn); static int biospnp_call(int func, const char *fmt, ...); -#define vsegofs(vptr) (((u_int32_t)VTOPSEG(vptr) << 16) + VTOPOFF(vptr)) +#define vsegofs(vptr) (((uint32_t)VTOPSEG(vptr) << 16) + VTOPOFF(vptr)) -typedef void v86bios_t(u_int32_t, u_int32_t, u_int32_t, u_int32_t); +typedef void v86bios_t(uint32_t, uint32_t, uint32_t, uint32_t); v86bios_t *v86bios = (v86bios_t *)v86int; #define biospnp_f00(NumNodes, NodeSize) biospnp_call(0x00, "ll", NumNodes, NodeSize) @@ -155,7 +155,7 @@ biospnp_init(void) static void biospnp_enumerate(void) { - u_int8_t Node; + uint8_t Node; struct pnp_devNode *devNodeBuffer; int result; struct pnpinfo *pi; @@ -189,11 +189,11 @@ static void biospnp_scanresdata(struct pnpinfo *pi, struct pnp_devNode *dn) { u_int tag, i, rlen, dlen; - u_int8_t *p; + uint8_t *p; char *str; p = dn->dn_data; /* point to resource data */ - dlen = dn->dn_size - (p - (u_int8_t *)dn); /* length of resource data */ + dlen = dn->dn_size - (p - (uint8_t *)dn); /* length of resource data */ for (i = 0; i < dlen; i+= rlen) { tag = p[i]; @@ -213,8 +213,8 @@ biospnp_scanresdata(struct pnpinfo *pi, struct pnp_devNode *dn) } } else { /* large resource */ - rlen = *(u_int16_t *)(p + i); - i += sizeof(u_int16_t); + rlen = *(uint16_t *)(p + i); + i += sizeof(uint16_t); switch(PNP_LRES_NUM(tag)) { @@ -249,14 +249,14 @@ biospnp_call(int func, const char *fmt, ...) { va_list ap; const char *p; - u_int8_t *argp; - u_int32_t args[4]; - u_int32_t i; + uint8_t *argp; + uint32_t args[4]; + uint32_t i; /* function number first */ - argp = (u_int8_t *)args; - *(u_int16_t *)argp = func; - argp += sizeof(u_int16_t); + argp = (uint8_t *)args; + *(uint16_t *)argp = func; + argp += sizeof(uint16_t); /* take args according to format */ va_start(ap, fmt); @@ -265,26 +265,26 @@ biospnp_call(int func, const char *fmt, ...) case 'w': i = va_arg(ap, u_int); - *(u_int16_t *)argp = i; - argp += sizeof(u_int16_t); + *(uint16_t *)argp = i; + argp += sizeof(uint16_t); break; case 'l': - i = va_arg(ap, u_int32_t); - *(u_int32_t *)argp = i; - argp += sizeof(u_int32_t); + i = va_arg(ap, uint32_t); + *(uint32_t *)argp = i; + argp += sizeof(uint32_t); break; } } va_end(ap); /* BIOS segment last */ - *(u_int16_t *)argp = pnp_Icheck->pnp_rmds; - argp += sizeof(u_int16_t); + *(uint16_t *)argp = pnp_Icheck->pnp_rmds; + argp += sizeof(uint16_t); /* prepare for call */ v86.ctl = V86_ADDR | V86_CALLF; - v86.addr = ((u_int32_t)pnp_Icheck->pnp_rmcs << 16) + pnp_Icheck->pnp_rmip; + v86.addr = ((uint32_t)pnp_Icheck->pnp_rmcs << 16) + pnp_Icheck->pnp_rmip; /* call with packed stack and return */ v86bios(args[0], args[1], args[2], args[3]); diff --git a/stand/i386/libi386/bootinfo32.c b/stand/i386/libi386/bootinfo32.c index 494688f..c185144 100644 --- a/stand/i386/libi386/bootinfo32.c +++ b/stand/i386/libi386/bootinfo32.c @@ -63,7 +63,7 @@ static struct bootinfo bi; * MOD_METADATA (variable) type-specific metadata */ #define COPY32(v, a, c) { \ - u_int32_t x = (v); \ + uint32_t x = (v); \ if (c) \ i386_copyin(&x, a, sizeof(x)); \ a += sizeof(x); \ @@ -181,16 +181,16 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t /* XXX - use a default bootdev of 0. Is this ok??? */ bootdevnr = 0; - switch(rootdev->d_type) { + switch(rootdev->dd.d_dev->dv_type) { case DEVT_CD: /* Pass in BIOS device number. */ - bi.bi_bios_dev = bc_unit2bios(rootdev->d_unit); + bi.bi_bios_dev = bc_unit2bios(rootdev->dd.d_unit); bootdevnr = bc_getdev(rootdev); break; case DEVT_DISK: /* pass in the BIOS device number of the current disk */ - bi.bi_bios_dev = bd_unit2bios(rootdev->d_unit); + bi.bi_bios_dev = bd_unit2bios(rootdev->dd.d_unit); bootdevnr = bd_getdev(rootdev); break; @@ -199,7 +199,8 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t break; default: - printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type); + printf("WARNING - don't know how to boot from device type %d\n", + rootdev->dd.d_dev->dv_type); } if (bootdevnr == -1) { printf("root device %s invalid\n", i386_fmtdev(rootdev)); diff --git a/stand/i386/libi386/bootinfo64.c b/stand/i386/libi386/bootinfo64.c index 02fcf72..80bb835 100644 --- a/stand/i386/libi386/bootinfo64.c +++ b/stand/i386/libi386/bootinfo64.c @@ -64,7 +64,7 @@ static const size_t keybuf_size = sizeof(struct keybuf) + * MOD_METADATA (variable) type-specific metadata */ #define COPY32(v, a, c) { \ - u_int32_t x = (v); \ + uint32_t x = (v); \ if (c) \ i386_copyin(&x, a, sizeof(x)); \ a += sizeof(x); \ @@ -75,7 +75,7 @@ static const size_t keybuf_size = sizeof(struct keybuf) + COPY32(strlen(s) + 1, a, c); \ if (c) \ i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_int64_t));\ + a += roundup(strlen(s) + 1, sizeof(uint64_t));\ } #define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) @@ -87,7 +87,7 @@ static const size_t keybuf_size = sizeof(struct keybuf) + COPY32(sizeof(s), a, c); \ if (c) \ i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_int64_t)); \ + a += roundup(sizeof(s), sizeof(uint64_t)); \ } #define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) @@ -98,7 +98,7 @@ static const size_t keybuf_size = sizeof(struct keybuf) + COPY32(mm->md_size, a, c); \ if (c) \ i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_int64_t));\ + a += roundup(mm->md_size, sizeof(uint64_t));\ } #define MOD_END(a, c) { \ @@ -112,7 +112,7 @@ bi_copymodules64(vm_offset_t addr) struct preloaded_file *fp; struct file_metadata *md; int c; - u_int64_t v; + uint64_t v; c = addr != 0; /* start with the first module on the list, should be the kernel */ @@ -190,9 +190,9 @@ bi_load64(char *args, vm_offset_t addr, vm_offset_t *modulep, struct preloaded_file *xp, *kfp; struct i386_devdesc *rootdev; struct file_metadata *md; - u_int64_t kernend; - u_int64_t envp; - u_int64_t module; + uint64_t kernend; + uint64_t envp; + uint64_t module; vm_offset_t size; char *rootdevname; int howto; diff --git a/stand/i386/libi386/devicename.c b/stand/i386/libi386/devicename.c index c7705d7..9780d59 100644 --- a/stand/i386/libi386/devicename.c +++ b/stand/i386/libi386/devicename.c @@ -135,7 +135,7 @@ i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path) goto fail; } - idev->d_unit = unit; + idev->dd.d_unit = unit; if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; break; @@ -148,8 +148,7 @@ i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path) err = EINVAL; goto fail; } - idev->d_dev = dv; - idev->d_type = dv->dv_type; + idev->dd.d_dev = dv; if (dev == NULL) { free(idev); } else { @@ -169,14 +168,14 @@ i386_fmtdev(void *vdev) struct i386_devdesc *dev = (struct i386_devdesc *)vdev; static char buf[128]; /* XXX device length constant? */ - switch(dev->d_type) { + switch(dev->dd.d_dev->dv_type) { case DEVT_NONE: strcpy(buf, "(no device)"); break; case DEVT_CD: case DEVT_NET: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); break; case DEVT_DISK: diff --git a/stand/i386/libi386/elf64_freebsd.c b/stand/i386/libi386/elf64_freebsd.c index 338a745..47e83e8 100644 --- a/stand/i386/libi386/elf64_freebsd.c +++ b/stand/i386/libi386/elf64_freebsd.c @@ -51,15 +51,15 @@ struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; #define PG_U 0x004 #define PG_PS 0x080 -typedef u_int64_t p4_entry_t; -typedef u_int64_t p3_entry_t; -typedef u_int64_t p2_entry_t; +typedef uint64_t p4_entry_t; +typedef uint64_t p3_entry_t; +typedef uint64_t p2_entry_t; extern p4_entry_t PT4[]; extern p3_entry_t PT3[]; extern p2_entry_t PT2[]; -u_int32_t entry_hi; -u_int32_t entry_lo; +uint32_t entry_hi; +uint32_t entry_lo; extern void amd64_tramp(); diff --git a/stand/i386/libi386/libi386.h b/stand/i386/libi386/libi386.h index 297d493..da1ba4d 100644 --- a/stand/i386/libi386/libi386.h +++ b/stand/i386/libi386/libi386.h @@ -29,31 +29,21 @@ /* * i386 fully-qualified device descriptor. - * Note, this must match the 'struct devdesc' declaration - * in bootstrap.h and also with struct zfs_devdesc for zfs - * support. + * Note, this must match struct zfs_devdesc for zfs support. */ -struct i386_devdesc -{ - struct devsw *d_dev; - int d_type; - int d_unit; +/* Note: Must match the 'struct devdesc' in stand.h */ +struct i386_devdesc { + struct devdesc dd; union { struct { - void *data; int slice; int partition; off_t offset; } biosdisk; struct { - void *data; - } bioscd; - struct - { - void *data; uint64_t pool_guid; uint64_t root_guid; } zfs; diff --git a/stand/i386/libi386/multiboot.c b/stand/i386/libi386/multiboot.c index 252a1f5..a29696e 100644 --- a/stand/i386/libi386/multiboot.c +++ b/stand/i386/libi386/multiboot.c @@ -61,16 +61,16 @@ __FBSDID("$FreeBSD$"); #define METADATA_RESV_SIZE(mod_num) \ roundup(METADATA_FIXED_SIZE + METADATA_MODULE_SIZE * mod_num, PAGE_SIZE) -extern int elf32_loadfile_raw(char *filename, u_int64_t dest, +extern int elf32_loadfile_raw(char *filename, uint64_t dest, struct preloaded_file **result, int multiboot); -extern int elf64_load_modmetadata(struct preloaded_file *fp, u_int64_t dest); -extern int elf64_obj_loadfile(char *filename, u_int64_t dest, +extern int elf64_load_modmetadata(struct preloaded_file *fp, uint64_t dest); +extern int elf64_obj_loadfile(char *filename, uint64_t dest, struct preloaded_file **result); -static int multiboot_loadfile(char *, u_int64_t, struct preloaded_file **); +static int multiboot_loadfile(char *, uint64_t, struct preloaded_file **); static int multiboot_exec(struct preloaded_file *); -static int multiboot_obj_loadfile(char *, u_int64_t, struct preloaded_file **); +static int multiboot_obj_loadfile(char *, uint64_t, struct preloaded_file **); static int multiboot_obj_exec(struct preloaded_file *fp); struct file_format multiboot = { multiboot_loadfile, multiboot_exec }; @@ -108,7 +108,7 @@ max_addr(void) } static int -multiboot_loadfile(char *filename, u_int64_t dest, +multiboot_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { uint32_t *magic; @@ -394,7 +394,7 @@ error: } static int -multiboot_obj_loadfile(char *filename, u_int64_t dest, +multiboot_obj_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { struct preloaded_file *mfp, *kfp, *rfp; diff --git a/stand/i386/libi386/pxe.c b/stand/i386/libi386/pxe.c index 7cb4833..17c831c 100644 --- a/stand/i386/libi386/pxe.c +++ b/stand/i386/libi386/pxe.c @@ -85,11 +85,11 @@ static ssize_t pxe_netif_put(struct iodesc *desc, void *pkt, size_t len); static void pxe_netif_end(struct netif *nif); extern struct netif_stats pxe_st[]; -extern u_int16_t __bangpxeseg; -extern u_int16_t __bangpxeoff; +extern uint16_t __bangpxeseg; +extern uint16_t __bangpxeoff; extern void __bangpxeentry(void); -extern u_int16_t __pxenvseg; -extern u_int16_t __pxenvoff; +extern uint16_t __pxenvseg; +extern uint16_t __pxenvoff; extern void __pxenventry(void); struct netif_dif pxe_ifs[] = { diff --git a/stand/i386/libi386/vidconsole.c b/stand/i386/libi386/vidconsole.c index 073d531..abb03e3 100644 --- a/stand/i386/libi386/vidconsole.c +++ b/stand/i386/libi386/vidconsole.c @@ -449,6 +449,13 @@ vidc_term_emu(int c) fg_c = bg_c; bg_c = t; break; + case 22: /* normal intensity */ + fg_c &= ~0x8; + break; + case 24: /* not underline */ + case 25: /* not blinking */ + bg_c &= ~0x8; + break; case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: fg_c = ansi_col[args[i] - 30]; diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile index 92ac5b9..ac30415 100644 --- a/stand/i386/loader/Makefile +++ b/stand/i386/loader/Makefile @@ -5,9 +5,9 @@ HAVE_GELI= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= yes -LOADER_CD9660_SUPPORT?= no -LOADER_EXT2FS_SUPPORT?= no -LOADER_MSDOS_SUPPORT?= no +LOADER_CD9660_SUPPORT?= yes +LOADER_EXT2FS_SUPPORT?= yes +LOADER_MSDOS_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes LOADER_GZIP_SUPPORT?= yes LOADER_BZIP2_SUPPORT?= yes diff --git a/stand/i386/loader/chain.c b/stand/i386/loader/chain.c index d6810ef..5b61528 100644 --- a/stand/i386/loader/chain.c +++ b/stand/i386/loader/chain.c @@ -111,7 +111,7 @@ command_chain(int argc, char *argv[]) relocater_data[0].dest = 0x7C00; relocater_data[0].size = SECTOR_SIZE; - relocator_edx = bd_unit2bios(rootdev->d_unit); + relocator_edx = bd_unit2bios(rootdev->dd.d_unit); relocator_esi = relocater_size; relocator_ds = 0; relocator_es = 0; diff --git a/stand/i386/loader/conf.c b/stand/i386/loader/conf.c index 29ce1e3..821b239 100644 --- a/stand/i386/loader/conf.c +++ b/stand/i386/loader/conf.c @@ -69,10 +69,18 @@ struct fs_ops *file_system[] = { #if defined(LOADER_ZFS_SUPPORT) &zfs_fsops, #endif +#if defined(LOADER_UFS_SUPPORT) &ufs_fsops, +#endif +#if defined(LOADER_EXT2FS_SUPPORT) &ext2fs_fsops, +#endif +#if defined(LOADER_MSDOS_SUPPORT) &dosfs_fsops, +#endif +#if defined(LOADER_CD9660_SUPPORT) &cd9660_fsops, +#endif #if defined(LOADER_NANDFS_SUPPORT) &nandfs_fsops, #endif diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c index 543dae1..2fc1728 100644 --- a/stand/i386/loader/main.c +++ b/stand/i386/loader/main.c @@ -60,8 +60,8 @@ CTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE); /* Arguments passed in from the boot1/boot2 loader */ static struct bootargs *kargs; -static u_int32_t initial_howto; -static u_int32_t initial_bootdev; +static uint32_t initial_howto; +static uint32_t initial_bootdev; static struct bootinfo *initial_bootinfo; struct arch_switch archsw; /* MI/MD interface boundary */ @@ -254,18 +254,18 @@ extract_currdev(void) int biosdev = -1; /* Assume we are booting from a BIOS disk by default */ - new_currdev.d_dev = &biosdisk; + new_currdev.dd.d_dev = &biosdisk; /* new-style boot loaders such as pxeldr and cdldr */ if (kargs->bootinfo == 0) { if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) { /* we are booting from a CD with cdboot */ - new_currdev.d_dev = &bioscd; - new_currdev.d_unit = bc_bios2unit(initial_bootdev); + new_currdev.dd.d_dev = &bioscd; + new_currdev.dd.d_unit = bc_bios2unit(initial_bootdev); } else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) { /* we are booting from pxeldr */ - new_currdev.d_dev = &pxedisk; - new_currdev.d_unit = 0; + new_currdev.dd.d_dev = &pxedisk; + new_currdev.dd.d_unit = 0; } else { /* we don't know what our boot device is */ new_currdev.d_kind.biosdisk.slice = -1; @@ -295,7 +295,7 @@ extract_currdev(void) new_currdev.d_kind.zfs.pool_guid = kargs->zfspool; new_currdev.d_kind.zfs.root_guid = 0; } - new_currdev.d_dev = &zfs_dev; + new_currdev.dd.d_dev = &zfs_dev; #endif } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) { /* The passed-in boot device is bad */ @@ -316,21 +316,20 @@ extract_currdev(void) if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2)) /* biosdev doesn't match major */ biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */ } - new_currdev.d_type = new_currdev.d_dev->dv_type; /* * If we are booting off of a BIOS disk and we didn't succeed in determining * which one we booted off of, just use disk0: as a reasonable default. */ - if ((new_currdev.d_type == biosdisk.dv_type) && - ((new_currdev.d_unit = bd_bios2unit(biosdev)) == -1)) { + if ((new_currdev.dd.d_dev->dv_type == biosdisk.dv_type) && + ((new_currdev.dd.d_unit = bd_bios2unit(biosdev)) == -1)) { printf("Can't work out which disk we are booting from.\n" "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev); - new_currdev.d_unit = 0; + new_currdev.dd.d_unit = 0; } #ifdef LOADER_ZFS_SUPPORT - if (new_currdev.d_type == DEVT_ZFS) + if (new_currdev.dd.d_dev->dv_type == DEVT_ZFS) init_zfs_bootenv(zfs_fmtdev(&new_currdev)); #endif @@ -374,63 +373,6 @@ command_heap(int argc, char *argv[]) return(CMD_OK); } -#ifdef LOADER_ZFS_SUPPORT -COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset", - command_lszfs); - -static int -command_lszfs(int argc, char *argv[]) -{ - int err; - - if (argc != 2) { - command_errmsg = "wrong number of arguments"; - return (CMD_ERROR); - } - - err = zfs_list(argv[1]); - if (err != 0) { - command_errmsg = strerror(err); - return (CMD_ERROR); - } - - return (CMD_OK); -} - -COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments", - command_reloadbe); - -static int -command_reloadbe(int argc, char *argv[]) -{ - int err; - char *root; - - if (argc > 2) { - command_errmsg = "wrong number of arguments"; - return (CMD_ERROR); - } - - if (argc == 2) { - err = zfs_bootenv(argv[1]); - } else { - root = getenv("zfs_be_root"); - if (root == NULL) { - /* There does not appear to be a ZFS pool here, exit without error */ - return (CMD_OK); - } - err = zfs_bootenv(root); - } - - if (err != 0) { - command_errmsg = strerror(err); - return (CMD_ERROR); - } - - return (CMD_OK); -} -#endif - /* ISA bus access functions for PnP. */ static int isa_inb(int port) @@ -464,14 +406,4 @@ i386_zfs_probe(void) zfs_probe_dev(devname, NULL); } } - -uint64_t -ldi_get_size(void *priv) -{ - int fd = (uintptr_t) priv; - uint64_t size; - - ioctl(fd, DIOCGMEDIASIZE, &size); - return (size); -} #endif diff --git a/stand/i386/zfsboot/zfsboot.8 b/stand/i386/zfsboot/zfsboot.8 index 6450939..64a6ac6 100644 --- a/stand/i386/zfsboot/zfsboot.8 +++ b/stand/i386/zfsboot/zfsboot.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 15, 2014 +.Dd March 27, 2018 .Dt ZFSBOOT 8 .Os .Sh NAME @@ -99,9 +99,9 @@ can also be installed in an MBR slice: .Bd -literal -offset indent gpart create -s mbr ada0 gpart add -t freebsd ada0 -gpart create -s BSD ada0s1 gpart bootcode -b /boot/boot0 ada0 gpart set -a active -i 1 ada0 +dd if=/dev/zero of=/dev/ada0s1 count=2 dd if=/boot/zfsboot of=/dev/ada0s1 count=1 dd if=/boot/zfsboot of=/dev/ada0s1 iseek=1 oseek=1024 .Ed diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile index 988ac30..9daa7e7 100644 --- a/stand/libsa/Makefile +++ b/stand/libsa/Makefile @@ -147,5 +147,4 @@ CFLAGS.bzipfs.c+= -I${SRCTOP}/contrib/bzip2 .PATH: ${SYSDIR}/libkern SRCS+= explicit_bzero.c -.include <bsd.stand.mk> .include <bsd.lib.mk> diff --git a/stand/libsa/arp.c b/stand/libsa/arp.c index 61b5f1f..626ee34 100644 --- a/stand/libsa/arp.c +++ b/stand/libsa/arp.c @@ -65,7 +65,7 @@ int arp_num = 1; /* Local forwards */ static ssize_t arpsend(struct iodesc *, void *, size_t); -static ssize_t arprecv(struct iodesc *, void **, void **, time_t); +static ssize_t arprecv(struct iodesc *, void **, void **, time_t, void *); /* Broadcast an ARP packet, asking who has addr on interface d */ u_char * @@ -118,7 +118,7 @@ arpwhohas(struct iodesc *d, struct in_addr addr) ah = NULL; i = sendrecv(d, arpsend, &wbuf.data, sizeof(wbuf.data), - arprecv, &pkt, (void **)&ah); + arprecv, &pkt, (void **)&ah, NULL); if (i == -1) { panic("arp: no response for %s\n", inet_ntoa(addr)); @@ -160,11 +160,11 @@ arpsend(struct iodesc *d, void *pkt, size_t len) * else -1 (and errno == 0) */ static ssize_t -arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft) +arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) { ssize_t n; struct ether_arp *ah; - u_int16_t etype; /* host order */ + uint16_t etype; /* host order */ void *ptr; #ifdef ARP_DEBUG diff --git a/stand/libsa/bootp.c b/stand/libsa/bootp.c index a6d5052..fd4477e 100644 --- a/stand/libsa/bootp.c +++ b/stand/libsa/bootp.c @@ -73,7 +73,7 @@ static char vm_cmu[4] = VM_CMU; /* Local forwards */ static ssize_t bootpsend(struct iodesc *, void *, size_t); -static ssize_t bootprecv(struct iodesc *, void **, void **, time_t); +static ssize_t bootprecv(struct iodesc *, void **, void **, time_t, void *); static int vend_rfc1048(u_char *, u_int); #ifdef BOOTP_VEND_CMU static void vend_cmu(u_char *); @@ -183,14 +183,14 @@ bootp(int sock) if(sendrecv(d, bootpsend, bp, sizeof(*bp), - bootprecv, &pkt, (void **)&rbootp) == -1) { + bootprecv, &pkt, (void **)&rbootp, NULL) == -1) { printf("bootp: no reply\n"); return; } #ifdef SUPPORT_DHCP if(dhcp_ok) { - u_int32_t leasetime; + uint32_t leasetime; bp->bp_vend[6] = DHCPREQUEST; bp->bp_vend[7] = TAG_REQ_ADDR; bp->bp_vend[8] = 4; @@ -209,7 +209,7 @@ bootp(int sock) free(pkt); if(sendrecv(d, bootpsend, bp, sizeof(*bp), - bootprecv, &pkt, (void **)&rbootp) == -1) { + bootprecv, &pkt, (void **)&rbootp, NULL) == -1) { printf("DHCPREQUEST failed\n"); return; } @@ -286,7 +286,8 @@ bootpsend(struct iodesc *d, void *pkt, size_t len) } static ssize_t -bootprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft) +bootprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, + void *extra) { ssize_t n; struct bootp *bp; diff --git a/stand/libsa/bootparam.c b/stand/libsa/bootparam.c index 1de2d53..30e109e 100644 --- a/stand/libsa/bootparam.c +++ b/stand/libsa/bootparam.c @@ -77,7 +77,7 @@ n_short bp_server_port; /* net order */ * (Note, really four ints, NOT chars. Blech.) */ struct xdr_inaddr { - u_int32_t atype; + uint32_t atype; int32_t addr[4]; }; @@ -108,16 +108,16 @@ bp_whoami(int sockfd) { /* RPC structures for PMAPPROC_CALLIT */ struct args { - u_int32_t prog; - u_int32_t vers; - u_int32_t proc; - u_int32_t arglen; + uint32_t prog; + uint32_t vers; + uint32_t proc; + uint32_t arglen; struct xdr_inaddr xina; } *args; struct repl { - u_int16_t _pad; - u_int16_t port; - u_int32_t encap_len; + uint16_t _pad; + uint16_t port; + uint32_t encap_len; /* encapsulated data here */ n_long capsule[64]; } *repl; diff --git a/stand/libsa/cd9660.c b/stand/libsa/cd9660.c index a1711fb..059d59b 100644 --- a/stand/libsa/cd9660.c +++ b/stand/libsa/cd9660.c @@ -66,8 +66,6 @@ static int cd9660_open(const char *path, struct open_file *f); static int cd9660_close(struct open_file *f); static int cd9660_read(struct open_file *f, void *buf, size_t size, size_t *resid); -static int cd9660_write(struct open_file *f, void *buf, size_t size, - size_t *resid); static off_t cd9660_seek(struct open_file *f, off_t offset, int where); static int cd9660_stat(struct open_file *f, struct stat *sb); static int cd9660_readdir(struct open_file *f, struct dirent *d); @@ -86,7 +84,7 @@ struct fs_ops cd9660_fsops = { cd9660_open, cd9660_close, cd9660_read, - cd9660_write, + null_write, cd9660_seek, cd9660_stat, cd9660_readdir @@ -556,12 +554,6 @@ again: return (0); } -static int -cd9660_write(struct open_file *f __unused, void *start __unused, size_t size __unused, size_t *resid __unused) -{ - return EROFS; -} - static off_t cd9660_seek(struct open_file *f, off_t offset, int where) { diff --git a/stand/libsa/cd9660read.c b/stand/libsa/cd9660read.c new file mode 100644 index 0000000..03d2987 --- /dev/null +++ b/stand/libsa/cd9660read.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 1996 Wolfgang Solfrank. + * Copyright (C) 1996 TooLs GmbH. + * All rights reserved. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + */ + +/* Originally derived from libsa/cd9660.c: */ +/* $NetBSD: cd9660.c,v 1.5 1997/06/26 19:11:33 drochner Exp $ */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <fs/cd9660/iso.h> +#include <fs/cd9660/cd9660_rrip.h> + +static uint64_t cd9660_lookup(const char *); +static ssize_t cd9660_fsread(uint64_t, void *, size_t); + +#define SUSP_CONTINUATION "CE" +#define SUSP_PRESENT "SP" +#define SUSP_STOP "ST" +#define SUSP_EXTREF "ER" +#define RRIP_NAME "NM" + +typedef struct { + ISO_SUSP_HEADER h; + u_char signature [ISODCL ( 5, 6)]; + u_char len_skp [ISODCL ( 7, 7)]; /* 711 */ +} ISO_SUSP_PRESENT; + +static int +read_iso_block(void *buffer, daddr_t blkno) +{ + + return (drvread(&dsk, buffer, blkno * 4, 4)); +} + +static ISO_SUSP_HEADER * +susp_lookup_record(const char *identifier, struct iso_directory_record *dp, + int lenskip) +{ + static char susp_buffer[ISO_DEFAULT_BLOCK_SIZE]; + ISO_SUSP_HEADER *sh; + ISO_RRIP_CONT *shc; + char *p, *end; + int error; + + p = dp->name + isonum_711(dp->name_len) + lenskip; + /* Names of even length have a padding byte after the name. */ + if ((isonum_711(dp->name_len) & 1) == 0) + p++; + end = (char *)dp + isonum_711(dp->length); + while (p + 3 < end) { + sh = (ISO_SUSP_HEADER *)p; + if (bcmp(sh->type, identifier, 2) == 0) + return (sh); + if (bcmp(sh->type, SUSP_STOP, 2) == 0) + return (NULL); + if (bcmp(sh->type, SUSP_CONTINUATION, 2) == 0) { + shc = (ISO_RRIP_CONT *)sh; + error = read_iso_block(susp_buffer, + isonum_733(shc->location)); + + /* Bail if it fails. */ + if (error != 0) + return (NULL); + p = susp_buffer + isonum_733(shc->offset); + end = p + isonum_733(shc->length); + } else { + /* Ignore this record and skip to the next. */ + p += isonum_711(sh->length); + + /* Avoid infinite loops with corrupted file systems */ + if (isonum_711(sh->length) == 0) + return (NULL); + } + } + return (NULL); +} + +static const char * +rrip_lookup_name(struct iso_directory_record *dp, int lenskip, size_t *len) +{ + ISO_RRIP_ALTNAME *p; + + if (len == NULL) + return (NULL); + + p = (ISO_RRIP_ALTNAME *)susp_lookup_record(RRIP_NAME, dp, lenskip); + if (p == NULL) + return (NULL); + switch (*p->flags) { + case ISO_SUSP_CFLAG_CURRENT: + *len = 1; + return ("."); + case ISO_SUSP_CFLAG_PARENT: + *len = 2; + return (".."); + case 0: + *len = isonum_711(p->h.length) - 5; + return ((char *)p + 5); + default: + /* + * We don't handle hostnames or continued names as they are + * too hard, so just bail and use the default name. + */ + return (NULL); + } +} + +static int +rrip_check(struct iso_directory_record *dp, int *lenskip) +{ + ISO_SUSP_PRESENT *sp; + ISO_RRIP_EXTREF *er; + char *p; + + /* First, see if we can find a SP field. */ + p = dp->name + isonum_711(dp->name_len); + if (p > (char *)dp + isonum_711(dp->length)) { + return (0); + } + sp = (ISO_SUSP_PRESENT *)p; + if (bcmp(sp->h.type, SUSP_PRESENT, 2) != 0) { + return (0); + } + if (isonum_711(sp->h.length) != sizeof(ISO_SUSP_PRESENT)) { + return (0); + } + if (sp->signature[0] != 0xbe || sp->signature[1] != 0xef) { + return (0); + } + *lenskip = isonum_711(sp->len_skp); + + /* + * Now look for an ER field. If RRIP is present, then there must + * be at least one of these. It would be more pedantic to walk + * through the list of fields looking for a Rock Ridge ER field. + */ + er = (ISO_RRIP_EXTREF *)susp_lookup_record(SUSP_EXTREF, dp, 0); + if (er == NULL) { + return (0); + } + return (1); +} + +static int +dirmatch(const char *path, struct iso_directory_record *dp, int use_rrip, + int lenskip) +{ + size_t len; + const char *cp = NULL, *name = NULL; + int i, icase; + + if (use_rrip) + cp = rrip_lookup_name(dp, lenskip, &len); + else + cp = NULL; + if (cp == NULL) { + len = isonum_711(dp->name_len); + cp = dp->name; + icase = 1; + } else + icase = 0; + name = cp; + for (i = len; --i >= 0; path++, cp++) { + if (!*path || *path == '/') + break; + if (*path == *cp) + continue; + if (!icase && toupper(*path) == *cp) + continue; + return 0; + } + if (*path && *path != '/') { + return 0; + } + /* + * Allow stripping of trailing dots and the version number. + * Note that this will find the first instead of the last version + * of a file. + */ + if (i >= 0 && (*cp == ';' || *cp == '.')) { + /* This is to prevent matching of numeric extensions */ + if (*cp == '.' && cp[1] != ';') { + return 0; + } + while (--i >= 0) + if (*++cp != ';' && (*cp < '0' || *cp > '9')) { + return 0; + } + } + return 1; +} + +static uint64_t +cd9660_lookup(const char *path) +{ + static char blkbuf[ISO_DEFAULT_BLOCK_SIZE]; + struct iso_primary_descriptor *vd; + struct iso_directory_record rec; + struct iso_directory_record *dp = NULL; + size_t dsize, off; + daddr_t bno, boff; + int rc, first, use_rrip, lenskip; + uint64_t cookie; + + for (bno = 16;; bno++) { + rc = read_iso_block(blkbuf, bno); + vd = (struct iso_primary_descriptor *)blkbuf; + + if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0) + return (0); + if (isonum_711(vd->type) == ISO_VD_END) + return (0); + if (isonum_711(vd->type) == ISO_VD_PRIMARY) + break; + } + + rec = *(struct iso_directory_record *) vd->root_directory_record; + if (*path == '/') path++; /* eat leading '/' */ + + first = 1; + use_rrip = 0; + while (*path) { + bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length); + dsize = isonum_733(rec.size); + off = 0; + boff = 0; + + while (off < dsize) { + if ((off % ISO_DEFAULT_BLOCK_SIZE) == 0) { + rc = read_iso_block(blkbuf, bno + boff); + if (rc) { + return (0); + } + boff++; + dp = (struct iso_directory_record *) blkbuf; + } + if (isonum_711(dp->length) == 0) { + /* skip to next block, if any */ + off = boff * ISO_DEFAULT_BLOCK_SIZE; + continue; + } + + /* See if RRIP is in use. */ + if (first) + use_rrip = rrip_check(dp, &lenskip); + + if (dirmatch(path, dp, use_rrip, + first ? 0 : lenskip)) { + first = 0; + break; + } else + first = 0; + + dp = (struct iso_directory_record *) + ((char *) dp + isonum_711(dp->length)); + /* If the new block has zero length, it is padding. */ + if (isonum_711(dp->length) == 0) { + /* Skip to next block, if any. */ + off = boff * ISO_DEFAULT_BLOCK_SIZE; + continue; + } + off += isonum_711(dp->length); + } + if (off >= dsize) { + return (0); + } + + rec = *dp; + while (*path && *path != '/') /* look for next component */ + path++; + if (*path) path++; /* skip '/' */ + } + + if ((isonum_711(rec.flags) & 2) != 0) { + return (0); + } + + cookie = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length); + cookie = (cookie << 32) | isonum_733(rec.size); + + return (cookie); +} + +static ssize_t +cd9660_fsread(uint64_t cookie, void *buf, size_t nbytes) +{ + static char blkbuf[ISO_DEFAULT_BLOCK_SIZE]; + static daddr_t curstart = 0, curblk = 0; + daddr_t blk, blk_off; + off_t byte_off; + size_t size, remaining, n; + char *s; + + size = cookie & 0xffffffff; + blk = (cookie >> 32) & 0xffffffff; + + /* Make sure we're looking at the right file. */ + if (((blk << 32) | size) != cookie) { + return (-1); + } + + if (blk != curstart) { + curstart = blk; + fs_off = 0; + } + + size -= fs_off; + if (size < nbytes) { + nbytes = size; + } + remaining = nbytes; + s = buf; + + while (remaining > 0) { + blk_off = fs_off >> ISO_DEFAULT_BLOCK_SHIFT; + byte_off = fs_off & (ISO_DEFAULT_BLOCK_SIZE - 1); + + if (curblk != curstart + blk_off) { + curblk = curstart + blk_off; + read_iso_block(blkbuf, curblk); + } + + if (remaining < ISO_DEFAULT_BLOCK_SIZE - byte_off) { + n = remaining; + } else { + n = ISO_DEFAULT_BLOCK_SIZE - byte_off; + } + memcpy(s, blkbuf + byte_off, n); + remaining -= n; + s += n; + + fs_off += n; + } + + return (nbytes); +} diff --git a/stand/libsa/dosfs.h b/stand/libsa/dosfs.h index 5b11e0f..30bb435 100644 --- a/stand/libsa/dosfs.h +++ b/stand/libsa/dosfs.h @@ -47,12 +47,12 @@ * Macros to convert DOS-format 16-bit and 32-bit quantities */ -#define cv2(p) ((u_int16_t)(p)[0] | \ - ((u_int16_t)(p)[1] << 010)) -#define cv4(p) ((u_int32_t)(p)[0] | \ - ((u_int32_t)(p)[1] << 010) | \ - ((u_int32_t)(p)[2] << 020) | \ - ((u_int32_t)(p)[3] << 030)) +#define cv2(p) ((uint16_t)(p)[0] | \ + ((uint16_t)(p)[1] << 010)) +#define cv4(p) ((uint32_t)(p)[0] | \ + ((uint32_t)(p)[1] << 010) | \ + ((uint32_t)(p)[2] << 020) | \ + ((uint32_t)(p)[3] << 030)) /* * Directory, filesystem, and file structures. diff --git a/stand/libsa/ext2fs.c b/stand/libsa/ext2fs.c index d0b91e0..21865dd 100644 --- a/stand/libsa/ext2fs.c +++ b/stand/libsa/ext2fs.c @@ -152,7 +152,7 @@ struct fs_ops ext2fs_fsops = { #define ino_to_bo(fs, ino) (ino_to_bgo(fs, ino) % (fs)->fs_ipb) #define nindir(fs) \ - ((fs)->fs_bsize / sizeof(u_int32_t)) + ((fs)->fs_bsize / sizeof(uint32_t)) #define lblkno(fs, loc) /* loc / bsize */ \ ((loc) >> (fs)->fs_bshift) #define smalllblktosize(fs, blk) /* blk * bsize */ \ @@ -170,45 +170,45 @@ struct fs_ops ext2fs_fsops = { * superblock describing ext2fs */ struct ext2fs_disk { - u_int32_t fd_inodes; /* # of inodes */ - u_int32_t fd_blocks; /* # of blocks */ - u_int32_t fd_resblk; /* # of reserved blocks */ - u_int32_t fd_freeblk; /* # of free blocks */ - u_int32_t fd_freeino; /* # of free inodes */ - u_int32_t fd_firstblk; /* first data block */ - u_int32_t fd_bsize; /* block size */ - u_int32_t fd_fsize; /* frag size */ - u_int32_t fd_bpg; /* blocks per group */ - u_int32_t fd_fpg; /* frags per group */ - u_int32_t fd_ipg; /* inodes per group */ - u_int32_t fd_mtime; /* mount time */ - u_int32_t fd_wtime; /* write time */ - u_int16_t fd_mount; /* # of mounts */ + uint32_t fd_inodes; /* # of inodes */ + uint32_t fd_blocks; /* # of blocks */ + uint32_t fd_resblk; /* # of reserved blocks */ + uint32_t fd_freeblk; /* # of free blocks */ + uint32_t fd_freeino; /* # of free inodes */ + uint32_t fd_firstblk; /* first data block */ + uint32_t fd_bsize; /* block size */ + uint32_t fd_fsize; /* frag size */ + uint32_t fd_bpg; /* blocks per group */ + uint32_t fd_fpg; /* frags per group */ + uint32_t fd_ipg; /* inodes per group */ + uint32_t fd_mtime; /* mount time */ + uint32_t fd_wtime; /* write time */ + uint16_t fd_mount; /* # of mounts */ int16_t fd_maxmount; /* max # of mounts */ - u_int16_t fd_magic; /* magic number */ - u_int16_t fd_state; /* state */ - u_int16_t fd_eflag; /* error flags */ - u_int16_t fd_mnrrev; /* minor revision */ - u_int32_t fd_lastchk; /* last check */ - u_int32_t fd_chkintvl; /* maximum check interval */ - u_int32_t fd_os; /* os */ - u_int32_t fd_revision; /* revision */ - u_int16_t fd_uid; /* uid for reserved blocks */ - u_int16_t fd_gid; /* gid for reserved blocks */ - - u_int32_t fd_firstino; /* first non-reserved inode */ - u_int16_t fd_isize; /* inode size */ - u_int16_t fd_nblkgrp; /* block group # of superblock */ - u_int32_t fd_fcompat; /* compatible features */ - u_int32_t fd_fincompat; /* incompatible features */ - u_int32_t fd_frocompat; /* read-only compatibilties */ - u_int8_t fd_uuid[16]; /* volume uuid */ + uint16_t fd_magic; /* magic number */ + uint16_t fd_state; /* state */ + uint16_t fd_eflag; /* error flags */ + uint16_t fd_mnrrev; /* minor revision */ + uint32_t fd_lastchk; /* last check */ + uint32_t fd_chkintvl; /* maximum check interval */ + uint32_t fd_os; /* os */ + uint32_t fd_revision; /* revision */ + uint16_t fd_uid; /* uid for reserved blocks */ + uint16_t fd_gid; /* gid for reserved blocks */ + + uint32_t fd_firstino; /* first non-reserved inode */ + uint16_t fd_isize; /* inode size */ + uint16_t fd_nblkgrp; /* block group # of superblock */ + uint32_t fd_fcompat; /* compatible features */ + uint32_t fd_fincompat; /* incompatible features */ + uint32_t fd_frocompat; /* read-only compatibilties */ + uint8_t fd_uuid[16]; /* volume uuid */ char fd_volname[16]; /* volume name */ char fd_fsmnt[64]; /* name last mounted on */ - u_int32_t fd_bitmap; /* compression bitmap */ + uint32_t fd_bitmap; /* compression bitmap */ - u_int8_t fd_nblkpa; /* # of blocks to preallocate */ - u_int8_t fd_ndblkpa; /* # of dir blocks to preallocate */ + uint8_t fd_nblkpa; /* # of blocks to preallocate */ + uint8_t fd_ndblkpa; /* # of dir blocks to preallocate */ }; struct ext2fs_core { @@ -251,39 +251,39 @@ struct ext2fs { }; struct ext2blkgrp { - u_int32_t bg_blkmap; /* block bitmap */ - u_int32_t bg_inomap; /* inode bitmap */ - u_int32_t bg_inotbl; /* inode table */ - u_int16_t bg_nfblk; /* # of free blocks */ - u_int16_t bg_nfino; /* # of free inodes */ - u_int16_t bg_ndirs; /* # of dirs */ + uint32_t bg_blkmap; /* block bitmap */ + uint32_t bg_inomap; /* inode bitmap */ + uint32_t bg_inotbl; /* inode table */ + uint16_t bg_nfblk; /* # of free blocks */ + uint16_t bg_nfino; /* # of free inodes */ + uint16_t bg_ndirs; /* # of dirs */ char bg_pad[14]; }; struct ext2dinode { - u_int16_t di_mode; /* mode */ - u_int16_t di_uid; /* uid */ - u_int32_t di_size; /* byte size */ - u_int32_t di_atime; /* access time */ - u_int32_t di_ctime; /* creation time */ - u_int32_t di_mtime; /* modification time */ - u_int32_t di_dtime; /* deletion time */ - u_int16_t di_gid; /* gid */ - u_int16_t di_nlink; /* link count */ - u_int32_t di_nblk; /* block count */ - u_int32_t di_flags; /* file flags */ - - u_int32_t di_osdep1; /* os dependent stuff */ - - u_int32_t di_db[NDADDR]; /* direct blocks */ - u_int32_t di_ib[NIADDR]; /* indirect blocks */ - u_int32_t di_version; /* version */ - u_int32_t di_facl; /* file acl */ - u_int32_t di_dacl; /* dir acl */ - u_int32_t di_faddr; /* fragment addr */ - - u_int8_t di_frag; /* fragment number */ - u_int8_t di_fsize; /* fragment size */ + uint16_t di_mode; /* mode */ + uint16_t di_uid; /* uid */ + uint32_t di_size; /* byte size */ + uint32_t di_atime; /* access time */ + uint32_t di_ctime; /* creation time */ + uint32_t di_mtime; /* modification time */ + uint32_t di_dtime; /* deletion time */ + uint16_t di_gid; /* gid */ + uint16_t di_nlink; /* link count */ + uint32_t di_nblk; /* block count */ + uint32_t di_flags; /* file flags */ + + uint32_t di_osdep1; /* os dependent stuff */ + + uint32_t di_db[NDADDR]; /* direct blocks */ + uint32_t di_ib[NIADDR]; /* indirect blocks */ + uint32_t di_version; /* version */ + uint32_t di_facl; /* file acl */ + uint32_t di_dacl; /* dir acl */ + uint32_t di_faddr; /* fragment addr */ + + uint8_t di_frag; /* fragment number */ + uint8_t di_fsize; /* fragment size */ char di_pad[10]; @@ -293,10 +293,10 @@ struct ext2dinode { #define EXT2_MAXNAMLEN 255 struct ext2dirent { - u_int32_t d_ino; /* inode */ - u_int16_t d_reclen; /* directory entry length */ - u_int8_t d_namlen; /* name length */ - u_int8_t d_type; /* file type */ + uint32_t d_ino; /* inode */ + uint16_t d_reclen; /* directory entry length */ + uint8_t d_namlen; /* name length */ + uint8_t d_type; /* file type */ char d_name[EXT2_MAXNAMLEN]; }; diff --git a/stand/libsa/net.c b/stand/libsa/net.c index 900eece..8d170cf 100644 --- a/stand/libsa/net.c +++ b/stand/libsa/net.c @@ -58,6 +58,20 @@ __FBSDID("$FreeBSD$"); #include "net.h" /* + * Maximum wait time for sending and receiving before we give up and timeout. + * If set to 0, operations will eventually timeout completely, but send/recv + * timeouts must progress exponentially from MINTMO to MAXTMO before final + * timeout is hit. + */ +#ifndef MAXWAIT +#define MAXWAIT 0 /* seconds */ +#endif + +#if MAXWAIT < 0 +#error MAXWAIT must not be a negative number +#endif + +/* * Send a packet and wait for a reply, with exponential backoff. * * The send routine must return the actual number of bytes written, @@ -72,11 +86,12 @@ ssize_t sendrecv(struct iodesc *d, ssize_t (*sproc)(struct iodesc *, void *, size_t), void *sbuf, size_t ssize, - ssize_t (*rproc)(struct iodesc *, void **, void **, time_t), - void **pkt, void **payload) + ssize_t (*rproc)(struct iodesc *, void **, void **, time_t, void *), + void **pkt, void **payload, void *recv_extra) { ssize_t cc; time_t t, tmo, tlast; + time_t tref; long tleft; #ifdef NET_DEBUG @@ -87,8 +102,13 @@ sendrecv(struct iodesc *d, tmo = MINTMO; tlast = 0; tleft = 0; + tref = getsecs(); t = getsecs(); for (;;) { + if (MAXWAIT > 0 && (getsecs() - tref) >= MAXWAIT) { + errno = ETIMEDOUT; + return -1; + } if (tleft <= 0) { if (tmo >= MAXTMO) { errno = ETIMEDOUT; @@ -116,7 +136,7 @@ sendrecv(struct iodesc *d, } /* Try to get a packet and process it. */ - cc = (*rproc)(d, pkt, payload, tleft); + cc = (*rproc)(d, pkt, payload, tleft, recv_extra); /* Return on data, EOF or real error. */ if (cc != -1 || (errno != 0 && errno != ETIMEDOUT)) return (cc); diff --git a/stand/libsa/net.h b/stand/libsa/net.h index ac5414f..1870db1 100644 --- a/stand/libsa/net.h +++ b/stand/libsa/net.h @@ -40,7 +40,7 @@ #define _STAND_NET_H #ifndef _KERNEL /* XXX - see <netinet/in.h> */ #undef __IPADDR -#define __IPADDR(x) htonl((u_int32_t)(x)) +#define __IPADDR(x) htonl((uint32_t)(x)) #endif #include "iodesc.h" @@ -115,8 +115,9 @@ ssize_t readudp(struct iodesc *, void **, void **, time_t); ssize_t sendrecv(struct iodesc *, ssize_t (*)(struct iodesc *, void *, size_t), void *, size_t, - ssize_t (*)(struct iodesc *, void **, void **, time_t), - void **, void **); + ssize_t (*)(struct iodesc *, void **, void **, time_t, + void *), + void **, void **, void *); /* bootp/DHCP */ void bootp(int); diff --git a/stand/libsa/nfs.c b/stand/libsa/nfs.c index 7e2e1ab..5e160b5 100644 --- a/stand/libsa/nfs.c +++ b/stand/libsa/nfs.c @@ -126,7 +126,6 @@ struct nfs_iodesc { int nfs_open(const char *path, struct open_file *f); static int nfs_close(struct open_file *f); static int nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); -static int nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t nfs_seek(struct open_file *f, off_t offset, int where); static int nfs_stat(struct open_file *f, struct stat *sb); static int nfs_readdir(struct open_file *f, struct dirent *d); @@ -138,7 +137,7 @@ struct fs_ops nfs_fsops = { nfs_open, nfs_close, nfs_read, - nfs_write, + null_write, nfs_seek, nfs_stat, nfs_readdir @@ -715,15 +714,6 @@ ret: return (0); } -/* - * Not implemented. - */ -int -nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid) -{ - return (EROFS); -} - off_t nfs_seek(struct open_file *f, off_t offset, int where) { diff --git a/stand/libsa/nullfs.c b/stand/libsa/nullfs.c index e4c0b7c..1f425a1 100644 --- a/stand/libsa/nullfs.c +++ b/stand/libsa/nullfs.c @@ -83,9 +83,9 @@ int null_read (struct open_file *f, void *buf, size_t size, size_t *resid) return EIO; } -int null_write (struct open_file *f, void *buf, size_t size, size_t *resid) +int null_write (struct open_file *f, const void *buf, size_t size, size_t *resid) { - return EIO; + return EROFS; } off_t null_seek (struct open_file *f, off_t offset, int where) diff --git a/stand/libsa/rarp.c b/stand/libsa/rarp.c index 3b8088e..00f5023 100644 --- a/stand/libsa/rarp.c +++ b/stand/libsa/rarp.c @@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$"); static ssize_t rarpsend(struct iodesc *, void *, size_t); -static ssize_t rarprecv(struct iodesc *, void **, void **, time_t); +static ssize_t rarprecv(struct iodesc *, void **, void **, time_t, void *); /* * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826). @@ -99,7 +99,7 @@ rarp_getipaddress(int sock) if (sendrecv(d, rarpsend, &wbuf.data, sizeof(wbuf.data), - rarprecv, &pkt, (void *)&ap) < 0) { + rarprecv, &pkt, (void *)&ap, NULL) < 0) { printf("No response for RARP request\n"); return (-1); } @@ -143,7 +143,8 @@ rarpsend(struct iodesc *d, void *pkt, size_t len) * else -1 (and errno == 0) */ static ssize_t -rarprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft) +rarprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, + void *extra) { ssize_t n; struct ether_arp *ap; diff --git a/stand/libsa/rpc.c b/stand/libsa/rpc.c index 94e6ce6..5d5e598 100644 --- a/stand/libsa/rpc.c +++ b/stand/libsa/rpc.c @@ -63,7 +63,7 @@ __FBSDID("$FreeBSD$"); struct auth_info { int32_t authtype; /* auth type */ - u_int32_t authlen; /* auth length */ + uint32_t authlen; /* auth length */ }; struct auth_unix { @@ -75,29 +75,29 @@ struct auth_unix { }; struct rpc_call { - u_int32_t rp_xid; /* request transaction id */ + uint32_t rp_xid; /* request transaction id */ int32_t rp_direction; /* call direction (0) */ - u_int32_t rp_rpcvers; /* rpc version (2) */ - u_int32_t rp_prog; /* program */ - u_int32_t rp_vers; /* version */ - u_int32_t rp_proc; /* procedure */ + uint32_t rp_rpcvers; /* rpc version (2) */ + uint32_t rp_prog; /* program */ + uint32_t rp_vers; /* version */ + uint32_t rp_proc; /* procedure */ }; struct rpc_reply { - u_int32_t rp_xid; /* request transaction id */ + uint32_t rp_xid; /* request transaction id */ int32_t rp_direction; /* call direction (1) */ int32_t rp_astatus; /* accept status (0: accepted) */ union { - u_int32_t rpu_errno; + uint32_t rpu_errno; struct { struct auth_info rok_auth; - u_int32_t rok_status; + uint32_t rok_status; } rpu_rok; } rp_u; }; /* Local forwards */ -static ssize_t recvrpc(struct iodesc *, void **, void **, time_t); +static ssize_t recvrpc(struct iodesc *, void **, void **, time_t, void *); static int rpc_getport(struct iodesc *, n_long, n_long); int rpc_xid; @@ -167,7 +167,7 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc, ptr = NULL; cc = sendrecv(d, sendudp, send_head, send_tail - send_head, - recvrpc, &ptr, (void **)&reply); + recvrpc, &ptr, (void **)&reply, NULL); #ifdef RPC_DEBUG if (debug) @@ -217,7 +217,7 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc, * Remaining checks are done by callrpc */ static ssize_t -recvrpc(struct iodesc *d, void **pkt, void **payload, time_t tleft) +recvrpc(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) { void *ptr; struct rpc_reply *reply; @@ -283,10 +283,10 @@ rpc_fromaddr(void *pkt, struct in_addr *addr, u_short *port) n_long ip_src; n_long ip_dst; /* UDP header: */ - u_int16_t uh_sport; /* source port */ - u_int16_t uh_dport; /* destination port */ + uint16_t uh_sport; /* source port */ + uint16_t uh_dport; /* destination port */ int16_t uh_ulen; /* udp length */ - u_int16_t uh_sum; /* udp checksum */ + uint16_t uh_sum; /* udp checksum */ /* RPC reply header: */ struct rpc_reply rpc; } *hhdr; diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h index 6968c3e..aebf07a 100644 --- a/stand/libsa/stand.h +++ b/stand/libsa/stand.h @@ -105,7 +105,7 @@ struct fs_ops { int (*fo_close)(struct open_file *f); int (*fo_read)(struct open_file *f, void *buf, size_t size, size_t *resid); - int (*fo_write)(struct open_file *f, void *buf, + int (*fo_write)(struct open_file *f, const void *buf, size_t size, size_t *resid); off_t (*fo_seek)(struct open_file *f, off_t offset, int where); int (*fo_stat)(struct open_file *f, struct stat *sb); @@ -138,6 +138,12 @@ extern struct fs_ops pkgfs_fsops; struct devsw { const char dv_name[8]; int dv_type; /* opaque type constant, arch-dependant */ +#define DEVT_NONE 0 +#define DEVT_DISK 1 +#define DEVT_NET 2 +#define DEVT_CD 3 +#define DEVT_ZFS 4 +#define DEVT_FD 5 int (*dv_init)(void); /* early probe call */ int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); @@ -160,16 +166,8 @@ extern int errno; * versions may be larger, but should be allowed to * overlap. */ -struct devdesc -{ +struct devdesc { struct devsw *d_dev; - int d_type; -#define DEVT_NONE 0 -#define DEVT_DISK 1 -#define DEVT_NET 2 -#define DEVT_CD 3 -#define DEVT_ZFS 4 -#define DEVT_FD 5 int d_unit; void *d_opendata; }; @@ -289,7 +287,7 @@ extern int open(const char *, int); extern int close(int); extern void closeall(void); extern ssize_t read(int, void *, size_t); -extern ssize_t write(int, void *, size_t); +extern ssize_t write(int, const void *, size_t); extern struct dirent *readdirfd(int); extern void srandom(u_long seed); @@ -383,7 +381,7 @@ extern void nullsys(void); extern int null_open(const char *path, struct open_file *f); extern int null_close(struct open_file *f); extern int null_read(struct open_file *f, void *buf, size_t size, size_t *resid); -extern int null_write(struct open_file *f, void *buf, size_t size, size_t *resid); +extern int null_write(struct open_file *f, const void *buf, size_t size, size_t *resid); extern off_t null_seek(struct open_file *f, off_t offset, int where); extern int null_stat(struct open_file *f, struct stat *sb); extern int null_readdir(struct open_file *f, struct dirent *d); diff --git a/stand/libsa/tftp.c b/stand/libsa/tftp.c index 7e83e48..fb58202 100644 --- a/stand/libsa/tftp.c +++ b/stand/libsa/tftp.c @@ -61,27 +61,24 @@ __FBSDID("$FreeBSD$"); #include "tftp.h" struct tftp_handle; +struct tftprecv_extra; +static ssize_t recvtftp(struct iodesc *d, void **pkt, void **payload, + time_t tleft, void *recv_extra); static int tftp_open(const char *path, struct open_file *f); static int tftp_close(struct open_file *f); static int tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len); static int tftp_read(struct open_file *f, void *buf, size_t size, size_t *resid); -static int tftp_write(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t tftp_seek(struct open_file *f, off_t offset, int where); static int tftp_set_blksize(struct tftp_handle *h, const char *str); static int tftp_stat(struct open_file *f, struct stat *sb); -static ssize_t sendrecv_tftp(struct tftp_handle *h, - ssize_t (*sproc)(struct iodesc *, void *, size_t), - void *sbuf, size_t ssize, - ssize_t (*rproc)(struct tftp_handle *h, void **, void **, time_t, unsigned short *), - void **, void **, unsigned short *rtype); struct fs_ops tftp_fsops = { "tftp", tftp_open, tftp_close, tftp_read, - tftp_write, + null_write, tftp_seek, tftp_stat, null_readdir @@ -118,6 +115,11 @@ struct tftp_handle { struct tftphdr *tftp_hdr; }; +struct tftprecv_extra { + struct tftp_handle *tftp_handle; + unsigned short rtype; /* Received type */ +}; + #define TFTP_MAX_ERRCODE EOPTNEG static const int tftperrors[TFTP_MAX_ERRCODE + 1] = { 0, /* ??? */ @@ -178,15 +180,19 @@ tftp_sendack(struct tftp_handle *h) } static ssize_t -recvtftp(struct tftp_handle *h, void **pkt, void **payload, time_t tleft, - unsigned short *rtype) +recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, + void *recv_extra) { - struct iodesc *d = h->iodesc; + struct tftprecv_extra *extra; + struct tftp_handle *h; struct tftphdr *t; + unsigned short *rtype; void *ptr = NULL; ssize_t len; errno = 0; + extra = (struct tftprecv_extra *)recv_extra; + h = extra->tftp_handle; len = readudp(d, &ptr, (void **)&t, tleft); @@ -195,7 +201,7 @@ recvtftp(struct tftp_handle *h, void **pkt, void **payload, time_t tleft, return (-1); } - *rtype = ntohs(t->th_opcode); + extra->rtype = ntohs(t->th_opcode); switch (ntohs(t->th_opcode)) { case DATA: { int got; @@ -282,6 +288,7 @@ tftp_makereq(struct tftp_handle *h) struct tftphdr t; u_char space[FNAME_SIZE + 6]; } __packed __aligned(4) wbuf; + struct tftprecv_extra recv_extra; char *wtail; int l; ssize_t res; @@ -289,7 +296,6 @@ tftp_makereq(struct tftp_handle *h) struct tftphdr *t; char *tftp_blksize = NULL; int blksize_l; - unsigned short rtype = 0; /* * Allow overriding default TFTP block size by setting @@ -334,8 +340,9 @@ tftp_makereq(struct tftp_handle *h) h->validsize = 0; pkt = NULL; - res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, - &recvtftp, &pkt, (void **)&t, &rtype); + recv_extra.tftp_handle = h; + res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, + (void *)&recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { free(pkt); return (errno); @@ -345,13 +352,13 @@ tftp_makereq(struct tftp_handle *h) h->pkt = pkt; h->tftp_hdr = t; - if (rtype == OACK) + if (recv_extra.rtype == OACK) return (tftp_getnextblock(h)); /* Server ignored our blksize request, revert to TFTP default. */ h->tftp_blksize = SEGSIZE; - switch (rtype) { + switch (recv_extra.rtype) { case DATA: { h->currblock = 1; h->validsize = res; @@ -377,11 +384,11 @@ tftp_getnextblock(struct tftp_handle *h) u_char header[HEADER_SIZE]; struct tftphdr t; } __packed __aligned(4) wbuf; + struct tftprecv_extra recv_extra; char *wtail; int res; void *pkt; struct tftphdr *t; - unsigned short rtype = 0; wbuf.t.th_opcode = htons((u_short) ACK); wtail = (char *) &wbuf.t.th_block; wbuf.t.th_block = htons((u_short) h->currblock); @@ -390,8 +397,9 @@ tftp_getnextblock(struct tftp_handle *h) h->iodesc->xid = h->currblock + 1; /* expected block */ pkt = NULL; - res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, - &recvtftp, &pkt, (void **)&t, &rtype); + recv_extra.tftp_handle = h; + res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, + (void *)&recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { /* 0 is OK! */ free(pkt); @@ -564,13 +572,6 @@ tftp_close(struct open_file *f) return (0); } -static int -tftp_write(struct open_file *f __unused, void *start __unused, size_t size __unused, - size_t *resid __unused /* out */) -{ - return (EROFS); -} - static int tftp_stat(struct open_file *f, struct stat *sb) { @@ -605,67 +606,6 @@ tftp_seek(struct open_file *f, off_t offset, int where) return (tftpfile->off); } -static ssize_t -sendrecv_tftp(struct tftp_handle *h, - ssize_t (*sproc)(struct iodesc *, void *, size_t), - void *sbuf, size_t ssize, - ssize_t (*rproc)(struct tftp_handle *, void **, void **, time_t, - unsigned short *), - void **pkt, void **payload, unsigned short *rtype) -{ - struct iodesc *d = h->iodesc; - ssize_t cc; - time_t t, t1, tleft; - -#ifdef TFTP_DEBUG - if (debug) - printf("sendrecv: called\n"); -#endif - - tleft = MINTMO; - t = t1 = getsecs(); - for (;;) { - if ((getsecs() - t) > MAXTMO) { - errno = ETIMEDOUT; - return -1; - } - - cc = (*sproc)(d, sbuf, ssize); - if (cc != -1 && cc < ssize) - panic("sendrecv: short write! (%zd < %zu)", - cc, ssize); - - if (cc == -1) { - /* Error on transmit; wait before retrying */ - while ((getsecs() - t1) < tleft); - t1 = getsecs(); - continue; - } - - t1 = getsecs(); -recvnext: - if ((getsecs() - t) > MAXTMO) { - errno = ETIMEDOUT; - return -1; - } - /* Try to get a packet and process it. */ - cc = (*rproc)(h, pkt, payload, tleft, rtype); - /* Return on data, EOF or real error. */ - if (cc != -1 || (errno != 0 && errno != ETIMEDOUT)) - return (cc); - if ((getsecs() - t1) < tleft) { - goto recvnext; - } - - /* Timed out or didn't get the packet we're waiting for */ - tleft += MINTMO; - if (tleft > (2 * MINTMO)) { - tleft = (2 * MINTMO); - } - t1 = getsecs(); - } -} - static int tftp_set_blksize(struct tftp_handle *h, const char *str) { diff --git a/stand/libsa/ufs.c b/stand/libsa/ufs.c index 928a1d1..83f7a7b 100644 --- a/stand/libsa/ufs.c +++ b/stand/libsa/ufs.c @@ -84,7 +84,8 @@ __FBSDID("$FreeBSD$"); #include "string.h" static int ufs_open(const char *path, struct open_file *f); -static int ufs_write(struct open_file *f, void *buf, size_t size, size_t *resid); +static int ufs_write(struct open_file *f, const void *buf, size_t size, + size_t *resid); static int ufs_close(struct open_file *f); static int ufs_read(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t ufs_seek(struct open_file *f, off_t offset, int where); @@ -131,7 +132,7 @@ struct file { static int read_inode(ino_t, struct open_file *); static int block_map(struct open_file *, ufs2_daddr_t, ufs2_daddr_t *); static int buf_read_file(struct open_file *, char **, size_t *); -static int buf_write_file(struct open_file *, char *, size_t *); +static int buf_write_file(struct open_file *, const char *, size_t *); static int search_directory(char *, struct open_file *, ino_t *); /* @@ -301,7 +302,7 @@ block_map(f, file_block, disk_block_p) static int buf_write_file(f, buf_p, size_p) struct open_file *f; - char *buf_p; + const char *buf_p; size_t *size_p; /* out */ { struct file *fp = (struct file *)f->f_fsdata; @@ -764,14 +765,14 @@ ufs_read(f, start, size, resid) static int ufs_write(f, start, size, resid) struct open_file *f; - void *start; + const void *start; size_t size; size_t *resid; /* out */ { struct file *fp = (struct file *)f->f_fsdata; size_t csize; int rc = 0; - char *addr = start; + const char *addr = start; csize = size; while ((size != 0) && (csize != 0)) { diff --git a/stand/libsa/write.c b/stand/libsa/write.c index 9e02f08..608773b 100644 --- a/stand/libsa/write.c +++ b/stand/libsa/write.c @@ -69,7 +69,7 @@ __FBSDID("$FreeBSD$"); ssize_t write(fd, dest, bcount) int fd; - void *dest; + const void *dest; size_t bcount; { struct open_file *f = &files[fd]; @@ -82,7 +82,8 @@ write(fd, dest, bcount) if (f->f_flags & F_RAW) { twiddle(4); errno = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE, - btodb(f->f_offset), bcount, dest, &resid); + btodb(f->f_offset), bcount, __DECONST(void *, dest), + &resid); if (errno) return (-1); f->f_offset += resid; diff --git a/stand/loader.mk b/stand/loader.mk index e2c4718..06b85d4 100644 --- a/stand/loader.mk +++ b/stand/loader.mk @@ -22,12 +22,16 @@ SRCS+= load_elf32.c reloc_elf32.c .elif ${MACHINE_CPUARCH} == "powerpc" SRCS+= load_elf32.c reloc_elf32.c SRCS+= load_elf64.c reloc_elf64.c +SRCS+= metadata.c .elif ${MACHINE_CPUARCH} == "sparc64" SRCS+= load_elf64.c reloc_elf64.c +SRCS+= metadata.c .elif ${MACHINE_ARCH:Mmips64*} != "" SRCS+= load_elf64.c reloc_elf64.c +SRCS+= metadata.c .elif ${MACHINE} == "mips" SRCS+= load_elf32.c reloc_elf32.c +SRCS+= metadata.c .endif .if ${LOADER_DISK_SUPPORT:Uyes} == "yes" @@ -121,7 +125,8 @@ CFLAGS+= -DLOADER_MBR_SUPPORT CFLAGS+= -DLOADER_ZFS_SUPPORT CFLAGS+= -I${ZFSSRC} CFLAGS+= -I${SYSDIR}/cddl/boot/zfs -.if ${MACHINE} == "amd64" +SRCS+= zfs_cmd.c +.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 1 # Have to override to use 32-bit version of zfs library... # kinda lame to select that there XXX LIBZFSBOOT= ${BOOTOBJ}/zfs32/libzfsboot.a diff --git a/stand/mips/Makefile b/stand/mips/Makefile index 760c557..90341b2 100644 --- a/stand/mips/Makefile +++ b/stand/mips/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +NO_OBJ=t + SUBDIR= uboot # diff --git a/stand/mips/beri/boot2/boot2.c b/stand/mips/beri/boot2/boot2.c index 3c8cc3d..a875ff7 100644 --- a/stand/mips/beri/boot2/boot2.c +++ b/stand/mips/beri/boot2/boot2.c @@ -627,7 +627,7 @@ static int xputc(int c) { if (ioctrl & IO_KEYBOARD) - putc(c); + beri_putc(c); #if 0 if (ioctrl & IO_SERIAL) sio_putc(c); @@ -642,7 +642,7 @@ xgetc(int fn) return 0; for (;;) { if (ioctrl & IO_KEYBOARD && keyhit(0)) - return fn ? 1 : getc(); + return fn ? 1 : beri_getc(); #if 0 if (ioctrl & IO_SERIAL && sio_ischar()) return fn ? 1 : sio_getc(); diff --git a/stand/mips/beri/common/altera_jtag_uart.c b/stand/mips/beri/common/altera_jtag_uart.c index 4bed67d..173672e 100644 --- a/stand/mips/beri/common/altera_jtag_uart.c +++ b/stand/mips/beri/common/altera_jtag_uart.c @@ -159,7 +159,7 @@ keyhit(int seconds) } int -getc(void) +beri_getc(void) { while (!(uart_readable())); @@ -168,7 +168,7 @@ getc(void) } void -putc(int ch) +beri_putc(int ch) { uart_data_write(ch); diff --git a/stand/mips/beri/common/cons.h b/stand/mips/beri/common/cons.h index 18a466a..7d27173 100644 --- a/stand/mips/beri/common/cons.h +++ b/stand/mips/beri/common/cons.h @@ -33,8 +33,8 @@ #ifndef _CONS_H_ #define _CONS_H_ -int getc(void); +int beri_getc(void); int keyhit(int); -void putc(int); +void beri_putc(int); #endif diff --git a/stand/mips/beri/loader/Makefile b/stand/mips/beri/loader/Makefile index f8c1bd9..8e554b4 100644 --- a/stand/mips/beri/loader/Makefile +++ b/stand/mips/beri/loader/Makefile @@ -47,7 +47,6 @@ SRCS= start.S \ main.c \ devicename.c \ exec.c \ - metadata.c \ vers.c \ arch.c diff --git a/stand/mips/beri/loader/beri_console.c b/stand/mips/beri/loader/beri_console.c index 9a4ae19..3c95d75 100644 --- a/stand/mips/beri/loader/beri_console.c +++ b/stand/mips/beri/loader/beri_console.c @@ -72,14 +72,14 @@ static void c_out(int c) { - putc(c); + beri_putc(c); } static int c_in(void) { - return (getc()); + return (beri_getc()); } static int diff --git a/stand/mips/beri/loader/beri_disk_cfi.c b/stand/mips/beri/loader/beri_disk_cfi.c index a21947f..76b7bb7 100644 --- a/stand/mips/beri/loader/beri_disk_cfi.c +++ b/stand/mips/beri/loader/beri_disk_cfi.c @@ -98,7 +98,7 @@ beri_cfi_disk_open(struct open_file *f, ...) dev = va_arg(ap, struct disk_devdesc *); va_end(ap); - if (dev->d_unit != 0) + if (dev->dd.d_unit != 0) return (EIO); return (disk_open(dev, cfi_get_mediasize(), cfi_get_sectorsize())); } @@ -127,8 +127,8 @@ beri_cfi_disk_print(int verbose) ret = pager_output(line); if (ret != 0) return (ret); - dev.d_dev = &beri_cfi_disk; - dev.d_unit = 0; + dev.dd.d_dev = &beri_cfi_disk; + dev.dd.d_unit = 0; dev.d_slice = -1; dev.d_partition = -1; if (disk_open(&dev, cfi_get_mediasize(), cfi_get_sectorsize()) == 0) { diff --git a/stand/mips/beri/loader/beri_disk_sdcard.c b/stand/mips/beri/loader/beri_disk_sdcard.c index 266fb4a..f577eaf 100644 --- a/stand/mips/beri/loader/beri_disk_sdcard.c +++ b/stand/mips/beri/loader/beri_disk_sdcard.c @@ -103,7 +103,7 @@ beri_sdcard_disk_open(struct open_file *f, ...) return (ENXIO); } - if (dev->d_unit != 0) + if (dev->dd.d_unit != 0) return (EIO); return (disk_open(dev, altera_sdcard_get_mediasize(), altera_sdcard_get_sectorsize())); @@ -133,8 +133,8 @@ beri_sdcard_disk_print(int verbose) ret = pager_output(line); if (ret != 0) return (ret); - dev.d_dev = &beri_sdcard_disk; - dev.d_unit = 0; + dev.dd.d_dev = &beri_sdcard_disk; + dev.dd.d_unit = 0; dev.d_slice = -1; dev.d_partition = -1; if (disk_open(&dev, altera_sdcard_get_mediasize(), diff --git a/stand/mips/beri/loader/devicename.c b/stand/mips/beri/loader/devicename.c index 968c946..89eee32 100644 --- a/stand/mips/beri/loader/devicename.c +++ b/stand/mips/beri/loader/devicename.c @@ -139,7 +139,7 @@ beri_arch_parsedev(struct disk_devdesc **dev, const char *devspec, goto fail; } - idev->d_unit = unit; + idev->dd.d_unit = unit; if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; break; @@ -148,8 +148,7 @@ beri_arch_parsedev(struct disk_devdesc **dev, const char *devspec, err = EINVAL; goto fail; } - idev->d_dev = dv; - idev->d_type = dv->dv_type; + idev->dd.d_dev = dv; if (dev == NULL) { free(idev); } else { @@ -169,13 +168,13 @@ beri_arch_fmtdev(void *vdev) struct disk_devdesc *dev = (struct disk_devdesc *)vdev; static char buf[128]; /* XXX device length constant? */ - switch(dev->d_type) { + switch(dev->dd.d_dev->dv_type) { case DEVT_NONE: strcpy(buf, "(no device)"); break; case DEVT_CD: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); break; case DEVT_DISK: @@ -183,7 +182,7 @@ beri_arch_fmtdev(void *vdev) case DEVT_NET: case DEVT_ZFS: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); break; } return(buf); diff --git a/stand/mips/beri/loader/exec.c b/stand/mips/beri/loader/exec.c index 3c1b7a6..5399e8a 100644 --- a/stand/mips/beri/loader/exec.c +++ b/stand/mips/beri/loader/exec.c @@ -85,7 +85,7 @@ beri_elf64_exec(struct preloaded_file *fp) } ehdr = (Elf_Ehdr *)md->md_data; - error = md_load64(fp->f_args, &mdp); + error = md_load64(fp->f_args, &mdp, NULL); if (error) { printf("%s: md_load64 failed\n", fp->f_name); return (error); diff --git a/stand/mips/beri/loader/loader.h b/stand/mips/beri/loader/loader.h index 4005caa..d73a7f8 100644 --- a/stand/mips/beri/loader/loader.h +++ b/stand/mips/beri/loader/loader.h @@ -56,7 +56,7 @@ extern char **boot2_envv; extern struct bootinfo boot2_bootinfo; /* metadata.c */ -int md_load64(char *args, vm_offset_t *modulep); +int md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtbp); /* vers.c */ extern char bootprog_info[]; diff --git a/stand/mips/beri/loader/metadata.c b/stand/mips/beri/loader/metadata.c deleted file mode 100644 index 0698cd1..0000000 --- a/stand/mips/beri/loader/metadata.c +++ /dev/null @@ -1,355 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * from: FreeBSD: src/sys/boot/sparc64/loader/metadata.c,v 1.6 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <sys/param.h> -#include <sys/reboot.h> -#include <sys/linker.h> - -#include <machine/metadata.h> - -#include "bootstrap.h" - -/* - * Return a 'boothowto' value corresponding to the kernel arguments in - * (kargs) and any relevant environment variables. - */ -static struct -{ - const char *ev; - int mask; -} howto_names[] = { - {"boot_askname", RB_ASKNAME}, - {"boot_cdrom", RB_CDROM}, - {"boot_ddb", RB_KDB}, - {"boot_dfltroot", RB_DFLTROOT}, - {"boot_gdb", RB_GDB}, - {"boot_multicons", RB_MULTIPLE}, - {"boot_mute", RB_MUTE}, - {"boot_pause", RB_PAUSE}, - {"boot_serial", RB_SERIAL}, - {"boot_single", RB_SINGLE}, - {"boot_verbose", RB_VERBOSE}, - {NULL, 0} -}; - -int -md_getboothowto(char *kargs) -{ - char *cp; - int howto; - int active; - int i; - - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - if (!strcmp(getenv("console"), "comconsole")) - howto |= RB_SERIAL; - if (!strcmp(getenv("console"), "nullconsole")) - howto |= RB_MUTE; - return(howto); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -md_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - archsw.arch_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - archsw.arch_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - archsw.arch_copyin("", addr, 1); - addr++; - } - archsw.arch_copyin("", addr, 1); - addr++; - return(addr); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ - -static int align; - -#define COPY32(v, a, c) { \ - u_int32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c) \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += roundup(strlen(s) + 1, align); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), align); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c);\ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += roundup(mm->md_size, align); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -vm_offset_t -md_copymodules(vm_offset_t addr, int kern64) -{ - struct preloaded_file *fp; - struct file_metadata *md; - uint64_t scratch64; - int c; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - if (kern64) { - scratch64 = fp->f_addr; - MOD_ADDR(addr, scratch64, c); - scratch64 = fp->f_size; - MOD_SIZE(addr, scratch64, c); - } else { - MOD_ADDR(addr, fp->f_addr, c); - MOD_SIZE(addr, fp->f_size, c); - } - for (md = fp->f_metadata; md != NULL; md = md->md_next) { - if (!(md->md_type & MODINFOMD_NOCOPY)) { - MOD_METADATA(addr, md, c); - } - } - } - MOD_END(addr, c); - return(addr); -} - -/* - * Load the information expected by a powerpc kernel. - * - * - The 'boothowto' argument is constructed - * - The 'bootdev' argument is constructed - * - The kernel environment is copied into kernel space. - * - Module metadata are formatted and placed in kernel space. - */ -int -md_load_dual(char *args, vm_offset_t *modulep, int kern64) -{ - struct preloaded_file *kfp; - struct preloaded_file *xp; - struct file_metadata *md; - vm_offset_t kernend; - vm_offset_t addr; - vm_offset_t envp; - vm_offset_t size; - uint64_t scratch64; - char *rootdevname; - int howto; - - align = kern64 ? 8 : 4; - howto = md_getboothowto(args); - - /* - * Allow the environment variable 'rootdev' to override the supplied device - * This should perhaps go to MI code and/or have $rootdev tested/set by - * MI code before launching the kernel. - */ - rootdevname = getenv("rootdev"); - if (rootdevname == NULL) - rootdevname = getenv("currdev"); - /* Try reading the /etc/fstab file to select the root device */ - getrootmount(rootdevname); - - /* find the last module in the chain */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; - } - /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - - /* copy our environment */ - envp = addr; - addr = md_copyenv(addr); - - /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - - kernend = 0; - kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - panic("can't find kernel file"); - file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); - if (kern64) { - scratch64 = envp; - file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64); - scratch64 = kernend; - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64); - } else { - file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); - } - - *modulep = addr; - size = md_copymodules(0, kern64); - kernend = roundup(addr + size, PAGE_SIZE); - - md = file_findmetadata(kfp, MODINFOMD_KERNEND); - if (kern64) { - scratch64 = kernend; - bcopy(&scratch64, md->md_data, sizeof scratch64); - } else { - bcopy(&kernend, md->md_data, sizeof kernend); - } - - (void)md_copymodules(addr, kern64); - - return(0); -} - -int -md_load(char *args, vm_offset_t *modulep) -{ - return (md_load_dual(args, modulep, 0)); -} - -int -md_load64(char *args, vm_offset_t *modulep) -{ - return (md_load_dual(args, modulep, 1)); -} - diff --git a/stand/mips/uboot/Makefile b/stand/mips/uboot/Makefile index 4323f45..1751bcb 100644 --- a/stand/mips/uboot/Makefile +++ b/stand/mips/uboot/Makefile @@ -53,5 +53,4 @@ ubldr: ${OBJS} ldscript.abs ${.CURDIR}/ldscript.${MACHINE_CPUARCH} ${DPADD} CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin -.include <bsd.stand.mk> .include <bsd.prog.mk> diff --git a/stand/mips/uboot/loader.conf b/stand/mips/uboot/loader.conf deleted file mode 100644 index dd2a23a..0000000 --- a/stand/mips/uboot/loader.conf +++ /dev/null @@ -1,13 +0,0 @@ -# This is defaults/loader.conf for ARM, containing defaults for loader(8). -# Do not modify the contents of this file, instead put your customizations -# into /boot/loader.conf or /boot/loader.conf.local -# $FreeBSD$ - -autoboot_delay=10 -bootfile="kernel" # Kernel name (possibly absolute path) -kernel="kernel" # /boot sub-directory containing kernel and modules -loader_conf_files="/boot/loader.conf /boot/loader.conf.local" -module_path="/boot/kernel;/boot/modules;/boot/dtb;/boot/overlays" -nextboot_conf="/boot/nextboot.conf" -nextboot_enable="NO" -verbose_loading="NO" diff --git a/stand/ofw/common/Makefile.inc b/stand/ofw/common/Makefile.inc deleted file mode 100644 index 5d20372..0000000 --- a/stand/ofw/common/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -SRCS+= main.c diff --git a/stand/ofw/libofw/Makefile b/stand/ofw/libofw/Makefile index 80ca993..5ab94e0 100644 --- a/stand/ofw/libofw/Makefile +++ b/stand/ofw/libofw/Makefile @@ -4,7 +4,7 @@ LIB= ofw -SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \ +SRCS= devicename.c ofw_console.c ofw_copy.c ofw_disk.c \ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \ ofw_time.c openfirm.c .PATH: ${ZFSSRC} @@ -13,10 +13,6 @@ SRCS+= devicename_stubs.c # Pick up the bootstrap header for some interface items CFLAGS+= -I${LDRSRC} -.if ${MACHINE_CPUARCH} == "powerpc" -SRCS+= ppc64_elf_freebsd.c -.endif - .ifdef(BOOT_DISK_DEBUG) # Make the disk code more talkative CFLAGS+= -DDISK_DEBUG diff --git a/stand/ofw/libofw/devicename.c b/stand/ofw/libofw/devicename.c index c9814b7..1f45a95 100644 --- a/stand/ofw/libofw/devicename.c +++ b/stand/ofw/libofw/devicename.c @@ -113,9 +113,8 @@ found: return ENOMEM; } strcpy(idev->d_path, name); - idev->d_dev = dv; - idev->d_type = dv->dv_type; - if (idev->d_type == DEVT_ZFS) { + idev->dd.d_dev = dv; + if (dv->dv_type == DEVT_ZFS) { p = devspec + strlen(dv->dv_name); err = zfs_parsedev((struct zfs_devdesc *)idev, p, path); if (err != 0) { diff --git a/stand/ofw/libofw/libofw.h b/stand/ofw/libofw/libofw.h index 24a5d08..a4bfc27 100644 --- a/stand/ofw/libofw/libofw.h +++ b/stand/ofw/libofw/libofw.h @@ -27,14 +27,13 @@ #include "openfirm.h" -/* Note: Must match the 'struct devdesc' in bootstrap.h */ struct ofw_devdesc { - struct devsw *d_dev; - int d_type; - int d_unit; - ihandle_t d_handle; + struct devdesc dd; union { - char d_path[256]; + struct { + ihandle_t d_handle; + char d_path[256]; + }; struct { uint64_t pool_guid; uint64_t root_guid; @@ -62,18 +61,10 @@ void ofw_memmap(int); struct preloaded_file; struct file_format; -int ofw_elf_loadfile(char *, vm_offset_t, struct preloaded_file **); -int ofw_elf_exec(struct preloaded_file *); - /* MD code implementing MI interfaces */ vm_offset_t md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb); vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); -extern struct file_format ofw_elf; -#ifdef __powerpc__ -extern struct file_format ofw_elf64; -#endif - extern void reboot(void); struct ofw_reg diff --git a/stand/ofw/libofw/openfirm.c b/stand/ofw/libofw/openfirm.c index 84e81d9..7a5aac0 100644 --- a/stand/ofw/libofw/openfirm.c +++ b/stand/ofw/libofw/openfirm.c @@ -598,7 +598,7 @@ OF_write(ihandle_t instance, void *addr, int len) /* Seek to a position. */ int -OF_seek(ihandle_t instance, u_int64_t pos) +OF_seek(ihandle_t instance, uint64_t pos) { static struct { cell_t name; diff --git a/stand/pc98/Makefile b/stand/pc98/Makefile index e8f9dbf..e1a01f5 100644 --- a/stand/pc98/Makefile +++ b/stand/pc98/Makefile @@ -1,5 +1,9 @@ # $FreeBSD$ +NO_OBJ=t + +.include <bsd.init.mk> + SUBDIR= boot0 boot0.5 pc98boot btx boot2 cdboot kgzldr libpc98 loader .include <bsd.subdir.mk> diff --git a/stand/pc98/Makefile.inc b/stand/pc98/Makefile.inc index d766303..b492ef7 100644 --- a/stand/pc98/Makefile.inc +++ b/stand/pc98/Makefile.inc @@ -2,28 +2,24 @@ # # $FreeBSD$ -BINDIR?= /boot - LOADER_ADDRESS?=0x200000 -CFLAGS+= -march=i386 -ffreestanding -CFLAGS.gcc+= -mpreferred-stack-boundary=2 -CFLAGS+= ${CFLAGS_NO_SIMD} -msoft-float -CFLAGS+= -Os -DPC98 LDFLAGS+= -nostdlib # BTX components -.if exists(${.OBJDIR}/../btx) -BTXDIR= ${.OBJDIR}/../btx -.else -BTXDIR= ${.CURDIR}/../btx -.endif +BTXDIR= ${BOOTOBJ}/pc98/btx BTXLDR= ${BTXDIR}/btxldr/btxldr BTXKERN= ${BTXDIR}/btx/btx + +BTXSRC= ${BOOTSRC}/pc98/btx BTXCRT= ${BTXDIR}/lib/crt0.o # compact binary with no padding between text, data, bss -LDSCRIPT= ${SRCTOP}/stand/i386/boot.ldscript -LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary -LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections +LDSCRIPT= ${BOOTSRC}/i386/boot.ldscript +#LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary +LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary +#LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections +LD_FLAGS_BIN=-static -N --gc-sections + +WARNS?= 0 .include "../Makefile.inc" diff --git a/stand/pc98/boot0.5/Makefile b/stand/pc98/boot0.5/Makefile index ec40fe5..5760b74 100644 --- a/stand/pc98/boot0.5/Makefile +++ b/stand/pc98/boot0.5/Makefile @@ -3,10 +3,9 @@ PROG= ${BOOT}.out INTERNALPROG= FILES= ${BOOT} -MAN= SRCS= start.s boot.s boot0.5.s disk.s selector.s support.s syscons.s \ putssjis.s -CLEANFILES= ${BOOT} ${BOOT}.bin +CLEANFILES+= ${BOOT} ${BOOT}.bin BOOT= boot0.5 @@ -14,7 +13,7 @@ BOOT= boot0.5 # unless you are glutton for punishment. BOOT_BOOT0_ORG?= 0x0000 -LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} -Wl,-N,-T,${.CURDIR}/ldscript +LDFLAGS+=-e start -Ttext ${BOOT_BOOT0_ORG} -Wl,-N,-T,${.CURDIR}/ldscript # The size of boot0.5 must be 7168 bytes ${BOOT}: ${BOOT}.bin diff --git a/stand/pc98/boot0/Makefile b/stand/pc98/boot0/Makefile index d348f60..84433da 100644 --- a/stand/pc98/boot0/Makefile +++ b/stand/pc98/boot0/Makefile @@ -3,9 +3,8 @@ PROG= ${BOOT} INTERNALPROG= FILES= ${BOOT} -MAN= SRCS= ${BOOT}.s -CLEANFILES= ${BOOT} +CLEANFILES+= ${BOOT} BOOT= boot0 @@ -14,6 +13,6 @@ BOOT= boot0 BOOT_BOOT0_ORG?= 0x0000 ORG=${BOOT_BOOT0_ORG} -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include <bsd.prog.mk> diff --git a/stand/pc98/boot2/Makefile b/stand/pc98/boot2/Makefile index 2db0590..816a1d7 100644 --- a/stand/pc98/boot2/Makefile +++ b/stand/pc98/boot2/Makefile @@ -27,10 +27,11 @@ CFLAGS= -fomit-frame-pointer \ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ -DSIOFMT=${B2SIOFMT} \ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ - -I${.CURDIR}/../../.. \ - -I${.CURDIR}/../../i386/boot2 \ - -I${.CURDIR}/../../common \ - -I${.CURDIR}/../btx/lib -I. \ + -I${LDRSRC} \ + -I${SYSDIR} \ + -I${BOOTSRC}/i386/boot2 \ + -I${BOOTSRC}/common \ + -I${BOOTSRC}/pc98/btx/lib \ -Wall -Waggregate-return -Wbad-function-cast -Wcast-align \ -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ @@ -52,14 +53,14 @@ CFLAGS.gcc+= -mno-align-long-strings CFLAGS.clang+= -Oz ${CLANG_OPT_SMALL} -LD_FLAGS=${LD_FLAGS_BIN} +LD_FLAGS+=${LD_FLAGS_BIN} # Pick up ../Makefile.inc early. .include <bsd.init.mk> -.PATH: ${.CURDIR}/../../i386/boot2 +.PATH: ${BOOTSRC}/i386/boot2 -CLEANFILES= boot +CLEANFILES+= boot boot: boot1 boot2 cat boot1 boot2 > boot @@ -98,7 +99,7 @@ boot2.o: boot2.s SRCS= boot2.c boot2.h -boot2.s: boot2.c boot2.h ${.CURDIR}/../../common/ufsread.c +boot2.s: boot2.c boot2.h ${CC} ${CFLAGS} -S -o boot2.s.tmp ${.CURDIR}/boot2.c sed -e '/align/d' -e '/nop/d' < boot2.s.tmp > boot2.s rm -f boot2.s.tmp diff --git a/stand/pc98/boot2/boot2.c b/stand/pc98/boot2/boot2.c index b582516..3a9a54b 100644 --- a/stand/pc98/boot2/boot2.c +++ b/stand/pc98/boot2/boot2.c @@ -71,20 +71,20 @@ extern uint32_t _end; static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ static const unsigned char flags[NOPT] = { - RBX_DUAL, - RBX_SERIAL, - RBX_ASKNAME, - RBX_CDROM, - RBX_CONFIG, - RBX_KDB, - RBX_GDB, - RBX_MUTE, - RBX_NOINTR, - RBX_PAUSE, - RBX_QUIET, - RBX_DFLTROOT, - RBX_SINGLE, - RBX_VERBOSE + RBX_DUAL, + RBX_SERIAL, + RBX_ASKNAME, + RBX_CDROM, + RBX_CONFIG, + RBX_KDB, + RBX_GDB, + RBX_MUTE, + RBX_NOINTR, + RBX_PAUSE, + RBX_QUIET, + RBX_DFLTROOT, + RBX_SINGLE, + RBX_VERBOSE }; static const char *const dev_nm[NDEV] = {"ad", "da", "fd"}; @@ -92,15 +92,15 @@ static const unsigned char dev_maj[NDEV] = {30, 4, 2}; static const unsigned char dev_daua[NDEV] = {0x80, 0xa0, 0x90}; static struct dsk { - unsigned daua; - unsigned type; - unsigned disk; - unsigned unit; - unsigned head; - unsigned sec; - uint8_t slice; - uint8_t part; - unsigned start; + unsigned daua; + unsigned type; + unsigned disk; + unsigned unit; + unsigned head; + unsigned sec; + uint8_t slice; + uint8_t part; + unsigned start; } dsk; static char cmd[512], cmddup[512], knamebuf[1024]; static const char *kname; @@ -128,18 +128,19 @@ static void memcpy(void *, const void *, int); static void memcpy(void *dst, const void *src, int len) { - const char *s = src; - char *d = dst; + const char *s = src; + char *d = dst; - while (len--) - *d++ = *s++; + while (len--) + *d++ = *s++; } static inline 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 ((unsigned char)*s1 - (unsigned char)*s2); } #define UFS_SMALL_CGBASE @@ -148,52 +149,53 @@ strcmp(const char *s1, const char *s2) static inline int xfsread(ufs_ino_t inode, void *buf, size_t nbyte) { - if ((size_t)fsread(inode, buf, nbyte) != nbyte) { - printf("Invalid %s\n", "format"); - return -1; - } - return 0; + + if ((size_t)fsread(inode, buf, nbyte) != nbyte) { + printf("Invalid %s\n", "format"); + return (-1); + } + return (0); } static inline void getstr(void) { - char *s; - int c; - - s = cmd; - for (;;) { - switch (c = xgetc(0)) { - case 0: - break; - case '\177': - case '\b': - if (s > cmd) { - s--; - printf("\b \b"); - } - break; - case '\n': - case '\r': - *s = 0; - return; - default: - if (s - cmd < sizeof(cmd) - 1) - *s++ = c; - putchar(c); + char *s; + int c; + + s = cmd; + for (;;) { + switch (c = xgetc(0)) { + case 0: + break; + case '\177': + case '\b': + if (s > cmd) { + s--; + printf("\b \b"); + } + break; + case '\n': + case '\r': + *s = 0; + return; + default: + if (s - cmd < sizeof(cmd) - 1) + *s++ = c; + putchar(c); + } } - } } static inline void putc(int c) { - v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; - v86.addr = PUTCORG; /* call to putc in boot1 */ - v86.eax = c; - v86int(); - v86.ctl = V86_FLAGS; + v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; + v86.addr = PUTCORG; /* call to putc in boot1 */ + v86.eax = c; + v86int(); + v86.ctl = V86_FLAGS; } static inline int @@ -322,482 +324,491 @@ int main(void) { #ifdef GET_BIOSGEOM - int i; + int i; #endif - uint8_t autoboot; - ufs_ino_t ino; - size_t nbyte; - - dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); - v86.ctl = V86_FLAGS; - v86.efl = PSL_RESERVED_DEFAULT | PSL_I; - dsk.daua = *(uint8_t *)PTOV(0x584); - dsk.disk = dsk.daua & DRV_DISK; - dsk.unit = dsk.daua & DRV_UNIT; - if (dsk.disk == 0x80) - dsk.type = TYPE_AD; - else if (dsk.disk == 0xa0) - dsk.type = TYPE_DA; - else /* if (dsk.disk == 0x30 || dsk.disk == 0x90) */ - dsk.type = TYPE_FD; - dsk.slice = check_slice(); + uint8_t autoboot; + ufs_ino_t ino; + size_t nbyte; + + dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); + v86.ctl = V86_FLAGS; + v86.efl = PSL_RESERVED_DEFAULT | PSL_I; + dsk.daua = *(uint8_t *)PTOV(0x584); + dsk.disk = dsk.daua & DRV_DISK; + dsk.unit = dsk.daua & DRV_UNIT; + if (dsk.disk == 0x80) + dsk.type = TYPE_AD; + else if (dsk.disk == 0xa0) + dsk.type = TYPE_DA; + else /* if (dsk.disk == 0x30 || dsk.disk == 0x90) */ + dsk.type = TYPE_FD; + dsk.slice = check_slice(); #ifdef GET_BIOSGEOM - for (i = 0; i < N_BIOS_GEOM; i++) - bootinfo.bi_bios_geom[i] = bd_getbigeom(i); + for (i = 0; i < N_BIOS_GEOM; i++) + bootinfo.bi_bios_geom[i] = bd_getbigeom(i); #endif - bootinfo.bi_version = BOOTINFO_VERSION; - bootinfo.bi_size = sizeof(bootinfo); + bootinfo.bi_version = BOOTINFO_VERSION; + bootinfo.bi_size = sizeof(bootinfo); - /* Process configuration file */ + /* Process configuration file */ - autoboot = 1; + autoboot = 1; - if ((ino = lookup(PATH_CONFIG)) || - (ino = lookup(PATH_DOTCONFIG))) { - nbyte = fsread(ino, cmd, sizeof(cmd) - 1); - cmd[nbyte] = '\0'; - } + if ((ino = lookup(PATH_CONFIG)) || + (ino = lookup(PATH_DOTCONFIG))) { + nbyte = fsread(ino, cmd, sizeof(cmd) - 1); + cmd[nbyte] = '\0'; + } - if (*cmd) { - memcpy(cmddup, cmd, sizeof(cmd)); - if (parse()) - autoboot = 0; - if (!OPT_CHECK(RBX_QUIET)) - printf("%s: %s", PATH_CONFIG, cmddup); - /* Do not process this command twice */ - *cmd = 0; - } + if (*cmd) { + memcpy(cmddup, cmd, sizeof(cmd)); + if (parse()) + autoboot = 0; + if (!OPT_CHECK(RBX_QUIET)) + printf("%s: %s", PATH_CONFIG, cmddup); + /* 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, try to load a kernel directly instead. - */ + /* + * Try to exec stage 3 boot loader. If interrupted by a keypress, + * or in case of failure, try to load a kernel directly instead. + */ - if (!kname) { - kname = PATH_LOADER; - if (autoboot && !keyhit(3*SECOND)) { - load(); - kname = PATH_KERNEL; + if (!kname) { + kname = PATH_LOADER; + if (autoboot && !keyhit(3*SECOND)) { + load(); + kname = PATH_KERNEL; + } } - } - - /* Present the user with the boot2 prompt. */ - for (;;) { - if (!autoboot || !OPT_CHECK(RBX_QUIET)) - printf("\nFreeBSD/pc98 boot\n" - "Default: %u:%s(%u,%c)%s\n" - "boot: ", - dsk.unit, dev_nm[dsk.type], dsk.unit, - 'a' + dsk.part, kname); - if (DO_SIO) - sio_flush(); - if (!autoboot || keyhit(3*SECOND)) - getstr(); - else if (!autoboot || !OPT_CHECK(RBX_QUIET)) - putchar('\n'); - autoboot = 0; - if (parse()) - putchar('\a'); - else - load(); - } + /* Present the user with the boot2 prompt. */ + + for (;;) { + if (!autoboot || !OPT_CHECK(RBX_QUIET)) + printf("\nFreeBSD/pc98 boot\n" + "Default: %u:%s(%u,%c)%s\n" + "boot: ", + dsk.unit, dev_nm[dsk.type], dsk.unit, + 'a' + dsk.part, kname); + if (DO_SIO) + sio_flush(); + if (!autoboot || keyhit(3*SECOND)) + getstr(); + else if (!autoboot || !OPT_CHECK(RBX_QUIET)) + putchar('\n'); + autoboot = 0; + if (parse()) + 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 { - struct exec ex; - Elf32_Ehdr eh; - } hdr; - static Elf32_Phdr ep[2]; - static Elf32_Shdr es[2]; - caddr_t p; - ufs_ino_t ino; - uint32_t addr; - int k; - uint8_t i, j; - - if (!(ino = lookup(kname))) { - if (!ls) - printf("No %s\n", kname); - return; - } - if (xfsread(ino, &hdr, sizeof(hdr))) - return; - - if (N_GETMAGIC(hdr.ex) == ZMAGIC) { - addr = hdr.ex.a_entry & 0xffffff; - p = PTOV(addr); - fs_off = PAGE_SIZE; - if (xfsread(ino, p, hdr.ex.a_text)) - return; - p += roundup2(hdr.ex.a_text, PAGE_SIZE); - if (xfsread(ino, p, hdr.ex.a_data)) - return; - } else if (IS_ELF(hdr.eh)) { - fs_off = hdr.eh.e_phoff; - for (j = k = 0; k < hdr.eh.e_phnum && j < 2; k++) { - if (xfsread(ino, ep + j, sizeof(ep[0]))) + union { + struct exec ex; + Elf32_Ehdr eh; + } hdr; + static Elf32_Phdr ep[2]; + static Elf32_Shdr es[2]; + caddr_t p; + ufs_ino_t ino; + uint32_t addr; + int k; + uint8_t i, j; + + if (!(ino = lookup(kname))) { + if (!ls) + printf("No %s\n", kname); return; - if (ep[j].p_type == PT_LOAD) - j++; } - for (i = 0; i < 2; i++) { - p = PTOV(ep[i].p_paddr & 0xffffff); - fs_off = ep[i].p_offset; - if (xfsread(ino, p, ep[i].p_filesz)) + if (xfsread(ino, &hdr, sizeof(hdr))) return; - } - p += roundup2(ep[1].p_memsz, PAGE_SIZE); - bootinfo.bi_symtab = VTOP(p); - if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { - fs_off = hdr.eh.e_shoff + sizeof(es[0]) * - (hdr.eh.e_shstrndx + 1); - if (xfsread(ino, &es, sizeof(es))) + + if (N_GETMAGIC(hdr.ex) == ZMAGIC) { + addr = hdr.ex.a_entry & 0xffffff; + p = PTOV(addr); + fs_off = PAGE_SIZE; + if (xfsread(ino, p, hdr.ex.a_text)) + return; + p += roundup2(hdr.ex.a_text, PAGE_SIZE); + if (xfsread(ino, p, hdr.ex.a_data)) + return; + } else if (IS_ELF(hdr.eh)) { + fs_off = hdr.eh.e_phoff; + for (j = k = 0; k < hdr.eh.e_phnum && j < 2; k++) { + if (xfsread(ino, ep + j, sizeof(ep[0]))) + return; + if (ep[j].p_type == PT_LOAD) + j++; + } + for (i = 0; i < 2; i++) { + p = PTOV(ep[i].p_paddr & 0xffffff); + fs_off = ep[i].p_offset; + if (xfsread(ino, p, ep[i].p_filesz)) + return; + } + p += roundup2(ep[1].p_memsz, PAGE_SIZE); + bootinfo.bi_symtab = VTOP(p); + if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { + fs_off = hdr.eh.e_shoff + sizeof(es[0]) * + (hdr.eh.e_shstrndx + 1); + if (xfsread(ino, &es, sizeof(es))) + return; + for (i = 0; i < 2; i++) { + *(Elf32_Word *)p = es[i].sh_size; + p += sizeof(es[i].sh_size); + fs_off = es[i].sh_offset; + if (xfsread(ino, p, es[i].sh_size)) + return; + p += es[i].sh_size; + } + } + addr = hdr.eh.e_entry & 0xffffff; + bootinfo.bi_esymtab = VTOP(p); + } else { + printf("Invalid %s\n", "format"); return; - for (i = 0; i < 2; i++) { - *(Elf32_Word *)p = es[i].sh_size; - p += sizeof(es[i].sh_size); - fs_off = es[i].sh_offset; - if (xfsread(ino, p, es[i].sh_size)) - return; - p += es[i].sh_size; - } } - addr = hdr.eh.e_entry & 0xffffff; - bootinfo.bi_esymtab = VTOP(p); - } else { - printf("Invalid %s\n", "format"); - return; - } - bootinfo.bi_kernelname = VTOP(kname); - bootinfo.bi_bios_dev = dsk.daua; - __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), - MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part), - 0, 0, 0, VTOP(&bootinfo)); + bootinfo.bi_kernelname = VTOP(kname); + bootinfo.bi_bios_dev = dsk.daua; + __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), + MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part), + 0, 0, 0, VTOP(&bootinfo)); } static int parse() { - char *arg = cmd; - char *ep, *p, *q; - const char *cp; - unsigned int drv; - int c, i, j; - size_t k; - - while ((c = *arg++)) { - if (c == ' ' || c == '\t' || c == '\n') - continue; - for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); - ep = p; - if (*p) - *p++ = 0; - if (c == '-') { - while ((c = *arg++)) { - if (c == 'P') { - if (*(uint8_t *)PTOV(0x481) & 0x48) { - cp = "yes"; - } else { - opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); - cp = "no"; - } - printf("Keyboard: %s\n", cp); - continue; + char *arg = cmd; + char *ep, *p, *q; + const char *cp; + unsigned int drv; + int c, i, j; + size_t k; + + while ((c = *arg++)) { + if (c == ' ' || c == '\t' || c == '\n') + continue; + for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; + if (*p) + *p++ = 0; + if (c == '-') { + while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x481) & 0x48) { + cp = "yes"; + } else { + opts |= OPT_SET(RBX_DUAL) | + OPT_SET(RBX_SERIAL); + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; #if SERIAL - } else if (c == 'S') { - j = 0; - while ((unsigned int)(i = *arg++ - '0') <= 9) - j = j * 10 + i; - if (j > 0 && i == -'0') { - comspeed = j; - break; - } - /* Fall through to error below ('S' not in optstr[]). */ + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* + * Fall through to error below + * ('S' not in optstr[]). + */ #endif - } - for (i = 0; c != optstr[i]; i++) - if (i == NOPT - 1) - return -1; - opts ^= OPT_SET(flags[i]); - } + } + for (i = 0; c != optstr[i]; i++) + if (i == NOPT - 1) + return (-1); + opts ^= OPT_SET(flags[i]); + } #if SERIAL - ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : - OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; - if (DO_SIO) { - if (sio_init(115200 / comspeed) != 0) - ioctrl &= ~IO_SERIAL; - } + ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : + OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; + if (DO_SIO) { + if (sio_init(115200 / comspeed) != 0) + ioctrl &= ~IO_SERIAL; + } #endif - } else { - for (q = arg--; *q && *q != '('; q++); - if (*q) { - drv = -1; - if (arg[1] == ':') { - drv = *arg - '0'; - if (drv > 9) - return (-1); - arg += 2; - } - if (q - arg != 2) - return -1; - for (i = 0; arg[0] != dev_nm[i][0] || - arg[1] != dev_nm[i][1]; i++) - if (i == NDEV - 1) - return -1; - dsk.type = i; - arg += 3; - dsk.unit = *arg - '0'; - if (arg[1] != ',' || dsk.unit > 9) - return -1; - arg += 2; - dsk.slice = WHOLE_DISK_SLICE; - if (arg[1] == ',') { - dsk.slice = *arg - '0' + 1; - if (dsk.slice > PC98_NPARTS + 1) - return -1; - arg += 2; + } else { + for (q = arg--; *q && *q != '('; q++); + if (*q) { + drv = -1; + if (arg[1] == ':') { + drv = *arg - '0'; + if (drv > 9) + return (-1); + arg += 2; + } + if (q - arg != 2) + return (-1); + for (i = 0; arg[0] != dev_nm[i][0] || + arg[1] != dev_nm[i][1]; i++) + if (i == NDEV - 1) + return (-1); + dsk.type = i; + arg += 3; + dsk.unit = *arg - '0'; + if (arg[1] != ',' || dsk.unit > 9) + return (-1); + arg += 2; + dsk.slice = WHOLE_DISK_SLICE; + if (arg[1] == ',') { + dsk.slice = *arg - '0' + 1; + if (dsk.slice > PC98_NPARTS + 1) + return (-1); + arg += 2; + } + if (arg[1] != ')') + return (-1); + dsk.part = *arg - 'a'; + if (dsk.part > 7) + return (-1); + arg += 2; + if (drv == -1) + drv = dsk.unit; + dsk.disk = dev_daua[dsk.type]; + dsk.daua = dsk.disk | dsk.unit; + dsk_meta = 0; + } + k = ep - arg; + if (k > 0) { + if (k >= sizeof(knamebuf)) + return (-1); + memcpy(knamebuf, arg, k + 1); + kname = knamebuf; + } } - if (arg[1] != ')') - return -1; - dsk.part = *arg - 'a'; - if (dsk.part > 7) - return (-1); - arg += 2; - if (drv == -1) - drv = dsk.unit; - dsk.disk = dev_daua[dsk.type]; - dsk.daua = dsk.disk | dsk.unit; - dsk_meta = 0; - } - k = ep - arg; - if (k > 0) { - if (k >= sizeof(knamebuf)) - return -1; - memcpy(knamebuf, arg, k + 1); - kname = knamebuf; - } + arg = p; } - arg = p; - } - return 0; + return (0); } static int dskread(void *buf, unsigned lba, unsigned nblk) { - struct pc98_partition *dp; - struct disklabel *d; - char *sec; - unsigned i; - uint8_t sl; - u_char *p; - const char *reason; - - if (!dsk_meta) { - sec = dmadat->secbuf; - set_dsk(); - if (dsk.type == TYPE_FD) - goto unsliced; - if (drvread(sec, PC98_BBSECTOR)) - return -1; - dp = (void *)(sec + PC98_PARTOFF); - sl = dsk.slice; - if (sl < BASE_SLICE) { - for (i = 0; i < PC98_NPARTS; i++) - if (dp[i].dp_mid == DOSMID_386BSD) { - sl = BASE_SLICE + i; - break; + struct pc98_partition *dp; + struct disklabel *d; + char *sec; + unsigned i; + uint8_t sl; + u_char *p; + const char *reason; + + if (!dsk_meta) { + sec = dmadat->secbuf; + set_dsk(); + if (dsk.type == TYPE_FD) + goto unsliced; + if (drvread(sec, PC98_BBSECTOR)) + return -1; + dp = (void *)(sec + PC98_PARTOFF); + sl = dsk.slice; + if (sl < BASE_SLICE) { + for (i = 0; i < PC98_NPARTS; i++) + if (dp[i].dp_mid == DOSMID_386BSD) { + sl = BASE_SLICE + i; + break; + } + dsk.slice = sl; } - dsk.slice = sl; - } - if (sl != WHOLE_DISK_SLICE) { - dp += sl - BASE_SLICE; - if (dp->dp_mid != DOSMID_386BSD) { - reason = "slice"; - goto error; - } - dsk.start = dp->dp_scyl * dsk.head * dsk.sec + - dp->dp_shd * dsk.sec + dp->dp_ssect; + if (sl != WHOLE_DISK_SLICE) { + dp += sl - BASE_SLICE; + if (dp->dp_mid != DOSMID_386BSD) { + reason = "slice"; + goto error; + } + dsk.start = dp->dp_scyl * dsk.head * dsk.sec + + dp->dp_shd * dsk.sec + dp->dp_ssect; + } + if (drvread(sec, dsk.start + LABELSECTOR)) + return -1; + d = (void *)(sec + LABELOFFSET); + if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) { + if (dsk.part != RAW_PART) { + reason = "label"; + goto error; + } + } else { + if (dsk.part >= d->d_npartitions || + !d->d_partitions[dsk.part].p_size) { + reason = "partition"; + goto error; + } + dsk.start += d->d_partitions[dsk.part].p_offset; + dsk.start -= d->d_partitions[RAW_PART].p_offset; + } + unsliced: ; } - if (drvread(sec, dsk.start + LABELSECTOR)) - return -1; - d = (void *)(sec + LABELOFFSET); - if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) { - if (dsk.part != RAW_PART) { - reason = "label"; - goto error; - } - } else { - if (dsk.part >= d->d_npartitions || - !d->d_partitions[dsk.part].p_size) { - reason = "partition"; - goto error; - } - dsk.start += d->d_partitions[dsk.part].p_offset; - dsk.start -= d->d_partitions[RAW_PART].p_offset; + for (p = buf; nblk; p += 512, lba++, nblk--) { + if ((i = drvread(p, dsk.start + lba))) + return (i); } - unsliced: ; - } - for (p = buf; nblk; p += 512, lba++, nblk--) { - if ((i = drvread(p, dsk.start + lba))) - return i; - } - return 0; + return (0); error: - printf("Invalid %s\n", reason); - return -1; + printf("Invalid %s\n", reason); + return (-1); } static void printf(const char *fmt,...) { - va_list ap; - static char buf[10]; - char *s; - unsigned u; - int c; - - va_start(ap, fmt); - while ((c = *fmt++)) { - if (c == '%') { - c = *fmt++; - switch (c) { - case 'c': - putchar(va_arg(ap, int)); - continue; - case 's': - for (s = va_arg(ap, char *); *s; s++) - putchar(*s); - continue; - case 'u': - u = va_arg(ap, unsigned); - s = buf; - do - *s++ = '0' + u % 10U; - while (u /= 10U); - while (--s >= buf) - putchar(*s); - continue; - } + va_list ap; + static char buf[10]; + char *s; + unsigned u; + int c; + + va_start(ap, fmt); + while ((c = *fmt++)) { + if (c == '%') { + c = *fmt++; + switch (c) { + case 'c': + putchar(va_arg(ap, int)); + continue; + case 's': + for (s = va_arg(ap, char *); *s; s++) + putchar(*s); + continue; + case 'u': + u = va_arg(ap, unsigned); + s = buf; + do + *s++ = '0' + u % 10U; + while (u /= 10U); + while (--s >= buf) + putchar(*s); + continue; + } + } + putchar(c); } - putchar(c); - } - va_end(ap); - return; + va_end(ap); + return; } static void putchar(int c) { - if (c == '\n') - xputc('\r'); - xputc(c); + + if (c == '\n') + xputc('\r'); + xputc(c); } static int drvread(void *buf, unsigned lba) { - static unsigned c = 0x2d5c7c2f; - unsigned bpc, x, cyl, head, sec; - - bpc = dsk.sec * dsk.head; - cyl = lba / bpc; - x = lba % bpc; - head = x / dsk.sec; - sec = x % dsk.sec; - - if (!OPT_CHECK(RBX_QUIET)) { - xputc(c = c << 8 | c >> 24); - xputc('\b'); - } - v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; - v86.addr = READORG; /* call to read in boot1 */ - v86.ecx = cyl; - v86.edx = (head << 8) | sec; - v86.edi = lba; - v86.ebx = 512; - v86.es = VTOPSEG(buf); - v86.ebp = VTOPOFF(buf); - v86int(); - v86.ctl = V86_FLAGS; - if (V86_CY(v86.efl)) { - printf("error %u c/h/s %u/%u/%u lba %u\n", v86.eax >> 8 & 0xff, - cyl, head, sec, lba); - return -1; - } - return 0; + static unsigned c = 0x2d5c7c2f; + unsigned bpc, x, cyl, head, sec; + + bpc = dsk.sec * dsk.head; + cyl = lba / bpc; + x = lba % bpc; + head = x / dsk.sec; + sec = x % dsk.sec; + + if (!OPT_CHECK(RBX_QUIET)) { + xputc(c = c << 8 | c >> 24); + xputc('\b'); + } + v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; + v86.addr = READORG; /* call to read in boot1 */ + v86.ecx = cyl; + v86.edx = (head << 8) | sec; + v86.edi = lba; + v86.ebx = 512; + v86.es = VTOPSEG(buf); + v86.ebp = VTOPOFF(buf); + v86int(); + v86.ctl = V86_FLAGS; + if (V86_CY(v86.efl)) { + printf("error %u c/h/s %u/%u/%u lba %u\n", v86.eax >> 8 & 0xff, + cyl, head, sec, lba); + return (-1); + } + return (0); } static inline void delay(void) { - int i; + int i; - i = 800; - do { - outb(0x5f, 0); /* about 600ns */ - } while (--i >= 0); + i = 800; + do { + outb(0x5f, 0); /* about 600ns */ + } while (--i >= 0); } static int keyhit(unsigned sec) { - unsigned i; - - if (OPT_CHECK(RBX_NOINTR)) - return 0; - for (i = 0; i < sec * 1000; i++) { - if (xgetc(1)) - return 1; - delay(); - } - return 0; + unsigned i; + + if (OPT_CHECK(RBX_NOINTR)) + return (0); + for (i = 0; i < sec * 1000; i++) { + if (xgetc(1)) + return (1); + delay(); + } + return (0); } static int xputc(int c) { - if (DO_KBD) - putc(c); - if (DO_SIO) - sio_putc(c); - return c; + + if (DO_KBD) + putc(c); + if (DO_SIO) + sio_putc(c); + return (c); } static int getc(int fn) { - v86.addr = 0x18; - v86.eax = fn << 8; - v86int(); - if (fn) - return (v86.ebx >> 8) & 0x01; - else - return v86.eax & 0xff; + + v86.addr = 0x18; + v86.eax = fn << 8; + v86int(); + if (fn) + return ((v86.ebx >> 8) & 0x01); + else + return (v86.eax & 0xff); } static int xgetc(int fn) { - if (OPT_CHECK(RBX_NOINTR)) - return 0; - for (;;) { - if (DO_KBD && getc(1)) - return fn ? 1 : getc(0); - if (DO_SIO && sio_ischar()) - return fn ? 1 : sio_getc(); - if (fn) - return 0; - } + + if (OPT_CHECK(RBX_NOINTR)) + return (0); + for (;;) { + if (DO_KBD && getc(1)) + return (fn ? 1 : getc(0)); + if (DO_SIO && sio_ischar()) + return (fn ? 1 : sio_getc()); + if (fn) + return (0); + } } diff --git a/stand/pc98/btx/btx/Makefile b/stand/pc98/btx/btx/Makefile index 2755460..113671e 100644 --- a/stand/pc98/btx/btx/Makefile +++ b/stand/pc98/btx/btx/Makefile @@ -1,8 +1,9 @@ # $FreeBSD$ +.include <bsd.init.mk> + PROG= btx INTERNALPROG= -MAN= SRCS= btx.S .if defined(BOOT_BTX_NOHANG) @@ -12,7 +13,7 @@ BOOT_BTX_FLAGS=0x0 .endif CFLAGS+=-DBTX_FLAGS=${BOOT_BTX_FLAGS} -CFLAGS+=-I${.CURDIR}/../../../i386/common +CFLAGS+=-I${BOOTSRC}/i386/common .if defined(BTX_SERIAL) BOOT_COMCONSOLE_PORT?= 0x238 @@ -25,7 +26,7 @@ CFLAGS+=-DBTX_SERIAL -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ ORG= 0x9000 -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include <bsd.prog.mk> diff --git a/stand/pc98/btx/btxldr/Makefile b/stand/pc98/btx/btxldr/Makefile index 47e83a0..6a11276 100644 --- a/stand/pc98/btx/btxldr/Makefile +++ b/stand/pc98/btx/btxldr/Makefile @@ -1,19 +1,20 @@ # $FreeBSD$ +.include <bsd.init.mk> + PROG= btxldr INTERNALPROG= -MAN= SRCS= btxldr.S CFLAGS+=-DLOADER_ADDRESS=${LOADER_ADDRESS} -CFLAGS+=-I${.CURDIR}/../../../i386/common +CFLAGS+=-I${BOOTSRC}/i386/common .if defined(BTXLDR_VERBOSE) CFLAGS+=-DBTXLDR_VERBOSE .endif ORG=${LOADER_ADDRESS} -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include <bsd.prog.mk> diff --git a/stand/pc98/btx/lib/Makefile b/stand/pc98/btx/lib/Makefile index e5876bc..2988f42 100644 --- a/stand/pc98/btx/lib/Makefile +++ b/stand/pc98/btx/lib/Makefile @@ -1,10 +1,11 @@ # $FreeBSD$ +.include <bsd.init.mk> + PROG= crt0.o INTERNALPROG= -MAN= SRCS= btxcsu.S btxsys.s btxv86.s -CFLAGS+=-I${.CURDIR}/../../../i386/common -LDFLAGS=-Wl,-r +CFLAGS+=-I${BOOTSRC}/i386/common +LDFLAGS+=-Wl,-r .include <bsd.prog.mk> diff --git a/stand/pc98/cdboot/Makefile b/stand/pc98/cdboot/Makefile index ba94111..af69cc4 100644 --- a/stand/pc98/cdboot/Makefile +++ b/stand/pc98/cdboot/Makefile @@ -1,16 +1,18 @@ # $FreeBSD$ +.include <bsd.init.mk> + PROG= cdboot STRIP= BINMODE=${NOBINMODE} MAN= SRCS= ${PROG}.S -CFLAGS+=-I${.CURDIR}/../../i386/common +CFLAGS+=-I${BOOTSRC}/i386/common ORG= 0x0000 -LDFLAGS=${LDFLAGS_BIN} +LDFLAGS+=${LDFLAGS_BIN} .include <bsd.prog.mk> diff --git a/stand/pc98/kgzldr/Makefile b/stand/pc98/kgzldr/Makefile index 0070d70..7ab500e 100644 --- a/stand/pc98/kgzldr/Makefile +++ b/stand/pc98/kgzldr/Makefile @@ -1,18 +1,19 @@ # $FreeBSD$ +.include <bsd.init.mk> + PROG= kgzldr.o STRIP= BINMODE=${LIBMODE} BINDIR= ${LIBDIR} -MAN= SRCS= start.s boot.c inflate.c lib.c crt.s sio.s CFLAGS= -Os CFLAGS+=-DKZIP NO_SHARED= -LDFLAGS=-Wl,-r -.PATH: ${.CURDIR}/../../../kern -.PATH: ${.CURDIR}/../../i386/kgzldr +LDFLAGS+=-Wl,-r +.PATH: ${SYSDIR}/kern +.PATH: ${BOOTSRC}/i386/kgzldr BOOT_COMCONSOLE_PORT?= 0x238 AFLAGS+=--defsym SIO_PRT=${BOOT_COMCONSOLE_PORT} diff --git a/stand/pc98/libpc98/Makefile b/stand/pc98/libpc98/Makefile index f3e27a4..493fc37 100644 --- a/stand/pc98/libpc98/Makefile +++ b/stand/pc98/libpc98/Makefile @@ -1,25 +1,20 @@ # $FreeBSD$ # + +.include <bsd.init.mk> + LIB= pc98 -INTERNALLIB= -.PATH: ${.CURDIR}/../../i386/libi386 +.PATH: ${BOOTSRC}/i386/libi386 SRCS= bioscd.c biosdisk.c biosmem.c biospnp.c \ biospci.c biossmap.c bootinfo.c bootinfo32.c \ comconsole.c devicename.c elf32_freebsd.c \ i386_copy.c i386_module.c nullconsole.c pc98_sys.c pxe.c pxetramp.s \ time.c vidconsole.c -.PATH: ${.CURDIR}/../../zfs +.PATH: ${BOOTSRC}/zfs SRCS+= devicename_stubs.c -# Enable PXE TFTP or NFS support, not both. -.if defined(LOADER_TFTP_SUPPORT) -CFLAGS+= -DLOADER_TFTP_SUPPORT -.else -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif - BOOT_COMCONSOLE_PORT?= 0x238 CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT} @@ -37,13 +32,11 @@ CFLAGS+= -DTERM_EMU # XXX: make alloca() useable CFLAGS+= -Dalloca=__builtin_alloca -CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 \ - -I${.CURDIR}/../../common \ - -I${.CURDIR}/../btx/lib \ - -I${.CURDIR}/../../i386/libi386 \ - -I${.CURDIR}/../../.. -I. -# the location of libstand -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ +CFLAGS+= -I${BOOTSRC}/ficl -I${BOOTSRC}/ficl/i386 \ + -I${LDRSRC} -I${BOOTSRC}/common \ + -I${BOOTSRC}/pc98/btx/lib \ + -I${BOOTSRC}/i386/libi386 \ + -I${SYSDIR} # Handle FreeBSD specific %b and %D printf format specifiers CFLAGS+= ${FORMAT_EXTENSIONS} diff --git a/stand/pc98/libpc98/bioscd.c b/stand/pc98/libpc98/bioscd.c index f259701..1ef14f7 100644 --- a/stand/pc98/libpc98/bioscd.c +++ b/stand/pc98/libpc98/bioscd.c @@ -89,14 +89,14 @@ static struct bcinfo { } bcinfo [MAXBCDEV]; static int nbcinfo = 0; -#define BC(dev) (bcinfo[(dev)->d_unit]) +#define BC(dev) (bcinfo[(dev)->dd.d_unit]) static int bc_read(int unit, daddr_t dblk, int blks, caddr_t dest); static int bc_init(void); static int bc_strategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); + size_t size, char *buf, size_t *rsize); static int bc_realstrategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); + size_t size, char *buf, size_t *rsize); static int bc_open(struct open_file *f, ...); static int bc_close(struct open_file *f); static int bc_print(int verbose); @@ -207,7 +207,7 @@ bc_open(struct open_file *f, ...) va_start(ap, f); dev = va_arg(ap, struct i386_devdesc *); va_end(ap); - if (dev->d_unit >= nbcinfo) { + if (dev->dd.d_unit >= nbcinfo) { DEBUG("attempt to open nonexistent disk"); return(ENXIO); } @@ -267,7 +267,7 @@ bc_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, if (rw != F_READ) return(EROFS); dev = (struct i386_devdesc *)devdata; - unit = dev->d_unit; + unit = dev->dd.d_unit; blks = size / BIOSCD_SECSIZE; if (dblk % (BIOSCD_SECSIZE / DEV_BSIZE) != 0) return (EINVAL); @@ -397,7 +397,7 @@ bc_getdev(struct i386_devdesc *dev) int major; int rootdev; - unit = dev->d_unit; + unit = dev->dd.d_unit; biosdev = bc_unit2bios(unit); DEBUG("unit %d BIOS device %d", unit, biosdev); if (biosdev == -1) /* not a BIOS device */ diff --git a/stand/pc98/libpc98/biosdisk.c b/stand/pc98/libpc98/biosdisk.c index 86a550d..0d7ac6f 100644 --- a/stand/pc98/libpc98/biosdisk.c +++ b/stand/pc98/libpc98/biosdisk.c @@ -92,49 +92,48 @@ struct open_disk { */ static struct bdinfo { - int bd_unit; /* BIOS unit number */ - int bd_flags; - int bd_type; /* BIOS 'drive type' (floppy only) */ - int bd_da_unit; /* kernel unit number for da */ - int bd_open; /* reference counter */ - void *bd_bcache; /* buffer cache data */ + int bd_unit; /* BIOS unit number */ + int bd_flags; + int bd_type; /* BIOS 'drive type' (floppy only) */ + int bd_da_unit; /* kernel unit number for da */ + int bd_open; /* reference counter */ + void *bd_bcache; /* buffer cache data */ } bdinfo [MAXBDDEV]; static int nbdinfo = 0; -#define BD(dev) (bdinfo[(dev)->d_unit]) - -static int bd_getgeom(struct open_disk *od); -static int bd_read(struct open_disk *od, daddr_t dblk, int blks, - caddr_t dest); -static int bd_write(struct open_disk *od, daddr_t dblk, int blks, - caddr_t dest); - -static int bd_int13probe(struct bdinfo *bd); - -static int bd_printslice(struct open_disk *od, struct pc98_partition *dp, - char *prefix, int verbose); -static int bd_printbsdslice(struct open_disk *od, daddr_t offset, - char *prefix, int verbose); - -static int bd_init(void); -static int bd_strategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); -static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); -static int bd_open(struct open_file *f, ...); -static int bd_close(struct open_file *f); -static int bd_print(int verbose); +#define BD(dev) (bdinfo[(dev)->dd.d_unit]) + +static int bd_getgeom(struct open_disk *od); +static int bd_read(struct open_disk *od, daddr_t dblk, int blks, + caddr_t dest); +static int bd_write(struct open_disk *od, daddr_t dblk, int blks, + caddr_t dest); +static int bd_int13probe(struct bdinfo *bd); + +static int bd_printslice(struct open_disk *od, struct pc98_partition *dp, + char *prefix, int verbose); +static int bd_printbsdslice(struct open_disk *od, daddr_t offset, + char *prefix, int verbose); + +static int bd_init(void); +static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, + char *buf, size_t *rsize); +static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size, + char *buf, size_t *rsize); +static int bd_open(struct open_file *f, ...); +static int bd_close(struct open_file *f); +static int bd_print(int verbose); struct devsw biosdisk = { - "disk", - DEVT_DISK, - bd_init, - bd_strategy, - bd_open, - bd_close, - noioctl, - bd_print, - NULL + "disk", + DEVT_DISK, + bd_init, + bd_strategy, + bd_open, + bd_close, + noioctl, + bd_print, + NULL }; static int bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev); @@ -149,70 +148,78 @@ static void bd_checkextended(struct open_disk *od, int slicenum); int bd_bios2unit(int biosdev) { - int i; - - DEBUG("looking for bios device 0x%x", biosdev); - for (i = 0; i < nbdinfo; i++) { - DEBUG("bd unit %d is BIOS device 0x%x", i, bdinfo[i].bd_unit); - if (bdinfo[i].bd_unit == biosdev) - return(i); - } - return(-1); + int i; + + DEBUG("looking for bios device 0x%x", biosdev); + for (i = 0; i < nbdinfo; i++) { + DEBUG("bd unit %d is BIOS device 0x%x", i, bdinfo[i].bd_unit); + if (bdinfo[i].bd_unit == biosdev) + return (i); + } + return (-1); } int bd_unit2bios(int unit) { - if ((unit >= 0) && (unit < nbdinfo)) - return(bdinfo[unit].bd_unit); - return(-1); + + if ((unit >= 0) && (unit < nbdinfo)) + return (bdinfo[unit].bd_unit); + return (-1); } -/* +/* * Quiz the BIOS for disk devices, save a little info about them. */ static int -bd_init(void) +bd_init(void) { - int base, unit; - int da_drive=0, n=-0x10; - - /* sequence 0x90, 0x80, 0xa0 */ - for (base = 0x90; base <= 0xa0; base += n, n += 0x30) { - for (unit = base; (nbdinfo < MAXBDDEV) || ((unit & 0x0f) < 4); unit++) { - bdinfo[nbdinfo].bd_open = 0; - bdinfo[nbdinfo].bd_bcache = NULL; - bdinfo[nbdinfo].bd_unit = unit; - bdinfo[nbdinfo].bd_flags = (unit & 0xf0) == 0x90 ? BD_FLOPPY : 0; - - if (!bd_int13probe(&bdinfo[nbdinfo])){ - if (((unit & 0xf0) == 0x90 && (unit & 0x0f) < 4) || - ((unit & 0xf0) == 0xa0 && (unit & 0x0f) < 6)) - continue; /* Target IDs are not contiguous. */ - else - break; - } + int base, unit; + int da_drive=0, n=-0x10; + + /* sequence 0x90, 0x80, 0xa0 */ + for (base = 0x90; base <= 0xa0; base += n, n += 0x30) { + for (unit = base; (nbdinfo < MAXBDDEV) || ((unit & 0x0f) < 4); + unit++) { + bdinfo[nbdinfo].bd_open = 0; + bdinfo[nbdinfo].bd_bcache = NULL; + bdinfo[nbdinfo].bd_unit = unit; + bdinfo[nbdinfo].bd_flags = + (unit & 0xf0) == 0x90 ? BD_FLOPPY : 0; + if (!bd_int13probe(&bdinfo[nbdinfo])) { + if (((unit & 0xf0) == 0x90 && + (unit & 0x0f) < 4) || + ((unit & 0xf0) == 0xa0 && + (unit & 0x0f) < 6)) + /* Target IDs are not contiguous. */ + continue; + else + break; + } - if (bdinfo[nbdinfo].bd_flags & BD_FLOPPY){ - /* available 1.44MB access? */ - if (*(u_char *)PTOV(0xA15AE) & (1<<(unit & 0xf))) { - /* boot media 1.2MB FD? */ - if ((*(u_char *)PTOV(0xA1584) & 0xf0) != 0x90) - bdinfo[nbdinfo].bd_unit = 0x30 + (unit & 0xf); + if (bdinfo[nbdinfo].bd_flags & BD_FLOPPY) { + /* available 1.44MB access? */ + if (*(u_char *)PTOV(0xA15AE) & + (1<<(unit & 0xf))) { + /* boot media 1.2MB FD? */ + if ((*(u_char *)PTOV(0xA1584) & + 0xf0) != 0x90) + bdinfo[nbdinfo].bd_unit = + 0x30 + (unit & 0xf); + } + } else { + if ((unit & 0xF0) == 0xA0) /* SCSI HD or MO */ + bdinfo[nbdinfo].bd_da_unit = + da_drive++; + } + /* XXX we need "disk aliases" to make this simpler */ + printf("BIOS drive %c: is disk%d\n", + 'A' + nbdinfo, nbdinfo); + nbdinfo++; } - } - else { - if ((unit & 0xF0) == 0xA0) /* SCSI HD or MO */ - bdinfo[nbdinfo].bd_da_unit = da_drive++; - } - /* XXX we need "disk aliases" to make this simpler */ - printf("BIOS drive %c: is disk%d\n", - 'A' + nbdinfo, nbdinfo); - nbdinfo++; } - } - bcache_add_dev(nbdinfo); - return(0); + bcache_add_dev(nbdinfo); + return(0); } /* @@ -221,29 +228,30 @@ bd_init(void) static int bd_int13probe(struct bdinfo *bd) { - int addr; + int addr; - if (bd->bd_flags & BD_FLOPPY) { - addr = 0xa155c; - } else { - if ((bd->bd_unit & 0xf0) == 0x80) - addr = 0xa155d; - else - addr = 0xa1482; - } - if ( *(u_char *)PTOV(addr) & (1<<(bd->bd_unit & 0x0f))) { - bd->bd_flags |= BD_MODEINT13; - return(1); - } - if ((bd->bd_unit & 0xF0) == 0xA0) { - int media = ((unsigned *)PTOV(0xA1460))[bd->bd_unit & 0x0F] & 0x1F; + if (bd->bd_flags & BD_FLOPPY) { + addr = 0xa155c; + } else { + if ((bd->bd_unit & 0xf0) == 0x80) + addr = 0xa155d; + else + addr = 0xa1482; + } + if ( *(u_char *)PTOV(addr) & (1<<(bd->bd_unit & 0x0f))) { + bd->bd_flags |= BD_MODEINT13; + return (1); + } + if ((bd->bd_unit & 0xF0) == 0xA0) { + int media = + ((unsigned *)PTOV(0xA1460))[bd->bd_unit & 0x0F] & 0x1F; - if (media == 7) { /* MO */ - bd->bd_flags |= BD_MODEINT13 | BD_OPTICAL; - return(1); + if (media == 7) { /* MO */ + bd->bd_flags |= BD_MODEINT13 | BD_OPTICAL; + return(1); + } } - } - return(0); + return (0); } /* @@ -252,72 +260,74 @@ bd_int13probe(struct bdinfo *bd) static int bd_print(int verbose) { - int i, j, ret = 0; - char line[80]; - struct i386_devdesc dev; - struct open_disk *od; - struct pc98_partition *dptr; + int i, j, ret = 0; + char line[80]; + struct i386_devdesc dev; + struct open_disk *od; + struct pc98_partition *dptr; - if (nbdinfo == 0) - return (0); - - printf("%s devices:", biosdisk.dv_name); - if ((ret = pager_output("\n")) != 0) - return (ret); - - for (i = 0; i < nbdinfo; i++) { - snprintf(line, sizeof(line), " disk%d: BIOS drive %c:\n", - i, 'A' + i); - if ((ret = pager_output(line)) != 0) - break; - - /* try to open the whole disk */ - dev.d_unit = i; - dev.d_kind.biosdisk.slice = -1; - dev.d_kind.biosdisk.partition = -1; - - if (!bd_opendisk(&od, &dev)) { + if (nbdinfo == 0) + return (0); - /* Do we have a partition table? */ - if (od->od_flags & BD_PARTTABOK) { - dptr = &od->od_slicetab[0]; + printf("%s devices:", biosdisk.dv_name); + if ((ret = pager_output("\n")) != 0) + return (ret); - /* Check for a "dedicated" disk */ - for (j = 0; j < od->od_nslices; j++) { - snprintf(line, sizeof(line), " disk%ds%d", i, j + 1); - if ((ret = bd_printslice(od, &dptr[j], line, verbose)) != 0) + for (i = 0; i < nbdinfo; i++) { + snprintf(line, sizeof(line), " disk%d: BIOS drive %c:\n", + i, 'A' + i); + if ((ret = pager_output(line)) != 0) break; + + /* try to open the whole disk */ + dev.dd.d_unit = i; + dev.d_kind.biosdisk.slice = -1; + dev.d_kind.biosdisk.partition = -1; + + if (!bd_opendisk(&od, &dev)) { + + /* Do we have a partition table? */ + if (od->od_flags & BD_PARTTABOK) { + dptr = &od->od_slicetab[0]; + + /* Check for a "dedicated" disk */ + for (j = 0; j < od->od_nslices; j++) { + snprintf(line, sizeof(line), + " disk%ds%d", i, j + 1); + if ((ret = bd_printslice(od, &dptr[j], + line, verbose)) != 0) + break; + } + } + bd_closedisk(od); + if (ret != 0) + break; } - } - bd_closedisk(od); - if (ret != 0) - break; } - } - return (ret); + return (ret); } /* Given a size in 512 byte sectors, convert it to a human-readable number. */ static char * display_size(uint64_t size) { - static char buf[80]; - char unit; - - size /= 2; - unit = 'K'; - if (size >= 10485760000LL) { - size /= 1073741824; - unit = 'T'; - } else if (size >= 10240000) { - size /= 1048576; - unit = 'G'; - } else if (size >= 10000) { - size /= 1024; - unit = 'M'; - } - sprintf(buf, "%6ld%cB", (long)size, unit); - return (buf); + static char buf[80]; + char unit; + + size /= 2; + unit = 'K'; + if (size >= 10485760000LL) { + size /= 1073741824; + unit = 'T'; + } else if (size >= 10240000) { + size /= 1048576; + unit = 'G'; + } else if (size >= 10000) { + size /= 1024; + unit = 'M'; + } + sprintf(buf, "%6ld%cB", (long)size, unit); + return (buf); } /* @@ -465,7 +475,7 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev) struct open_disk *od; int error; - if (dev->d_unit >= nbdinfo) { + if (dev->dd.d_unit >= nbdinfo) { DEBUG("attempt to open nonexistent disk"); return(ENXIO); } @@ -477,13 +487,13 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev) } /* Look up BIOS unit number, intialise open_disk structure */ - od->od_dkunit = dev->d_unit; + od->od_dkunit = dev->dd.d_unit; od->od_unit = bdinfo[od->od_dkunit].bd_unit; od->od_flags = bdinfo[od->od_dkunit].bd_flags; od->od_boff = 0; error = 0; DEBUG("open '%s', unit 0x%x slice %d partition %d", - i386_fmtdev(dev), dev->d_unit, + i386_fmtdev(dev), dev->dd.d_unit, dev->d_kind.biosdisk.slice, dev->d_kind.biosdisk.partition); /* Get geometry for this open (removable device may have changed) */ @@ -760,8 +770,8 @@ bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, } static int -bd_realstrategy(void *devdata, int rw, daddr_t dblk, - size_t size, char *buf, size_t *rsize) +bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, + char *buf, size_t *rsize) { struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data); int blks; @@ -1066,8 +1076,8 @@ bd_getdev(struct i386_devdesc *dev) char *nip, *cp; int unitofs = 0, i, unit; - biosdev = bd_unit2bios(dev->d_unit); - DEBUG("unit %d BIOS device %d", dev->d_unit, biosdev); + biosdev = bd_unit2bios(dev->dd.d_unit); + DEBUG("unit %d BIOS device %d", dev->dd.d_unit, biosdev); if (biosdev == -1) /* not a BIOS device */ return(-1); if (bd_opendisk(&od, dev) != 0) /* oops, not a viable device */ @@ -1075,7 +1085,7 @@ bd_getdev(struct i386_devdesc *dev) if ((biosdev & 0xf0) == 0x90 || (biosdev & 0xf0) == 0x30) { /* floppy (or emulated floppy) or ATAPI device */ - if (bdinfo[dev->d_unit].bd_type == DT_ATAPI) { + if (bdinfo[dev->dd.d_unit].bd_type == DT_ATAPI) { /* is an ATAPI disk */ major = WFDMAJOR; } else { @@ -1101,7 +1111,7 @@ bd_getdev(struct i386_devdesc *dev) } /* default root disk unit number */ if ((biosdev & 0xf0) == 0xa0) - unit = bdinfo[dev->d_unit].bd_da_unit; + unit = bdinfo[dev->dd.d_unit].bd_da_unit; else unit = biosdev & 0xf; diff --git a/stand/pc98/loader/Makefile b/stand/pc98/loader/Makefile index d75e8d0..8c03fc3 100644 --- a/stand/pc98/loader/Makefile +++ b/stand/pc98/loader/Makefile @@ -1,25 +1,17 @@ # $FreeBSD$ -.include <src.opts.mk> -MK_SSP= no -MAN= - LOADER?= loader PROG= ${LOADER}.sym -INTERNALPROG= NEWVERSWHAT= "bootstrap loader" pc98 -VERSION_FILE= ${.CURDIR}/../../i386/loader/version +VERSION_FILE= ${BOOTSRC}/i386/loader/version + +LOADER_NET_SUPPORT= yes + +.include <bsd.init.mk> # architecture-specific loader code SRCS= main.c conf.c vers.c -.PATH: ${.CURDIR}/../../i386/loader - -# Enable PXE TFTP or NFS support, not both. -.if defined(LOADER_TFTP_SUPPORT) -CFLAGS+= -DLOADER_TFTP_SUPPORT -.else -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif +.PATH: ${BOOTSRC}/i386/loader # Include bcache code. HAVE_BCACHE= yes @@ -28,37 +20,18 @@ HAVE_BCACHE= yes HAVE_PNP= yes HAVE_ISABUS= yes -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - -.if defined(LOADER_BZIP2_SUPPORT) -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if !defined(LOADER_NO_GZIP_SUPPORT) -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif - # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -CFLAGS+= -I${.CURDIR}/../../i386 -CFLAGS+= -I. +.include "${BOOTSRC}/loader.mk" -CLEANFILES= ${LOADER} ${LOADER}.bin loader.help +CLEANFILES+= ${LOADER} ${LOADER}.bin loader.help CFLAGS+= -Wall -LDFLAGS= -static -Ttext 0x0 +LDFLAGS+= -static -Ttext 0x0 +CFLAGS+= -I${BOOTSRC} -I${BOOTSRC}/i386 # pc98 standalone support library -LIBPC98= ${.OBJDIR}/../libpc98/libpc98.a -CFLAGS+= -I${.CURDIR}/.. - -LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a +LIBPC98= ${BOOTOBJ}/pc98/libpc98/libpc98.a +CFLAGS+= -I${BOOTSRC}/pc98 # BTX components CFLAGS+= -I${.CURDIR}/../btx/lib @@ -67,9 +40,6 @@ CFLAGS+= -I${.CURDIR}/../btx/lib #CFLAGS+= -g #LDFLAGS+= -g -# Pick up ../Makefile.inc early. -.include <bsd.init.mk> - ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN} btxld -v -f aout -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \ -b ${BTXKERN} ${LOADER}.bin @@ -79,21 +49,16 @@ ${LOADER}.bin: ${LOADER}.sym strip -R .comment -R .note ${.TARGET} loader.help: help.common help.pc98 - cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + cat ${.ALLSRC} | awk -f ${BOOTSRC}/common/merge_help.awk > ${.TARGET} FILES= ${LOADER} # XXX INSTALLFLAGS_loader= -b FILESMODE_${LOADER}= ${BINMODE} -b -.PATH: ${.CURDIR}/../../forth -.include "${.CURDIR}/../../forth/Makefile.inc" - -FILES+= ${.CURDIR}/../../i386/loader/loader.rc menu.rc - # XXX crt0.o needs to be first for pxeboot(8) to work OBJS= ${BTXCRT} -DPADD= ${LIBFICL} ${LIBPC98} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBPC98} ${LIBSTAND} +DPADD= ${LDR_INTERP} ${LIBPC98} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBPC98} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/pc98/loader/main.c b/stand/pc98/loader/main.c index c31cc84..47bace6 100644 --- a/stand/pc98/loader/main.c +++ b/stand/pc98/loader/main.c @@ -191,7 +191,7 @@ main(void) extract_currdev(); /* set $currdev and $loaddev */ setenv("LINES", "24", 1); /* optional */ - interact(NULL); /* doesn't return */ + interact(); /* doesn't return */ /* if we ever get here, it is an error */ return (1); @@ -211,18 +211,18 @@ extract_currdev(void) int biosdev = -1; /* Assume we are booting from a BIOS disk by default */ - new_currdev.d_dev = &biosdisk; + new_currdev.dd.d_dev = &biosdisk; /* new-style boot loaders such as pxeldr and cdldr */ if (kargs->bootinfo == 0) { if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) { /* we are booting from a CD with cdboot */ - new_currdev.d_dev = &bioscd; - new_currdev.d_unit = bc_bios2unit(initial_bootdev); + new_currdev.dd.d_dev = &bioscd; + new_currdev.dd.d_unit = bc_bios2unit(initial_bootdev); } else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) { /* we are booting from pxeldr */ - new_currdev.d_dev = &pxedisk; - new_currdev.d_unit = 0; + new_currdev.dd.d_dev = &pxedisk; + new_currdev.dd.d_unit = 0; } else { /* we don't know what our boot device is */ new_currdev.d_kind.biosdisk.slice = -1; @@ -253,17 +253,17 @@ extract_currdev(void) biosdev = (major << 3) + 0x80 + B_UNIT(initial_bootdev); } } - new_currdev.d_type = new_currdev.d_dev->dv_type; + new_currdev.dd.d_type = new_currdev.dd.d_dev->dv_type; /* * If we are booting off of a BIOS disk and we didn't succeed in determining * which one we booted off of, just use disk0: as a reasonable default. */ - if ((new_currdev.d_type == biosdisk.dv_type) && - ((new_currdev.d_unit = bd_bios2unit(biosdev)) == -1)) { + if ((new_currdev.dd.d_type == biosdisk.dv_type) && + ((new_currdev.dd.d_unit = bd_bios2unit(biosdev)) == -1)) { printf("Can't work out which disk we are booting from.\n" "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev); - new_currdev.d_unit = 0; + new_currdev.dd.d_unit = 0; } env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev), diff --git a/stand/pc98/pc98boot/Makefile b/stand/pc98/pc98boot/Makefile index f33b15f..0787a56 100644 --- a/stand/pc98/pc98boot/Makefile +++ b/stand/pc98/pc98boot/Makefile @@ -1,19 +1,21 @@ # $FreeBSD$ +.include <bsd.init.mk> + FILES= ${BOOT} -CLEANFILES= ${BOOT} ${BOOT}.part +CLEANFILES+= ${BOOT} ${BOOT}.part BOOT= pc98boot -.if exists(${.OBJDIR}/../boot0) -BOOT0= ${.OBJDIR}/../boot0/boot0 +.if exists(${BOOTOBJ}/pc98/boot0) +BOOT0= ${BOOTOBJ}/pc98/boot0/boot0 .else -BOOT0= ${.CURDIR}/../boot0/boot0 +BOOT0= ${BOOTSRC}/pc98/boot0/boot0 .endif -.if exists(${.OBJDIR}/../boot0.5) -BOOT05= ${.OBJDIR}/../boot0.5/boot0.5 +.if exists(${BOOTOBJ}/pc98/boot0.5) +BOOT05= ${BOOTOBJ}/pc98/boot0.5/boot0.5 .else -BOOT05= ${.CURDIR}/../boot0.5/boot0.5 +BOOT05= ${BOOTSRC}/pc98/boot0.5/boot0.5 .endif ${BOOT}: ${BOOT0} ${BOOT05} ${BOOT}.part diff --git a/stand/powerpc/Makefile b/stand/powerpc/Makefile index c8bbb17..ca528fb 100644 --- a/stand/powerpc/Makefile +++ b/stand/powerpc/Makefile @@ -1,10 +1,10 @@ # $FreeBSD$ +NO_OBJ=t + .include <bsd.init.mk> -SUBDIR= boot1.chrp ofw uboot -.if ${MK_FDT} == "yes" -SUBDIR+= kboot -.endif +SUBDIR.yes= boot1.chrp ofw uboot +SUBDIR.${MK_FDT}+= kboot .include <bsd.subdir.mk> diff --git a/stand/powerpc/boot1.chrp/boot1.c b/stand/powerpc/boot1.chrp/boot1.c index e73186a..5e54c95 100644 --- a/stand/powerpc/boot1.chrp/boot1.c +++ b/stand/powerpc/boot1.chrp/boot1.c @@ -54,7 +54,7 @@ int main(int ac, char **av); static void exit(int) __dead2; static void load(const char *); -static int dskread(void *, u_int64_t, int); +static int dskread(void *, uint64_t, int); static void usage(void); @@ -79,8 +79,8 @@ static char *__ultoa(char *buf, u_long val, int base); /* * Open Firmware interface functions */ -typedef u_int32_t ofwcell_t; -typedef u_int32_t u_ofwh_t; +typedef uint32_t ofwcell_t; +typedef uint32_t u_ofwh_t; typedef int (*ofwfp_t)(void *); ofwfp_t ofw; /* the prom Open Firmware entry */ ofwh_t chosenh; @@ -94,7 +94,7 @@ static int ofw_setprop(ofwh_t, const char *, void *, size_t); static int ofw_read(ofwh_t, void *, size_t); static int ofw_write(ofwh_t, const void *, size_t); static int ofw_claim(void *virt, size_t len, u_int align); -static int ofw_seek(ofwh_t, u_int64_t); +static int ofw_seek(ofwh_t, uint64_t); static void ofw_exit(void) __dead2; ofwh_t bootdevh; @@ -322,7 +322,7 @@ ofw_write(ofwh_t devh, const void *buf, size_t len) } static int -ofw_seek(ofwh_t devh, u_int64_t off) +ofw_seek(ofwh_t devh, uint64_t off) { ofwcell_t args[] = { (ofwcell_t)"seek", @@ -541,7 +541,7 @@ load(const char *fname) } static int -dskread(void *buf, u_int64_t lba, int nblk) +dskread(void *buf, uint64_t lba, int nblk) { /* * The Open Firmware should open the correct partition for us. diff --git a/stand/powerpc/kboot/Makefile b/stand/powerpc/kboot/Makefile index d5b2025..8a6a0de 100644 --- a/stand/powerpc/kboot/Makefile +++ b/stand/powerpc/kboot/Makefile @@ -17,7 +17,7 @@ NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH} INSTALLFLAGS= -b # Architecture-specific loader code -SRCS= conf.c metadata.c vers.c main.c ppc64_elf_freebsd.c +SRCS= conf.c vers.c main.c ppc64_elf_freebsd.c SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c SRCS+= ucmpdi2.c diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c index d4f59ab..587968f 100644 --- a/stand/powerpc/kboot/main.c +++ b/stand/powerpc/kboot/main.c @@ -291,6 +291,7 @@ main(int argc, const char **argv) setenv("currdev", bootdev, 1); setenv("loaddev", bootdev, 1); setenv("LINES", "24", 1); + setenv("usefdt", "1", 1); interact(); /* doesn't return */ diff --git a/stand/powerpc/kboot/metadata.c b/stand/powerpc/kboot/metadata.c deleted file mode 100644 index 2892ce506..0000000 --- a/stand/powerpc/kboot/metadata.c +++ /dev/null @@ -1,348 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * from: FreeBSD: src/sys/boot/sparc64/loader/metadata.c,v 1.6 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <sys/param.h> -#include <sys/endian.h> -#include <sys/reboot.h> -#include <sys/linker.h> -#include <sys/boot.h> -#include <fdt_platform.h> - -#include <machine/metadata.h> - -#include "bootstrap.h" - -int -md_getboothowto(char *kargs) -{ - char *cp; - int howto; - int active; - int i; - - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - if (!strcmp(getenv("console"), "comconsole")) - howto |= RB_SERIAL; - if (!strcmp(getenv("console"), "nullconsole")) - howto |= RB_MUTE; - return(howto); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -md_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - archsw.arch_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - archsw.arch_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - archsw.arch_copyin("", addr, 1); - addr++; - } - archsw.arch_copyin("", addr, 1); - addr++; - return(addr); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ - -static int align; - -#define COPY32(v, a, c) { \ - u_int32_t x = htobe32(v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c) \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += roundup(strlen(s) + 1, align); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), align); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c);\ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += roundup(mm->md_size, align); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -vm_offset_t -md_copymodules(vm_offset_t addr, int kern64) -{ - struct preloaded_file *fp; - struct file_metadata *md; - uint64_t scratch64; - int c; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - if (kern64) { - scratch64 = fp->f_addr; - MOD_ADDR(addr, scratch64, c); - scratch64 = fp->f_size; - MOD_SIZE(addr, scratch64, c); - } else { - MOD_ADDR(addr, fp->f_addr, c); - MOD_SIZE(addr, fp->f_size, c); - } - for (md = fp->f_metadata; md != NULL; md = md->md_next) { - if (!(md->md_type & MODINFOMD_NOCOPY)) { - MOD_METADATA(addr, md, c); - } - } - } - MOD_END(addr, c); - return(addr); -} - -/* - * Load the information expected by a powerpc kernel. - * - * - The 'boothowto' argument is constructed - * - The 'bootdev' argument is constructed - * - The kernel environment is copied into kernel space. - * - Module metadata are formatted and placed in kernel space. - */ -int -md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) -{ - struct preloaded_file *kfp; - struct preloaded_file *xp; - struct file_metadata *md; - vm_offset_t kernend; - vm_offset_t addr; - vm_offset_t envp; - vm_offset_t fdtp; - vm_offset_t size; - uint64_t scratch64; - uint32_t scratch32; - char *rootdevname; - int howto; - - align = kern64 ? 8 : 4; - howto = htobe32(md_getboothowto(args)); - - /* - * Allow the environment variable 'rootdev' to override the supplied device - * This should perhaps go to MI code and/or have $rootdev tested/set by - * MI code before launching the kernel. - */ - rootdevname = getenv("rootdev"); - if (rootdevname == NULL) - rootdevname = getenv("currdev"); - /* Try reading the /etc/fstab file to select the root device */ - getrootmount(rootdevname); - - /* find the last module in the chain */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; - } - /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - - /* copy our environment */ - envp = addr; - addr = md_copyenv(addr); - - /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - - /* Copy out FDT */ - size = fdt_copy(addr); - *dtb = fdtp = addr; - addr = roundup(addr + size, PAGE_SIZE); - - kernend = 0; - kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - panic("can't find kernel file"); - file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); - if (kern64) { - scratch64 = htobe64(envp); - file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64); - scratch64 = htobe64(fdtp); - file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch64, &scratch64); - scratch64 = htobe64(kernend); - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64); - } else { - scratch32 = htobe32(envp); - file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch32, &scratch32); - scratch32 = htobe32(fdtp); - file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch32, &scratch32); - scratch32 = htobe32(kernend); - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch32, &scratch32); - } - - *modulep = addr; - size = md_copymodules(0, kern64); - kernend = roundup(addr + size, PAGE_SIZE); - - md = file_findmetadata(kfp, MODINFOMD_KERNEND); - if (kern64) { - scratch64 = htobe64(kernend); - bcopy(&scratch64, md->md_data, sizeof scratch64); - } else { - bcopy(&kernend, md->md_data, sizeof kernend); - } - - (void)md_copymodules(addr, kern64); - - return(0); -} - -int -md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb) -{ - return (md_load_dual(args, modulep, dtb, 0)); -} - -int -md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb) -{ - return (md_load_dual(args, modulep, dtb, 1)); -} - diff --git a/stand/powerpc/kboot/ppc64_elf_freebsd.c b/stand/powerpc/kboot/ppc64_elf_freebsd.c index 9547077..adbdc7f 100644 --- a/stand/powerpc/kboot/ppc64_elf_freebsd.c +++ b/stand/powerpc/kboot/ppc64_elf_freebsd.c @@ -57,7 +57,7 @@ struct trampoline_data { vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); int -ppc64_elf_loadfile(char *filename, u_int64_t dest, +ppc64_elf_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { int r; diff --git a/stand/powerpc/ofw/Makefile b/stand/powerpc/ofw/Makefile index ce24844..de5d5e0 100644 --- a/stand/powerpc/ofw/Makefile +++ b/stand/powerpc/ofw/Makefile @@ -17,7 +17,7 @@ NEWVERSWHAT= "Open Firmware loader" ${MACHINE_ARCH} INSTALLFLAGS= -b # Architecture-specific loader code -SRCS= conf.c metadata.c vers.c start.c +SRCS= conf.c vers.c main.c elf_freebsd.c ppc64_elf_freebsd.c start.c SRCS+= ucmpdi2.c .include "${BOOTSRC}/fdt.mk" @@ -38,10 +38,6 @@ CFLAGS+= -DRELOC=${RELOC} LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc -# Pull in common loader code -.PATH: ${BOOTSRC}/ofw/common -.include "${BOOTSRC}/ofw/common/Makefile.inc" - # Open Firmware standalone support library LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a CFLAGS+= -I${BOOTSRC}/ofw/libofw diff --git a/stand/powerpc/ofw/conf.c b/stand/powerpc/ofw/conf.c index 7cad372..ac815bf 100644 --- a/stand/powerpc/ofw/conf.c +++ b/stand/powerpc/ofw/conf.c @@ -97,6 +97,9 @@ struct netif_driver *netif_drivers[] = { * rather than reading the file go first. */ +struct file_format ofw_elf; +struct file_format ofw_elf64; + struct file_format *file_formats[] = { &ofw_elf, &ofw_elf64, diff --git a/stand/ofw/libofw/elf_freebsd.c b/stand/powerpc/ofw/elf_freebsd.c index 456b0cd..7693306 100644 --- a/stand/ofw/libofw/elf_freebsd.c +++ b/stand/powerpc/ofw/elf_freebsd.c @@ -46,7 +46,7 @@ extern char end[]; extern vm_offset_t reloc; /* From <arch>/conf.c */ int -__elfN(ofw_loadfile)(char *filename, u_int64_t dest, +__elfN(ofw_loadfile)(char *filename, uint64_t dest, struct preloaded_file **result) { int r; @@ -89,8 +89,8 @@ __elfN(ofw_exec)(struct preloaded_file *fp) dev_cleanup(); if (dtbp != 0) { OF_quiesce(); - ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0, - (void *)mdp, sizeof(mdp)); + ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, + 0, 0, (void *)mdp, 0xfb5d104d); } else { OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, (void *)mdp, 0xfb5d104d); diff --git a/stand/ofw/common/main.c b/stand/powerpc/ofw/main.c index b8c7a17..785c61b 100644 --- a/stand/ofw/common/main.c +++ b/stand/powerpc/ofw/main.c @@ -33,12 +33,14 @@ __FBSDID("$FreeBSD$"); #include "libofw.h" #include "bootstrap.h" +#include <machine/psl.h> + struct arch_switch archsw; /* MI/MD interface boundary */ extern char end[]; extern char bootprog_info[]; -u_int32_t acells, scells; +uint32_t acells, scells; static char bootargs[128]; @@ -47,6 +49,16 @@ static char heap[HEAP_SIZE]; // In BSS, so uses no space #define OF_puts(fd, text) OF_write(fd, text, strlen(text)) +static __inline register_t +mfmsr(void) +{ + register_t value; + + __asm __volatile ("mfmsr %0" : "=r"(value)); + + return (value); +} + void init_heap(void) { @@ -61,7 +73,7 @@ memsize(void) phandle_t memoryp; cell_t reg[24]; int i, sz; - u_int64_t memsz; + uint64_t memsz; memsz = 0; memoryp = OF_instance_to_package(memory); @@ -145,6 +157,15 @@ main(int (*openfirm)(void *)) env_nounset); setenv("LINES", "24", 1); /* optional */ + /* + * On non-Apple hardware, where it works reliably, pass flattened + * device trees to the kernel by default instead of OF CI pointers. + * Apple hardware is the only virtual-mode OF implementation in + * existence, so far as I am aware, so use that as a flag. + */ + if (!(mfmsr() & PSL_DR)) + setenv("usefdt", "1", 1); + archsw.arch_getdev = ofw_getdev; archsw.arch_copyin = ofw_copyin; archsw.arch_copyout = ofw_copyout; diff --git a/stand/ofw/libofw/ppc64_elf_freebsd.c b/stand/powerpc/ofw/ppc64_elf_freebsd.c index 6d85029..96efb16 100644 --- a/stand/ofw/libofw/ppc64_elf_freebsd.c +++ b/stand/powerpc/ofw/ppc64_elf_freebsd.c @@ -46,7 +46,7 @@ extern char end[]; extern vm_offset_t reloc; /* From <arch>/conf.c */ int -ppc64_ofw_elf_loadfile(char *filename, u_int64_t dest, +ppc64_ofw_elf_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { int r; diff --git a/stand/sparc64/Makefile b/stand/sparc64/Makefile index 6a81a05..94fc677 100644 --- a/stand/sparc64/Makefile +++ b/stand/sparc64/Makefile @@ -1,10 +1,10 @@ # $FreeBSD$ +NO_OBJ=t + .include <bsd.init.mk> -SUBDIR= boot1 loader -.if ${MK_ZFS} != "no" -SUBDIR+=zfsboot zfsloader -.endif +SUBDIR.yes= boot1 loader +SUBDIR.${MK_ZFS}+=zfsboot zfsloader .include <bsd.subdir.mk> diff --git a/stand/sparc64/boot1/boot1.c b/stand/sparc64/boot1/boot1.c index 4724ca1..3a84d23 100644 --- a/stand/sparc64/boot1/boot1.c +++ b/stand/sparc64/boot1/boot1.c @@ -61,7 +61,7 @@ static void bcopy(const void *src, void *dst, size_t len); static void bzero(void *b, size_t len); static int domount(const char *device); -static int dskread(void *buf, u_int64_t lba, int nblk); +static int dskread(void *buf, uint64_t lba, int nblk); static void panic(const char *fmt, ...) __dead2; static int printf(const char *fmt, ...); @@ -78,8 +78,8 @@ static char *__ultoa(char *buf, u_long val, int base); /* * Open Firmware interface functions */ -typedef u_int64_t ofwcell_t; -typedef u_int32_t u_ofwh_t; +typedef uint64_t ofwcell_t; +typedef uint32_t u_ofwh_t; typedef int (*ofwfp_t)(ofwcell_t []); static ofwfp_t ofw; /* the PROM Open Firmware entry */ @@ -89,7 +89,7 @@ static ofwh_t ofw_open(const char *); static int ofw_getprop(ofwh_t, const char *, void *, size_t); static int ofw_read(ofwh_t, void *, size_t); static int ofw_write(ofwh_t, const void *, size_t); -static int ofw_seek(ofwh_t, u_int64_t); +static int ofw_seek(ofwh_t, uint64_t); static void ofw_exit(void) __dead2; static ofwh_t stdinh, stdouth; @@ -251,7 +251,7 @@ ofw_write(ofwh_t devh, const void *buf, size_t len) } static int -ofw_seek(ofwh_t devh, u_int64_t off) +ofw_seek(ofwh_t devh, uint64_t off) { ofwcell_t args[] = { (ofwcell_t)"seek", @@ -515,7 +515,7 @@ domount(const char *device) } static int -dskread(void *buf, u_int64_t lba, int nblk) +dskread(void *buf, uint64_t lba, int nblk) { /* diff --git a/stand/sparc64/loader/Makefile b/stand/sparc64/loader/Makefile index 7f57409..3dea514 100644 --- a/stand/sparc64/loader/Makefile +++ b/stand/sparc64/loader/Makefile @@ -19,9 +19,13 @@ NEWVERSWHAT?= "bootstrap loader" sparc64 VERSION_FILE= ${.CURDIR}/../loader/version INSTALLFLAGS= -b +.if ${MK_ZFS} != "no" +HAVE_ZFS= yes +.endif + # Architecture-specific loader code .PATH: ${BOOTSRC}/sparc64/loader -SRCS= locore.S main.c metadata.c vers.c +SRCS= locore.S main.c vers.c .if ${LOADER_DEBUG} == "yes" CFLAGS+= -DLOADER_DEBUG diff --git a/stand/sparc64/loader/main.c b/stand/sparc64/loader/main.c index 140885d..7c1bf43 100644 --- a/stand/sparc64/loader/main.c +++ b/stand/sparc64/loader/main.c @@ -117,7 +117,7 @@ uint32_t cpu_get_mid_sun4u(void); static void tlb_init_sun4u(void); #ifdef LOADER_DEBUG -typedef u_int64_t tte_t; +typedef uint64_t tte_t; static void pmap_print_tlb_sun4u(void); static void pmap_print_tte_sun4u(tte_t, tte_t); @@ -735,15 +735,6 @@ tlb_init_sun4u(void) #ifdef LOADER_ZFS_SUPPORT -/* Set by sparc64_zfs_probe to provide partition size. */ -static size_t part_size; - -uint64_t -ldi_get_size(void *priv __unused) -{ - return ((uint64_t)part_size); -} - static void sparc64_zfs_probe(void) { @@ -799,7 +790,6 @@ sparc64_zfs_probe(void) if (part == 2 || vtoc.part[part].tag != VTOC_TAG_FREEBSD_ZFS) continue; - part_size = vtoc.map[part].nblks; (void)sprintf(devname, "%s:%c", alias, part + 'a'); /* Get the GUID of the ZFS pool on the boot device. */ if (strcmp(devname, bootpath) == 0) @@ -816,8 +806,7 @@ sparc64_zfs_probe(void) if (guid != 0) { zfs_currdev.pool_guid = guid; zfs_currdev.root_guid = 0; - zfs_currdev.d_dev = &zfs_dev; - zfs_currdev.d_type = zfs_currdev.d_dev->dv_type; + zfs_currdev.dd.d_dev = &zfs_dev; } } #endif /* LOADER_ZFS_SUPPORT */ diff --git a/stand/sparc64/loader/metadata.c b/stand/sparc64/loader/metadata.c deleted file mode 100644 index 51b3d7e..0000000 --- a/stand/sparc64/loader/metadata.c +++ /dev/null @@ -1,345 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * from: FreeBSD: src/sys/boot/i386/libi386/bootinfo.c,v 1.29 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <sys/param.h> -#include <sys/reboot.h> -#include <sys/linker.h> -#include <sys/boot.h> - -#include <machine/metadata.h> - -#include "bootstrap.h" -#include "libofw.h" - -extern struct tlb_entry *dtlb_store; -extern struct tlb_entry *itlb_store; - -extern int dtlb_slot; -extern int itlb_slot; - -static int md_bootserial(void); - -int -md_getboothowto(char *kargs) -{ - char *cp; - int howto; - int active; - int i; - - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - if (md_bootserial() != -1) - howto |= RB_SERIAL; - return(howto); -} - -static int -md_bootserial(void) -{ - char buf[64]; - ihandle_t inst; - phandle_t input; - phandle_t node; - phandle_t output; - - if ((node = OF_finddevice("/options")) == -1) - return(-1); - if (OF_getprop(node, "input-device", buf, sizeof(buf)) == -1) - return(-1); - input = OF_finddevice(buf); - if (OF_getprop(node, "output-device", buf, sizeof(buf)) == -1) - return(-1); - output = OF_finddevice(buf); - if (input == -1 || output == -1 || OF_getproplen(input, "keyboard") >= 0) { - if ((node = OF_finddevice("/chosen")) == -1) - return(-1); - if (OF_getprop(node, "stdin", &inst, sizeof(inst)) == -1) - return(-1); - if ((input = OF_instance_to_package(inst)) == -1) - return(-1); - if (OF_getprop(node, "stdout", &inst, sizeof(inst)) == -1) - return(-1); - if ((output = OF_instance_to_package(inst)) == -1) - return(-1); - } - if (input != output) - return(-1); - if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) - return(-1); - if (strcmp(buf, "serial") != 0) - return(-1); - return(0); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -md_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - archsw.arch_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - archsw.arch_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - archsw.arch_copyin("", addr, 1); - addr++; - } - archsw.arch_copyin("", addr, 1); - addr++; - return(addr); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - u_int32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c) \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += roundup(strlen(s) + 1, sizeof(u_long));\ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c);\ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += roundup(mm->md_size, sizeof(u_long)); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -vm_offset_t -md_copymodules(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must come first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - MOD_ADDR(addr, fp->f_addr, c); - MOD_SIZE(addr, fp->f_size, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) { - if (!(md->md_type & MODINFOMD_NOCOPY)) { - MOD_METADATA(addr, md, c); - } - } - } - MOD_END(addr, c); - return(addr); -} - -/* - * Load the information expected by a sparc64 kernel. - * - * - The 'boothowto' argument is constructed - * - The 'bootdev' argument is constructed - * - The kernel environment is copied into kernel space. - * - Module metadata are formatted and placed in kernel space. - */ -vm_offset_t -md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtbp) -{ - struct preloaded_file *kfp; - struct preloaded_file *xp; - struct file_metadata *md; - vm_offset_t kernend; - vm_offset_t addr; - vm_offset_t envp; - vm_offset_t size; - char *rootdevname; - int howto; - - howto = md_getboothowto(args); - *dtbp = 0; - - /* - * Allow the environment variable 'rootdev' to override the supplied device - * This should perhaps go to MI code and/or have $rootdev tested/set by - * MI code before launching the kernel. - */ - if ((rootdevname = getenv("rootdev")) == NULL) - rootdevname = getenv("currdev"); - getrootmount(rootdevname); - - /* find the last module in the chain */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; - } - /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - - /* copy our environment */ - envp = addr; - addr = md_copyenv(addr); - - /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - - kernend = 0; - kfp = file_findfile(NULL, "elf64 kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - panic("can't find kernel file"); - file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); - file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); - file_addmetadata(kfp, MODINFOMD_DTLB_SLOTS, sizeof dtlb_slot, &dtlb_slot); - file_addmetadata(kfp, MODINFOMD_ITLB_SLOTS, sizeof itlb_slot, &itlb_slot); - file_addmetadata(kfp, MODINFOMD_DTLB, - dtlb_slot * sizeof(*dtlb_store), dtlb_store); - file_addmetadata(kfp, MODINFOMD_ITLB, - itlb_slot * sizeof(*itlb_store), itlb_store); - - *modulep = addr; - size = md_copymodules(0); - kernend = roundup(addr + size, PAGE_SIZE); - - md = file_findmetadata(kfp, MODINFOMD_KERNEND); - bcopy(&kernend, md->md_data, sizeof kernend); - - (void)md_copymodules(addr); - - return(0); -} diff --git a/stand/uboot.mk b/stand/uboot.mk index d120481..0ff7fb3 100644 --- a/stand/uboot.mk +++ b/stand/uboot.mk @@ -1,6 +1,6 @@ # $FreeBSD$ -SRCS+= main.c metadata.c +SRCS+= main.c .PATH: ${UBOOTSRC}/common @@ -10,6 +10,9 @@ CFLAGS+= -I${UBOOTSRC}/common LIBUBOOT= ${BOOTOBJ}/uboot/lib/libuboot.a CFLAGS+= -I${UBOOTSRC}/lib CFLAGS+= -I${BOOTOBJ}/uboot/lib +.if ${MACHINE_CPUARCH} == "arm" +SRCS+= metadata.c +.endif .include "${BOOTSRC}/fdt.mk" diff --git a/stand/uboot/Makefile b/stand/uboot/Makefile index 8c3a80d..fde6f9c 100644 --- a/stand/uboot/Makefile +++ b/stand/uboot/Makefile @@ -2,10 +2,8 @@ .include <bsd.init.mk> -SUBDIR= lib +SUBDIR.yes= lib -.if ${MK_FDT} != "no" -SUBDIR+=fdt -.endif +SUBDIR.${MK_FDT}+=fdt .include <bsd.subdir.mk> diff --git a/stand/uboot/common/main.c b/stand/uboot/common/main.c index a88a8bd..8ad33f4 100644 --- a/stand/uboot/common/main.c +++ b/stand/uboot/common/main.c @@ -41,6 +41,10 @@ __FBSDID("$FreeBSD$"); #define nitems(x) (sizeof((x)) / sizeof((x)[0])) #endif +#ifndef HEAP_SIZE +#define HEAP_SIZE (1 * 1024 * 1024) +#endif + struct uboot_devdesc currdev; struct arch_switch archsw; /* MI/MD interface boundary */ int devs_no; @@ -318,7 +322,7 @@ print_disk_probe_info() strcpy(partition, "<auto>"); printf(" Checking unit=%d slice=%s partition=%s...", - currdev.d_unit, slice, partition); + currdev.dd.d_unit, slice, partition); } @@ -338,8 +342,8 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice, if (load_type == -1) { printf(" Probing all disk devices...\n"); /* Try each disk in succession until one works. */ - for (currdev.d_unit = 0; currdev.d_unit < UB_MAX_DEV; - currdev.d_unit++) { + for (currdev.dd.d_unit = 0; currdev.dd.d_unit < UB_MAX_DEV; + currdev.dd.d_unit++) { print_disk_probe_info(); open_result = devsw[devidx]->dv_open(&f, &currdev); if (open_result == 0) { @@ -355,8 +359,8 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice, printf(" Probing all %s devices...\n", device_typename(load_type)); /* Try each disk of given type in succession until one works. */ for (unit = 0; unit < UB_MAX_DEV; unit++) { - currdev.d_unit = uboot_diskgetunit(load_type, unit); - if (currdev.d_unit == -1) + currdev.dd.d_unit = uboot_diskgetunit(load_type, unit); + if (currdev.dd.d_unit == -1) break; print_disk_probe_info(); open_result = devsw[devidx]->dv_open(&f, &currdev); @@ -369,7 +373,7 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice, return (-1); } - if ((currdev.d_unit = uboot_diskgetunit(load_type, load_unit)) != -1) { + if ((currdev.dd.d_unit = uboot_diskgetunit(load_type, load_unit)) != -1) { print_disk_probe_info(); open_result = devsw[devidx]->dv_open(&f,&currdev); if (open_result == 0) { @@ -421,7 +425,7 @@ main(int argc, char **argv) * of our bss and the bottom of the u-boot stack to avoid overlap. */ uboot_heap_start = round_page((uintptr_t)end); - uboot_heap_end = uboot_heap_start + 512 * 1024; + uboot_heap_end = uboot_heap_start + HEAP_SIZE; setheap((void *)uboot_heap_start, (void *)uboot_heap_end); /* @@ -459,9 +463,8 @@ main(int argc, char **argv) printf("Found U-Boot device: %s\n", devsw[i]->dv_name); - currdev.d_dev = devsw[i]; - currdev.d_type = currdev.d_dev->dv_type; - currdev.d_unit = 0; + currdev.dd.d_dev = devsw[i]; + currdev.dd.d_unit = 0; if ((load_type == -1 || (load_type & DEV_TYP_STOR)) && strcmp(devsw[i]->dv_name, "disk") == 0) { diff --git a/stand/uboot/common/metadata.c b/stand/uboot/common/metadata.c deleted file mode 100644 index 38db4bc..0000000 --- a/stand/uboot/common/metadata.c +++ /dev/null @@ -1,366 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * Copyright (C) 2006 Semihalf, Piotr Kruszynski <ppk@semihalf.com> - * Copyright (C) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com> - * All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <sys/param.h> -#include <sys/reboot.h> -#include <sys/linker.h> -#include <sys/boot.h> - -#include <machine/elf.h> -#include <machine/metadata.h> - -#include "api_public.h" -#include "bootstrap.h" -#include "glue.h" - -#if defined(LOADER_FDT_SUPPORT) -#include <fdt_platform.h> -#endif - -static int -md_getboothowto(char *kargs) -{ - char *cp; - char *p; - int howto; - int active; - int i; - - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) - active = 1; - else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) { - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - } - if ((p = getenv("console"))) { - if (!strcmp(p, "comconsole")) - howto |= RB_SERIAL; - if (!strcmp(p, "nullconsole")) - howto |= RB_MUTE; - } - - return(howto); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -static vm_offset_t -md_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - archsw.arch_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - archsw.arch_copyin(ep->ev_value, addr, - strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - archsw.arch_copyin("", addr, 1); - addr++; - } - archsw.arch_copyin("", addr, 1); - addr++; - return(addr); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - u_int32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c) \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += roundup(strlen(s) + 1, sizeof(u_long));\ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c);\ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += roundup(mm->md_size, sizeof(u_long)); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -md_copymodules(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - vm_offset_t a; - - c = addr != 0; - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name, c); /* this field must be first */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - a = fp->f_addr - __elfN(relocation_offset); - MOD_ADDR(addr, a, c); - MOD_SIZE(addr, fp->f_size, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) { - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md, c); - } - } - MOD_END(addr, c); - return(addr); -} - -/* - * Load the information expected by a kernel. - * - * - The 'boothowto' argument is constructed - * - The 'bootdev' argument is constructed - * - The kernel environment is copied into kernel space. - * - Module metadata are formatted and placed in kernel space. - */ -int -md_load(char *args, vm_offset_t *modulep) -{ - struct preloaded_file *kfp, *bfp; - struct preloaded_file *xp; - struct file_metadata *md; - struct bootinfo *bip; - vm_offset_t kernend; - vm_offset_t addr; - vm_offset_t envp; - vm_offset_t size; - vm_offset_t vaddr; -#if defined(LOADER_FDT_SUPPORT) - vm_offset_t dtbp; - int dtb_size; -#endif - char *rootdevname; - int howto; - int i; - - /* - * These metadata addreses must be converted for kernel after - * relocation. - */ - uint32_t mdt[] = { - MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND, - MODINFOMD_ENVP, -#if defined(LOADER_FDT_SUPPORT) - MODINFOMD_DTBP -#endif - }; - - howto = md_getboothowto(args); - - /* - * Allow the environment variable 'rootdev' to override the supplied - * device. This should perhaps go to MI code and/or have $rootdev - * tested/set by MI code before launching the kernel. - */ - rootdevname = getenv("rootdev"); - if (rootdevname == NULL) - rootdevname = getenv("currdev"); - /* Try reading the /etc/fstab file to select the root device */ - getrootmount(rootdevname); - - /* Find the last module in the chain */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; - } - /* Pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - - /* Copy our environment */ - envp = addr; - addr = md_copyenv(addr); - - /* Pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); - -#if defined(LOADER_FDT_SUPPORT) - /* Handle device tree blob */ - dtbp = addr; - dtb_size = fdt_copy(addr); - - /* Pad to a page boundary */ - if (dtb_size) - addr += roundup(dtb_size, PAGE_SIZE); -#endif - - kernend = 0; - kfp = file_findfile(NULL, "elf32 kernel"); - if (kfp == NULL) - kfp = file_findfile(NULL, "elf kernel"); - if (kfp == NULL) - panic("can't find kernel file"); - file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); - file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); - -#if defined(LOADER_FDT_SUPPORT) - if (dtb_size) - file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp); - else - pager_output("WARNING! Trying to fire up the kernel, but no " - "device tree blob found!\n"); -#endif - - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); - - /* Figure out the size and location of the metadata */ - *modulep = addr; - size = md_copymodules(0); - kernend = roundup(addr + size, PAGE_SIZE); - - /* Provide MODINFOMD_KERNEND */ - md = file_findmetadata(kfp, MODINFOMD_KERNEND); - bcopy(&kernend, md->md_data, sizeof kernend); - - /* Convert addresses to the final VA */ - *modulep -= __elfN(relocation_offset); - - /* Do relocation fixup on metadata of each module. */ - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - for (i = 0; i < nitems(mdt); i++) { - md = file_findmetadata(xp, mdt[i]); - if (md) { - bcopy(md->md_data, &vaddr, sizeof vaddr); - vaddr -= __elfN(relocation_offset); - bcopy(&vaddr, md->md_data, sizeof vaddr); - } - } - } - - /* Only now copy actual modules and metadata */ - (void)md_copymodules(addr); - - return (0); -} diff --git a/stand/uboot/fdt/Makefile b/stand/uboot/fdt/Makefile index b1e9f8e..ef60f8b 100644 --- a/stand/uboot/fdt/Makefile +++ b/stand/uboot/fdt/Makefile @@ -18,5 +18,4 @@ CFLAGS+= -I${FDTSRC} # Pick up the bootstrap header for some interface items CFLAGS+= -I${LDRSRC} -.include <bsd.stand.mk> .include <bsd.lib.mk> diff --git a/stand/uboot/lib/Makefile b/stand/uboot/lib/Makefile index 19e4d3a..1964484 100644 --- a/stand/uboot/lib/Makefile +++ b/stand/uboot/lib/Makefile @@ -24,5 +24,4 @@ CFLAGS+= -I${LDRSRC} CFLAGS+= -DDISK_DEBUG .endif -.include <bsd.stand.mk> .include <bsd.lib.mk> diff --git a/stand/uboot/lib/devicename.c b/stand/uboot/lib/devicename.c index 9e68f9d..cda16de 100644 --- a/stand/uboot/lib/devicename.c +++ b/stand/uboot/lib/devicename.c @@ -136,7 +136,7 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec, err = EINVAL; goto fail; } - idev->d_unit = unit; + idev->dd.d_unit = unit; if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; @@ -146,8 +146,7 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec, err = EINVAL; goto fail; } - idev->d_dev = dv; - idev->d_type = dv->dv_type; + idev->dd.d_dev = dv; if (dev == NULL) { free(idev); } else { @@ -167,7 +166,7 @@ uboot_fmtdev(void *vdev) struct uboot_devdesc *dev = (struct uboot_devdesc *)vdev; static char buf[128]; - switch(dev->d_type) { + switch(dev->dd.d_dev->dv_type) { case DEVT_NONE: strcpy(buf, "(no device)"); break; @@ -178,7 +177,7 @@ uboot_fmtdev(void *vdev) #endif case DEVT_NET: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); break; } return(buf); diff --git a/stand/uboot/lib/disk.c b/stand/uboot/lib/disk.c index f5e44c7..bf07d04 100644 --- a/stand/uboot/lib/disk.c +++ b/stand/uboot/lib/disk.c @@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$"); #include "libuboot.h" #define stor_printf(fmt, args...) do { \ - printf("%s%d: ", dev->d_dev->dv_name, dev->d_unit); \ + printf("%s%d: ", dev->dd.d_dev->dv_name, dev->dd.d_unit); \ printf(fmt, ##args); \ } while (0) @@ -65,7 +65,7 @@ static struct { u_int bsize; /* block size */ } stor_info[UB_MAX_DEV]; -#define SI(dev) (stor_info[(dev)->d_unit]) +#define SI(dev) (stor_info[(dev)->dd.d_unit]) static int stor_info_no = 0; static int stor_opendev(struct disk_devdesc *); @@ -190,7 +190,7 @@ stor_opendev(struct disk_devdesc *dev) { int err; - if (dev->d_unit < 0 || dev->d_unit >= stor_info_no) + if (dev->dd.d_unit < 0 || dev->dd.d_unit >= stor_info_no) return (EIO); if (SI(dev).opened == 0) { @@ -252,8 +252,8 @@ stor_print(int verbose) return (ret); for (i = 0; i < stor_info_no; i++) { - dev.d_dev = &uboot_storage; - dev.d_unit = i; + dev.dd.d_dev = &uboot_storage; + dev.dd.d_unit = i; dev.d_slice = -1; dev.d_partition = -1; snprintf(line, sizeof(line), "\tdisk%d (%s)\n", i, diff --git a/stand/uboot/lib/elf_freebsd.c b/stand/uboot/lib/elf_freebsd.c index a65fa26..a11f0ac 100644 --- a/stand/uboot/lib/elf_freebsd.c +++ b/stand/uboot/lib/elf_freebsd.c @@ -44,10 +44,10 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "libuboot.h" -extern vm_offset_t md_load(char *, vm_offset_t *); +extern vm_offset_t md_load(char *, vm_offset_t *, vm_offset_t *); int -__elfN(uboot_load)(char *filename, u_int64_t dest, +__elfN(uboot_load)(char *filename, uint64_t dest, struct preloaded_file **result) { int r; @@ -81,7 +81,7 @@ __elfN(uboot_exec)(struct preloaded_file *fp) e = (Elf_Ehdr *)&fmp->md_data; - if ((error = md_load(fp->f_args, &mdp)) != 0) + if ((error = md_load(fp->f_args, &mdp, NULL)) != 0) return (error); entry = (void *)e->e_entry; diff --git a/stand/uboot/lib/libuboot.h b/stand/uboot/lib/libuboot.h index c6cf93c..221f48f7 100644 --- a/stand/uboot/lib/libuboot.h +++ b/stand/uboot/lib/libuboot.h @@ -27,12 +27,9 @@ * $FreeBSD$ */ -struct uboot_devdesc -{ - struct devsw *d_dev; - int d_type; - int d_unit; - void *d_opendata; +/* Note: Must match the 'struct devdesc' in stand.h */ +struct uboot_devdesc { + struct devdesc dd; union { struct { int slice; diff --git a/stand/userboot/userboot/Makefile b/stand/userboot/userboot/Makefile index 2aa4161..29fa12c 100644 --- a/stand/userboot/userboot/Makefile +++ b/stand/userboot/userboot/Makefile @@ -42,6 +42,7 @@ NEWVERSWHAT= "User boot" ${MACHINE_CPUARCH} .if ${MK_ZFS} != "no" CFLAGS+= -DUSERBOOT_ZFS_SUPPORT LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a +HAVE_ZFS=yes .endif # Always add MI sources diff --git a/stand/userboot/userboot/bootinfo32.c b/stand/userboot/userboot/bootinfo32.c index 6498461..4f1cef6 100644 --- a/stand/userboot/userboot/bootinfo32.c +++ b/stand/userboot/userboot/bootinfo32.c @@ -55,7 +55,7 @@ static struct bootinfo bi; * MOD_METADATA (variable) type-specific metadata */ #define COPY32(v, a, c) { \ - u_int32_t x = (v); \ + uint32_t x = (v); \ if (c) \ CALLBACK(copyin, &x, a, sizeof(x)); \ a += sizeof(x); \ diff --git a/stand/userboot/userboot/bootinfo64.c b/stand/userboot/userboot/bootinfo64.c index 10ff133..6088741 100644 --- a/stand/userboot/userboot/bootinfo64.c +++ b/stand/userboot/userboot/bootinfo64.c @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$"); * MOD_METADATA (variable) type-specific metadata */ #define COPY32(v, a, c) { \ - u_int32_t x = (v); \ + uint32_t x = (v); \ if (c) \ CALLBACK(copyin, &x, a, sizeof(x)); \ a += sizeof(x); \ @@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$"); COPY32(strlen(s) + 1, a, c); \ if (c) \ CALLBACK(copyin, s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_int64_t));\ + a += roundup(strlen(s) + 1, sizeof(uint64_t));\ } #define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) @@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$"); COPY32(sizeof(s), a, c); \ if (c) \ CALLBACK(copyin, &s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_int64_t)); \ + a += roundup(sizeof(s), sizeof(uint64_t)); \ } #define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) @@ -90,7 +90,7 @@ __FBSDID("$FreeBSD$"); COPY32(mm->md_size, a, c); \ if (c) \ CALLBACK(copyin, mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_int64_t));\ + a += roundup(mm->md_size, sizeof(uint64_t));\ } #define MOD_END(a, c) { \ @@ -104,7 +104,7 @@ bi_copymodules64(vm_offset_t addr) struct preloaded_file *fp; struct file_metadata *md; int c; - u_int64_t v; + uint64_t v; c = addr != 0; /* start with the first module on the list, should be the kernel */ @@ -185,8 +185,8 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) struct userboot_devdesc *rootdev; struct file_metadata *md; vm_offset_t addr; - u_int64_t kernend; - u_int64_t envp; + uint64_t kernend; + uint64_t envp; vm_offset_t size; char *rootdevname; int howto; diff --git a/stand/userboot/userboot/devicename.c b/stand/userboot/userboot/devicename.c index efa5634..06ec394 100644 --- a/stand/userboot/userboot/devicename.c +++ b/stand/userboot/userboot/devicename.c @@ -139,7 +139,7 @@ userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **p goto fail; } - idev->d_unit = unit; + idev->dd.d_unit = unit; if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; break; @@ -158,8 +158,7 @@ userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **p err = EINVAL; goto fail; } - idev->d_dev = dv; - idev->d_type = dv->dv_type; + idev->dd.d_dev = dv; if (dev == NULL) { free(idev); } else { @@ -179,27 +178,27 @@ userboot_fmtdev(void *vdev) struct disk_devdesc *dev = (struct disk_devdesc *)vdev; static char buf[128]; /* XXX device length constant? */ - switch(dev->d_type) { + switch(dev->dd.d_dev->dv_type) { case DEVT_NONE: strcpy(buf, "(no device)"); break; case DEVT_CD: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); break; case DEVT_DISK: return (disk_fmtdev(vdev)); case DEVT_NET: - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); break; case DEVT_ZFS: #if defined(USERBOOT_ZFS_SUPPORT) return (zfs_fmtdev(vdev)); #else - sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit); #endif break; } diff --git a/stand/userboot/userboot/elf64_freebsd.c b/stand/userboot/userboot/elf64_freebsd.c index 19d369d..0dd90fa 100644 --- a/stand/userboot/userboot/elf64_freebsd.c +++ b/stand/userboot/userboot/elf64_freebsd.c @@ -60,9 +60,9 @@ struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; #define PG_U 0x004 #define PG_PS 0x080 -typedef u_int64_t p4_entry_t; -typedef u_int64_t p3_entry_t; -typedef u_int64_t p2_entry_t; +typedef uint64_t p4_entry_t; +typedef uint64_t p3_entry_t; +typedef uint64_t p2_entry_t; #define GUEST_NULL_SEL 0 #define GUEST_CODE_SEL 1 diff --git a/stand/userboot/userboot/host.c b/stand/userboot/userboot/host.c index 94f8a3d..8618565 100644 --- a/stand/userboot/userboot/host.c +++ b/stand/userboot/userboot/host.c @@ -74,16 +74,6 @@ host_read(struct open_file *f, void *start, size_t size, size_t *resid) return (CALLBACK(read, f->f_fsdata, start, size, resid)); } -/* - * Don't be silly - the bootstrap has no business writing anything. - */ -static int -host_write(struct open_file *f, void *start, size_t size, size_t *resid) -{ - - return (EROFS); -} - static off_t host_seek(struct open_file *f, off_t offset, int where) { @@ -183,7 +173,7 @@ struct fs_ops host_fsops = { host_open, host_close, host_read, - host_write, + null_write, host_seek, host_stat, host_readdir diff --git a/stand/userboot/userboot/main.c b/stand/userboot/userboot/main.c index 95bff17..1f0901d 100644 --- a/stand/userboot/userboot/main.c +++ b/stand/userboot/userboot/main.c @@ -159,13 +159,13 @@ extract_currdev(void) //bzero(&dev, sizeof(dev)); #if defined(USERBOOT_ZFS_SUPPORT) + CTASSERT(sizeof(struct disk_devdesc) >= sizeof(struct zfs_devdesc)); if (userboot_zfs_found) { struct zfs_devdesc zdev; /* Leave the pool/root guid's unassigned */ bzero(&zdev, sizeof(zdev)); - zdev.d_dev = &zfs_dev; - zdev.d_type = zdev.d_dev->dv_type; + zdev.dd.d_dev = &zfs_dev; dev = *(struct disk_devdesc *)&zdev; init_zfs_bootenv(zfs_fmtdev(&dev)); @@ -173,23 +173,21 @@ extract_currdev(void) #endif if (userboot_disk_maxunit > 0) { - dev.d_dev = &userboot_disk; - dev.d_type = dev.d_dev->dv_type; - dev.d_unit = 0; + dev.dd.d_dev = &userboot_disk; + dev.dd.d_unit = 0; dev.d_slice = 0; dev.d_partition = 0; /* * If we cannot auto-detect the partition type then * access the disk as a raw device. */ - if (dev.d_dev->dv_open(NULL, &dev)) { + if (dev.dd.d_dev->dv_open(NULL, &dev)) { dev.d_slice = -1; dev.d_partition = -1; } } else { - dev.d_dev = &host_dev; - dev.d_type = dev.d_dev->dv_type; - dev.d_unit = 0; + dev.dd.d_dev = &host_dev; + dev.dd.d_unit = 0; } env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev), @@ -218,70 +216,7 @@ userboot_zfs_probe(void) userboot_zfs_found = 1; } } - -COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset", - command_lszfs); - -static int -command_lszfs(int argc, char *argv[]) -{ - int err; - - if (argc != 2) { - command_errmsg = "a single dataset must be supplied"; - return (CMD_ERROR); - } - - err = zfs_list(argv[1]); - if (err != 0) { - command_errmsg = strerror(err); - return (CMD_ERROR); - } - return (CMD_OK); -} - -COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments", - command_reloadbe); - -static int -command_reloadbe(int argc, char *argv[]) -{ - int err; - char *root; - - if (argc > 2) { - command_errmsg = "wrong number of arguments"; - return (CMD_ERROR); - } - - if (argc == 2) { - err = zfs_bootenv(argv[1]); - } else { - root = getenv("zfs_be_root"); - if (root == NULL) { - return (CMD_OK); - } - err = zfs_bootenv(root); - } - - if (err != 0) { - command_errmsg = strerror(err); - return (CMD_ERROR); - } - - return (CMD_OK); -} - -uint64_t -ldi_get_size(void *priv) -{ - int fd = (uintptr_t) priv; - uint64_t size; - - ioctl(fd, DIOCGMEDIASIZE, &size); - return (size); -} -#endif /* USERBOOT_ZFS_SUPPORT */ +#endif COMMAND_SET(quit, "quit", "exit the loader", command_quit); diff --git a/stand/userboot/userboot/userboot_disk.c b/stand/userboot/userboot/userboot_disk.c index fc21b5f..149ba25 100644 --- a/stand/userboot/userboot/userboot_disk.c +++ b/stand/userboot/userboot/userboot_disk.c @@ -135,8 +135,8 @@ userdisk_print(int verbose) ret = pager_output(line); if (ret != 0) break; - dev.d_dev = &userboot_disk; - dev.d_unit = i; + dev.dd.d_dev = &userboot_disk; + dev.dd.d_unit = i; dev.d_slice = -1; dev.d_partition = -1; if (disk_open(&dev, ud_info[i].mediasize, @@ -164,13 +164,13 @@ userdisk_open(struct open_file *f, ...) dev = va_arg(ap, struct disk_devdesc *); va_end(ap); - if (dev->d_unit < 0 || dev->d_unit >= userdisk_maxunit) + if (dev->dd.d_unit < 0 || dev->dd.d_unit >= userdisk_maxunit) return (EIO); - ud_info[dev->d_unit].ud_open++; - if (ud_info[dev->d_unit].ud_bcache == NULL) - ud_info[dev->d_unit].ud_bcache = bcache_allocate(); - return (disk_open(dev, ud_info[dev->d_unit].mediasize, - ud_info[dev->d_unit].sectorsize)); + ud_info[dev->dd.d_unit].ud_open++; + if (ud_info[dev->dd.d_unit].ud_bcache == NULL) + ud_info[dev->dd.d_unit].ud_bcache = bcache_allocate(); + return (disk_open(dev, ud_info[dev->dd.d_unit].mediasize, + ud_info[dev->dd.d_unit].sectorsize)); } static int @@ -179,10 +179,10 @@ userdisk_close(struct open_file *f) struct disk_devdesc *dev; dev = (struct disk_devdesc *)f->f_devdata; - ud_info[dev->d_unit].ud_open--; - if (ud_info[dev->d_unit].ud_open == 0) { - bcache_free(ud_info[dev->d_unit].ud_bcache); - ud_info[dev->d_unit].ud_bcache = NULL; + ud_info[dev->dd.d_unit].ud_open--; + if (ud_info[dev->dd.d_unit].ud_open == 0) { + bcache_free(ud_info[dev->dd.d_unit].ud_bcache); + ud_info[dev->dd.d_unit].ud_bcache = NULL; } return (disk_close(dev)); } @@ -197,7 +197,7 @@ userdisk_strategy(void *devdata, int rw, daddr_t dblk, size_t size, dev = (struct disk_devdesc *)devdata; bcd.dv_strategy = userdisk_realstrategy; bcd.dv_devdata = devdata; - bcd.dv_cache = ud_info[dev->d_unit].ud_bcache; + bcd.dv_cache = ud_info[dev->dd.d_unit].ud_bcache; return (bcache_strategy(&bcd, rw, dblk + dev->d_offset, size, buf, rsize)); } @@ -218,8 +218,8 @@ userdisk_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, return (EINVAL); if (rsize) *rsize = 0; - off = dblk * ud_info[dev->d_unit].sectorsize; - rc = CALLBACK(diskread, dev->d_unit, off, buf, size, &resid); + off = dblk * ud_info[dev->dd.d_unit].sectorsize; + rc = CALLBACK(diskread, dev->dd.d_unit, off, buf, size, &resid); if (rc) return (rc); if (rsize) @@ -238,5 +238,5 @@ userdisk_ioctl(struct open_file *f, u_long cmd, void *data) if (rc != ENOTTY) return (rc); - return (CALLBACK(diskioctl, dev->d_unit, cmd, data)); + return (CALLBACK(diskioctl, dev->dd.d_unit, cmd, data)); } diff --git a/stand/zfs/Makefile b/stand/zfs/Makefile index 3116b32..89c1bfd 100644 --- a/stand/zfs/Makefile +++ b/stand/zfs/Makefile @@ -17,5 +17,4 @@ CFLAGS+= -I${SYSDIR}/crypto/skein CFLAGS+= -Wformat -Wall -.include <bsd.stand.mk> .include <bsd.lib.mk> diff --git a/stand/zfs/libzfs.h b/stand/zfs/libzfs.h index d1b46746..4b1e636 100644 --- a/stand/zfs/libzfs.h +++ b/stand/zfs/libzfs.h @@ -33,18 +33,14 @@ /* * ZFS fully-qualified device descriptor. - * Note, this must match the 'struct devdesc' declaration in bootstrap.h. * Arch-specific device descriptors should be binary compatible with this * structure if they are to support ZFS. */ -struct zfs_devdesc -{ - struct devsw *d_dev; - int d_type; - int d_unit; - void *d_opendata; - uint64_t pool_guid; - uint64_t root_guid; +/* Note: Must match the 'struct devdesc' in stand.h */ +struct zfs_devdesc { + struct devdesc dd; + uint64_t pool_guid; + uint64_t root_guid; }; #ifdef LOADER_GELI_SUPPORT diff --git a/stand/zfs/zfs.c b/stand/zfs/zfs.c index 0334bdd..a818340 100644 --- a/stand/zfs/zfs.c +++ b/stand/zfs/zfs.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #define ZFS_BE_LAST 8 static int zfs_open(const char *path, struct open_file *f); -static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid); static int zfs_close(struct open_file *f); static int zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t zfs_seek(struct open_file *f, off_t offset, int where); @@ -67,7 +66,7 @@ struct fs_ops zfs_fsops = { zfs_open, zfs_close, zfs_read, - zfs_write, + null_write, zfs_seek, zfs_stat, zfs_readdir @@ -171,16 +170,6 @@ zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */) return (0); } -/* - * Don't be silly - the bootstrap has no business writing anything. - */ -static int -zfs_write(struct open_file *f, void *start, size_t size, size_t *resid /* out */) -{ - - return (EROFS); -} - static off_t zfs_seek(struct open_file *f, off_t offset, int where) { @@ -696,8 +685,7 @@ zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) return (rv); if (path != NULL) *path = (*end == '\0') ? end : end + 1; - dev->d_dev = &zfs_dev; - dev->d_type = zfs_dev.dv_type; + dev->dd.d_dev = &zfs_dev; return (0); } @@ -710,7 +698,7 @@ zfs_fmtdev(void *vdev) spa_t *spa; buf[0] = '\0'; - if (dev->d_type != DEVT_ZFS) + if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (buf); if (dev->pool_guid == 0) { @@ -732,9 +720,9 @@ zfs_fmtdev(void *vdev) } if (rootname[0] == '\0') - sprintf(buf, "%s:%s:", dev->d_dev->dv_name, spa->spa_name); + sprintf(buf, "%s:%s:", dev->dd.d_dev->dv_name, spa->spa_name); else - sprintf(buf, "%s:%s/%s:", dev->d_dev->dv_name, spa->spa_name, + sprintf(buf, "%s:%s/%s:", dev->dd.d_dev->dv_name, spa->spa_name, rootname); return (buf); } |