summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2001-12-12 21:52:44 +0000
committerhpa <hpa>2001-12-12 21:52:44 +0000
commit6b190cc5cf21708b6aacc50c9050e074f67bed90 (patch)
treebd03eaf65f970b3d4c9a5eca66198cda4e1d4237
parent52a13b0a49a59b993fb1a38675a0c731d733d228 (diff)
downloadsyslinux-6b190cc5cf21708b6aacc50c9050e074f67bed90.tar.gz
Support parsing the command line, and setting the geometry that way.syslinux-1.65-pre8
-rw-r--r--memdisk/conio.c11
-rw-r--r--memdisk/conio.h1
-rw-r--r--memdisk/init.S1623
-rw-r--r--memdisk/memdisk.doc9
-rw-r--r--memdisk/setup.c159
5 files changed, 160 insertions, 43 deletions
diff --git a/memdisk/conio.c b/memdisk/conio.c
index 8599dddb..f1ca699e 100644
--- a/memdisk/conio.c
+++ b/memdisk/conio.c
@@ -78,6 +78,14 @@ static int skip_atoi(const char **s)
return i;
}
+unsigned int atou(const char *s)
+{
+ unsigned int i = 0;
+ while (isdigit(*s))
+ i = i*10 + (*s++ - '0');
+ return i;
+}
+
static int strnlen(const char *s, int maxlen)
{
const char *es = s;
@@ -256,9 +264,6 @@ int vsprintf(char *buf, const char *fmt, va_list args)
case 's':
s = va_arg(args, char *);
- if (!s)
- s = "(null)";
-
len = strnlen(s, precision);
if (!(flags & LEFT))
diff --git a/memdisk/conio.h b/memdisk/conio.h
index 7f823aeb..93ad000e 100644
--- a/memdisk/conio.h
+++ b/memdisk/conio.h
@@ -26,5 +26,6 @@
int putchar(int);
int puts(const char *);
int printf(const char *, ...);
+unsigned int atou(const char *);
#endif
diff --git a/memdisk/init.S16 b/memdisk/init.S16
index 2e87d1dc..b07dc5bc 100644
--- a/memdisk/init.S16
+++ b/memdisk/init.S16
@@ -139,7 +139,28 @@ start:
startc:
/*
- * Set up the operating environment expected by the C code.
+ * Copy the command line, if there is one
+ */
+ xorw %di,%di # Bottom of our own segment
+ movl cmd_line_ptr, %eax
+ andl %eax,%eax
+ jz endcmd # No command line?
+ movw %ax,%si
+ shrl $4,%eax # Convert to a segment address
+ andw $0x000F,%si # Starting offset
+ movw %ax,%gs
+ movw $496,%cx # Maximum number of bytes
+copycmd:
+ lodsb %gs:(%si),%al
+ andb %al,%al # Make sure we're null-terminated
+ jz endcmd
+ stosb %al,%es:(%di)
+ loopw copycmd
+endcmd:
+ xorb %al,%al
+ stosb %al,%es:(%di)
+/*
+ * Jump to C code
*/
sti # Maybe not?
calll setup # Call the C code
diff --git a/memdisk/memdisk.doc b/memdisk/memdisk.doc
index 59a23089..64d19df3 100644
--- a/memdisk/memdisk.doc
+++ b/memdisk/memdisk.doc
@@ -43,6 +43,15 @@ should typically have an MBR and a partition table. The disk C/H/S
geometry is determined by examining the partition table, so the entire
image should be partitioned for proper operation.
+You can also specify the geometry manually with the following command
+line options (currently untested):
+
+ c=<number> Specify number of cylinders
+ h=<number> Specify number of heads
+ s=<number> Specify number of sectors
+ floppy The image is a floppy image
+ harddisk The image is a hard disk image
+
If you want to recompile it from sources, you will need to make sure that
you have a fairly recent binutils installed. I have been using the
binutils-2.11.90.0.8-9 RPM from RedHat.
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 74284795..0fa9dbf9 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -49,7 +49,7 @@ struct patch_area {
/* This is the header in the boot sector/setup area */
struct setup_header {
- uint8_t dummy[0x1f1]; /* Boot sector */
+ char cmdline[0x1f1];
uint8_t setup_secs;
uint16_t syssize;
uint16_t swap_dev;
@@ -115,7 +115,7 @@ static void high_bcopy(uint32_t dst, uint32_t src, uint16_t len)
high_mover.dst2 = dst >> 16;
high_mover.dst3 = dst >> 24;
- asm volatile("pushf ; movb $0x87,%%ah ; int $0x15 ; popf"
+ asm volatile("pushfl ; movb $0x87,%%ah ; int $0x15 ; popfl"
:: "S" (&high_mover), "c" (len >> 1)
: "eax", "ebx", "ecx", "edx",
"ebp", "esi", "edi", "memory");
@@ -185,6 +185,62 @@ rdz_32(uint32_t addr)
#define BIOS_BASEMEM 0x413 /* Amount of DOS memory */
/*
+ * Routine to seek for a command-line item and return a pointer
+ * to the data portion, if present
+ */
+static inline int
+isspace(int ch)
+{
+ return (ch == ' ') || ((ch >= '\b') && (ch <= '\r'));
+}
+
+/* Magic return values */
+#define CMD_NOTFOUND ((char *)-1) /* Not found */
+#define CMD_BOOL ((char *)-2) /* Found boolean option */
+#define CMD_HASDATA(X) ((int)(X) >= 0)
+const char *getcmditem(const char *what)
+{
+ const char *p, *wp;
+ int match = 0;
+
+ for ( p = shdr->cmdline ; *p ; p++ ) {
+ switch ( match ) {
+ case 0: /* Ground state */
+ if ( isspace(*p) )
+ break;
+
+ wp = what;
+ /* Fall through */
+
+ case 1: /* Matching */
+ if ( *wp == '\0' ) {
+ if ( *p == '=' )
+ return p+1;
+ else if ( isspace(*p) )
+ return CMD_BOOL;
+ else {
+ match = 2;
+ break;
+ }
+ }
+ if ( *p != *wp++ )
+ match = 2; /* Skipping bogus */
+ break;
+
+ case 2:
+ if ( isspace(*p) )
+ match = 0; /* Next option */
+ }
+ }
+
+ /* Check for matching string at end of line */
+ if ( match == 1 && *wp == '\0' )
+ return CMD_BOOL;
+
+ return CMD_NOTFOUND;
+}
+
+/*
* Figure out the "geometry" of the disk in question
*/
struct geometry {
@@ -216,63 +272,88 @@ struct ptab_entry {
const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
{
- static struct geometry hd_geometry;
+ static struct geometry hd_geometry = { 0, 0, 0, 0, 0, 0x80 };
struct ptab_entry ptab[4]; /* Partition table buffer */
- uint32_t sectors;
+ unsigned int sectors, v;
+ unsigned int max_c, max_h, max_s;
+ unsigned int c, h, s;
int i;
- int c, h, s;
- int max_c, max_h, max_s;
+ const char *p;
+
+ printf("command line: %s\n", shdr->cmdline);
if ( size & 0x1ff ) {
puts("MEMDISK: Image has fractional end sector\n");
size &= ~0x1ff;
}
+
sectors = size >> 9;
+ hd_geometry.sectors = sectors;
for ( i = 0 ; i < known_geometries ; i++ ) {
if ( sectors == geometries[i].sectors ) {
- return &geometries[i];
+ hd_geometry = geometries[i];
+ break;
}
}
- /* No match, must be a hard disk image */
- /* Need to examine the partition table for geometry */
- copy_from_high(&ptab, where+(512-2-4*16), sizeof ptab);
+ if ( CMD_HASDATA(p = getcmditem("c")) && (v = atou(p)) )
+ hd_geometry.c = v;
+ if ( CMD_HASDATA(p = getcmditem("h")) && (v = atou(p)) )
+ hd_geometry.h = v;
+ if ( CMD_HASDATA(p = getcmditem("s")) && (v = atou(p)) )
+ hd_geometry.s = v;
- max_c = max_h = 0; max_s = 1;
- for ( i = 0 ; i < 4 ; i++ ) {
- if ( ptab[i].type ) {
- c = ptab[i].start_c + (ptab[i].start_s >> 6);
- s = (ptab[i].start_s & 0x3f);
- h = ptab[i].start_h;
-
- if ( max_c < c ) max_c = c;
- if ( max_h < h ) max_h = h;
- if ( max_s < s ) max_s = s;
-
- c = ptab[i].end_c + (ptab[i].end_s >> 6);
- s = (ptab[i].end_s & 0x3f);
- h = ptab[i].end_h;
-
- if ( max_c < c ) max_c = c;
- if ( max_h < h ) max_h = h;
- if ( max_s < s ) max_s = s;
- }
+ if ( getcmditem("floppy") != CMD_NOTFOUND ) {
+ hd_geometry.driveno = 0;
+ if ( hd_geometry.type == 0 )
+ hd_geometry.type = 0x10; /* ATAPI floppy, e.g. LS-120 */
+ }
+ if ( getcmditem("harddisk") != CMD_NOTFOUND ) {
+ hd_geometry.driveno = 0x80;
+ hd_geometry.type = 0;
}
- max_c++; max_h++; /* Convert to count (1-based) */
-
- hd_geometry.sectors = sectors;
- hd_geometry.c = sectors/(max_h*max_s);
- hd_geometry.h = max_h;
- hd_geometry.s = max_s;
- hd_geometry.type = 0;
- hd_geometry.driveno = 0x80; /* Hard drive */
+ if ( (hd_geometry.c == 0) || (hd_geometry.h == 0) ||
+ (hd_geometry.s == 0) ) {
+ /* Hard disk image, need to examine the partition table for geometry */
+ copy_from_high(&ptab, where+(512-2-4*16), sizeof ptab);
+
+ max_c = max_h = 0; max_s = 1;
+ for ( i = 0 ; i < 4 ; i++ ) {
+ if ( ptab[i].type ) {
+ c = ptab[i].start_c + (ptab[i].start_s >> 6);
+ s = (ptab[i].start_s & 0x3f);
+ h = ptab[i].start_h;
+
+ if ( max_c < c ) max_c = c;
+ if ( max_h < h ) max_h = h;
+ if ( max_s < s ) max_s = s;
+
+ c = ptab[i].end_c + (ptab[i].end_s >> 6);
+ s = (ptab[i].end_s & 0x3f);
+ h = ptab[i].end_h;
+
+ if ( max_c < c ) max_c = c;
+ if ( max_h < h ) max_h = h;
+ if ( max_s < s ) max_s = s;
+ }
+ }
+
+ max_c++; max_h++; /* Convert to count (1-based) */
+
+ if ( !hd_geometry.h )
+ hd_geometry.h = max_h;
+ if ( !hd_geometry.s )
+ hd_geometry.s = max_s;
+ if ( !hd_geometry.c )
+ hd_geometry.c = sectors/(hd_geometry.h*hd_geometry.s);
+ }
- if ( sectors % (max_s*max_h) ) {
+ if ( sectors % (hd_geometry.h*hd_geometry.s) ) {
puts("MEMDISK: Image seems to have fractional end cylinder\n");
}
- if ( max_c > hd_geometry.c ) {
+ if ( (hd_geometry.c*hd_geometry.h*hd_geometry.s) > sectors ) {
puts("MEMDISK: Image appears to be truncated\n");
}