176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* -*- c -*- ------------------------------------------------------------- * 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Portions copyright 2010 Shao Miller 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program is free software; you can redistribute it and/or modify 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * it under the terms of the GNU General Public License as published by 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the Free Software Foundation, Inc., 53 Temple Place Ste 330, 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Boston MA 02111-1307, USA; either version 2 of the License, or 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (at your option) any later version; incorporated herein by reference. 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ----------------------------------------------------------------------- */ 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * mdiskchk.c 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * DOS program to check for the existence of a memdisk. 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program can be compiled for DOS with the OpenWatcom compiler 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (http://www.openwatcom.org/): 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * wcl -3 -osx -mt mdiskchk.c 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <ctype.h> 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h> 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <i86.h> /* For MK_FP() */ 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef unsigned long uint32_t; 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef unsigned short uint16_t; 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef unsigned char uint8_t; 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Pull in MEMDISK common structures */ 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "../memdisk/mstructs.h" 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct memdiskinfo { 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mdi mdi; 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We add our own fields at the end */ 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int cylinders; 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int heads; 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int sectors; 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct memdiskinfo *query_memdisk(int drive) 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static struct memdiskinfo mm; 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t _eax, _ebx, _ecx, _edx; 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t _es, _di; 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned char _dl = drive; 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t bytes; 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __asm { 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .386; 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov eax, 454d0800h; 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov ecx, 444d0000h; 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov edx, 53490000h; 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov dl, _dl; 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov ebx, 3f4b0000h; 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int 13h; 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov _eax, eax; 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov _ecx, ecx; 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov _edx, edx; 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov _ebx, ebx; 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov _es, es; 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mov _di, di; 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (_eax >> 16 != 0x4d21 || 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _ecx >> 16 != 0x4d45 || _edx >> 16 != 0x4944 || _ebx >> 16 != 0x4b53) 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return NULL; 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset(&mm, 0, sizeof mm); 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes = *(uint16_t far *) MK_FP(_es, _di); 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 27 is the most we know how to handle */ 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (bytes > 27) 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bytes = 27; 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _fmemcpy((void far *)&mm, (void far *)MK_FP(_es, _di), bytes); 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mm.cylinders = ((_ecx >> 8) & 0xff) + ((_ecx & 0xc0) << 2) + 1; 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mm.heads = ((_edx >> 8) & 0xff) + 1; 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mm.sectors = (_ecx & 0x3f); 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return &mm; 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanconst char *bootloadername(uint8_t id) 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static const struct { 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint8_t id, mask; 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *name; 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } *lp, list[] = { 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x00, 0xf0, "LILO"}, 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x10, 0xf0, "LOADLIN"}, 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x31, 0xff, "SYSLINUX"}, 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x32, 0xff, "PXELINUX"}, 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x33, 0xff, "ISOLINUX"}, 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x34, 0xff, "EXTLINUX"}, 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x30, 0xf0, "SYSLINUX family"}, 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x40, 0xf0, "Etherboot"}, 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x50, 0xf0, "ELILO"}, 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x70, 0xf0, "GrUB"}, 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x80, 0xf0, "U-Boot"}, 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0xA0, 0xf0, "Gujin"}, 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0xB0, 0xf0, "Qemu"}, 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x00, 0x00, "unknown"} 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (lp = list;; lp++) { 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (((id ^ lp->id) & lp->mask) == 0) 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return lp->name; 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* The function type for an output function */ 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define OUTPUT_FUNC_DECL(x) \ 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid x(const int d, const struct memdiskinfo * const m) 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef OUTPUT_FUNC_DECL((*output_func)); 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Show MEMDISK information for the passed structure */ 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic OUTPUT_FUNC_DECL(normal_output) 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (m == NULL) 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf("Drive %02X is MEMDISK %u.%02u:\n" 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n" 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "\tloader = 0x%02x (%s),\n" 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "\tcmdline = %Fs\n", 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d, m->mdi.version_major, m->mdi.version_minor, 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m->mdi.diskbuf, m->mdi.disksize, m->cylinders, m->heads, m->sectors, 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m->mdi.bootloaderid, bootloadername(m->mdi.bootloaderid), 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MK_FP(m->mdi.cmdline.seg_off.segment, 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m->mdi.cmdline.seg_off.offset)); 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Yield DOS SET command(s) as output for each MEMDISK kernel argument */ 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic OUTPUT_FUNC_DECL(batch_output) 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (m != NULL) { 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char buf[256], *bc; 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char far *c = 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MK_FP(m->mdi.cmdline.seg_off.segment, 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m->mdi.cmdline.seg_off.offset); 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *have_equals, is_set[] = "=1"; 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (*c != '\0') { 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Skip whitespace */ 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (isspace(*c)) 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c++; 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (*c == '\0') 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Trailing whitespace. That's enough processing */ 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Walk the kernel arguments while filling the buffer, 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * looking for space or NUL or checking for a full buffer 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bc = buf; 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman have_equals = is_set; 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while ((*c != '\0') && !isspace(*c) && 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (bc < &buf[sizeof(buf) - 1])) { 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check if the param is "x=y" */ 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (*c == '=') 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* "=1" not needed */ 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman have_equals = &is_set[sizeof(is_set) - 1]; 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *bc = *c; 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman c++; 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman bc++; 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Found the end of the parameter and optional value sequence */ 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *bc = '\0'; 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf("set %s%s\n", buf, have_equals); 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* We do not output batch file output by default. We show MEMDISK info */ 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic output_func show_memdisk = normal_output; 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* A generic function type */ 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MDISKCHK_FUNC_DECL(x) \ 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid x(void) 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef MDISKCHK_FUNC_DECL((*mdiskchk_func)); 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic MDISKCHK_FUNC_DECL(do_nothing) 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic MDISKCHK_FUNC_DECL(show_usage) 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf("\nUsage: mdiskchk [--safe-hooks] [--mbfts] [--batch-output]\n" 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "\n" 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "Action: --safe-hooks . . Will scan INT 13h \"safe hook\" chain\n" 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman " --mbfts . . . . Will scan memory for MEMDISK mBFTs\n" 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman " --batch-output . Will output SET command output based\n" 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman " on MEMDISK kernel arguments\n" 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman " --no-sequential Suppresses probing all drive numbers\n"); 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Search memory for mBFTs and report them via the output method */ 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic MDISKCHK_FUNC_DECL(show_mbfts) 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const uint16_t far * const free_base_mem = 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MK_FP(0x0040, 0x0013); 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int seg; 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint8_t chksum; 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t i; 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const struct mBFT far *mbft; 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct memdiskinfo m; 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct patch_area far *patch_area; 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (seg = *free_base_mem / 16; seg < 0x9FFF; seg++) { 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbft = MK_FP(seg, 0); 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check for signature */ 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mbft->acpi.signature[0] != 'm' || 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbft->acpi.signature[1] != 'B' || 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbft->acpi.signature[2] != 'F' || 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbft->acpi.signature[3] != 'T') 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman continue; 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mbft->acpi.length != sizeof(struct mBFT)) 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman continue; 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check sum */ 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman chksum = 0; 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < sizeof(struct mBFT); i++) 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman chksum += ((const uint8_t far *)mbft)[i]; 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (chksum) 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman continue; 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Copy the MDI from the mBFT */ 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi)); 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Adjust C/H/S since we actually know 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * it directly for any MEMDISK with an mBFT 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman patch_area = (struct patch_area far *)&mbft->mdi; 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m.cylinders = patch_area->cylinders; 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m.heads = patch_area->heads; 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m.sectors = patch_area->sectors; 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman show_memdisk(patch_area->driveno, &m); 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Walk the "safe hook" chain as far as possible 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and report MEMDISKs that we find via the output method 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic MDISKCHK_FUNC_DECL(show_safe_hooks) 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const real_addr_t far * const int13 = 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MK_FP(0x0000, 0x0013 * sizeof(real_addr_t)); 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const struct safe_hook far *hook = 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MK_FP(int13->seg_off.segment, int13->seg_off.offset); 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while ((hook->signature[0] == '$') && 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->signature[1] == 'I') && 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->signature[2] == 'N') && 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->signature[3] == 'T') && 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->signature[4] == '1') && 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->signature[5] == '3') && 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->signature[6] == 'S') && 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->signature[7] == 'F')) { 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Found a valid "safe hook" */ 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((hook->vendor[0] == 'M') && 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->vendor[1] == 'E') && 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->vendor[2] == 'M') && 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->vendor[3] == 'D') && 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->vendor[4] == 'I') && 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->vendor[5] == 'S') && 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (hook->vendor[6] == 'K')) { 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Found a valid MEMDISK "safe hook". It will have an mBFT */ 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const struct mBFT far *mbft; 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct memdiskinfo m; 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct patch_area far *patch_area; 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Copy the MDI from the mBFT. Offset is a misnomer here */ 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbft = MK_FP(hook->mbft >> 4, 0); /* Always aligned */ 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi)); 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Adjust C/H/S since we actually know 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * it directly for any MEMDISK with an mBFT 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman patch_area = (struct patch_area far *)&mbft->mdi; 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m.cylinders = patch_area->cylinders; 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m.heads = patch_area->heads; 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m.sectors = patch_area->sectors; 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman show_memdisk(patch_area->driveno, &m); 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } /* if */ 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Step to the next hook in the "safe hook" chain */ 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman hook = MK_FP(hook->old_hook.seg_off.segment, 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman hook->old_hook.seg_off.offset); 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } /* while */ 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint main(int argc, char *argv[]) 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int d; 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int found = 0; 29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int sequential_scan = 1; /* Classic behaviour */ 29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const struct memdiskinfo *m; 29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Default behaviour */ 30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdiskchk_func usage = do_nothing, 30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman safe_hooks = do_nothing, 30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbfts = do_nothing; 30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* For each argument */ 30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (--argc) { 30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Argument should begin with one of these chars */ 30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((*argv[argc] != '/') && (*argv[argc] != '-')) { 30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* It doesn't. Print usage soon */ 31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman usage = show_usage; 31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman argv[argc]++; 31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Next char might be '-' as in "--safe-hooks" */ 31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (*argv[argc] == '-') 31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman argv[argc]++; 31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch (*argv[argc]) { 32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 'S': 32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 's': 32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman safe_hooks = show_safe_hooks; 32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 'M': 32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 'm': 32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbfts = show_mbfts; 32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 'B': 32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 'b': 33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman show_memdisk = batch_output; 33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 'N': 33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 'n': 33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sequential_scan = 0; 33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default: 33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman usage = show_usage; 33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } /* switch */ 33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } /* while */ 34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman safe_hooks(); 34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mbfts(); 34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!sequential_scan) 34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto skip_sequential; 34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (d = 0; d <= 0xff; d++) { 34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m = query_memdisk(d); 34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (m != NULL) { 34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman found++; 34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman show_memdisk(d, m); 35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanskip_sequential: 35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman usage(); 35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return found; 35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 358