Module Name: src Committed By: martin Date: Tue Mar 13 14:54:52 UTC 2018
Modified Files: src/sys/arch/i386/stand/efiboot [netbsd-8]: Makefile.efiboot TODO.efiboot boot.c devopen.c efiboot.c efiboot.h efidisk.c efidisk.h efidisk_ll.c src/sys/arch/i386/stand/lib [netbsd-8]: biosdisk.c biosdisk.h biosdisk_ll.h src/sys/lib/libsa [netbsd-8]: cd9660.c Added Files: src/sys/arch/i386/stand/efiboot [netbsd-8]: efidev.c Log Message: Pull up following revision(s) (requested by nonaka in ticket #625): sys/arch/i386/stand/efiboot/efidisk.c: revision 1.2 sys/arch/i386/stand/efiboot/devopen.c: revision 1.2 sys/arch/i386/stand/efiboot/efidisk.h: revision 1.2 sys/arch/i386/stand/efiboot/boot.c: revision 1.6 sys/arch/i386/stand/efiboot/efidisk_ll.c: revision 1.2 sys/arch/i386/stand/efiboot/efidev.c: revision 1.1 sys/arch/i386/stand/lib/biosdisk_ll.h: revision 1.16 sys/arch/i386/stand/lib/biosdisk.h: revision 1.9 sys/lib/libsa/cd9660.c: revision 1.31 sys/arch/i386/stand/efiboot/efiboot.c: revision 1.5 sys/arch/i386/stand/efiboot/efiboot.h: revision 1.6 sys/arch/i386/stand/lib/biosdisk.c: revision 1.47 sys/arch/i386/stand/efiboot/Makefile.efiboot: revision 1.10 sys/arch/i386/stand/efiboot/TODO.efiboot: revision 1.4 efiboot: system can boot from CD/DVD-ROM media. Add missed file in previous commit. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.9.2.1 src/sys/arch/i386/stand/efiboot/Makefile.efiboot cvs rdiff -u -r1.3 -r1.3.10.1 src/sys/arch/i386/stand/efiboot/TODO.efiboot cvs rdiff -u -r1.5 -r1.5.2.1 src/sys/arch/i386/stand/efiboot/boot.c \ src/sys/arch/i386/stand/efiboot/efiboot.h cvs rdiff -u -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/devopen.c \ src/sys/arch/i386/stand/efiboot/efidisk.c \ src/sys/arch/i386/stand/efiboot/efidisk.h \ src/sys/arch/i386/stand/efiboot/efidisk_ll.c cvs rdiff -u -r1.4 -r1.4.10.1 src/sys/arch/i386/stand/efiboot/efiboot.c cvs rdiff -u -r0 -r1.1.2.2 src/sys/arch/i386/stand/efiboot/efidev.c cvs rdiff -u -r1.46 -r1.46.6.1 src/sys/arch/i386/stand/lib/biosdisk.c cvs rdiff -u -r1.8 -r1.8.52.1 src/sys/arch/i386/stand/lib/biosdisk.h cvs rdiff -u -r1.15 -r1.15.90.1 src/sys/arch/i386/stand/lib/biosdisk_ll.h cvs rdiff -u -r1.30 -r1.30.22.1 src/sys/lib/libsa/cd9660.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/efiboot/Makefile.efiboot diff -u src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.9 src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.9.2.1 --- src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.9 Sat Apr 29 00:05:35 2017 +++ src/sys/arch/i386/stand/efiboot/Makefile.efiboot Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.efiboot,v 1.9 2017/04/29 00:05:35 nonaka Exp $ +# $NetBSD: Makefile.efiboot,v 1.9.2.1 2018/03/13 14:54:52 martin Exp $ S= ${.CURDIR}/../../../../.. @@ -12,8 +12,8 @@ SOURCES?= start.S conf.c devopen.c efibo LIBI386SRCS= boot.c biosdisk.c bootinfo.c bootinfo_biosgeom.c LIBI386SRCS+= bootmenu.c diskbuf.c exec.c menuutils.c LIBI386SRCS+= panic.c parseutils.c pread.c -LIBI386SRCS+= eficons.c efidelay.c efidisk.c efidisk_ll.c efigetsecs.c -LIBI386SRCS+= efimemory.c +LIBI386SRCS+= eficons.c efidelay.c efidev.c efidisk.c efidisk_ll.c +LIBI386SRCS+= efigetsecs.c efimemory.c SRCS= ${SOURCES} ${EXTRA_SOURCES} ${LIBI386SRCS} PIE_CFLAGS= @@ -54,9 +54,11 @@ CPPFLAGS+= -Wno-pointer-sign CPPFLAGS+= -DEFI_ALLOCATE_MAX_ADDRESS=0x100000000ULL CPPFLAGS+= -DHEAP_VARIABLE CPPFLAGS+= -DSUPPORT_CD9660 +CPPFLAGS+= -D"devb2cdb(bno)=(bno)" CPPFLAGS+= -DSUPPORT_DOSFS CPPFLAGS+= -DSUPPORT_EXT2FS CPPFLAGS+= -DPASS_BIOSGEOM +CPPFLAGS+= -DBIOSDISK_DEFAULT_SECSIZE=2048 # for bootinfo_biosgeom.c CPPFLAGS+= -DLIBSA_ENABLE_LS_OP EFIDIR= ${S}/external/bsd/gnu-efi/dist @@ -66,6 +68,7 @@ CPPFLAGS+= -I${EFIDIR}/inc/protocol SAMISCCPPFLAGS+= -DLIBSA_PRINTF_LONGLONG_SUPPORT SAMISCCPPFLAGS+= -DLIBSA_PRINTF_WIDTH_SUPPORT +SAMISCCPPFLAGS+= -D"cdb2devb(bno)=(bno)" SAMISCMAKEFLAGS+= SA_USE_CREAD=yes # Read compressed kernels SAMISCMAKEFLAGS+= SA_INCLUDE_NET=no # Netboot via TFTP, NFS Index: src/sys/arch/i386/stand/efiboot/TODO.efiboot diff -u src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.3 src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.3.10.1 --- src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.3 Sun Mar 12 06:37:41 2017 +++ src/sys/arch/i386/stand/efiboot/TODO.efiboot Tue Mar 13 14:54:52 2018 @@ -1,6 +1,5 @@ - efiboot * handle UEFI variables - * boot from CD/DVD (bootable from CD/DVD, but root fs not found.) * load boot.cfg from EFI system partition (FAT32) - kernel Index: src/sys/arch/i386/stand/efiboot/boot.c diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.5 src/sys/arch/i386/stand/efiboot/boot.c:1.5.2.1 --- src/sys/arch/i386/stand/efiboot/boot.c:1.5 Mon May 1 13:03:01 2017 +++ src/sys/arch/i386/stand/efiboot/boot.c Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: boot.c,v 1.5 2017/05/01 13:03:01 nonaka Exp $ */ +/* $NetBSD: boot.c,v 1.5.2.1 2018/03/13 14:54:52 martin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -419,7 +419,7 @@ command_dev(char *arg) const char *file; /* dummy */ if (*arg == '\0') { - biosdisk_probe(); + efi_disk_show(); printf("default %s%d%c\n", default_devname, default_unit, 'a' + default_partition); return; @@ -554,6 +554,7 @@ command_multiboot(char *arg) void command_version(char *arg) { + CHAR16 *path; if (strcmp(arg, "full") == 0) { printf("ImageBase: 0x%" PRIxPTR "\n", @@ -563,6 +564,10 @@ command_version(char *arg) ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); Print(L"EFI Firmware: %s (rev %d.%02d)\n", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); + path = DevicePathToStr(efi_bootdp); + Print(L"Boot DevicePath: %d:%d:%s\n", DevicePathType(efi_bootdp), + DevicePathSubType(efi_bootdp), path); + FreePool(path); } printf("\n" Index: src/sys/arch/i386/stand/efiboot/efiboot.h diff -u src/sys/arch/i386/stand/efiboot/efiboot.h:1.5 src/sys/arch/i386/stand/efiboot/efiboot.h:1.5.2.1 --- src/sys/arch/i386/stand/efiboot/efiboot.h:1.5 Mon May 1 13:03:01 2017 +++ src/sys/arch/i386/stand/efiboot/efiboot.h Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: efiboot.h,v 1.5 2017/05/01 13:03:01 nonaka Exp $ */ +/* $NetBSD: efiboot.h,v 1.5.2.1 2018/03/13 14:54:52 martin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -46,6 +46,7 @@ void print_banner(void); /* efiboot.c */ extern EFI_HANDLE IH; extern EFI_DEVICE_PATH *efi_bootdp; +extern int efi_bootdp_type; extern EFI_LOADED_IMAGE *efi_li; extern uintptr_t efi_main_sp; extern physaddr_t efi_loadaddr, efi_kernel_start; @@ -59,8 +60,13 @@ void consinit(int, int, int); void command_text(char *); void command_gop(char *); +/* efidev.c */ +int efi_device_path_depth(EFI_DEVICE_PATH *dp, int); +int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int); + /* efidisk.c */ void efi_disk_probe(void); +void efi_disk_show(void); /* efimemory.c */ void efi_memory_probe(void); Index: src/sys/arch/i386/stand/efiboot/devopen.c diff -u src/sys/arch/i386/stand/efiboot/devopen.c:1.1 src/sys/arch/i386/stand/efiboot/devopen.c:1.1.12.1 --- src/sys/arch/i386/stand/efiboot/devopen.c:1.1 Tue Jan 24 11:09:14 2017 +++ src/sys/arch/i386/stand/efiboot/devopen.c Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: devopen.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */ +/* $NetBSD: devopen.c,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $ */ /*- * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -66,8 +66,11 @@ dev2bios(char *devname, int unit, int *b if (strcmp(devname, "hd") == 0) *biosdev = 0x80 + unit; + if (strcmp(devname, "cd") == 0) + *biosdev = 0x80 + get_harddrives() + unit; else return ENXIO; + return 0; } @@ -76,7 +79,13 @@ bios2dev(int biosdev, daddr_t sector, ch { *unit = biosdev & 0x7f; - *devname = "hd"; + + if (biosdev >= 0x80 + get_harddrives()) { + *devname = "cd"; + *unit -= get_harddrives(); + } else + *devname = "hd"; + *partition = biosdisk_findpartition(biosdev, sector); } Index: src/sys/arch/i386/stand/efiboot/efidisk.c diff -u src/sys/arch/i386/stand/efiboot/efidisk.c:1.1 src/sys/arch/i386/stand/efiboot/efidisk.c:1.1.12.1 --- src/sys/arch/i386/stand/efiboot/efidisk.c:1.1 Tue Jan 24 11:09:14 2017 +++ src/sys/arch/i386/stand/efiboot/efidisk.c Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: efidisk.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */ +/* $NetBSD: efidisk.c,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -26,8 +26,15 @@ * SUCH DAMAGE. */ +#define FSTYPENAMES /* for sys/disklabel.h */ + #include "efiboot.h" +#include <sys/disklabel.h> + +#include "biosdisk.h" +#include "biosdisk_ll.h" +#include "devopen.h" #include "efidisk.h" static struct efidiskinfo_lh efi_disklist; @@ -41,10 +48,9 @@ efi_disk_probe(void) EFI_HANDLE *handles; EFI_BLOCK_IO *bio; EFI_BLOCK_IO_MEDIA *media; + EFI_DEVICE_PATH *dp; struct efidiskinfo *edi; - EFI_DEVICE_PATH *dp, *bdp; - bool bootdev; - int dev; + int dev, depth = -1; TAILQ_INIT(&efi_disklist); @@ -53,6 +59,18 @@ efi_disk_probe(void) if (EFI_ERROR(status)) Panic(L"LocateHandle(BlockIoProtocol): %r", status); + if (efi_bootdp != NULL) + depth = efi_device_path_depth(efi_bootdp, MEDIA_DEVICE_PATH); + + /* + * U-Boot incorrectly represents devices with a single + * MEDIA_DEVICE_PATH component. In that case include that + * component into the matching, otherwise we'll blindly select + * the first device. + */ + if (depth == 0) + depth = 1; + for (i = 0; i < nhandles; i++) { status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i], &BlockIoProtocol, (void **)&bio); @@ -65,43 +83,114 @@ efi_disk_probe(void) edi = alloc(sizeof(struct efidiskinfo)); memset(edi, 0, sizeof(*edi)); + edi->type = BIOSDISK_TYPE_HD; edi->bio = bio; edi->media_id = media->MediaId; - bootdev = false; - if (efi_bootdp == NULL) - goto next; - - status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i], - &DevicePathProtocol, (void **)&dp); - if (EFI_ERROR(status)) - goto next; - - bdp = efi_bootdp; - for (;;) { - if (IsDevicePathEnd(dp)) { - bootdev = true; - break; + if (efi_bootdp != NULL && depth > 0) { + status = uefi_call_wrapper(BS->HandleProtocol, 3, + handles[i], &DevicePathProtocol, (void **)&dp); + if (EFI_ERROR(status)) + goto next; + if (efi_device_path_ncmp(efi_bootdp, dp, depth) == 0) { + edi->bootdev = true; + TAILQ_INSERT_HEAD(&efi_disklist, edi, + list); + continue; } - if (memcmp(dp, bdp, sizeof(EFI_DEVICE_PATH)) != 0 || - memcmp(dp, bdp, DevicePathNodeLength(dp)) != 0) - break; - dp = NextDevicePathNode(dp); - bdp = NextDevicePathNode(bdp); } next: - if (bootdev) - TAILQ_INSERT_HEAD(&efi_disklist, edi, list); - else - TAILQ_INSERT_TAIL(&efi_disklist, edi, list); + TAILQ_INSERT_TAIL(&efi_disklist, edi, list); } FreePool(handles); + if (efi_bootdp_type == BIOSDISK_TYPE_CD) { + TAILQ_FOREACH(edi, &efi_disklist, list) { + if (edi->bootdev) { + edi = TAILQ_FIRST(&efi_disklist); + edi->type = BIOSDISK_TYPE_CD; + TAILQ_REMOVE(&efi_disklist, edi, list); + TAILQ_INSERT_TAIL(&efi_disklist, edi, list); + break; + } + } + } + dev = 0x80; TAILQ_FOREACH(edi, &efi_disklist, list) { edi->dev = dev++; - nefidisks++; + if (edi->type == BIOSDISK_TYPE_HD) + nefidisks++; + if (edi->bootdev) + boot_biosdev = edi->dev; + } +} + +void +efi_disk_show(void) +{ + const struct efidiskinfo *edi; + EFI_BLOCK_IO_MEDIA *media; + struct biosdisk_partition *part; + uint64_t size; + int i, nparts; + bool first; + + TAILQ_FOREACH(edi, &efi_disklist, list) { + media = edi->bio->Media; + first = true; + printf("disk "); + switch (edi->type) { + case BIOSDISK_TYPE_CD: + printf("cd0"); + printf(" mediaId %u", media->MediaId); + if (edi->media_id != media->MediaId) + printf("(%u)", edi->media_id); + printf("\n"); + printf(" cd0a\n"); + break; + case BIOSDISK_TYPE_HD: + printf("hd%d", edi->dev & 0x7f); + printf(" mediaId %u", media->MediaId); + if (edi->media_id != media->MediaId) + printf("(%u)", edi->media_id); + printf(" size "); + size = (media->LastBlock + 1) * media->BlockSize; + if (size >= (10ULL * 1024 * 1024 * 1024)) + printf("%"PRIu64" GB", size / (1024 * 1024 * 1024)); + else + printf("%"PRIu64" MB", size / (1024 * 1024)); + printf("\n"); + break; + } + if (edi->type != BIOSDISK_TYPE_HD) + continue; + + if (biosdisk_readpartition(edi->dev, &part, &nparts)) + continue; + + for (i = 0; i < nparts; i++) { + if (part[i].size == 0) + continue; + if (part[i].fstype == FS_UNUSED) + continue; + if (first) { + printf(" "); + first = false; + } + printf(" hd%d%c(", edi->dev & 0x7f, i + 'a'); + if (part[i].guid != NULL) + printf("%s", part[i].guid->name); + else if (part[i].fstype < FSMAXTYPES) + printf("%s", fstypenames[part[i].fstype]); + else + printf("%d", part[i].fstype); + printf(")"); + } + if (!first) + printf("\n"); + dealloc(part, sizeof(*part) * nparts); } } Index: src/sys/arch/i386/stand/efiboot/efidisk.h diff -u src/sys/arch/i386/stand/efiboot/efidisk.h:1.1 src/sys/arch/i386/stand/efiboot/efidisk.h:1.1.12.1 --- src/sys/arch/i386/stand/efiboot/efidisk.h:1.1 Tue Jan 24 11:09:14 2017 +++ src/sys/arch/i386/stand/efiboot/efidisk.h Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: efidisk.h,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */ +/* $NetBSD: efidisk.h,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -32,8 +32,10 @@ struct efidiskinfo { TAILQ_ENTRY(efidiskinfo) list; int dev; + int type; EFI_BLOCK_IO *bio; UINT32 media_id; + bool bootdev; }; TAILQ_HEAD(efidiskinfo_lh, efidiskinfo); Index: src/sys/arch/i386/stand/efiboot/efidisk_ll.c diff -u src/sys/arch/i386/stand/efiboot/efidisk_ll.c:1.1 src/sys/arch/i386/stand/efiboot/efidisk_ll.c:1.1.12.1 --- src/sys/arch/i386/stand/efiboot/efidisk_ll.c:1.1 Tue Jan 24 11:09:14 2017 +++ src/sys/arch/i386/stand/efiboot/efidisk_ll.c Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: efidisk_ll.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */ +/* $NetBSD: efidisk_ll.c,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $ */ /* NetBSD: biosdisk_ll.c,v 1.31 2011/02/21 02:58:02 jakllsch Exp */ /*- @@ -95,14 +95,16 @@ set_geometry(struct biosdisk_ll *d, stru media = edi->bio->Media; d->secsize = media->BlockSize; - d->type = BIOSDISK_TYPE_HD; + d->type = edi->type; d->flags = BIOSDISK_INT13EXT; - ed->totsec = media->LastBlock + 1; - ed->sbytes = media->BlockSize; - ed->flags = 0; - if (media->RemovableMedia) - ed->flags |= EXTINFO_REMOVABLE; + if (ed != NULL) { + ed->totsec = media->LastBlock + 1; + ed->sbytes = media->BlockSize; + ed->flags = 0; + if (media->RemovableMedia) + ed->flags |= EXTINFO_REMOVABLE; + } return 0; } Index: src/sys/arch/i386/stand/efiboot/efiboot.c diff -u src/sys/arch/i386/stand/efiboot/efiboot.c:1.4 src/sys/arch/i386/stand/efiboot/efiboot.c:1.4.10.1 --- src/sys/arch/i386/stand/efiboot/efiboot.c:1.4 Sat Feb 11 10:23:39 2017 +++ src/sys/arch/i386/stand/efiboot/efiboot.c Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: efiboot.c,v 1.4 2017/02/11 10:23:39 nonaka Exp $ */ +/* $NetBSD: efiboot.c,v 1.4.10.1 2018/03/13 14:54:52 martin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -28,11 +28,13 @@ #include "efiboot.h" +#include "biosdisk_ll.h" #include "bootinfo.h" #include "devopen.h" EFI_HANDLE IH; EFI_DEVICE_PATH *efi_bootdp; +int efi_bootdp_type = BIOSDISK_TYPE_HD; EFI_LOADED_IMAGE *efi_li; uintptr_t efi_main_sp; physaddr_t efi_loadaddr, efi_kernel_start; @@ -71,15 +73,13 @@ efi_main(EFI_HANDLE imageHandle, EFI_SYS &DevicePathProtocol, (void **)&dp0); if (EFI_ERROR(status)) Panic(L"HandleProtocol(DevicePathProtocol): %r", status); + efi_bootdp = dp0; for (dp = dp0; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) { - if (DevicePathType(dp) == MEDIA_DEVICE_PATH) - continue; - if (DevicePathSubType(dp) == MEDIA_HARDDRIVE_DP) { - boot_biosdev = 0x80; - efi_bootdp = dp; + if (DevicePathType(dp) == MEDIA_DEVICE_PATH && + DevicePathSubType(dp) == MEDIA_CDROM_DP) { + efi_bootdp_type = BIOSDISK_TYPE_CD; break; } - break; } efi_disk_probe(); Index: src/sys/arch/i386/stand/lib/biosdisk.c diff -u src/sys/arch/i386/stand/lib/biosdisk.c:1.46 src/sys/arch/i386/stand/lib/biosdisk.c:1.46.6.1 --- src/sys/arch/i386/stand/lib/biosdisk.c:1.46 Tue Jan 24 11:09:14 2017 +++ src/sys/arch/i386/stand/lib/biosdisk.c Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: biosdisk.c,v 1.46 2017/01/24 11:09:14 nonaka Exp $ */ +/* $NetBSD: biosdisk.c,v 1.46.6.1 2018/03/13 14:54:52 martin Exp $ */ /* * Copyright (c) 1996, 1998 @@ -89,27 +89,18 @@ #include "bootinfo.h" #endif -#define BUFSIZE 2048 /* must be large enough for a CD sector */ +#ifndef BIOSDISK_BUFSIZE +#define BIOSDISK_BUFSIZE 2048 /* must be large enough for a CD sector */ +#endif #define BIOSDISKNPART 26 struct biosdisk { struct biosdisk_ll ll; daddr_t boff; - char buf[BUFSIZE]; + char buf[BIOSDISK_BUFSIZE]; #if !defined(NO_DISKLABEL) || !defined(NO_GPT) - struct { - daddr_t offset; - daddr_t size; - int fstype; -#ifdef EFIBOOT - const struct gpt_part { - const struct uuid *guid; - const char *name; - } *guid; - uint64_t attr; -#endif - } part[BIOSDISKNPART]; + struct biosdisk_partition part[BIOSDISKNPART]; #endif }; @@ -178,6 +169,10 @@ static struct btinfo_bootwedge bi_wedge; #define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */ +#ifndef devb2cdb +#define devb2cdb(bno) (((bno) * DEV_BSIZE) / ISO_DEFAULT_BLOCK_SIZE) +#endif + int biosdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize) @@ -191,7 +186,7 @@ biosdisk_strategy(void *devdata, int fla d = (struct biosdisk *) devdata; if (d->ll.type == BIOSDISK_TYPE_CD) - dblk = dblk * DEV_BSIZE / ISO_DEFAULT_BLOCK_SIZE; + dblk = devb2cdb(dblk); dblk += d->boff; @@ -517,6 +512,39 @@ read_minix_subp(struct biosdisk *d, stru return 0; } +#if defined(EFIBOOT) && defined(SUPPORT_CD9660) +static int +check_cd9660(struct biosdisk *d) +{ + struct biosdisk_extinfo ed; + struct iso_primary_descriptor *vd; + daddr_t bno; + + for (bno = 16;; bno++) { + if (readsects(&d->ll, bno, 1, d->buf, 0)) + return -1; + vd = (struct iso_primary_descriptor *)d->buf; + if (memcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0) + return -1; + if (isonum_711(vd->type) == ISO_VD_END) + return -1; + if (isonum_711(vd->type) == ISO_VD_PRIMARY) + break; + } + if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE) + return -1; + + if (set_geometry(&d->ll, &ed)) + return -1; + + memset(d->part, 0, sizeof(d->part)); + d->part[0].fstype = FS_ISO9660; + d->part[0].offset = 0; + d->part[0].size = ed.totsec; + return 0; +} +#endif + static int read_label(struct biosdisk *d) { @@ -624,6 +652,13 @@ read_label(struct biosdisk *d) if (error >= 0) return error; +#if defined(EFIBOOT) && defined(SUPPORT_CD9660) + /* Check CD/DVD */ + error = check_cd9660(d); + if (error >= 0) + return error; +#endif + /* * Nothing at start of disk, return info from mbr partitions. */ @@ -774,6 +809,7 @@ biosdisk_findpartition(int biosdev, dadd case FS_RAID: case FS_CCD: case FS_CGD: + case FS_ISO9660: break; default: @@ -798,6 +834,43 @@ biosdisk_findpartition(int biosdev, dadd #endif /* NO_DISKLABEL && NO_GPT */ } +int +biosdisk_readpartition(int biosdev, struct biosdisk_partition **partpp, + int *rnum) +{ +#if defined(NO_DISKLABEL) && defined(NO_GPT) + return ENOTSUP; +#else + struct biosdisk *d; + struct biosdisk_partition *part; + int rv; + + /* Look for netbsd partition that is the dos boot one */ + d = alloc_biosdisk(biosdev); + if (d == NULL) + return ENOMEM; + + if (read_partitions(d)) { + rv = EINVAL; + goto out; + } + + part = alloc(sizeof(d->part)); + if (part == NULL) { + rv = ENOMEM; + goto out; + } + + memcpy(part, d->part, sizeof(d->part)); + *partpp = part; + *rnum = (int)__arraycount(d->part); + rv = 0; +out: + dealloc(d, sizeof(*d)); + return rv; +#endif /* NO_DISKLABEL && NO_GPT */ +} + #ifdef _STANDALONE static void add_biosdisk_bootinfo(void) Index: src/sys/arch/i386/stand/lib/biosdisk.h diff -u src/sys/arch/i386/stand/lib/biosdisk.h:1.8 src/sys/arch/i386/stand/lib/biosdisk.h:1.8.52.1 --- src/sys/arch/i386/stand/lib/biosdisk.h:1.8 Fri Dec 24 20:36:51 2010 +++ src/sys/arch/i386/stand/lib/biosdisk.h Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: biosdisk.h,v 1.8 2010/12/24 20:36:51 jakllsch Exp $ */ +/* $NetBSD: biosdisk.h,v 1.8.52.1 2018/03/13 14:54:52 martin Exp $ */ /* * Copyright (c) 1996 @@ -25,8 +25,22 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +struct biosdisk_partition { + daddr_t offset; + daddr_t size; + int fstype; +#ifdef EFIBOOT + const struct gpt_part { + const struct uuid *guid; + const char *name; + } *guid; + uint64_t attr; +#endif +}; + int biosdisk_strategy(void *, int, daddr_t, size_t, void *, size_t *); int biosdisk_open(struct open_file *, ...); int biosdisk_close(struct open_file *); int biosdisk_ioctl(struct open_file *, u_long, void *); int biosdisk_findpartition(int, daddr_t); +int biosdisk_readpartition(int, struct biosdisk_partition **, int *); Index: src/sys/arch/i386/stand/lib/biosdisk_ll.h diff -u src/sys/arch/i386/stand/lib/biosdisk_ll.h:1.15 src/sys/arch/i386/stand/lib/biosdisk_ll.h:1.15.90.1 --- src/sys/arch/i386/stand/lib/biosdisk_ll.h:1.15 Tue Dec 25 18:33:34 2007 +++ src/sys/arch/i386/stand/lib/biosdisk_ll.h Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: biosdisk_ll.h,v 1.15 2007/12/25 18:33:34 perry Exp $ */ +/* $NetBSD: biosdisk_ll.h,v 1.15.90.1 2018/03/13 14:54:52 martin Exp $ */ /* * Copyright (c) 1996 @@ -120,7 +120,9 @@ struct biosdisk_extinfo { #define EXTINFO_LOCKABLE 0x0020 /* device is lockable */ #define EXTINFO_MAXGEOM 0x0040 /* geometry set to max; no media */ +#ifndef BIOSDISK_DEFAULT_SECSIZE #define BIOSDISK_DEFAULT_SECSIZE 512 +#endif int set_geometry(struct biosdisk_ll *, struct biosdisk_extinfo *); int readsects(struct biosdisk_ll *, daddr_t, int, char *, int); Index: src/sys/lib/libsa/cd9660.c diff -u src/sys/lib/libsa/cd9660.c:1.30 src/sys/lib/libsa/cd9660.c:1.30.22.1 --- src/sys/lib/libsa/cd9660.c:1.30 Thu Mar 20 03:13:18 2014 +++ src/sys/lib/libsa/cd9660.c Tue Mar 13 14:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660.c,v 1.30 2014/03/20 03:13:18 christos Exp $ */ +/* $NetBSD: cd9660.c,v 1.30.22.1 2018/03/13 14:54:52 martin Exp $ */ /* * Copyright (C) 1996 Wolfgang Solfrank. @@ -71,7 +71,9 @@ struct ptable_ent { #define PTFIXSZ 8 #define PTSIZE(pp) roundup(PTFIXSZ + isonum_711((pp)->namlen), 2) +#ifndef cdb2devb #define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / DEV_BSIZE) +#endif static int pnmatch(const char *, struct ptable_ent *); static int dirmatch(const char *, struct iso_directory_record *); Added files: Index: src/sys/arch/i386/stand/efiboot/efidev.c diff -u /dev/null src/sys/arch/i386/stand/efiboot/efidev.c:1.1.2.2 --- /dev/null Tue Mar 13 14:54:52 2018 +++ src/sys/arch/i386/stand/efiboot/efidev.c Tue Mar 13 14:54:52 2018 @@ -0,0 +1,59 @@ +/* $NetBSD: efidev.c,v 1.1.2.2 2018/03/13 14:54:52 martin Exp $ */ +/* $OpenBSD: efiboot.c,v 1.28 2017/11/25 19:02:07 patrick Exp $ */ + +/* + * Copyright (c) 2015 YASUOKA Masahiko <yasu...@yasuoka.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "efiboot.h" + +/* + * Determine the number of nodes up to, but not including, the first + * node of the specified type. + */ +int +efi_device_path_depth(EFI_DEVICE_PATH *dp, int dptype) +{ + int i; + + for (i = 0; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp), i++) { + if (DevicePathType(dp) == dptype) + return (i); + } + + return (-1); +} + +int +efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int deptn) +{ + int i, cmp; + + for (i = 0; i < deptn; i++) { + if (IsDevicePathEnd(dpa) || IsDevicePathEnd(dpb)) + return ((IsDevicePathEnd(dpa) && IsDevicePathEnd(dpb)) + ? 0 : (IsDevicePathEnd(dpa))? -1 : 1); + cmp = DevicePathNodeLength(dpa) - DevicePathNodeLength(dpb); + if (cmp) + return (cmp); + cmp = memcmp(dpa, dpb, DevicePathNodeLength(dpa)); + if (cmp) + return (cmp); + dpa = NextDevicePathNode(dpa); + dpb = NextDevicePathNode(dpb); + } + + return (0); +}