Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144784944
D45404.1776485142.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D45404.1776485142.diff
View Options
diff --git a/stand/i386/libi386/Makefile b/stand/i386/libi386/Makefile
--- a/stand/i386/libi386/Makefile
+++ b/stand/i386/libi386/Makefile
@@ -8,6 +8,7 @@
SRCS+= biosacpi.c
SRCS+= biosdisk.c
SRCS+= biosmem.c
+SRCS+= biosmemdisk.c
SRCS+= biospci.c
SRCS+= biospnp.c
SRCS+= biossmap.c
diff --git a/stand/i386/libi386/biosmemdisk.c b/stand/i386/libi386/biosmemdisk.c
new file mode 100644
--- /dev/null
+++ b/stand/i386/libi386/biosmemdisk.c
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2020 Richard Russo <russor@ruka.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stand.h>
+#include <machine/stdarg.h>
+#include <bootstrap.h>
+#include <btxv86.h>
+#include "libi386.h"
+
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#include "actypes.h"
+#include "actbl.h"
+
+struct memdisk_info {
+ uint32_t mdi_13h_hook_ptr; // not included in length!
+ uint16_t mdi_length;
+ uint8_t mdi_minor;
+ uint8_t mdi_major;
+ uint32_t mdi_disk_ptr;
+ uint32_t mdi_disk_sectors;
+ uint32_t mdi_far_ptr_cmdline;
+ uint32_t mdi_old_int13h;
+ uint32_t mdi_old_int15h;
+ uint16_t mdi_dos_mem_before;
+ uint8_t mdi_boot_loader_id;
+ uint8_t mdi_sector_size;
+} __attribute__((packed));
+
+struct safe_13h_hook {
+ char sh_jmp[3];
+ char sh_id[8];
+ char sh_vendor[8];
+ uint16_t sh_next_offset;
+ uint16_t sh_next_segment;
+ uint32_t sh_flags;
+ uint32_t sh_mbft;
+} __attribute__((packed));
+
+/*
+ * Scan for MEMDISK virtual block devices
+ */
+
+void
+biosmemdisk_detect()
+{
+ char line[80], scratch[80];
+ int idx, hook = 0, count = 0, sector_size;
+ uint16_t segment, offset;
+ struct safe_13h_hook *probe;
+ ACPI_TABLE_HEADER *mbft;
+ uint8_t *cp, sum;
+ struct memdisk_info *mdi;
+
+ offset = *(uint16_t *)PTOV(0x4C); // int 13H handler point to linked list
+ segment = *(uint16_t *)PTOV(0x4C + 2);
+
+ /*
+ * Walk through the int13 hanlder linked list, looking for possible
+ * MEMDISKs.
+ *
+ * XXX max of 32 is arbitrary.
+ */
+ while (hook < 32 && !(segment == 0 && offset == 0)) {
+ probe = (struct safe_13h_hook*)PTOV(segment * 16 + offset);
+ /*
+ * Make sure the linked list node is the right type
+ */
+ if (memcmp(probe->sh_id, "$INT13SF", sizeof(probe->sh_id)) != 0) {
+ printf("Found int 13h unsafe hook at %p (%x:%x)\n",
+ probe, segment, offset);
+ break;
+ }
+
+ /*
+ * Skip all the nodes that aren't a MEMDISK.
+ */
+ if (memcmp(probe->sh_vendor, "MEMDISK ", sizeof(probe->sh_vendor)) != 0)
+ goto end_of_loop;
+
+ /*
+ * If it is a memdisk, make sure the mBFT signature is correct
+ */
+ mbft = (ACPI_TABLE_HEADER *)PTOV(probe->sh_mbft);
+ cp = (uint8_t *)mbft;
+ if (memcmp(mbft->Signature, "mBFT", sizeof(mbft->Signature)) != 0)
+ goto end_of_loop;
+
+ /*
+ * Check the checksum for the mbft.
+ */
+ sum = 0;
+ for (idx = 0; idx < mbft->Length; ++idx)
+ sum += *(cp + idx);
+ if (sum != 0)
+ goto end_of_loop;
+
+ /*
+ * 512 unless MEMDISK struct is from 3.71+ and is non-zero
+ */
+ mdi = (struct memdisk_info *)PTOV(probe->sh_mbft + sizeof(*mbft));
+ sector_size = 512;
+ if (mdi->mdi_length + sizeof(mdi->mdi_13h_hook_ptr) >= sizeof(*mdi) &&
+ mdi->mdi_sector_size != 0)
+ sector_size = 1 << mdi->mdi_sector_size;
+
+ printf("memdisk %d.%d disk at %#x (%d sectors = %d bytes)\n",
+ mdi->mdi_major, mdi->mdi_minor, mdi->mdi_disk_ptr,
+ mdi->mdi_disk_sectors, mdi->mdi_disk_sectors * sector_size);
+
+ snprintf(line, sizeof(line), "hint.md.%d.physaddr", count);
+ snprintf(scratch, sizeof(scratch), "0x%08x", mdi->mdi_disk_ptr);
+ setenv(line, scratch, 1);
+ snprintf(line, sizeof(line), "hint.md.%d.len", count);
+ snprintf(scratch, sizeof(scratch), "%d", mdi->mdi_disk_sectors * sector_size);
+ setenv(line, scratch, 1);
+ count++;
+end_of_loop:
+ hook++;
+ offset = probe->sh_next_offset;
+ segment = probe->sh_next_segment;
+ }
+}
diff --git a/stand/i386/libi386/libi386.h b/stand/i386/libi386/libi386.h
--- a/stand/i386/libi386/libi386.h
+++ b/stand/i386/libi386/libi386.h
@@ -149,3 +149,5 @@
vm_offset_t *kernend, int add_smap);
void pxe_enable(void *pxeinfo);
+
+void biosmemdisk_detect(void);
diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c
--- a/stand/i386/loader/main.c
+++ b/stand/i386/loader/main.c
@@ -247,6 +247,9 @@
initial_bootinfo->bi_extmem = bios_extmem / 1024;
}
+ /* detect MEMDISK virtual disks */
+ biosmemdisk_detect();
+
/* detect SMBIOS for future reference */
smbios_detect(NULL);
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -89,6 +89,8 @@
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/disk.h>
+#include <sys/param.h>
+#include <sys/bus.h>
#include <geom/geom.h>
#include <geom/geom_int.h>
@@ -2037,8 +2039,10 @@
{
caddr_t mod;
u_char *ptr, *name, *type;
+ u_char scratch[40];
unsigned len;
int i;
+ vm_offset_t paddr;
/* figure out log2(NINDIR) */
for (i = NINDIR, nshift = -1; i; nshift++)
@@ -2078,6 +2082,25 @@
sx_xunlock(&md_sx);
}
}
+
+ /*
+ * Load up to 32 pre-loaded disks
+ */
+ for (int i = 0; i < 32; i++) {
+ if (resource_long_value("md", i, "physaddr",
+ (long *) &paddr) != 0 ||
+ resource_int_value("md", i, "len", &len) != 0)
+ break;
+ ptr = (char *)pmap_map(NULL, paddr, paddr + len, VM_PROT_READ);
+ if (ptr != NULL && len != 0) {
+ sprintf(scratch, "preload%d 0x%016jx", i,
+ (uintmax_t)paddr);
+ sx_xlock(&md_sx);
+ md_preloaded(ptr, len, scratch);
+ sx_xunlock(&md_sx);
+ }
+ }
+
status_dev = make_dev(&mdctl_cdevsw, INT_MAX, UID_ROOT, GID_WHEEL,
0600, MDCTL_NAME);
g_topology_lock();
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 18, 4:05 AM (13 h, 26 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28372842
Default Alt Text
D45404.1776485142.diff (5 KB)
Attached To
Mode
D45404: biosboot: Detect memory disks from PXE
Attached
Detach File
Event Timeline
Log In to Comment