Page MenuHomeFreeBSD

D27349.diff
No OneTemporary

D27349.diff

Index: stand/i386/libi386/Makefile
===================================================================
--- stand/i386/libi386/Makefile
+++ stand/i386/libi386/Makefile
@@ -4,7 +4,7 @@
LIB= i386
-SRCS= bio.c biosacpi.c biosdisk.c biosmem.c biospnp.c \
+SRCS= bio.c biosacpi.c biosdisk.c biosmem.c biosmemdisk.c biospnp.c \
biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \
comconsole.c devicename.c elf32_freebsd.c \
elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \
Index: stand/i386/libi386/biosmemdisk.c
===================================================================
--- /dev/null
+++ stand/i386/libi386/biosmemdisk.c
@@ -0,0 +1,100 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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;
+ char *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;
+
+ offset = *(uint16_t *)PTOV(0x4C); // int 13H handler in interrupt vector table
+ segment = *(uint16_t *)PTOV(0x4C + 2);
+
+ while (hook < 32 && !(segment == 0 && offset == 0)) {
+ probe = (struct safe_13h_hook*)PTOV(segment * 16 + offset);
+ if (memcmp(probe->sh_id, "$INT13SF", sizeof(probe->sh_id)) == 0) {
+ if (memcmp(probe->sh_vendor, "MEMDISK ", sizeof(probe->sh_vendor)) == 0) {
+ mbft = (ACPI_TABLE_HEADER *)PTOV(probe->sh_mbft);
+ if (memcmp(mbft->Signature, "mBFT", sizeof(mbft->Signature)) == 0) {
+ cp = (uint8_t *)mbft;
+ sum = 0;
+ for (idx = 0; idx < mbft->Length; ++idx)
+ sum += *(cp + idx);
+ if (sum == 0) {
+ struct memdisk_info *mdi = (struct memdisk_info *)PTOV(probe->sh_mbft + sizeof(*mbft));
+ sector_size = 512; // assume 512 unless MEMDISK struct is from 3.71+ and is non-zero))
+ 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 %p (%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", (vm_offset_t)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;
+ }
+ }
+
+ } else {
+ printf("Found int 13h safe hook at %p, vendor %.8s\n", probe, probe->sh_vendor);
+ }
+ offset = probe->sh_next_offset;
+ segment = probe->sh_next_segment;
+ } else {
+ printf("Found int 13h unsafe hook at %p (%x:%x)\n", probe, segment, offset);
+ segment = offset = 0;
+ }
+ ++hook;
+ }
+}
Index: stand/i386/libi386/libi386.h
===================================================================
--- stand/i386/libi386/libi386.h
+++ stand/i386/libi386/libi386.h
@@ -154,3 +154,5 @@
vm_offset_t *kernend, int add_smap);
void pxe_enable(void *pxeinfo);
+
+void biosmemdisk_detect(void);
Index: stand/i386/loader/main.c
===================================================================
--- stand/i386/loader/main.c
+++ stand/i386/loader/main.c
@@ -256,6 +256,9 @@
extract_currdev(); /* set $currdev and $loaddev */
bios_getsmap();
+
+ /* detect MEMDISK virtual disks */
+ biosmemdisk_detect();
interact();
Index: sys/dev/md/md.c
===================================================================
--- sys/dev/md/md.c
+++ sys/dev/md/md.c
@@ -92,6 +92,8 @@
#include <sys/uio.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>
@@ -2027,8 +2029,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++)
@@ -2068,6 +2072,23 @@
sx_xunlock(&md_sx);
}
}
+
+ for (i = 0; i < 32; ++i) {
+ if (resource_long_value("md", i, "physaddr", (signed long*) &paddr) != 0 ||
+ resource_int_value("md", i, "len", (signed *)&len) != 0) {
+
+ break;
+ }
+
+ ptr = (char *)pmap_map(NULL, paddr, paddr + len, VM_PROT_READ);
+ if (ptr != NULL && len != 0) {
+ sprintf(scratch, "preload%d 0x%016lx", i, paddr);
+ sx_xlock(&md_sx);
+ md_preloaded(ptr, len, scratch);
+ sx_xunlock(&md_sx);
+ }
+ }
+
md_pbuf_zone = pbuf_zsecond_create("mdpbuf", nswbuf / 10);
status_dev = make_dev(&mdctl_cdevsw, INT_MAX, UID_ROOT, GID_WHEEL,
0600, MDCTL_NAME);

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 23, 4:06 AM (17 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17264214
Default Alt Text
D27349.diff (6 KB)

Event Timeline