aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2010-08-14 13:16:48 +0200
committerMichal Soltys <soltys@ziu.info>2010-08-14 13:16:48 +0200
commit3d54a518a2be236bbbc44a6fc25cdf04d299ba03 (patch)
treea0483ffca65c9280e3d4df4544915064b109d5cb
parent00fff30973174315088b358402a9ef73dab31cf8 (diff)
parent460675909dd059f5fa84985402fcd6490503c884 (diff)
downloadsyslinux-3d54a518a2be236bbbc44a6fc25cdf04d299ba03.tar.gz
syslinux-3d54a518a2be236bbbc44a6fc25cdf04d299ba03.tar.xz
syslinux-3d54a518a2be236bbbc44a6fc25cdf04d299ba03.zip
Merge branch 'master' into chaindev
-rw-r--r--com32/modules/chain.c26
-rw-r--r--core/diskstart.inc15
-rw-r--r--core/fs/diskio.c2
-rwxr-xr-xextlinux/main.c43
-rw-r--r--version2
5 files changed, 77 insertions, 11 deletions
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 60e3abce..b22caa14 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -132,6 +132,7 @@ static struct options {
bool swap;
bool hide;
bool sethidden;
+ bool drmk;
} opt;
struct data_area {
@@ -786,6 +787,7 @@ Options: file=<loader> Load and execute file, instead of boot sector\n\
freedos=<loader> Load FreeDOS KERNEL.SYS\n\
msdos=<loader> Load MS-DOS IO.SYS\n\
pcdos=<loader> Load PC-DOS IBMBIO.COM\n\
+ drmk=<loader> Load DRMK DELLBIO.BIN\n\
grub=<loader> Load GRUB Legacy stage2\n\
grubcfg=<filename> Set alternative config filename for GRUB Legacy\n\
grldr=<loader> Load GRUB4DOS grldr\n\
@@ -856,6 +858,11 @@ int main(int argc, char *argv[])
opt.seg = 0x70; /* MS-DOS 2.0+ wants this address */
opt.loadfile = argv[i] + 6;
opt.sethidden = true;
+ } else if (!strncmp(argv[i], "drmk=", 5)) {
+ opt.seg = 0x70; /* DRMK wants this address */
+ opt.loadfile = argv[i] + 5;
+ opt.sethidden = true;
+ opt.drmk = true;
} else if (!strncmp(argv[i], "grub=", 5)) {
opt.seg = 0x800; /* stage2 wants this address */
opt.loadfile = argv[i] + 5;
@@ -1202,6 +1209,25 @@ int main(int argc, char *argv[])
}
}
+ if (opt.drmk) {
+ /* DRMK entry is different than MS-DOS/PC-DOS */
+ /*
+ * A new size, aligned to 16 bytes to ease use of ds:[bp+28].
+ * We only really need 4 new, usable bytes at the end.
+ */
+ int tsize = (data[ndata].size + 19) & 0xfffffff0;
+ regs.ss = regs.fs = regs.gs = 0; /* Used before initialized */
+ if (!realloc(data[ndata].data, tsize)) {
+ error("Failed to realloc for DRMK\n");
+ goto bail;
+ }
+ data[ndata].size = tsize;
+ /* ds:[bp+28] must be 0x0000003f */
+ regs.ds = (tsize >> 4) + (opt.seg - 2);
+ /* "Patch" into tail of the new space */
+ *(int *)(data[ndata].data + tsize - 4) = 0x0000003f;
+ }
+
ndata++;
}
diff --git a/core/diskstart.inc b/core/diskstart.inc
index c0ba52a0..c0301d4b 100644
--- a/core/diskstart.inc
+++ b/core/diskstart.inc
@@ -31,9 +31,10 @@ PartInfo equ StackBuf
.gpt equ PartInfo+20
FloppyTable equ PartInfo+76
; Total size of PartInfo + FloppyTable == 76+16 = 92 bytes
-Hidden equ StackBuf-20 ; Partition offset
-OrigFDCTabPtr equ StackBuf-12 ; The 2nd high dword on the stack
-OrigESDI equ StackBuf-8 ; The high dword on the stack
+Hidden equ StackBuf-24 ; Partition offset (qword)
+OrigFDCTabPtr equ StackBuf-16 ; Original FDC table
+OrigDSSI equ StackBuf-12 ; DS:SI -> partinfo
+OrigESDI equ StackBuf-8 ; ES:DI -> $PnP structure
DriveNumber equ StackBuf-4 ; Drive number
StackHome equ Hidden ; The start of the canonical stack
@@ -116,6 +117,8 @@ start:
push dx ; Save drive number (in DL)
push es ; Save initial ES:DI -> $PnP pointer
push di
+ push ds ; Save original DS:SI -> partinfo
+ push si
mov es,cx
;
@@ -174,6 +177,12 @@ floppy:
; Note: di points to beyond the end of PartInfo
;
harddisk:
+ mov dx,[di-76-10] ; Original DS
+ mov si,[di-76-12] ; Original SI
+ shr si,4
+ add dx,si
+ cmp dx,PartInfo >> 4
+ jae .no_partition
test byte [di-76],7Fh ; Sanity check: "active flag" should
jnz .no_partition ; be 00 or 80
cmp [di-76+4],cl ; Sanity check: partition type != 0
diff --git a/core/fs/diskio.c b/core/fs/diskio.c
index 481b59b0..38d3da35 100644
--- a/core/fs/diskio.c
+++ b/core/fs/diskio.c
@@ -163,8 +163,6 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf,
memset(&reset, 0, sizeof reset);
- ireg.edx.b[0] = disk->disk_number;
-
lba += disk->part_start;
while (count) {
chunk = count;
diff --git a/extlinux/main.c b/extlinux/main.c
index 002cecd9..30422c2d 100755
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -100,6 +100,32 @@ struct geometry_table {
struct hd_geometry g;
};
+static int sysfs_get_offset(int devfd, unsigned long *start)
+{
+ struct stat st;
+ char sysfs_name[128];
+ FILE *f;
+ int rv;
+
+ if (fstat(devfd, &st))
+ return -1;
+
+ if ((size_t)snprintf(sysfs_name, sizeof sysfs_name,
+ "/sys/dev/block/%u:%u/start",
+ major(st.st_dev), minor(st.st_dev))
+ >= sizeof sysfs_name)
+ return -1;
+
+ f = fopen(sysfs_name, "r");
+ if (!f)
+ return -1;
+
+ rv = fscanf(f, "%lu", start);
+ fclose(f);
+
+ return (rv == 1) ? 0 : -1;
+}
+
/* Standard floppy disk geometries, plus LS-120. Zipdisk geometry
(x/64/32) is the final fallback. I don't know what LS-240 has
as its geometry, since I don't have one and don't know anyone that does,
@@ -123,24 +149,25 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
struct loop_info li;
struct loop_info64 li64;
const struct geometry_table *gp;
+ int rv = 0;
memset(geo, 0, sizeof *geo);
if (!ioctl(devfd, HDIO_GETGEO, &geo)) {
- return 0;
+ goto ok;
} else if (!ioctl(devfd, FDGETPRM, &fd_str)) {
geo->heads = fd_str.head;
geo->sectors = fd_str.sect;
geo->cylinders = fd_str.track;
geo->start = 0;
- return 0;
+ goto ok;
}
/* Didn't work. Let's see if this is one of the standard geometries */
for (gp = standard_geometries; gp->bytes; gp++) {
if (gp->bytes == totalbytes) {
memcpy(geo, &gp->g, sizeof *geo);
- return 0;
+ goto ok;
}
}
@@ -153,19 +180,25 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT);
geo->start = 0;
- if (!opt.sectors && !opt.heads)
+ if (!opt.sectors && !opt.heads) {
fprintf(stderr,
"Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n"
" (on hard disks, this is usually harmless.)\n",
geo->heads, geo->sectors);
+ rv = 1; /* Suboptimal result */
+ }
+ok:
/* If this is a loopback device, try to set the start */
if (!ioctl(devfd, LOOP_GET_STATUS64, &li64))
geo->start = li64.lo_offset >> SECTOR_SHIFT;
else if (!ioctl(devfd, LOOP_GET_STATUS, &li))
geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT;
+ else if (!sysfs_get_offset(devfd, &geo->start)) {
+ /* OK */
+ }
- return 1;
+ return rv;
}
/*
diff --git a/version b/version
index 0e60f145..1152a5aa 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-4.02 2010
+4.03 2010