Date: Thu, 28 Jan 2016 17:24:41 +0000 (UTC) From: Steven Hartland <smh@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r294999 - in stable/10/sys/boot/efi: boot1 include libefi loader Message-ID: <201601281724.u0SHOfgn050280@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: smh Date: Thu Jan 28 17:24:40 2016 New Revision: 294999 URL: https://svnweb.freebsd.org/changeset/base/294999 Log: MFC r294068, r294265 MFC r294068: Add EFI ZFS boot support MFC r294265: Fix broken DPRINTF and wire up EFI_DEBUG so -DEFI_DEBUG to make works. Relnotes: Yes Sponsored by: Multiplay Added: stable/10/sys/boot/efi/boot1/zfs_module.c - copied, changed from r294068, head/sys/boot/efi/boot1/zfs_module.c Modified: stable/10/sys/boot/efi/boot1/Makefile stable/10/sys/boot/efi/boot1/boot1.c stable/10/sys/boot/efi/boot1/boot_module.h stable/10/sys/boot/efi/include/efilib.h stable/10/sys/boot/efi/libefi/handles.c stable/10/sys/boot/efi/loader/Makefile stable/10/sys/boot/efi/loader/conf.c stable/10/sys/boot/efi/loader/devicename.c stable/10/sys/boot/efi/loader/main.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/boot/efi/boot1/Makefile ============================================================================== --- stable/10/sys/boot/efi/boot1/Makefile Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/boot1/Makefile Thu Jan 28 17:24:40 2016 (r294999) @@ -10,8 +10,22 @@ PROG= boot1.sym INTERNALPROG= WARNS?= 6 +.if ${MK_ZFS} != "no" +# Disable warnings that are currently incompatible with the zfs boot code +CWARNFLAGS.zfs_module.c += -Wno-array-bounds +CWARNFLAGS.zfs_module.c += -Wno-cast-align +CWARNFLAGS.zfs_module.c += -Wno-cast-qual +CWARNFLAGS.zfs_module.c += -Wno-missing-prototypes +CWARNFLAGS.zfs_module.c += -Wno-sign-compare +CWARNFLAGS.zfs_module.c += -Wno-unused-parameter +CWARNFLAGS.zfs_module.c += -Wno-unused-function +.endif + # architecture-specific loader code SRCS= boot1.c reloc.c start.S ufs_module.c +.if ${MK_ZFS} != "no" +SRCS+= zfs_module.c +.endif CFLAGS+= -fPIC CFLAGS+= -I. @@ -20,6 +34,15 @@ CFLAGS+= -I${.CURDIR}/../include/${MACHI CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -DEFI_UFS_BOOT +.ifdef(EFI_DEBUG) +CFLAGS+= -DEFI_DEBUG +.endif + +.if ${MK_ZFS} != "no" +CFLAGS+= -I${.CURDIR}/../../zfs/ +CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs/ +CFLAGS+= -DEFI_ZFS_BOOT +.endif # Always add MI sources and REGULAR efi loader bits .PATH: ${.CURDIR}/../loader/arch/${MACHINE} Modified: stable/10/sys/boot/efi/boot1/boot1.c ============================================================================== --- stable/10/sys/boot/efi/boot1/boot1.c Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/boot1/boot1.c Thu Jan 28 17:24:40 2016 (r294999) @@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$"); static const boot_module_t *boot_modules[] = { +#ifdef EFI_ZFS_BOOT + &zfs_module, +#endif #ifdef EFI_UFS_BOOT &ufs_module #endif Modified: stable/10/sys/boot/efi/boot1/boot_module.h ============================================================================== --- stable/10/sys/boot/efi/boot1/boot_module.h Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/boot1/boot_module.h Thu Jan 28 17:24:40 2016 (r294999) @@ -36,12 +36,9 @@ #include <eficonsctl.h> #ifdef EFI_DEBUG -#define DPRINTF(fmt, args...) \ - do { \ - printf(fmt, ##args) \ - } while (0) +#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__) #else -#define DPRINTF(fmt, args...) {} +#define DPRINTF(fmt, ...) {} #endif /* EFI device info */ @@ -97,6 +94,9 @@ typedef struct boot_module_t #ifdef EFI_UFS_BOOT extern const boot_module_t ufs_module; #endif +#ifdef EFI_ZFS_BOOT +extern const boot_module_t zfs_module; +#endif /* Functions available to modules. */ extern void add_device(dev_info_t **devinfop, dev_info_t *devinfo); Copied and modified: stable/10/sys/boot/efi/boot1/zfs_module.c (from r294068, head/sys/boot/efi/boot1/zfs_module.c) ============================================================================== --- head/sys/boot/efi/boot1/zfs_module.c Fri Jan 15 02:33:47 2016 (r294068, copy source) +++ stable/10/sys/boot/efi/boot1/zfs_module.c Thu Jan 28 17:24:40 2016 (r294999) @@ -53,9 +53,9 @@ vdev_read(vdev_t *vdev, void *priv, off_ status = devinfo->dev->ReadBlocks(devinfo->dev, devinfo->dev->Media->MediaId, lba, bytes, buf); if (status != EFI_SUCCESS) { - DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %lu, size: %d," + DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %zu, size: %zu," " status: %lu\n", devinfo->dev, - devinfo->dev->Media->MediaId, lba, size, + devinfo->dev->Media->MediaId, lba, bytes, EFI_ERROR_CODE(status)); return (-1); } Modified: stable/10/sys/boot/efi/include/efilib.h ============================================================================== --- stable/10/sys/boot/efi/include/efilib.h Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/include/efilib.h Thu Jan 28 17:24:40 2016 (r294999) @@ -42,7 +42,8 @@ void *efi_get_table(EFI_GUID *tbl); int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int); EFI_HANDLE efi_find_handle(struct devsw *, int); -int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *); +int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *); +int efi_handle_update_dev(EFI_HANDLE, struct devsw *, int, uint64_t); int efi_status_to_errno(EFI_STATUS); time_t efi_time(EFI_TIME *); Modified: stable/10/sys/boot/efi/libefi/handles.c ============================================================================== --- stable/10/sys/boot/efi/libefi/handles.c Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/libefi/handles.c Thu Jan 28 17:24:40 2016 (r294999) @@ -35,6 +35,7 @@ struct entry { EFI_HANDLE alias; struct devsw *dev; int unit; + uint64_t extra; }; struct entry *entry; @@ -79,7 +80,7 @@ efi_find_handle(struct devsw *dev, int u } int -efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit) +efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit, uint64_t *extra) { int idx; @@ -90,7 +91,28 @@ efi_handle_lookup(EFI_HANDLE h, struct d *dev = entry[idx].dev; if (unit != NULL) *unit = entry[idx].unit; + if (extra != NULL) + *extra = entry[idx].extra; return (0); } return (ENOENT); } + +int +efi_handle_update_dev(EFI_HANDLE h, struct devsw *dev, int unit, + uint64_t guid) +{ + int idx; + + for (idx = 0; idx < nentries; idx++) { + if (entry[idx].handle != h) + continue; + entry[idx].dev = dev; + entry[idx].unit = unit; + entry[idx].alias = NULL; + entry[idx].extra = guid; + return (0); + } + + return (ENOENT); +} Modified: stable/10/sys/boot/efi/loader/Makefile ============================================================================== --- stable/10/sys/boot/efi/loader/Makefile Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/loader/Makefile Thu Jan 28 17:24:40 2016 (r294999) @@ -20,6 +20,16 @@ SRCS= autoload.c \ smbios.c \ vers.c +.if ${MK_ZFS} != "no" +SRCS+= zfs.c +.PATH: ${.CURDIR}/../../zfs + +# Disable warnings that are currently incompatible with the zfs boot code +CWARNFLAGS.zfs.c+= -Wno-sign-compare +CWARNFLAGS.zfs.c+= -Wno-array-bounds +CWARNFLAGS.zfs.c+= -Wno-missing-prototypes +.endif + .PATH: ${.CURDIR}/arch/${MACHINE} # For smbios.c .PATH: ${.CURDIR}/../../i386/libi386 @@ -33,6 +43,11 @@ CFLAGS+= -I${.CURDIR}/../include/${MACHI CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -I${.CURDIR}/../../i386/libi386 +.if ${MK_ZFS} != "no" +CFLAGS+= -I${.CURDIR}/../../zfs +CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs +CFLAGS+= -DEFI_ZFS_BOOT +.endif CFLAGS+= -DNO_PCI -DEFI .if ${MK_FORTH} != "no" Modified: stable/10/sys/boot/efi/loader/conf.c ============================================================================== --- stable/10/sys/boot/efi/loader/conf.c Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/loader/conf.c Thu Jan 28 17:24:40 2016 (r294999) @@ -31,14 +31,23 @@ __FBSDID("$FreeBSD$"); #include <bootstrap.h> #include <efi.h> #include <efilib.h> +#ifdef EFI_ZFS_BOOT +#include <libzfs.h> +#endif struct devsw *devsw[] = { &efipart_dev, &efinet_dev, +#ifdef EFI_ZFS_BOOT + &zfs_dev, +#endif NULL }; struct fs_ops *file_system[] = { +#ifdef EFI_ZFS_BOOT + &zfs_fsops, +#endif &dosfs_fsops, &ufs_fsops, &cd9660_fsops, Modified: stable/10/sys/boot/efi/loader/devicename.c ============================================================================== --- stable/10/sys/boot/efi/loader/devicename.c Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/loader/devicename.c Thu Jan 28 17:24:40 2016 (r294999) @@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$"); #include <sys/disklabel.h> #include <sys/param.h> #include <bootstrap.h> +#ifdef EFI_ZFS_BOOT +#include <libzfs.h> +#endif #include <efi.h> #include <efilib.h> @@ -104,6 +107,23 @@ efi_parsedev(struct devdesc **dev, const np = devspec + strlen(dv->dv_name); +#ifdef EFI_ZFS_BOOT + if (dv->dv_type == DEVT_ZFS) { + int err; + + idev = malloc(sizeof(struct zfs_devdesc)); + if (idev == NULL) + return (ENOMEM); + + err = zfs_parsedev((struct zfs_devdesc*)idev, np, path); + if (err != 0) { + free(idev); + return (err); + } + *dev = idev; + cp = strchr(np + 1, ':'); + } else +#endif { idev = malloc(sizeof(struct devdesc)); if (idev == NULL) @@ -143,6 +163,10 @@ efi_fmtdev(void *vdev) static char buf[SPECNAMELEN + 1]; switch(dev->d_type) { +#ifdef EFI_ZFS_BOOT + case DEVT_ZFS: + return (zfs_fmtdev(dev)); +#endif case DEVT_NONE: strcpy(buf, "(no device)"); break; Modified: stable/10/sys/boot/efi/loader/main.c ============================================================================== --- stable/10/sys/boot/efi/loader/main.c Thu Jan 28 16:58:49 2016 (r294998) +++ stable/10/sys/boot/efi/loader/main.c Thu Jan 28 17:24:40 2016 (r294999) @@ -39,6 +39,10 @@ __FBSDID("$FreeBSD$"); #include <bootstrap.h> #include <smbios.h> +#ifdef EFI_ZFS_BOOT +#include <libzfs.h> +#endif + #include "loader_efi.h" extern char bootprog_name[]; @@ -60,6 +64,10 @@ EFI_GUID hoblist = HOB_LIST_TABLE_GUID; EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; +#ifdef EFI_ZFS_BOOT +static void efi_zfs_probe(void); +#endif + /* * Need this because EFI uses UTF-16 unicode string constants, but we * use UTF-8. We can't use printf due to the possiblity of \0 and we @@ -82,6 +90,7 @@ main(int argc, CHAR16 *argv[]) EFI_GUID *guid; int i, j, vargood, unit; struct devsw *dev; + uint64_t pool_guid; UINTN k; archsw.arch_autoload = efi_autoload; @@ -89,6 +98,10 @@ main(int argc, CHAR16 *argv[]) archsw.arch_copyin = efi_copyin; archsw.arch_copyout = efi_copyout; archsw.arch_readin = efi_readin; +#ifdef EFI_ZFS_BOOT + /* Note this needs to be set before ZFS init. */ + archsw.arch_zfs_probe = efi_zfs_probe; +#endif /* * XXX Chicken-and-egg problem; we want to have console output @@ -167,10 +180,27 @@ main(int argc, CHAR16 *argv[]) */ BS->SetWatchdogTimer(0, 0, 0, NULL); - if (efi_handle_lookup(img->DeviceHandle, &dev, &unit) != 0) + if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &pool_guid) != 0) return (EFI_NOT_FOUND); switch (dev->dv_type) { +#ifdef EFI_ZFS_BOOT + case DEVT_ZFS: { + struct zfs_devdesc currdev; + + currdev.d_dev = dev; + currdev.d_unit = unit; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_opendata = NULL; + currdev.pool_guid = pool_guid; + currdev.root_guid = 0; + env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), + efi_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, + env_nounset); + break; + } +#endif default: { struct devdesc currdev; @@ -452,3 +482,46 @@ command_nvram(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); +} +#endif + +#ifdef EFI_ZFS_BOOT +static void +efi_zfs_probe(void) +{ + EFI_HANDLE h; + u_int unit; + int i; + char dname[SPECNAMELEN + 1]; + uint64_t guid; + + unit = 0; + h = efi_find_handle(&efipart_dev, 0); + for (i = 0; h != NULL; h = efi_find_handle(&efipart_dev, ++i)) { + snprintf(dname, sizeof(dname), "%s%d:", efipart_dev.dv_name, i); + if (zfs_probe_dev(dname, &guid) == 0) + (void)efi_handle_update_dev(h, &zfs_dev, unit++, guid); + } +} +#endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601281724.u0SHOfgn050280>