#include "partiter.h"
#include "mangle.h"
-struct options opt;
-
static int fixed_cnt = 128; /* see comments in main() */
static int overlap(const struct data_area *a, const struct data_area *b)
int main(int argc, char *argv[])
{
struct part_iter *iter = NULL;
-
void *sbck = NULL;
struct data_area fdat, hdat, sdat, data[3];
int ndata = 0;
console_ansi_raw();
-/* openconsole(&dev_null_r, &dev_stdcon_w);*/
- /* Prepare and set defaults */
memset(&fdat, 0, sizeof(fdat));
memset(&hdat, 0, sizeof(hdat));
memset(&sdat, 0, sizeof(sdat));
- memset(&opt, 0, sizeof(opt));
- opt.sect = true; /* by def. load sector */
- opt.maps = true; /* by def. map sector */
- opt.hand = true; /* by def. prepare handover */
- opt.chain = true; /* by def. do chainload */
- opt.foff = opt.soff = opt.fip = opt.sip = 0x7C00;
- opt.drivename = "boot";
-#ifdef DEBUG
- opt.warn = true;
-#endif
- /* Parse arguments */
- if (parse_args(argc, argv))
+ opt_set_defs();
+ if (opt_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
+ * hmm, looks like we can't do that -
+ * some bioses/vms just set it to 1
+ * and go on living happily
* any better options than hardcoded 0x80 - 0xFF ?
*/
#endif
error("The sector cannot be loaded at such high address.\n");
goto bail;
}
- if (opt.file && opt.maps && overlap(&fdat, &sdat)) {
- error("WARNING: The sector won't be loaded, as it would conflict with the boot file.\n");
- opt.sect = false;
- } else {
- if (!(sdat.data = disk_read_sectors(&iter->di, iter->start_lba, 1))) {
- error("Couldn't read the sector.\n");
+ if (!(sdat.data = disk_read_sectors(&iter->di, iter->start_lba, 1))) {
+ error("Couldn't read the sector.\n");
+ goto bail;
+ }
+ if (opt.save) {
+ if (!(sbck = malloc(sdat.size))) {
+ error("Couldn't allocate cmp-buf for option 'save'.\n");
goto bail;
}
- if (opt.save) {
- if (!(sbck = malloc(sdat.size))) {
- error("Couldn't allocate cmp-buf for option 'save'.\n");
- goto bail;
- }
- memcpy(sbck, sdat.data, sdat.size);
- }
+ memcpy(sbck, sdat.data, sdat.size);
+ }
+ if (opt.file && opt.maps && overlap(&fdat, &sdat)) {
+ error("WARNING: The sector won't be mmapped, as it would conflict with the boot file.\n");
+ opt.maps = false;
}
}
goto bail;
/* Verify possible conflicts */
if ( ( opt.file && overlap(&fdat, &hdat)) ||
- ( opt.sect && overlap(&sdat, &hdat) && opt.maps) ) {
+ ( opt.maps && overlap(&sdat, &hdat)) ) {
error("WARNING: Handover area won't be prepared,\n"
"as it would conflict with the boot file and/or the sector.\n");
opt.hand = false;
/* Adjust registers */
- mangler_common(iter);
+ mangler_init(iter);
mangler_handover(iter, &hdat);
mangler_grldr(iter);
if (opt.file)
memcpy(data + ndata++, &fdat, sizeof(fdat));
- if (opt.sect && opt.maps)
+ if (opt.maps)
memcpy(data + ndata++, &sdat, sizeof(sdat));
if (opt.hand)
memcpy(data + ndata++, &hdat, sizeof(hdat));
#ifndef _COM32_CHAIN_CHAIN_H
#define _COM32_CHAIN_CHAIN_H
-#include <stdint.h>
-#include <syslinux/bootrm.h>
-#include "options.h"
+#include <syslinux/movebits.h>
struct data_area {
void *data;
addr_t size;
};
-extern struct options opt;
-
#endif
/* vim: set ts=8 sts=4 sw=4 noet: */
}
/* Set common registers */
-int mangler_common(const struct part_iter *iter)
+int mangler_init(const struct part_iter *iter)
{
/* Set initial registry values */
if (opt.file) {
/* ds:si & ds:bp */
int mangler_handover(const struct part_iter *iter, const struct data_area *data)
{
- if (opt.sect && opt.file && opt.maps && !opt.hptr) {
+ if (opt.file && opt.maps && !opt.hptr) {
opt.regs.esi.l = opt.regs.ebp.l = opt.soff;
opt.regs.ds = (uint16_t)opt.sseg;
opt.regs.eax.l = 0;
/* base is really 0x7be */
opt.regs.esi.l = opt.regs.ebp.l = data->base;
opt.regs.ds = 0;
- if (iter->type == typegpt)
+ if (iter->index && iter->type == typegpt) /* must be iterated and GPT */
opt.regs.eax.l = 0x54504721; /* '!GPT' */
else
opt.regs.eax.l = 0;
#include "chain.h"
#include "partiter.h"
+/* file's manglers */
int manglef_isolinux(struct data_area *data);
int manglef_grub(const struct part_iter *iter, struct data_area *data);
int manglef_bpb(const struct part_iter *iter, struct data_area *data);
/* int manglef_drmk(struct data_area *data);*/
+/* sector's manglers */
int mangles_bpb(const struct part_iter *iter, struct data_area *data);
int mangles_save(const struct part_iter *iter, const struct data_area *data, void *org);
int mangles_cmldr(struct data_area *data);
+/* sector + file's manglers */
int manglesf_bss(struct data_area *sec, struct data_area *fil);
-int mangler_common(const struct part_iter *iter);
+/* registers' manglers */
+int mangler_init(const struct part_iter *iter);
int mangler_handover(const struct part_iter *iter, const struct data_area *data);
int mangler_grldr(const struct part_iter *iter);
+/* partition layout's manglers */
int manglepe_mbrchshide(struct part_iter *miter);
#endif
#include "utility.h"
#include "options.h"
-int soi_s2n(char *ptr, unsigned int *seg,
+struct options opt;
+
+static int soi_s2n(char *ptr, unsigned int *seg,
unsigned int *off,
unsigned int *ip,
unsigned int def)
return -1;
}
-void usage(void)
+static void usage(void)
{
unsigned int i;
static const char key[] = "Press any key...\n";
}
}
-int parse_args(int argc, char *argv[])
+void opt_set_defs(void)
+{
+ memset(&opt, 0, sizeof(opt));
+ opt.sect = true; /* by def. load sector */
+ opt.maps = true; /* by def. map sector */
+ opt.hand = true; /* by def. prepare handover */
+ opt.chain = true; /* by def. do chainload */
+ opt.foff = opt.soff = opt.fip = opt.sip = 0x7C00;
+ opt.drivename = "boot";
+#ifdef DEBUG
+ opt.warn = true;
+#endif
+}
+
+int opt_parse_args(int argc, char *argv[])
{
int i;
unsigned int v;
} else if (!strncmp(argv[i], "sect=", 5) ||
!strcmp(argv[i], "sect")) {
if (argv[i][4]) {
- if (soi_s2n(argv[i] + 5, &opt.sseg, &opt.soff, &opt.sip, 0x7c00))
+ if (soi_s2n(argv[i] + 5, &opt.sseg, &opt.soff, &opt.sip, 0))
goto bail;
}
opt.sect = true;
} else if (!strcmp(argv[i], "nosect")) {
opt.sect = false;
+ opt.maps = false;
} else if (!strcmp(argv[i], "save")) {
opt.save = true;
} else if (!strcmp(argv[i], "nosave")) {
goto bail;
}
+ if (opt.maps && !opt.sect) {
+ error("Option 'maps' requires option 'sect'.\n");
+ goto bail;
+ }
+
return 0;
bail:
return -1;
#ifndef _COM32_CHAIN_OPTIONS_H
#define _COM32_CHAIN_OPTIONS_H
+#include <stdint.h>
+#include <syslinux/bootrm.h>
+
struct options {
unsigned int fseg;
unsigned int foff;
struct syslinux_rm_regs regs;
};
-int soi_s2n(char *ptr, unsigned int *seg, unsigned int *off,
- unsigned int *ip, unsigned int def);
-void usage(void);
-int parse_args(int argc, char *argv[]);
+extern struct options opt;
+
+void opt_set_defs(void);
+int opt_parse_args(int argc, char *argv[]);
#endif
or
-- 'nofile' and 'nomaps' are in effect
+- 'nofile' and 'nomaps' (or 'nosect') are in effect
This is useful for invocations such as:
sect=<segment>:<offset>:<ip>
nosect
*sect=0:0x7c00:0x7c00
+ nosect sets: nomaps
This triplet lets you alter the addresses a sector will use. File is loaded at
<segment:offset>, the jump is made to <segment:ip>. This option is mostly used
is being chainloaded, sector is not necessary.
The defaults if option is not specified, are 0:0x7c00:0x7c00.
-If some of the fields are ommited (e.g. 0x2000::), segment defaults to 0,
-offset and ip to 0x7c00.
+If some of the fields are ommited (e.g. 0x2000::), they default to 0.
*maps
nomaps
- this option never applies to a loaded file
- chain module will never save anything to disk by default
-- writing is only performed, if the values actually got changed
+- writing is only performed, if the values actually changed
*hand
nohand
-By default, a handover area is always prepared if possible and potentially
-useful - meaning it doesn't overlap with other areas, and syslinux chainloads a
-partition. It's often not necessary though - usually, a chainloaded file or
-kernel don't care about it anymore, so a user can disable it explicitly with
-this option.
+By default, a handover area is always prepared if possible - meaning it doesn't
+overlap with other areas. It's often not necessary though - usually, a
+chainloaded file or kernel don't care about it anymore, so a user can disable
+it explicitly with this option.
hptr
*nohptr