diff options
author | Shao Miller <shao.miller@yrdsb.edu.on.ca> | 2009-08-03 21:45:34 -0400 |
---|---|---|
committer | Shao Miller <shao.miller@yrdsb.edu.on.ca> | 2009-08-03 23:50:20 -0400 |
commit | 3369a18e1a3eae71a8b37bd91cff61dbbe389a2b (patch) | |
tree | fb0db869d0a1a5e1314762c5c4676769840a17a4 /memdisk | |
parent | 1275c1535315174f355b4bf74e69e572d8b38fc6 (diff) | |
download | syslinux-3369a18e1a3eae71a8b37bd91cff61dbbe389a2b.tar.gz |
[memdisk] Add El Torito emulation for .ISO images
With this patch, users can now boot El Torito-bootable .ISO (CD/DVD) images.
The user should specify "iso" on the kernel command-line.
Diffstat (limited to 'memdisk')
-rw-r--r-- | memdisk/Makefile | 4 | ||||
-rw-r--r-- | memdisk/eltorito.c | 58 | ||||
-rw-r--r-- | memdisk/eltorito.h | 83 | ||||
-rw-r--r-- | memdisk/memdisk.inc | 69 | ||||
-rw-r--r-- | memdisk/memdisk_chs_512.asm | 1 | ||||
-rw-r--r-- | memdisk/memdisk_edd_512.asm | 1 | ||||
-rw-r--r-- | memdisk/memdisk_iso_2048.asm | 1 | ||||
-rw-r--r-- | memdisk/memdisk_iso_512.asm | 1 | ||||
-rw-r--r-- | memdisk/setup.c | 147 |
9 files changed, 347 insertions, 18 deletions
diff --git a/memdisk/Makefile b/memdisk/Makefile index 8e76f3d2..f397c979 100644 --- a/memdisk/Makefile +++ b/memdisk/Makefile @@ -38,11 +38,11 @@ endif # Important: init.o16 must be first!! OBJS16 = init.o16 init32.o OBJS32 = start32.o setup.o msetup.o e820func.o conio.o memcpy.o memset.o \ - memmove.o unzip.o dskprobe.o \ + memmove.o unzip.o dskprobe.o eltorito.o \ memdisk_chs_512.o memdisk_edd_512.o \ memdisk_iso_512.o memdisk_iso_2048.o -CSRC = setup.c msetup.c e820func.c conio.c unzip.c dskprobe.c +CSRC = setup.c msetup.c e820func.c conio.c unzip.c dskprobe.c eltorito.c SSRC = start32.S memcpy.S memset.S memmove.S NASMSRC = memdisk_chs_512.asm memdisk_edd_512.asm \ memdisk_iso_512.asm memdisk_iso_2048.asm \ diff --git a/memdisk/eltorito.c b/memdisk/eltorito.c new file mode 100644 index 00000000..7e0ba89b --- /dev/null +++ b/memdisk/eltorito.c @@ -0,0 +1,58 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2009 Shao Miller - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * eltorito.c + * + * EDD-4 El Torito structures and debugging routines + */ + +#include <stdint.h> +#include "memdisk.h" +#include "conio.h" +#include "eltorito.h" + +#ifdef DBG_ELTORITO +void eltorito_dump(uint32_t image) +{ + printf("-- El Torito dump --\n", image); + + /* BVD starts at sector 17. */ + struct edd4_bvd *bvd = (struct edd4_bvd *)(image + 17 * 2048); + + printf("bvd.boot_rec_ind: 0x%02x\n", bvd->boot_rec_ind); + printf("bvd.iso9660_id: %c%c%c%c%c\n", bvd->iso9660_id[0], + bvd->iso9660_id[1], bvd->iso9660_id[2], bvd->iso9660_id[3], + bvd->iso9660_id[4]); + printf("bvd.ver: 0x%02x\n", bvd->ver); + printf("bvd.eltorito: %s\n", bvd->eltorito); + printf("bvd.boot_cat: 0x%08x\n", bvd->boot_cat); + + struct edd4_bootcat *boot_cat = + (struct edd4_bootcat *)(image + bvd->boot_cat * 2048); + + printf("boot_cat.validation_entry\n"); + printf(" .header_id: 0x%02x\n", boot_cat->validation_entry.header_id); + printf(" .platform_id: 0x%02x\n", boot_cat->validation_entry.platform_id); + printf(" .id_string: %s\n", boot_cat->validation_entry.id_string); + printf(" .checksum: 0x%04x\n", boot_cat->validation_entry.checksum); + printf(" .key55: 0x%02x\n", boot_cat->validation_entry.key55); + printf(" .keyAA: 0x%02x\n", boot_cat->validation_entry.keyAA); + printf("boot_cat.initial_entry\n"); + printf(" .header_id: 0x%02x\n", boot_cat->initial_entry.header_id); + printf(" .media_type: 0x%02x\n", boot_cat->initial_entry.media_type); + printf(" .load_seg: 0x%04x\n", boot_cat->initial_entry.load_seg); + printf(" .system_type: 0x%02x\n", boot_cat->initial_entry.system_type); + printf(" .sect_count: %d\n", boot_cat->initial_entry.sect_count); + printf(" .load_block: 0x%08x\n", boot_cat->initial_entry.load_block); +} +#endif diff --git a/memdisk/eltorito.h b/memdisk/eltorito.h new file mode 100644 index 00000000..7d46e1d9 --- /dev/null +++ b/memdisk/eltorito.h @@ -0,0 +1,83 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2009 Shao Miller - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * eltorito.h + * + * EDD-4 El Torito structures and debugging routines + */ + +#include <stdint.h> + +/* + * Uncomment for El Torito debugging + * + * #define DBG_ELTORITO 1 + */ + +#ifdef DBG_ELTORITO +extern void eltorito_dump(uint32_t); +#endif + +/* EDD-4 Bootable Optical Disc Drive Boot Volume Descriptor */ +struct edd4_bvd { + uint8_t boot_rec_ind; /* Boot Record Indicator */ + uint8_t iso9660_id[5]; /* ISO9660 ID */ + uint8_t ver; /* Descriptor Version */ + uint8_t eltorito[32]; /* "EL TORITO" etc. */ + uint8_t res1[32]; /* Reserved */ + uint32_t boot_cat; /* Boot catalog sector */ + uint8_t res2[1973]; /* Reserved */ +} __attribute__ ((packed)); + +struct validation_entry { + uint8_t header_id; /* Header ID */ + uint8_t platform_id; /* Platform ID */ + uint16_t res1; /* Reserved */ + uint8_t id_string[24]; /* Manufacturer */ + uint16_t checksum; /* Sums with whole record to zero */ + uint8_t key55; /* Key byte 0x55 */ + uint8_t keyAA; /* Key byte 0xAA */ +} __attribute__ ((packed)); + +struct initial_entry { + uint8_t header_id; /* Header ID */ + uint8_t media_type; /* Media type */ + uint16_t load_seg; /* Load segment */ + uint8_t system_type; /* (Filesystem ID) */ + uint8_t res1; /* Reserved */ + uint16_t sect_count; /* Emulated sectors to load */ + uint32_t load_block; /* Starting sector of image */ + uint8_t res2[4]; /* Reserved */ +} __attribute__ ((packed)); + +/* EDD-4 Bootable Optical Disc Drive Boot Catalog (fixed-size portions) */ +struct edd4_bootcat { + struct validation_entry validation_entry; + struct initial_entry initial_entry; +} __attribute__ ((packed)); + +/* EDD-4 CD Specification Packet */ +struct edd4_cd_pkt { + uint8_t size; /* Packet size */ + uint8_t type; /* Boot media type (flags) */ + uint8_t driveno; /* INT 13h drive number */ + uint8_t controller; /* Controller index */ + uint32_t start; /* Starting LBA of image */ + uint16_t devno; /* Device number */ + uint16_t userbuf; /* User buffer segment */ + uint16_t load_seg; /* Load segment */ + uint16_t sect_count; /* Emulated sectors to load */ + uint8_t geom1; /* Cylinders bits 0 thru 7 */ + uint8_t geom2; /* Sects/track 0 thru 5, cyls 8, 9 */ + uint8_t geom3; /* Heads */ +} __attribute__ ((packed)); diff --git a/memdisk/memdisk.inc b/memdisk/memdisk.inc index 14f077ab..98ad52b7 100644 --- a/memdisk/memdisk.inc +++ b/memdisk/memdisk.inc @@ -8,6 +8,7 @@ ; ; Copyright 2001-2009 H. Peter Anvin - All Rights Reserved ; Copyright 2009 Intel Corporation; author: H. Peter Anvin +; Portions copyright 2009 Shao Miller [El Torito code] ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by @@ -135,6 +136,10 @@ Int13Start: mov ss,ax mov sp,[cs:MyStack] +%if ELTORITO + cmp word [cs:SavedAX],4a00h ; El Torito function? + jae our_drive ; We grab it +%endif ; See if DL points to our class of device (FD, HD) push dx push dx @@ -205,6 +210,14 @@ our_drive: ; Note: AX == P_AX here cmp ah,Int13FuncsCnt-1 ja Invalid_jump +%if ELTORITO + mov al,[CD_PKT.type] ; Check if we are in + cmp al,0 ; El Torito no emulation mode + ja .emulation ; No. We support the function + cmp ah,3fh ; Yes. We must not support functions + jbe Invalid_jump ; 0 through 3Fh. Check and decide +.emulation: +%endif xor al,al ; AL = 0 is standard entry condition mov di,ax shr di,7 ; Convert AH to an offset in DI @@ -393,8 +406,9 @@ EDDPresence: jne Invalid mov P_BX,0AA55h ; EDD signature mov P_AX,03000h ; EDD 3.0 - mov P_CX,0003h ; Bit 0 - Fixed disk access subset + mov P_CX,0007h ; Bit 0 - Fixed disk access subset ; Bit 1 - Locking and ejecting subset + ; Bit 2 - EDD subset pop ax ; Drop return address xor ax,ax ; Success jmp DoneWeird ; Success, but AH != 0, sigh... @@ -575,10 +589,31 @@ edd_setup_regs: EDDEject: mov ax,0B200h ; Volume Not Removable ret - +%if ELTORITO +ElToritoTerminate: + TRACER 'T' + mov ax,[cs:SavedAX] + cmp al,1 ; We only support query, not terminate + jne ElToritoErr ; Fail + mov es,P_DS ; Caller's DS:SI pointed to packet + mov di,P_SI ; We'll use ES:DI + mov si,CD_PKT.size ; First byte is packet size + xor cx,0 ; Empty our count + ;mov cl,[ds:si] ; We'll copy that many bytes + mov cl,13h + rep movsb ; Copy until CX is zero + mov ax,0 ; Success + ret +ElToritoEmulate: +ElToritoBoot: +ElToritoCatalog: +ElToritoErr: + TRACER '!' + mov ax,100h ; Invalid parameter + ret +%endif ; ELTORITO %endif ; EDD - ; ; INT 15h intercept routines ; @@ -960,7 +995,14 @@ Int13Funcs dw Reset ; 00h - RESET dw EDDSeek ; 47h - EDD SEEK dw EDDGetParms ; 48h - EDD GET PARAMETERS dw EDDDetectChange ; 49h - EDD MEDIA CHANGE STATUS -%endif +%if ELTORITO ; EDD El Torito Functions + ; ELTORITO _must_ also have EDD + dw ElToritoEmulate ; 4Ah - Initiate Disk Emulation + dw ElToritoTerminate ; 4Bh - Terminate Disk Emulation + dw ElToritoBoot ; 4Ch - Initiate Disk Emu. and Reboot + dw ElToritoCatalog ; 4Dh - Return Boot Catalog +%endif ; ELTORITO +%endif ; EDD Int13FuncsEnd equ $ Int13FuncsCnt equ (Int13FuncsEnd-Int13Funcs) >> 1 @@ -1070,7 +1112,24 @@ EDD_DPT: .res3 db 0 ; Reserved .chksum db 0 ; DPI checksum -%endif +%if ELTORITO +; El Torito CD Specification Packet - mostly filled in by installer +CD_PKT: +.size db 13h ; Packet size (19 bytes) +.type db 0 ; Boot media type (flags) +.driveno db 0E0h ; INT 13h drive number +.controller db 0 ; Controller index +.start dd 0 ; Starting LBA of image +.devno dw 0 ; Device number +.user_buf dw 0 ; User buffer segment +.load_seg dw 0 ; Load segment +.sect_count dw 0 ; Emulated sectors to load +.geom1 db 0 ; Cylinders bits 0 thru 7 +.geom2 db 0 ; Sects/track 0 thru 5, cyls 8, 9 +.geom3 db 0 ; Heads +%endif ; ELTORITO + +%endif ; EDD ; End patch area alignb 4, db 0 diff --git a/memdisk/memdisk_chs_512.asm b/memdisk/memdisk_chs_512.asm index 35acbbd8..d4b0f753 100644 --- a/memdisk/memdisk_chs_512.asm +++ b/memdisk/memdisk_chs_512.asm @@ -1,3 +1,4 @@ %define EDD 0 +%define ELTORITO 0 %define SECTORSIZE_LG2 9 ; log2(sector size) %include "memdisk.inc" diff --git a/memdisk/memdisk_edd_512.asm b/memdisk/memdisk_edd_512.asm index fbd90c15..02d1737f 100644 --- a/memdisk/memdisk_edd_512.asm +++ b/memdisk/memdisk_edd_512.asm @@ -1,3 +1,4 @@ %define EDD 1 +%define ELTORITO 0 %define SECTORSIZE_LG2 9 ; log2(sector size) %include "memdisk.inc" diff --git a/memdisk/memdisk_iso_2048.asm b/memdisk/memdisk_iso_2048.asm index 84a05542..0a444976 100644 --- a/memdisk/memdisk_iso_2048.asm +++ b/memdisk/memdisk_iso_2048.asm @@ -1,3 +1,4 @@ %define EDD 1 +%define ELTORITO 1 %define SECTORSIZE_LG2 11 ; log2(sector size) %include "memdisk.inc" diff --git a/memdisk/memdisk_iso_512.asm b/memdisk/memdisk_iso_512.asm index fbd90c15..e49b449d 100644 --- a/memdisk/memdisk_iso_512.asm +++ b/memdisk/memdisk_iso_512.asm @@ -1,3 +1,4 @@ %define EDD 1 +%define ELTORITO 1 %define SECTORSIZE_LG2 9 ; log2(sector size) %include "memdisk.inc" diff --git a/memdisk/setup.c b/memdisk/setup.c index 9fd5c9e8..41e87c12 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -2,6 +2,7 @@ * * Copyright 2001-2009 H. Peter Anvin - All Rights Reserved * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * Portions copyright 2009 Shao Miller [El Torito code] * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +16,7 @@ #include "bda.h" #include "dskprobe.h" #include "e820.h" +#include "eltorito.h" #include "conio.h" #include "version.h" #include "memdisk.h" @@ -143,8 +145,19 @@ struct patch_area { dpt_t dpt; struct edd_dpt edd_dpt; + struct edd4_cd_pkt cd_pkt; /* Only really in a memdisk_iso_* hook */ } __attribute__((packed)); +/* An EDD disk packet */ +struct edd_dsk_pkt { + uint8_t size; /* Packet size */ + uint8_t res1; /* Reserved */ + uint16_t count; /* Count to transfer */ + uint32_t buf; /* Buffer pointer */ + uint64_t start; /* LBA to start from */ + uint64_t buf64; /* 64-bit buf pointer */ +} __attribute__ ((packed)); + /* * Routine to seek for a command-line item and return a pointer * to the data portion, if present @@ -322,11 +335,12 @@ void unzip_if_needed(uint32_t * where_p, uint32_t * size_p) * Figure out the "geometry" of the disk in question */ struct geometry { - uint32_t sectors; /* 512-byte sector count */ + uint32_t sectors; /* Sector count */ uint32_t c, h, s; /* C/H/S geometry */ uint32_t offset; /* Byte offset for disk */ uint8_t type; /* Type byte for INT 13h AH=08h */ uint8_t driveno; /* Drive no */ + uint16_t sector_size; /* Sector size in bytes (512 vs. 2048) */ const char *hsrc, *ssrc; /* Origins of H and S geometries */ }; @@ -406,6 +420,8 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, printf("command line: %s\n", shdr->cmdline); + hd_geometry.sector_size = 512; /* Assume floppy/HDD at first */ + offset = 0; if (CMD_HASDATA(p = getcmditem("offset")) && (v = atou(p))) offset = v; @@ -417,6 +433,71 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, hd_geometry.sectors = sectors; hd_geometry.offset = offset; + if ((p = getcmditem("iso")) != CMD_NOTFOUND) { +#ifdef DBG_ELTORITO + eltorito_dump(where); +#endif + struct edd4_bvd *bvd = (struct edd4_bvd *)(where + 17 * 2048); + /* Tiny sanity check */ + if ((bvd->boot_rec_ind != 0) || (bvd->ver != 1)) + printf("El Torito BVD sanity check failed.\n"); + struct edd4_bootcat *boot_cat = + (struct edd4_bootcat *)(where + bvd->boot_cat * 2048); + /* Another tiny sanity check */ + if ((boot_cat->validation_entry.platform_id != 0) || + (boot_cat->validation_entry.key55 != 0x55) || + (boot_cat->validation_entry.keyAA != 0xAA)) + printf("El Torito boot catalog sanity check failed.\n"); + /* If we have an emulation mode, set the offset to the image */ + if (boot_cat->initial_entry.media_type) + hd_geometry.offset += boot_cat->initial_entry.load_block * 2048; + if (boot_cat->initial_entry.media_type < 4) { + /* We're a floppy emulation mode or our params will be + * overwritten by the no emulation mode case + */ + hd_geometry.driveno = 0x00; + hd_geometry.c = 80; + hd_geometry.h = 2; + } + switch (boot_cat->initial_entry.media_type) { + case 0: /* No emulation */ + hd_geometry.driveno = 0xE0; + hd_geometry.type = 10; /* ATAPI removable media device */ + hd_geometry.c = 65535; + hd_geometry.h = 255; + hd_geometry.s = 15; + /* 2048-byte sectors, so adjust the size and count */ + hd_geometry.sector_size = 2048; + sectors = (size - hd_geometry.offset) >> 11; + break; + case 1: /* 1.2 MB floppy */ + hd_geometry.s = 15; + hd_geometry.type = 2; + sectors = 2400; + break; + case 2: /* 1.44 MB floppy */ + hd_geometry.s = 18; + hd_geometry.type = 4; + sectors = 2880; + break; + case 3: /* 2.88 MB floppy */ + hd_geometry.s = 36; + hd_geometry.type = 6; + sectors = 5760; + break; + case 4: + hd_geometry.driveno = 0x80; + hd_geometry.type = 0; + sectors = (size - hd_geometry.offset) >> 9; + break; + } + /* For HDD emulation, we figure out the geometry later. Otherwise: */ + if (hd_geometry.s) { + hd_geometry.hsrc = hd_geometry.ssrc = "El Torito"; + } + hd_geometry.sectors = sectors; + } + /* Do we have a DOSEMU header? */ memcpy(&dosemu, (char *)where + hd_geometry.offset, sizeof dosemu); if (!memcmp("DOSEMU", dosemu.magic, 7)) { @@ -480,7 +561,7 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, if (!(max_h | max_s)) { /* No FAT filesystem found to steal geometry from... */ - if (sectors < 4096 * 2) { + if ((sectors < 4096 * 2) && (hd_geometry.sector_size == 512)) { int ok = 0; unsigned int xsectors = sectors; @@ -541,7 +622,9 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, const struct ptab_entry *ptab = (const struct ptab_entry *) ((char *)where + hd_geometry.offset + (512 - 2 - 4 * 16)); - hd_geometry.driveno = 0x80; /* Assume hard disk */ + /* Assume hard disk */ + if (!hd_geometry.driveno) + hd_geometry.driveno = 0x80; if (*(uint16_t *) ((char *)where + 512 - 2) == 0xaa55) { for (i = 0; i < 4; i++) { @@ -718,12 +801,15 @@ void setup(const struct real_mode_args *rm_args_ptr) uint16_t dosmem_k; uint32_t stddosmem; const struct geometry *geometry; + const struct edd4_bvd *bvd; + const struct edd4_bootcat *boot_cat = 0; int total_size, cmdlinelen; com32sys_t regs; uint32_t ramdisk_image, ramdisk_size; uint32_t boot_base, rm_base; int bios_drives; int do_edd = 1; /* 0 = no, 1 = yes, default is yes */ + int do_eltorito = 0; /* default is no */ int no_bpt; /* No valid BPT presented */ uint32_t boot_seg = 0; /* Meaning 0000:7C00 */ uint32_t boot_len = 512; /* One sector */ @@ -762,13 +848,28 @@ void setup(const struct real_mode_args *rm_args_ptr) else do_edd = (geometry->driveno & 0x80) ? 1 : 0; + if (getcmditem("iso") != CMD_NOTFOUND) { + do_eltorito = 1; + do_edd = 1; /* Mandatory */ + } + /* Choose the appropriate installable memdisk hook */ - if (do_edd) { - bin_size = (int)&_binary_memdisk_edd_512_bin_size; - memdisk_hook = (char *)&_binary_memdisk_edd_512_bin_start; + if (do_eltorito) { + if (geometry->sector_size == 2048) { + bin_size = (int)&_binary_memdisk_iso_2048_bin_size; + memdisk_hook = (char *)&_binary_memdisk_iso_2048_bin_start; + } else { + bin_size = (int)&_binary_memdisk_iso_512_bin_size; + memdisk_hook = (char *)&_binary_memdisk_iso_512_bin_start; + } } else { - bin_size = (int)&_binary_memdisk_chs_512_bin_size; - memdisk_hook = (char *)&_binary_memdisk_chs_512_bin_start; + if (do_edd) { + bin_size = (int)&_binary_memdisk_edd_512_bin_size; + memdisk_hook = (char *)&_binary_memdisk_edd_512_bin_start; + } else { + bin_size = (int)&_binary_memdisk_chs_512_bin_size; + memdisk_hook = (char *)&_binary_memdisk_chs_512_bin_start; + } } /* Reserve the ramdisk memory */ @@ -788,7 +889,7 @@ void setup(const struct real_mode_args *rm_args_ptr) pptr->driveno = geometry->driveno; pptr->drivetype = geometry->type; - pptr->cylinders = geometry->c; + pptr->cylinders = geometry->c; /* Possible precision loss */ pptr->heads = geometry->h; pptr->sectors = geometry->s; pptr->disksize = geometry->sectors; @@ -884,7 +985,12 @@ void setup(const struct real_mode_args *rm_args_ptr) pptr->edd_dpt.c = geometry->c; pptr->edd_dpt.h = geometry->h; pptr->edd_dpt.s = geometry->s; - pptr->edd_dpt.flags |= 0x0002; /* Geometry valid */ + /* EDD-4 states that invalid geometry should be returned + * for INT 0x13, AH=0x48 "EDD Get Disk Parameters" call on an + * El Torito ODD. Check for 2048-byte sector size + */ + if (geometry->sector_size != 2048) + pptr->edd_dpt.flags |= 0x0002; /* Geometry valid */ } if (!(geometry->driveno & 0x80)) { /* Floppy drive. Mark it as a removable device with @@ -896,6 +1002,21 @@ void setup(const struct real_mode_args *rm_args_ptr) pptr->edd_dpt.chksum = -checksum_buf(&pptr->edd_dpt.dpikey, 73 - 30); } + if (do_eltorito) { + bvd = (struct edd4_bvd *)(ramdisk_image + 17 * 2048); + boot_cat = + (struct edd4_bootcat *)(ramdisk_image + bvd->boot_cat * 2048); + pptr->cd_pkt.type = boot_cat->initial_entry.media_type; /* Cheat */ + pptr->cd_pkt.driveno = geometry->driveno; + pptr->cd_pkt.start = boot_cat->initial_entry.load_block; + pptr->cd_pkt.load_seg = boot_cat->initial_entry.load_seg; + pptr->cd_pkt.sect_count = boot_cat->initial_entry.sect_count; + boot_len = pptr->cd_pkt.sect_count * 2048; + pptr->cd_pkt.geom1 = (uint8_t)(pptr->cylinders) & 0xFF; + pptr->cd_pkt.geom2 = (uint8_t)(pptr->sectors) | (uint8_t)((pptr->cylinders >> 2) & 0xC0); + pptr->cd_pkt.geom3 = (uint8_t)(pptr->heads); + } + /* The size is given by hptr->total_size plus the size of the E820 map -- 12 bytes per range; we may need as many as 2 additional ranges (each insertrange() can worst-case turn 1 area into 3) @@ -1041,7 +1162,7 @@ void setup(const struct real_mode_args *rm_args_ptr) if (nhd > 128) nhd = 128; - wrz_8(BIOS_HD_COUNT, nhd); + if (!do_eltorito) wrz_8(BIOS_HD_COUNT, nhd); } else { /* Update BIOS floppy disk count */ uint8_t equip = rdz_8(BIOS_EQUIP); @@ -1097,6 +1218,10 @@ void setup(const struct real_mode_args *rm_args_ptr) /* Reboot into the new "disk" */ puts("Loading boot sector... "); + if (do_eltorito) { + /* 4 times as many 512-byte sectors in a 2048-byte sector */ + boot_lba = pptr->cd_pkt.start * 4; + } memcpy((void *)boot_base, (char *)pptr->diskbuf + boot_lba * 512, boot_len); if (getcmditem("pause") != CMD_NOTFOUND) { |