On Fri, Aug 02, 2019 at 03:16:55PM -0400, sven falempin wrote: > Dear ARM gurus, > > I m trying to tftp boot last snaphots on pine64+. > Not sure if it s possible. > So far I tried loading minitroot like an idiot and then, a boolader, > now I cant get the efi bootloader to do some tftp ( which I guess is normal ) > But maybe I am just missing a small pieces.
Hi, our efiboot/BOOTAA64.EFI checks for the DHCP ack received bit to see if we should look at the the contents of the DHCP ack for the address information. U-Boot unfortunately does not set it, and I have been trying to up- stream that change on and off a few times: https://marc.info/?l=u-boot&m=155488833610034&w=2 Thus, my bet is that it doesn't work because of the missing bit. Patrick > I also created etc/boot.conf in the tftp directory.. just in case. > > getting some bsd code to boot : > > => dhcp > BOOTP broadcast 1 > DHCP client bound to address 172.16.65.55 (1445 ms) > Using ethernet@01c30000 device > TFTP from server 172.16.65.1; our IP address is 172.16.65.55 > Filename 'BOOTAA64.EFI'. > Load address: 0x42000000 > Loading: ########### > 5.1 MiB/s > done > => bootefi 0x42000000 > ## Starting EFI application at 42000000 ... > Scanning disks on usb... > Disk usb0 not ready > Disk usb1 not ready > Disk usb2 not ready > Disk usb3 not ready > Scanning disks on mmc... > MMC Device 1 not found > MMC Device 2 not found > MMC Device 3 not found > Found 3 disks > WARNING: Invalid device tree, expect boot to fail > disks: sd0 > >> OpenBSD/arm64 BOOTAA64 0.16 > open(tftp0a:/etc/boot.conf): Operation not permitted > boot> > booting tftp0a:/bsd: open tftp0a:/bsd: Operation not permitted > failed(1). will try /bsd > boot> > booting tftp0a:/bsd: open tftp0a:/bsd: Operation not permitted > failed(1). will try /bsd > Turning timeout off. > boot> l > stat(tftp0a:/.): Operation not permitted > boot> l > stat(tftp0a:/.): Operation not permitted > boot> l > stat(tftp0a:/.): Operation not permitted > boot> boot tftp:bsd.rd > cannot open tftp:/etc/random.seed: bad drive number > booting tftp:bsd.rd: open tftp:bsd.rd: bad drive number > failed(98). will try /bsd > boot> boot 172.16.65.1:/bsd.rd > boot> boot tftp:/bsd.rd > cannot open tftp:/etc/random.seed: bad drive number > booting tftp:/bsd.rd: open tftp:/bsd.rd: bad drive number > failed(98). will try /bsd > boot> boot tftp0a:/bsd.rd > booting tftp0a:/bsd.rd: open tftp0a:/bsd.rd: Operation not permitted > failed(1). will try /bsd > > is there some kind of trick to boot this ? > > > On Thu, Jan 31, 2019 at 7:54 AM Mark Kettenis <[email protected]> wrote: > > > > > Date: Wed, 30 Jan 2019 22:31:31 +0100 > > > From: Patrick Wildt <[email protected]> > > > > > > Hi, > > > > > > to boot a pinebook with softraid crypto there are three parts that need > > > to be implemented, which this diff hopefully does well enough. > > > > > > First, our EFI bootloader so far only supports one disk, so we need to > > > extend this so we can see all connected block devices. The second part > > > is adding the softraid code, which probes for softraid partitions on the > > > block devices and "spawns" its own block device. At last, we need to > > > push the softraid uuid and key up to the kernel. > > > > > > Pushing the informaton to the kernel is the easiest part. We can add > > > another openbsd-specific property in the device tree which we read out > > > early on, so that we can zero the space in the device tree so it can not > > > be read by anyone else. > > > > > > For the other part there's a bit more to do. Very early on efiboot > > > looks for the boot device. While doing that, we create a list of block > > > devices. While there, already try to read the disklabel because after > > > this the softraid probing needs to know the partition table. > > > > > > We then call srprobe() which will go over the disklist to look for a > > > disk that contains RAID volumes, but calling the disk's diskio and > > > strategy function to read from the device. This creates the sr_volumes > > > list of softraid volumes. The MI boot code will then look for the boot > > > device name by calling devboot(). If we don't have the device path for > > > the boot device, it's a PXE boot. Otherwise we will find it in either > > > the disklist or sr_volumes list. > > > > > > The next part is the MI code opening the device, looking for a file- > > > system. The boot device name now is e.g. sr0a, which will then be > > > looked up in the devsw[] array. From there it's straight forward. > > > Softraid maps the unit number to a volume, the volume already has a > > > pointer to the diskinfo structure from the actual device and then > > > calls the IO functions of that device. > > > > > > softraid_arm64.[ch] is copied from amd64 and adjusted a little bit > > > for arm64, including adding the small devsw[] abstraction. > > > > > > With this I can successfully boot from softraid crypto on bluhm@'s > > > Pinebook. > > > > > > Feedback? > > > > Apart from the property names, this looks good to me. So feel free to > > go ahead once you changed those properties. > > > > > diff --git sys/arch/arm64/arm64/machdep.c sys/arch/arm64/arm64/machdep.c > > > index 45f6451066a..03bc8464f3a 100644 > > > --- sys/arch/arm64/arm64/machdep.c > > > +++ sys/arch/arm64/arm64/machdep.c > > > @@ -30,6 +30,7 @@ > > > #include <sys/msgbuf.h> > > > #include <sys/buf.h> > > > #include <sys/termios.h> > > > +#include <sys/sensors.h> > > > > > > #include <net/if.h> > > > #include <uvm/uvm.h> > > > @@ -49,6 +50,11 @@ > > > > > > #include <dev/acpi/efi.h> > > > > > > +#include "softraid.h" > > > +#if NSOFTRAID > 0 > > > +#include <dev/softraidvar.h> > > > +#endif > > > + > > > char *boot_args = NULL; > > > char *boot_file = ""; > > > > > > @@ -826,6 +832,22 @@ initarm(struct arm64_bootparams *abp) > > > bootmac = lladdr; > > > } > > > > > > + len = fdt_node_property(node, "openbsd,bootsr-uuid", &prop); > > > +#if NSOFTRAID > 0 > > > + if (len == sizeof(sr_bootuuid)) > > > + memcpy(&sr_bootuuid, prop, sizeof(sr_bootuuid)); > > > +#endif > > > + if (len > 0) > > > + explicit_bzero(prop, len); > > > + > > > + len = fdt_node_property(node, "openbsd,bootsr-maskkey", > > > &prop); > > > +#if NSOFTRAID > 0 > > > + if (len == sizeof(sr_bootkey)) > > > + memcpy(&sr_bootkey, prop, sizeof(sr_bootkey)); > > > +#endif > > > + if (len > 0) > > > + explicit_bzero(prop, len); > > > + > > > len = fdt_node_property(node, "openbsd,uefi-mmap-start", > > > &prop); > > > if (len == sizeof(mmap_start)) > > > mmap_start = bemtoh64((uint64_t *)prop); > > > diff --git sys/arch/arm64/stand/efiboot/Makefile > > > sys/arch/arm64/stand/efiboot/Makefile > > > index 36eecd6ca9c..d0ec46662ee 100644 > > > --- sys/arch/arm64/stand/efiboot/Makefile > > > +++ sys/arch/arm64/stand/efiboot/Makefile > > > @@ -10,6 +10,7 @@ INSTALL_STRIP= > > > BINDIR= /usr/mdec > > > SRCS= start.S self_reloc.c efiboot.c conf.c exec.c > > > efiacpi.c > > > SRCS+= efidev.c efipxe.c efirng.c fdt.c dt_blob.S > > > +SRCS+= softraid_arm64.c > > > > > > S= ${.CURDIR}/../../../.. > > > EFIDIR= ${S}/stand/efi > > > @@ -31,6 +32,8 @@ SRCS+= close.c closeall.c cons.c cread.c dev.c > > > disklabel.c dkcksum.c fstat.c \ > > > SRCS+= loadfile.c > > > SRCS+= ufs.c > > > SRCS+= arp.c ether.c globals.c in_cksum.c net.c netif.c netudp.c > > > tftp.c > > > +SRCS+= aes_xts.c bcrypt_pbkdf.c blowfish.c explicit_bzero.c > > > hmac_sha1.c \ > > > + pkcs5_pbkdf2.c rijndael.c sha1.c sha2.c softraid.c > > > > > > .PATH: ${S}/lib/libkern/arch/arm64 ${S}/lib/libkern > > > SRCS+= divdi3.c moddi3.c qdivrem.c strlcpy.c strlen.c > > > diff --git sys/arch/arm64/stand/efiboot/conf.c > > > sys/arch/arm64/stand/efiboot/conf.c > > > index 5e8fd5fa0e7..be301b4a9d4 100644 > > > --- sys/arch/arm64/stand/efiboot/conf.c > > > +++ sys/arch/arm64/stand/efiboot/conf.c > > > @@ -27,14 +27,23 @@ > > > */ > > > > > > #include <sys/param.h> > > > +#include <sys/queue.h> > > > +#include <sys/disklabel.h> > > > #include <lib/libsa/stand.h> > > > #include <lib/libsa/tftp.h> > > > #include <lib/libsa/ufs.h> > > > #include <dev/cons.h> > > > > > > +#include <dev/biovar.h> > > > +#include <dev/softraidvar.h> > > > + > > > +#include <efi.h> > > > + > > > +#include "disk.h" > > > #include "efiboot.h" > > > #include "efidev.h" > > > #include "efipxe.h" > > > +#include "softraid_arm64.h" > > > > > > const char version[] = "0.13"; > > > int debug = 0; > > > @@ -52,6 +61,7 @@ int nfsys = nitems(file_system); > > > struct devsw devsw[] = { > > > { "tftp", tftpstrategy, tftpopen, tftpclose, tftpioctl }, > > > { "sd", efistrategy, efiopen, eficlose, efiioctl }, > > > + { "sr", srstrategy, sropen, srclose, srioctl }, > > > }; > > > int ndevs = nitems(devsw); > > > > > > diff --git sys/arch/arm64/stand/efiboot/disk.h > > > sys/arch/arm64/stand/efiboot/disk.h > > > index 4007259da32..2a6bf3db93f 100644 > > > --- sys/arch/arm64/stand/efiboot/disk.h > > > +++ sys/arch/arm64/stand/efiboot/disk.h > > > @@ -3,6 +3,8 @@ > > > #ifndef _DISK_H > > > #define _DISK_H > > > > > > +#include <sys/queue.h> > > > + > > > typedef struct efi_diskinfo { > > > EFI_BLOCK_IO *blkio; > > > UINT32 mediaid; > > > @@ -11,10 +13,21 @@ typedef struct efi_diskinfo { > > > struct diskinfo { > > > struct efi_diskinfo ed; > > > struct disklabel disklabel; > > > + struct sr_boot_volume *sr_vol; > > > + > > > + u_int part; > > > + u_int flags; > > > +#define DISKINFO_FLAG_GOODLABEL (1 << 0) > > > > > > - u_int sc_part; > > > + int (*diskio)(int, struct diskinfo *, u_int, int, void *); > > > + int (*strategy)(void *, int, daddr32_t, size_t, void *, size_t *); > > > + > > > + TAILQ_ENTRY(diskinfo) list; > > > }; > > > +TAILQ_HEAD(disklist_lh, diskinfo); > > > + > > > +extern struct diskinfo *bootdev_dip; > > > > > > -extern struct diskinfo diskinfo; > > > +extern struct disklist_lh disklist; > > > > > > #endif /* _DISK_H */ > > > diff --git sys/arch/arm64/stand/efiboot/efiboot.c > > > sys/arch/arm64/stand/efiboot/efiboot.c > > > index 4dc9d7e32fa..f3045639d91 100644 > > > --- sys/arch/arm64/stand/efiboot/efiboot.c > > > +++ sys/arch/arm64/stand/efiboot/efiboot.c > > > @@ -28,14 +28,21 @@ > > > #include <efiprot.h> > > > #include <eficonsctl.h> > > > > > > +#include <dev/biovar.h> > > > +#include <dev/softraidvar.h> > > > + > > > #include <lib/libkern/libkern.h> > > > +#include <lib/libsa/softraid.h> > > > #include <stand/boot/cmd.h> > > > > > > +#include "libsa.h" > > > #include "disk.h" > > > +#include "softraid_arm64.h" > > > + > > > +#include "efidev.h" > > > #include "efiboot.h" > > > #include "eficall.h" > > > #include "fdt.h" > > > -#include "libsa.h" > > > > > > EFI_SYSTEM_TABLE *ST; > > > EFI_BOOT_SERVICES *BS; > > > @@ -173,19 +180,23 @@ efi_heap_init(void) > > > panic("BS->AllocatePages()"); > > > } > > > > > > -EFI_BLOCK_IO *disk; > > > +struct disklist_lh disklist; > > > +struct diskinfo *bootdev_dip; > > > > > > void > > > efi_diskprobe(void) > > > { > > > - int i, depth = -1; > > > + int i, bootdev = 0, depth = -1; > > > UINTN sz; > > > EFI_STATUS status; > > > EFI_HANDLE *handles = NULL; > > > EFI_BLOCK_IO *blkio; > > > EFI_BLOCK_IO_MEDIA *media; > > > + struct diskinfo *di; > > > EFI_DEVICE_PATH *dp; > > > > > > + TAILQ_INIT(&disklist); > > > + > > > sz = 0; > > > status = EFI_CALL(BS->LocateHandle, ByProtocol, &blkio_guid, 0, > > > &sz, 0); > > > if (status == EFI_BUFFER_TOO_SMALL) { > > > @@ -217,20 +228,36 @@ efi_diskprobe(void) > > > media = blkio->Media; > > > if (media->LogicalPartition || !media->MediaPresent) > > > continue; > > > + di = alloc(sizeof(struct diskinfo)); > > > + efid_init(di, blkio); > > > > > > - if (efi_bootdp == NULL || depth == -1) > > > - continue; > > > + if (efi_bootdp == NULL || depth == -1 || bootdev != 0) > > > + goto next; > > > status = EFI_CALL(BS->HandleProtocol, handles[i], > > > &devp_guid, > > > (void **)&dp); > > > if (EFI_ERROR(status)) > > > - continue; > > > + goto next; > > > if (efi_device_path_ncmp(efi_bootdp, dp, depth) == 0) { > > > - disk = blkio; > > > - break; > > > + TAILQ_INSERT_HEAD(&disklist, di, list); > > > + bootdev_dip = di; > > > + bootdev = 1; > > > + continue; > > > } > > > +next: > > > + TAILQ_INSERT_TAIL(&disklist, di, list); > > > } > > > > > > free(handles, sz); > > > + > > > + /* Print available disks and probe for softraid. */ > > > + i = 0; > > > + printf("disks:"); > > > + TAILQ_FOREACH(di, &disklist, list) { > > > + printf(" sd%d%s", i, di == bootdev_dip ? "*" : ""); > > > + i++; > > > + } > > > + srprobe(); > > > + printf("\n"); > > > } > > > > > > /* > > > @@ -370,6 +397,7 @@ static EFI_GUID fdt_guid = FDT_TABLE_GUID; > > > void * > > > efi_makebootargs(char *bootargs) > > > { > > > + struct sr_boot_volume *bv; > > > u_char bootduid[8]; > > > u_char zero[8] = { 0 }; > > > uint64_t uefi_system_table = htobe64((uintptr_t)ST); > > > @@ -399,12 +427,27 @@ efi_makebootargs(char *bootargs) > > > fdt_node_add_property(node, "bootargs", bootargs, len); > > > > > > /* Pass DUID of the boot disk. */ > > > - memcpy(&bootduid, diskinfo.disklabel.d_uid, sizeof(bootduid)); > > > - if (memcmp(bootduid, zero, sizeof(bootduid)) != 0) { > > > - fdt_node_add_property(node, "openbsd,bootduid", bootduid, > > > + if (bootdev_dip) { > > > + memcpy(&bootduid, bootdev_dip->disklabel.d_uid, > > > sizeof(bootduid)); > > > + if (memcmp(bootduid, zero, sizeof(bootduid)) != 0) { > > > + fdt_node_add_property(node, "openbsd,bootduid", > > > + bootduid, sizeof(bootduid)); > > > + } > > > + > > > + if (bootdev_dip->sr_vol != NULL) { > > > + bv = bootdev_dip->sr_vol; > > > + fdt_node_add_property(node, "openbsd,bootsr-uuid", > > > + &bv->sbv_uuid, sizeof(bv->sbv_uuid)); > > > + if (bv->sbv_maskkey != NULL) > > > + fdt_node_add_property(node, > > > + "openbsd,bootsr-maskkey", > > > bv->sbv_maskkey, > > > + SR_CRYPTO_MAXKEYBYTES); > > > + } > > > } > > > > > > + sr_clear_keys(); > > > + > > > /* Pass netboot interface address. */ > > > if (bootmac) > > > fdt_node_add_property(node, "openbsd,bootmac", bootmac, 6); > > > @@ -558,10 +601,51 @@ getsecs(void) > > > void > > > devboot(dev_t dev, char *p) > > > { > > > - if (disk) > > > - strlcpy(p, "sd0a", 5); > > > - else > > > + struct sr_boot_volume *bv; > > > + struct sr_boot_chunk *bc; > > > + struct diskinfo *dip; > > > + int sd_boot_vol = 0; > > > + int sr_boot_vol = -1; > > > + int part_type = FS_UNUSED; > > > + > > > + if (bootdev_dip == NULL) { > > > strlcpy(p, "tftp0a", 7); > > > + return; > > > + } > > > + > > > + TAILQ_FOREACH(dip, &disklist, list) { > > > + if (bootdev_dip == dip) > > > + break; > > > + sd_boot_vol++; > > > + } > > > + > > > + /* > > > + * Determine the partition type for the 'a' partition of the > > > + * boot device. > > > + */ > > > + if ((bootdev_dip->flags & DISKINFO_FLAG_GOODLABEL) != 0) > > > + part_type = bootdev_dip->disklabel.d_partitions[0].p_fstype; > > > + > > > + /* > > > + * See if we booted from a disk that is a member of a bootable > > > + * softraid volume. > > > + */ > > > + SLIST_FOREACH(bv, &sr_volumes, sbv_link) { > > > + SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link) > > > + if (bc->sbc_diskinfo == bootdev_dip) > > > + sr_boot_vol = bv->sbv_unit; > > > + if (sr_boot_vol != -1) > > > + break; > > > + } > > > + > > > + if (sr_boot_vol != -1 && part_type != FS_BSDFFS) { > > > + strlcpy(p, "sr0a", 5); > > > + p[2] = '0' + sr_boot_vol; > > > + return; > > > + } > > > + > > > + strlcpy(p, "sd0a", 5); > > > + p[2] = '0' + sd_boot_vol; > > > } > > > > > > int > > > diff --git sys/arch/arm64/stand/efiboot/efidev.c > > > sys/arch/arm64/stand/efiboot/efidev.c > > > index 91c1ce5f90d..3cd4fac874b 100644 > > > --- sys/arch/arm64/stand/efiboot/efidev.c > > > +++ sys/arch/arm64/stand/efiboot/efidev.c > > > @@ -48,17 +48,30 @@ extern int debug; > > > #define EFI_BLKSPERSEC(_ed) ((_ed)->blkio->Media->BlockSize / DEV_BSIZE) > > > #define EFI_SECTOBLK(_ed, _n) ((_n) * EFI_BLKSPERSEC(_ed)) > > > > > > -extern EFI_BLOCK_IO *disk; > > > -struct diskinfo diskinfo; > > > - > > > static EFI_STATUS > > > efid_io(int, efi_diskinfo_t, u_int, int, void *); > > > static int efid_diskio(int, struct diskinfo *, u_int, int, void *); > > > +const char * efi_getdisklabel(efi_diskinfo_t, struct disklabel *); > > > static int efi_getdisklabel_cd9660(efi_diskinfo_t, struct disklabel > > > *); > > > static u_int findopenbsd(efi_diskinfo_t, const char **); > > > static u_int findopenbsd_gpt(efi_diskinfo_t, const char **); > > > static int gpt_chk_mbr(struct dos_partition *, u_int64_t); > > > > > > +void > > > +efid_init(struct diskinfo *dip, void *handle) > > > +{ > > > + EFI_BLOCK_IO *blkio = handle; > > > + > > > + memset(dip, 0, sizeof(struct diskinfo)); > > > + dip->ed.blkio = blkio; > > > + dip->ed.mediaid = blkio->Media->MediaId; > > > + dip->diskio = efid_diskio; > > > + dip->strategy = efistrategy; > > > + > > > + if (efi_getdisklabel(&dip->ed, &dip->disklabel) == NULL) > > > + dip->flags |= DISKINFO_FLAG_GOODLABEL; > > > +} > > > + > > > static EFI_STATUS > > > efid_io(int rw, efi_diskinfo_t ed, u_int off, int nsect, void *buf) > > > { > > > @@ -471,32 +484,33 @@ efi_getdisklabel_cd9660(efi_diskinfo_t ed, struct > > > disklabel *label) > > > int > > > efiopen(struct open_file *f, ...) > > > { > > > - struct diskinfo *dip = &diskinfo; > > > + struct diskinfo *dip = NULL; > > > va_list ap; > > > u_int unit, part; > > > - const char *err; > > > - > > > - if (disk == NULL) > > > - return (ENXIO); > > > + int i = 0; > > > > > > va_start(ap, f); > > > unit = va_arg(ap, u_int); > > > part = va_arg(ap, u_int); > > > va_end(ap); > > > > > > - if (unit != 0 || part >= MAXPARTITIONS) > > > + if (part >= MAXPARTITIONS) > > > return (ENXIO); > > > > > > - diskinfo.ed.blkio = disk; > > > - diskinfo.ed.mediaid = disk->Media->MediaId; > > > - diskinfo.sc_part = part; > > > - > > > - err = efi_getdisklabel(&dip->ed, &dip->disklabel); > > > - if (err) { > > > - printf("%s\n", err); > > > - return EINVAL; > > > + TAILQ_FOREACH(dip, &disklist, list) { > > > + if (i == unit) > > > + break; > > > + i++; > > > } > > > > > > + if (dip == NULL) > > > + return (ENXIO); > > > + > > > + if ((dip->flags & DISKINFO_FLAG_GOODLABEL) == 0) > > > + return (ENXIO); > > > + > > > + dip->part = part; > > > + bootdev_dip = dip; > > > f->f_devdata = dip; > > > > > > return 0; > > > @@ -512,7 +526,7 @@ efistrategy(void *devdata, int rw, daddr32_t blk, > > > size_t size, void *buf, > > > > > > nsect = (size + DEV_BSIZE - 1) / DEV_BSIZE; > > > blk += DL_SECTOBLK(&dip->disklabel, > > > - dip->disklabel.d_partitions[dip->sc_part].p_offset); > > > + dip->disklabel.d_partitions[dip->part].p_offset); > > > > > > if (blk < 0) > > > error = EINVAL; > > > diff --git sys/arch/arm64/stand/efiboot/efidev.h > > > sys/arch/arm64/stand/efiboot/efidev.h > > > index a771bfcc1f7..95a09463ab5 100644 > > > --- sys/arch/arm64/stand/efiboot/efidev.h > > > +++ sys/arch/arm64/stand/efiboot/efidev.h > > > @@ -29,6 +29,7 @@ > > > */ > > > > > > /* efidev.c */ > > > +void efid_init(struct diskinfo *, void *handle); > > > int efiopen(struct open_file *, ...); > > > int efistrategy(void *, int, daddr32_t, size_t, void *, size_t > > > *); > > > int eficlose(struct open_file *); > > > diff --git sys/arch/arm64/stand/efiboot/softraid_arm64.c > > > sys/arch/arm64/stand/efiboot/softraid_arm64.c > > > new file mode 100644 > > > index 00000000000..693198d2357 > > > --- /dev/null > > > +++ sys/arch/arm64/stand/efiboot/softraid_arm64.c > > > @@ -0,0 +1,665 @@ > > > +/* $OpenBSD: softraid_amd64.c,v 1.5 2017/12/18 12:53:33 fcambus Exp $ > > > */ > > > + > > > +/* > > > + * Copyright (c) 2012 Joel Sing <[email protected]> > > > + * > > > + * 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 <sys/param.h> > > > +#include <sys/queue.h> > > > +#include <sys/disklabel.h> > > > +#include <sys/reboot.h> > > > + > > > +#include <dev/biovar.h> > > > +#include <dev/softraidvar.h> > > > + > > > +#include <lib/libsa/aes_xts.h> > > > +#include <lib/libsa/softraid.h> > > > +#include <lib/libz/zlib.h> > > > + > > > +#include <efi.h> > > > + > > > +#include "libsa.h" > > > +#include "disk.h" > > > +#include "efidev.h" > > > +#include "softraid_arm64.h" > > > + > > > +static int gpt_chk_mbr(struct dos_partition *, u_int64_t); > > > +static uint64_t findopenbsd_gpt(struct sr_boot_volume *, const char **); > > > + > > > +void > > > +srprobe_meta_opt_load(struct sr_metadata *sm, struct sr_meta_opt_head > > > *som) > > > +{ > > > + struct sr_meta_opt_hdr *omh; > > > + struct sr_meta_opt_item *omi; > > > +#if 0 > > > + u_int8_t checksum[MD5_DIGEST_LENGTH]; > > > +#endif > > > + int i; > > > + > > > + /* Process optional metadata. */ > > > + omh = (struct sr_meta_opt_hdr *)((u_int8_t *)(sm + 1) + > > > + sizeof(struct sr_meta_chunk) * sm->ssdi.ssd_chunk_no); > > > + for (i = 0; i < sm->ssdi.ssd_opt_no; i++) { > > > + > > > +#ifdef BIOS_DEBUG > > > + printf("Found optional metadata of type %u, length %u\n", > > > + omh->som_type, omh->som_length); > > > +#endif > > > + > > > + /* Unsupported old fixed length optional metadata. */ > > > + if (omh->som_length == 0) { > > > + omh = (struct sr_meta_opt_hdr *)((void *)omh + > > > + SR_OLD_META_OPT_SIZE); > > > + continue; > > > + } > > > + > > > + /* Load variable length optional metadata. */ > > > + omi = alloc(sizeof(struct sr_meta_opt_item)); > > > + bzero(omi, sizeof(struct sr_meta_opt_item)); > > > + SLIST_INSERT_HEAD(som, omi, omi_link); > > > + omi->omi_som = alloc(omh->som_length); > > > + bzero(omi->omi_som, omh->som_length); > > > + bcopy(omh, omi->omi_som, omh->som_length); > > > + > > > +#if 0 > > > + /* XXX - Validate checksum. */ > > > + bcopy(&omi->omi_som->som_checksum, &checksum, > > > + MD5_DIGEST_LENGTH); > > > + bzero(&omi->omi_som->som_checksum, MD5_DIGEST_LENGTH); > > > + sr_checksum(sc, omi->omi_som, > > > + &omi->omi_som->som_checksum, omh->som_length); > > > + if (bcmp(&checksum, &omi->omi_som->som_checksum, > > > + sizeof(checksum))) > > > + panic("%s: invalid optional metadata checksum", > > > + DEVNAME(sc)); > > > +#endif > > > + > > > + omh = (struct sr_meta_opt_hdr *)((void *)omh + > > > + omh->som_length); > > > + } > > > +} > > > + > > > +void > > > +srprobe_keydisk_load(struct sr_metadata *sm) > > > +{ > > > + struct sr_meta_opt_hdr *omh; > > > + struct sr_meta_keydisk *skm; > > > + struct sr_boot_keydisk *kd; > > > + int i; > > > + > > > + /* Process optional metadata. */ > > > + omh = (struct sr_meta_opt_hdr *)((u_int8_t *)(sm + 1) + > > > + sizeof(struct sr_meta_chunk) * sm->ssdi.ssd_chunk_no); > > > + for (i = 0; i < sm->ssdi.ssd_opt_no; i++) { > > > + > > > + /* Unsupported old fixed length optional metadata. */ > > > + if (omh->som_length == 0) { > > > + omh = (struct sr_meta_opt_hdr *)((void *)omh + > > > + SR_OLD_META_OPT_SIZE); > > > + continue; > > > + } > > > + > > > + if (omh->som_type != SR_OPT_KEYDISK) { > > > + omh = (struct sr_meta_opt_hdr *)((void *)omh + > > > + omh->som_length); > > > + continue; > > > + } > > > + > > > + kd = alloc(sizeof(struct sr_boot_keydisk)); > > > + bcopy(&sm->ssdi.ssd_uuid, &kd->kd_uuid, > > > sizeof(kd->kd_uuid)); > > > + skm = (struct sr_meta_keydisk*)omh; > > > + bcopy(&skm->skm_maskkey, &kd->kd_key, sizeof(kd->kd_key)); > > > + SLIST_INSERT_HEAD(&sr_keydisks, kd, kd_link); > > > + } > > > +} > > > + > > > +void > > > +srprobe(void) > > > +{ > > > + struct sr_boot_volume *bv, *bv1, *bv2; > > > + struct sr_boot_chunk *bc, *bc1, *bc2; > > > + struct sr_meta_chunk *mc; > > > + struct sr_metadata *md; > > > + struct diskinfo *dip; > > > + struct partition *pp; > > > + int i, error, volno; > > > + daddr_t off; > > > + > > > + /* Probe for softraid volumes. */ > > > + SLIST_INIT(&sr_volumes); > > > + SLIST_INIT(&sr_keydisks); > > > + > > > + md = alloc(SR_META_SIZE * DEV_BSIZE); > > > + > > > + TAILQ_FOREACH(dip, &disklist, list) { > > > + > > > + /* Make sure disklabel has been read. */ > > > + if ((dip->flags & DISKINFO_FLAG_GOODLABEL) == 0) > > > + continue; > > > + > > > + for (i = 0; i < MAXPARTITIONS; i++) { > > > + > > > + pp = &dip->disklabel.d_partitions[i]; > > > + if (pp->p_fstype != FS_RAID || pp->p_size == 0) > > > + continue; > > > + > > > + /* Read softraid metadata. */ > > > + bzero(md, SR_META_SIZE * DEV_BSIZE); > > > + off = DL_SECTOBLK(&dip->disklabel, > > > DL_GETPOFFSET(pp)); > > > + off += SR_META_OFFSET; > > > + error = dip->diskio(F_READ, dip, off, SR_META_SIZE, > > > md); > > > + if (error) > > > + continue; > > > + > > > + /* Is this valid softraid metadata? */ > > > + if (md->ssdi.ssd_magic != SR_MAGIC) > > > + continue; > > > + > > > + /* XXX - validate checksum. */ > > > + > > > + /* Handle key disks separately... */ > > > + if (md->ssdi.ssd_level == SR_KEYDISK_LEVEL) { > > > + srprobe_keydisk_load(md); > > > + continue; > > > + } > > > + > > > + /* Locate chunk-specific metadata for this chunk. */ > > > + mc = (struct sr_meta_chunk *)(md + 1); > > > + mc += md->ssdi.ssd_chunk_id; > > > + > > > + bc = alloc(sizeof(struct sr_boot_chunk)); > > > + bc->sbc_diskinfo = dip; > > > + bc->sbc_disk = 0; > > > + bc->sbc_part = 'a' + i; > > > + > > > + bc->sbc_mm = 0; > > > + > > > + bc->sbc_chunk_id = md->ssdi.ssd_chunk_id; > > > + bc->sbc_ondisk = md->ssd_ondisk; > > > + bc->sbc_state = mc->scm_status; > > > + > > > + SLIST_FOREACH(bv, &sr_volumes, sbv_link) { > > > + if (bcmp(&md->ssdi.ssd_uuid, &bv->sbv_uuid, > > > + sizeof(md->ssdi.ssd_uuid)) == 0) > > > + break; > > > + } > > > + > > > + if (bv == NULL) { > > > + bv = alloc(sizeof(struct sr_boot_volume)); > > > + bzero(bv, sizeof(struct sr_boot_volume)); > > > + bv->sbv_level = md->ssdi.ssd_level; > > > + bv->sbv_volid = md->ssdi.ssd_volid; > > > + bv->sbv_chunk_no = md->ssdi.ssd_chunk_no; > > > + bv->sbv_flags = md->ssdi.ssd_vol_flags; > > > + bv->sbv_size = md->ssdi.ssd_size; > > > + bv->sbv_secsize = md->ssdi.ssd_secsize; > > > + bv->sbv_data_blkno = md->ssd_data_blkno; > > > + bcopy(&md->ssdi.ssd_uuid, &bv->sbv_uuid, > > > + sizeof(md->ssdi.ssd_uuid)); > > > + SLIST_INIT(&bv->sbv_chunks); > > > + SLIST_INIT(&bv->sbv_meta_opt); > > > + > > > + /* Load optional metadata for this volume. > > > */ > > > + srprobe_meta_opt_load(md, > > > &bv->sbv_meta_opt); > > > + > > > + /* Maintain volume order. */ > > > + bv2 = NULL; > > > + SLIST_FOREACH(bv1, &sr_volumes, sbv_link) { > > > + if (bv1->sbv_volid > bv->sbv_volid) > > > + break; > > > + bv2 = bv1; > > > + } > > > + if (bv2 == NULL) > > > + SLIST_INSERT_HEAD(&sr_volumes, bv, > > > + sbv_link); > > > + else > > > + SLIST_INSERT_AFTER(bv2, bv, > > > sbv_link); > > > + } > > > + > > > + /* Maintain chunk order. */ > > > + bc2 = NULL; > > > + SLIST_FOREACH(bc1, &bv->sbv_chunks, sbc_link) { > > > + if (bc1->sbc_chunk_id > bc->sbc_chunk_id) > > > + break; > > > + bc2 = bc1; > > > + } > > > + if (bc2 == NULL) > > > + SLIST_INSERT_HEAD(&bv->sbv_chunks, > > > + bc, sbc_link); > > > + else > > > + SLIST_INSERT_AFTER(bc2, bc, sbc_link); > > > + > > > + bv->sbv_chunks_found++; > > > + } > > > + } > > > + > > > + /* > > > + * Assemble RAID volumes. > > > + */ > > > + volno = 0; > > > + SLIST_FOREACH(bv, &sr_volumes, sbv_link) { > > > + > > > + /* Skip if this is a hotspare "volume". */ > > > + if (bv->sbv_level == SR_HOTSPARE_LEVEL && > > > + bv->sbv_chunk_no == 1) > > > + continue; > > > + > > > + /* Determine current ondisk version. */ > > > + bv->sbv_ondisk = 0; > > > + SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link) { > > > + if (bc->sbc_ondisk > bv->sbv_ondisk) > > > + bv->sbv_ondisk = bc->sbc_ondisk; > > > + } > > > + SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link) { > > > + if (bc->sbc_ondisk != bv->sbv_ondisk) > > > + bc->sbc_state = BIOC_SDOFFLINE; > > > + } > > > + > > > + /* XXX - Check for duplicate chunks. */ > > > + > > > + /* > > > + * Validate that volume has sufficient chunks for > > > + * read-only access. > > > + * > > > + * XXX - check chunk states. > > > + */ > > > + bv->sbv_state = BIOC_SVOFFLINE; > > > + switch (bv->sbv_level) { > > > + case 0: > > > + case 'C': > > > + case 'c': > > > + if (bv->sbv_chunk_no == bv->sbv_chunks_found) > > > + bv->sbv_state = BIOC_SVONLINE; > > > + break; > > > + > > > + case 1: > > > + if (bv->sbv_chunk_no == bv->sbv_chunks_found) > > > + bv->sbv_state = BIOC_SVONLINE; > > > + else if (bv->sbv_chunks_found > 0) > > > + bv->sbv_state = BIOC_SVDEGRADED; > > > + break; > > > + } > > > + > > > + bv->sbv_unit = volno++; > > > + if (bv->sbv_state != BIOC_SVOFFLINE) > > > + printf(" sr%d%s", bv->sbv_unit, > > > + bv->sbv_flags & BIOC_SCBOOTABLE ? "*" : ""); > > > + } > > > + > > > + explicit_bzero(md, SR_META_SIZE * DEV_BSIZE); > > > + free(md, SR_META_SIZE * DEV_BSIZE); > > > +} > > > + > > > +int > > > +sr_strategy(struct sr_boot_volume *bv, int rw, daddr32_t blk, size_t > > > size, > > > + void *buf, size_t *rsize) > > > +{ > > > + struct diskinfo *sr_dip, *dip; > > > + struct sr_boot_chunk *bc; > > > + struct aes_xts_ctx ctx; > > > + size_t i, j, nsect; > > > + daddr_t blkno; > > > + u_char iv[8]; > > > + u_char *bp; > > > + int err; > > > + > > > + /* We only support read-only softraid. */ > > > + if (rw != F_READ) > > > + return ENOTSUP; > > > + > > > + /* Partition offset within softraid volume. */ > > > + sr_dip = (struct diskinfo *)bv->sbv_diskinfo; > > > + blk += DL_SECTOBLK(&sr_dip->disklabel, > > > + sr_dip->disklabel.d_partitions[bv->sbv_part - 'a'].p_offset); > > > + > > > + if (bv->sbv_level == 0) { > > > + return ENOTSUP; > > > + } else if (bv->sbv_level == 1) { > > > + > > > + /* Select first online chunk. */ > > > + SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link) > > > + if (bc->sbc_state == BIOC_SDONLINE) > > > + break; > > > + if (bc == NULL) > > > + return EIO; > > > + > > > + dip = (struct diskinfo *)bc->sbc_diskinfo; > > > + blk += bv->sbv_data_blkno; > > > + > > > + /* XXX - If I/O failed we should try another chunk... */ > > > + return dip->strategy(dip, rw, blk, size, buf, rsize); > > > + > > > + } else if (bv->sbv_level == 'C') { > > > + > > > + /* Select first online chunk. */ > > > + SLIST_FOREACH(bc, &bv->sbv_chunks, sbc_link) > > > + if (bc->sbc_state == BIOC_SDONLINE) > > > + break; > > > + if (bc == NULL) > > > + return EIO; > > > + > > > + dip = (struct diskinfo *)bc->sbc_diskinfo; > > > + > > > + /* XXX - select correct key. */ > > > + aes_xts_setkey(&ctx, (u_char *)bv->sbv_keys, 64); > > > + > > > + nsect = (size + DEV_BSIZE - 1) / DEV_BSIZE; > > > + for (i = 0; i < nsect; i++) { > > > + blkno = blk + i; > > > + bp = ((u_char *)buf) + i * DEV_BSIZE; > > > + err = dip->strategy(dip, rw, bv->sbv_data_blkno + > > > blkno, > > > + DEV_BSIZE, bp, NULL); > > > + if (err != 0) > > > + return err; > > > + > > > + bcopy(&blkno, iv, sizeof(blkno)); > > > + aes_xts_reinit(&ctx, iv); > > > + for (j = 0; j < DEV_BSIZE; j += AES_XTS_BLOCKSIZE) > > > + aes_xts_decrypt(&ctx, bp + j); > > > + } > > > + if (rsize != NULL) > > > + *rsize = nsect * DEV_BSIZE; > > > + > > > + return err; > > > + > > > + } else > > > + return ENOTSUP; > > > +} > > > + > > > +/* > > > + * Returns 0 if the MBR with the provided partition array is a GPT > > > protective > > > + * MBR, and returns 1 otherwise. A GPT protective MBR would have one and > > > only > > > + * one MBR partition, an EFI partition that either covers the whole disk > > > or as > > > + * much of it as is possible with a 32bit size field. > > > + * > > > + * Taken from kern/subr_disk.c. > > > + * > > > + * NOTE: MS always uses a size of UINT32_MAX for the EFI partition!** > > > + */ > > > +static int > > > +gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize) > > > +{ > > > + struct dos_partition *dp2; > > > + int efi, found, i; > > > + u_int32_t psize; > > > + > > > + found = efi = 0; > > > + for (dp2=dp, i=0; i < NDOSPART; i++, dp2++) { > > > + if (dp2->dp_typ == DOSPTYP_UNUSED) > > > + continue; > > > + found++; > > > + if (dp2->dp_typ != DOSPTYP_EFI) > > > + continue; > > > + psize = letoh32(dp2->dp_size); > > > + if (psize == (dsize - 1) || > > > + psize == UINT32_MAX) { > > > + if (letoh32(dp2->dp_start) == 1) > > > + efi++; > > > + } > > > + } > > > + if (found == 1 && efi == 1) > > > + return (0); > > > + > > > + return (1); > > > +} > > > + > > > +static uint64_t > > > +findopenbsd_gpt(struct sr_boot_volume *bv, const char **err) > > > +{ > > > + struct gpt_header gh; > > > + int i, part, found; > > > + uint64_t lba; > > > + uint32_t orig_csum, new_csum; > > > + uint32_t ghsize, ghpartsize, ghpartnum, > > > ghpartspersec; > > > + uint32_t gpsectors; > > > + const char openbsd_uuid_code[] = GPT_UUID_OPENBSD; > > > + struct gpt_partition gp; > > > + static struct uuid *openbsd_uuid = NULL, openbsd_uuid_space; > > > + u_char *buf; > > > + > > > + /* Prepare OpenBSD UUID */ > > > + if (openbsd_uuid == NULL) { > > > + /* XXX: should be replaced by uuid_dec_be() */ > > > + memcpy(&openbsd_uuid_space, openbsd_uuid_code, > > > + sizeof(openbsd_uuid_space)); > > > + openbsd_uuid_space.time_low = > > > + betoh32(openbsd_uuid_space.time_low); > > > + openbsd_uuid_space.time_mid = > > > + betoh16(openbsd_uuid_space.time_mid); > > > + openbsd_uuid_space.time_hi_and_version = > > > + betoh16(openbsd_uuid_space.time_hi_and_version); > > > + > > > + openbsd_uuid = &openbsd_uuid_space; > > > + } > > > + > > > + if (bv->sbv_secsize > 4096) { > > > + *err = "disk sector > 4096 bytes\n"; > > > + return (-1); > > > + } > > > + buf = alloc(bv->sbv_secsize); > > > + if (buf == NULL) { > > > + *err = "out of memory\n"; > > > + return (-1); > > > + } > > > + bzero(buf, bv->sbv_secsize); > > > + > > > + /* LBA1: GPT Header */ > > > + lba = 1; > > > + sr_strategy(bv, F_READ, lba * (bv->sbv_secsize / DEV_BSIZE), > > > DEV_BSIZE, > > > + buf, NULL); > > > + memcpy(&gh, buf, sizeof(gh)); > > > + > > > + /* Check signature */ > > > + if (letoh64(gh.gh_sig) != GPTSIGNATURE) { > > > + *err = "bad GPT signature\n"; > > > + free(buf, bv->sbv_secsize); > > > + return (-1); > > > + } > > > + > > > + if (letoh32(gh.gh_rev) != GPTREVISION) { > > > + *err = "bad GPT revision\n"; > > > + free(buf, bv->sbv_secsize); > > > + return (-1); > > > + } > > > + > > > + ghsize = letoh32(gh.gh_size); > > > + if (ghsize < GPTMINHDRSIZE || ghsize > sizeof(struct gpt_header)) { > > > + *err = "bad GPT header size\n"; > > > + free(buf, bv->sbv_secsize); > > > + return (-1); > > > + } > > > + > > > + /* Check checksum */ > > > + orig_csum = gh.gh_csum; > > > + gh.gh_csum = 0; > > > + new_csum = crc32(0, (unsigned char *)&gh, ghsize); > > > + gh.gh_csum = orig_csum; > > > + if (letoh32(orig_csum) != new_csum) { > > > + *err = "bad GPT header checksum\n"; > > > + free(buf, bv->sbv_secsize); > > > + return (-1); > > > + } > > > + > > > + lba = letoh64(gh.gh_part_lba); > > > + ghpartsize = letoh32(gh.gh_part_size); > > > + ghpartspersec = bv->sbv_secsize / ghpartsize; > > > + ghpartnum = letoh32(gh.gh_part_num); > > > + gpsectors = (ghpartnum + ghpartspersec - 1) / ghpartspersec; > > > + new_csum = crc32(0L, Z_NULL, 0); > > > + found = 0; > > > + for (i = 0; i < gpsectors; i++, lba++) { > > > + sr_strategy(bv, F_READ, lba * (bv->sbv_secsize / DEV_BSIZE), > > > + bv->sbv_secsize, buf, NULL); > > > + for (part = 0; part < ghpartspersec; part++) { > > > + if (ghpartnum == 0) > > > + break; > > > + new_csum = crc32(new_csum, buf + part * sizeof(gp), > > > + sizeof(gp)); > > > + ghpartnum--; > > > + if (found) > > > + continue; > > > + memcpy(&gp, buf + part * sizeof(gp), sizeof(gp)); > > > + if (memcmp(&gp.gp_type, openbsd_uuid, > > > + sizeof(struct uuid)) == 0) > > > + found = 1; > > > + } > > > + } > > > + > > > + free(buf, bv->sbv_secsize); > > > + > > > + if (new_csum != letoh32(gh.gh_part_csum)) { > > > + *err = "bad GPT entries checksum\n"; > > > + return (-1); > > > + } > > > + if (found) > > > + return (letoh64(gp.gp_lba_start)); > > > + > > > + return (-1); > > > +} > > > + > > > +const char * > > > +sr_getdisklabel(struct sr_boot_volume *bv, struct disklabel *label) > > > +{ > > > + struct dos_partition *dp; > > > + struct dos_mbr mbr; > > > + const char *err = NULL; > > > + u_int start = 0; > > > + char buf[DEV_BSIZE]; > > > + int i; > > > + > > > + /* Check for MBR to determine partition offset. */ > > > + bzero(&mbr, sizeof(mbr)); > > > + sr_strategy(bv, F_READ, DOSBBSECTOR, sizeof(mbr), &mbr, NULL); > > > + if (gpt_chk_mbr(mbr.dmbr_parts, bv->sbv_size / > > > + (bv->sbv_secsize / DEV_BSIZE)) == 0) { > > > + start = findopenbsd_gpt(bv, &err); > > > + if (start == (u_int)-1) { > > > + if (err != NULL) > > > + return (err); > > > + return "no OpenBSD partition\n"; > > > + } > > > + } else if (mbr.dmbr_sign == DOSMBR_SIGNATURE) { > > > + > > > + /* Search for OpenBSD partition */ > > > + for (i = 0; i < NDOSPART; i++) { > > > + dp = &mbr.dmbr_parts[i]; > > > + if (!dp->dp_size) > > > + continue; > > > + if (dp->dp_typ == DOSPTYP_OPENBSD) { > > > + start = dp->dp_start; > > > + break; > > > + } > > > + } > > > + } > > > + > > > + /* Read the disklabel. */ > > > + sr_strategy(bv, F_READ, > > > + start * (bv->sbv_secsize / DEV_BSIZE) + DOS_LABELSECTOR, > > > + sizeof(struct disklabel), buf, NULL); > > > + > > > +#ifdef BIOS_DEBUG > > > + printf("sr_getdisklabel: magic %lx\n", > > > + ((struct disklabel *)buf)->d_magic); > > > + for (i = 0; i < MAXPARTITIONS; i++) > > > + printf("part %c: type = %d, size = %d, offset = %d\n", 'a' > > > + i, > > > + (int)((struct disklabel > > > *)buf)->d_partitions[i].p_fstype, > > > + (int)((struct disklabel *)buf)->d_partitions[i].p_size, > > > + (int)((struct disklabel > > > *)buf)->d_partitions[i].p_offset); > > > +#endif > > > + > > > + /* Fill in disklabel */ > > > + return (getdisklabel(buf, label)); > > > +} > > > + > > > +int > > > +sropen(struct open_file *f, ...) > > > +{ > > > + struct diskinfo *dip = NULL; > > > + struct sr_boot_volume *bv; > > > + va_list ap; > > > + u_int unit, part; > > > + > > > + va_start(ap, f); > > > + unit = va_arg(ap, u_int); > > > + part = va_arg(ap, u_int); > > > + va_end(ap); > > > + > > > + /* Create a fake diskinfo for this softraid volume. */ > > > + SLIST_FOREACH(bv, &sr_volumes, sbv_link) > > > + if (bv->sbv_unit == unit) > > > + break; > > > + if (bv == NULL) { > > > + printf("Unknown device: sr%d\n", unit); > > > + return EADAPT; > > > + } > > > + > > > + if (bv->sbv_level == 'C' && bv->sbv_keys == NULL) > > > + if (sr_crypto_unlock_volume(bv) != 0) > > > + return EPERM; > > > + > > > + if (bv->sbv_diskinfo == NULL) { > > > + dip = alloc(sizeof(struct diskinfo)); > > > + bzero(dip, sizeof(*dip)); > > > + dip->diskio = srdiskio; > > > + dip->strategy = srstrategy; > > > + bv->sbv_diskinfo = dip; > > > + dip->sr_vol = bv; > > > + } > > > + > > > + dip = bv->sbv_diskinfo; > > > + > > > + if ((dip->flags & DISKINFO_FLAG_GOODLABEL) == 0) { > > > + /* Attempt to read disklabel. */ > > > + bv->sbv_part = 'c'; > > > + if (sr_getdisklabel(bv, &dip->disklabel)) > > > + return ERDLAB; > > > + dip->flags |= DISKINFO_FLAG_GOODLABEL; > > > + } > > > + > > > + bv->sbv_part = part + 'a'; > > > + > > > + bootdev_dip = dip; > > > + f->f_devdata = dip; > > > + > > > + return 0; > > > +} > > > + > > > +int > > > +srstrategy(void *devdata, int rw, daddr32_t blk, size_t size, void *buf, > > > + size_t *rsize) > > > +{ > > > + struct diskinfo *dip = (struct diskinfo *)devdata; > > > + return sr_strategy(dip->sr_vol, rw, blk, size, buf, rsize); > > > +} > > > + > > > +int > > > +srdiskio(int rw, struct diskinfo *dip, u_int off, int nsect, void *buf) > > > +{ > > > + return dip->diskio(rw, dip, off, nsect, buf); > > > +} > > > + > > > +int > > > +srclose(struct open_file *f) > > > +{ > > > + f->f_devdata = NULL; > > > + > > > + return 0; > > > +} > > > + > > > +int > > > +srioctl(struct open_file *f, u_long cmd, void *data) > > > +{ > > > + return 0; > > > +} > > > diff --git sys/arch/arm64/stand/efiboot/softraid_arm64.h > > > sys/arch/arm64/stand/efiboot/softraid_arm64.h > > > new file mode 100644 > > > index 00000000000..bd6b0f6e4c3 > > > --- /dev/null > > > +++ sys/arch/arm64/stand/efiboot/softraid_arm64.h > > > @@ -0,0 +1,33 @@ > > > +/* $OpenBSD: softraid_amd64.h,v 1.3 2016/09/11 17:51:21 jsing Exp $ > > > */ > > > + > > > +/* > > > + * Copyright (c) 2012 Joel Sing <[email protected]> > > > + * > > > + * 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. > > > + */ > > > + > > > +#ifndef _SOFTRAID_ARM64_H_ > > > +#define _SOFTRAID_ARM64_H_ > > > + > > > +void srprobe(void); > > > + > > > +const char *sr_getdisklabel(struct sr_boot_volume *, struct disklabel *); > > > +int sr_strategy(struct sr_boot_volume *, int, daddr32_t, size_t, > > > + void *, size_t *); > > > +int sropen(struct open_file *, ...); > > > +int srstrategy(void *, int, daddr32_t, size_t, void *, size_t *); > > > +int srdiskio(int, struct diskinfo *, u_int, int, void *); > > > +int srclose(struct open_file *); > > > +int srioctl(struct open_file *, u_long, void *); > > > + > > > +#endif /* _SOFTRAID_ARM64_H */ > > > > > > > > > > > -- > -- > --------------------------------------------------------------------------------------------------------------------- > Knowing is not enough; we must apply. Willing is not enough; we must do >
