*
* Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
* Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
- * Significant portions copyright (C) 2010 Shao Miller
- * [partition iteration, GPT, "fs"]
+ * Copyright 2010 Shao Miller
+ * Copyright 2010 Michal Soltys
*
* 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
struct options opt;
-static int fixed_cnt;
+static int fixed_cnt = 128; /* see comments in main() */
static int overlap(const struct data_area *a, const struct data_area *b)
{
if (opt.mbrchs) {
wb |= pem_setchs(&iter->di, dp, (uint32_t)iter->start_lba);
if (ridx > 4)
- wb |= pem_setchs(&iter->di, mbr.table + 1, iter->sub.dos.ebr_lba);
+ wb |= pem_setchs(&iter->di, mbr.table + 1, iter->sub.dos.nebr_lba);
}
}
/* last write */
sdi = syslinux_derivative_info();
if (!strncmp(opt.drivename, "mbr", 3)) {
- if (find_by_sig(strtoul(opt.drivename + 4, NULL, 0), &iter)) {
+ if (find_by_sig(strtoul(opt.drivename + 4, NULL, 0), &iter) < 0) {
error("Unable to find requested MBR signature.\n");
goto bail;
}
} else if (!strncmp(opt.drivename, "guid", 4)) {
if (str_to_guid(opt.drivename + 5, &gpt_guid))
goto bail;
- if (find_by_guid(&gpt_guid, &iter)) {
+ if (find_by_guid(&gpt_guid, &iter) < 0) {
error("Unable to find requested GPT disk or partition by guid.\n");
goto bail;
}
error("No label specified.\n");
goto bail;
}
- if (find_by_label(opt.drivename + 6, &iter)) {
+ if (find_by_label(opt.drivename + 6, &iter) < 0) {
error("Unable to find requested GPT partition by label.\n");
goto bail;
}
/* Parse arguments */
if (parse_args(argc, argv))
goto bail;
-
+#if 0
/* Get max fixed disk number */
fixed_cnt = *(uint8_t *)(0x475);
+ /*
+ * hmm, looks like we can't do that
+ * any better options than hardcoded 0x80 - 0xFF ?
+ */
+#endif
+
/* Get disk/part iterator matching user supplied options */
if (find_dp(&iter))
goto bail;
} else if (opt.hand) {
if (setup_handover(iter, &hdat))
goto bail;
+
/* Verify possible conflicts */
if ( ( opt.file && overlap(&fdat, &hdat)) ||
( opt.sect && overlap(&sdat, &hdat) && opt.maps) ) {
}
/* Adjust registers */
+
mangler_common(iter);
mangler_handover(iter, &hdat);
mangler_grldr(iter);
- /*
- * Patching functions
- * opt.* are tested inside
- */
+ /* Patching functions */
if (manglef_isolinux(&fdat))
goto bail;
if (mangles_cmldr(&sdat))
goto bail;
- /* Prepare boot-time mmap data */
+ /*
+ * Prepare boot-time mmap data We should to it here, as manglers could
+ * potentially alter some of the data.
+ */
if (opt.file)
memcpy(data + ndata++, &fdat, sizeof(fdat));
printf("iter idx: %d\n", iter->index);
printf("iter lba: %llu\n", iter->start_lba);
if (opt.hand)
- printf("hand lba: %u\n", ((disk_dos_part_entry *)hdat.data)->start_lba);
+ printf("hand lba: %u\n",
+ ((struct disk_dos_part_entry *)hdat.data)->start_lba);
#endif
if (opt.warn) {
type1 = bpb_detect(fil->data);
type2 = bpb_detect(sec->data);
- if (type1 < 0 || type2 < 0) {
- error("Option 'bss' can't determine BPB type.\n");
+ if (!type1 || !type2) {
+ error("Couldn't determine the BPB type for option 'bss'.\n");
goto bail;
}
if (type1 != type2) {
|| !strncmp(argv[i], "boot,", 5)
|| !strcmp(argv[i], "fs")) {
opt.drivename = argv[i];
- if (strncmp(argv[i], "label", 5)) {
+ if (strncmp(argv[i], "label", 5))
p = strchr(opt.drivename, ',');
- if (p) {
- *p = '\0';
- opt.partition = p + 1;
- } else if (argv[i + 1] && argv[i + 1][0] >= '0'
- && argv[i + 1][0] <= '9') {
- opt.partition = argv[++i];
- }
+ else
+ p = NULL;
+ if (p) {
+ *p = '\0';
+ opt.partition = p + 1;
+ } else if (argv[i + 1] && argv[i + 1][0] >= '0'
+ && argv[i + 1][0] <= '9') {
+ opt.partition = argv[++i];
}
} else {
usage();
iter->sub.dos.ebr_size = iter->sub.dos.bebr_size;
iter->sub.dos.cebr_lba = 0;
- iter->sub.dos.ebr_lba = iter->sub.dos.bebr_start;
+ iter->sub.dos.nebr_lba = iter->sub.dos.bebr_start;
iter->index0--;
}
if (prep_base_ebr(iter))
return -1;
- while (++iter->index0 < 1024 && iter->sub.dos.ebr_lba) {
+ while (++iter->index0 < 1024 && iter->sub.dos.nebr_lba) {
free(iter->data);
if (!(iter->data =
- disk_read_sectors(&iter->di, iter->sub.dos.ebr_lba, 1))) {
+ disk_read_sectors(&iter->di, iter->sub.dos.nebr_lba, 1))) {
error("Couldn't load EBR.\n");
return -1;
}
dp = ((struct disk_dos_mbr *)iter->data)->table;
- iter->sub.dos.cebr_lba = iter->sub.dos.ebr_lba;
+ iter->sub.dos.cebr_lba = iter->sub.dos.nebr_lba;
/* setup next frame values */
if (dp[1].ostype) {
iter->sub.dos.ebr_start = dp[1].start_lba;
iter->sub.dos.ebr_size = dp[1].length;
- iter->sub.dos.ebr_lba = iter->sub.dos.bebr_start + dp[1].start_lba;
+ iter->sub.dos.nebr_lba = iter->sub.dos.bebr_start + dp[1].start_lba;
} else {
iter->sub.dos.ebr_start = 0;
iter->sub.dos.ebr_size = 0;
- iter->sub.dos.ebr_lba = 0;
+ iter->sub.dos.nebr_lba = 0;
}
if (!dp[0].ostype)
union _sub {
struct _dos {
uint32_t disk_sig;
- uint32_t ebr_lba;
+ uint32_t nebr_lba;
uint32_t cebr_lba;
/* internal */
uint32_t ebr_start;
#include <syslinux/disk.h>
#include "utility.h"
+#ifdef DEBUG
+static const char *bpbtypes[] = {
+ [0] = "BPB unknown",
+ [1] = "BPB v.2.0",
+ [2] = "BPB v.3.0",
+ [3] = "BPB v.3.2",
+ [4] = "BPB v.3.4",
+ [5] = "BPB v.4.0",
+ [6] = "BPB v.NT+",
+ [7] = "BPB v.7.0",
+};
+#endif
+
void error(const char *msg)
{
fputs(msg, stderr);
*/
int bpb_detect(const uint8_t *sec)
{
- int a, b, c, jmp = -1, rev = -1;
+ int a, b, c, jmp = -1, rev = 0;
/* media descriptor check */
if ((sec[0x15] & 0xF0) != 0xF0)
- return -1;
+ goto out;
if (sec[0] == 0xEB) /* jump short */
jmp = 2 + *(int8_t *)(sec + 1);
/* sanity */
if (jmp < 0x18 || jmp > 0x1F0)
- return -1;
+ goto out;
/* detect by jump */
if (jmp >= 0x18 && jmp < 0x1E)
/* TODO: some better V2 - V3.4 checks ? */
- if (rev >= 0)
- return rev;
+ if (rev)
+ goto out;
+ /*
+ * BPB info:
+ * 2.0 == 0x0B - 0x17
+ * 3.0 == 2.0 + 0x18 - 0x1D
+ * 3.2 == 3.0 + 0x1E - 0x1F
+ * 3.4 ==!2.0 + 0x18 - 0x23
+ * 4.0 == 3.4 + 0x24 - 0x45
+ * NT ==~3.4 + 0x24 - 0x53
+ * 7.0 == 3.4 + 0x24 - 0x59
+ */
nocode:
a = memcmp(sec + 0x03, "NTFS", 4);
rev = bpbV70;
}
+out:
+#ifdef DEBUG
+ printf("INFO: BPB detection: %s\n", bpbtypes[rev]);
+#endif
return rev;
}
#include <stdint.h>
#include <syslinux/disk.h>
+#define bpbUNK 0
#define bpbV20 1
#define bpbV30 2
#define bpbV32 3
sector at 0x2000 and overall valid BPB values. As in other DOS-ish cases,
likely candidates for use are 'save' and 'hide'.
- grub=<file>
- grubcfg=<config>
+ grub=<file> [grubcfg=<config>]
sets: file=<file> seg=0x800::0x200 nohand nosect grub
Chainloads grub legacy's stage2, performing additional corrections on the file
This emulates syslinux's native BSS option. This loads both the file and the
sector, adjusts BPB values in the loaded sector, then copies all possible BPB
-fields to the loaded file. Everything is made with reference to selected
+fields to the loaded file. Everything is made with reference to the selected
disk/partition.
bs=<file>
sets: bs=<file> nosect filebpb
This emulates syslinux's native BS option. This loads the file and if possible
-- adjusts its BPB values. Everything is made with reference to selected
+- adjusts its BPB values. Everything is made with reference to the selected
disk/partition.