This is a patch to use struct geometry for geometry instead of
int. I haven't implemented INT 13 AH=48h yet.
diff -urN /home/okuji/work/grub/ChangeLog grub/ChangeLog
--- /home/okuji/work/grub/ChangeLog Mon Mar 15 18:24:41 1999
+++ grub/ChangeLog Tue Mar 16 04:42:11 1999
@@ -1,3 +1,23 @@
+1999-03-16 OKUJI Yoshinori <[EMAIL PROTECTED]>
+
+ * shared_src/asm.S (biosdisk): Use a structure for geometry
+ instead of a interger.
+ (get_diskinfo): Take a pointer to a geometry structure as the
+ second argument, and fill a geometry in it. Return 1 if an error
+ occurs, otherwise return 0.
+ * shared_src/boot.c (bsd_boot): Compute BIOS geometries for BSD.
+ * shared_src/cmdline.c (enter_cmdline): Declare dest_geom as
+ struct geometry.
+ * shared_src/disk_io.c (buf_geom): Declare as struct geometry.
+ * shared_src/filesys.h (SECTORS): Deleted.
+ (HEADS): Likewise.
+ (CYLINDERS): Likewise.
+ * shared_src/shared.h (BIOSDISK_FLAG_LBA_EXTENSION): New macro.
+ (struct geometry): New structure.
+ (buf_geom): Correct the prototype.
+ (get_diskinfo): Likewise.
+ (biosdisk): Likewise.
+
1999-03-14 Gordon Matzigkeit <[EMAIL PROTECTED]>
* shared_src/stage2.c (run_menu): Use A_REVERSE and A_NORMAL
diff -urN /home/okuji/work/grub/shared_src/asm.S grub/shared_src/asm.S
--- /home/okuji/work/grub/shared_src/asm.S Mon Mar 15 18:24:52 1999
+++ grub/shared_src/asm.S Tue Mar 16 04:30:10 1999
@@ -352,10 +352,12 @@
push %ecx
push %edx
push %esi
-
+ push %edi
+
/* Check whether we have LBA. */
- movb 0x13(%ebp), %al
- andb $0x10, %al
+ movl 0x10(%ebp), %eax
+ movl 0xc(%eax), %eax
+ andl $BIOSDISK_FLAG_LBA_EXTENSION, %eax
jz disk_compute_args /* nope. */
/* set up disk address packet for extended calls (LBA mode) */
@@ -416,39 +418,37 @@
/* either failed, or a floppy, so try standard BIOS calls */
disk_compute_args:
/*
- * GEOMETRY is a longword representing the BIOS geometry:
- * 4 bit BIOS extension (0 = none, 1 = LBA)
- * 12 bit cylinder (bytes 2 & 3)
- * 8 bit head (byte 1)
- * 8 bit sector (byte 0)
+ * GEOMETRY is a structure representing the BIOS geometry:
+ * 32 bit flags (bytes 12-15)
+ * 32 bit cylinders (bytes 8-11)
+ * 32 bit heads (byte 4-7)
+ * 32 bit sectors (byte 0-3)
*/
/* set up original sector number */
xorl %edx, %edx
movl 0x14(%ebp), %eax
+ /* get the pointer to GEOMETRY */
+ movl 0x10(%ebp), %edi
+
/* get sector offset, place in %ecx */
- xorl %ebx, %ebx
- movb 0x10(%ebp), %bl
+ movl 0x8(%edi), %ebx
divl %ebx
movl %edx, %ecx
/* get track offset (head number) in %edx,
and cylinder offset in %eax */
xorl %edx, %edx
- xorl %ebx, %ebx
- movb 0x11(%ebp), %bl
- inc %ebx
+ movl 0x4(%edi), %ebx
divl %ebx
/* check cylinder offset, is there a geometry problem here? */
- movl 0x10(%ebp), %ebx
- shrl $16, %ebx
- andb $0xf, %bh /* mask out bios extension code */
+ movl (%edi), %ebx
cmpl %ebx, %eax
/* if not, go on to standard read function */
- jle disk_use_standard_bios
+ jl disk_use_standard_bios
movl $BIOSDISK_ERROR_GEOMETRY, %eax
jmp disk_exit_32
@@ -538,6 +538,7 @@
movb %bl, %al /* return value in %eax */
disk_exit_32:
+ pop %edi
pop %esi
pop %edx
pop %ecx
@@ -549,8 +550,9 @@
/*
*
- * get_diskinfo(drive): return a word that represents the
- * max number of sectors and heads and cylinders for this drive
+ * get_diskinfo(drive, geometry): return a structure that represents the
+ * max number of sectors and heads and cylinders for DRIVE in GEOMETRY.
+ * If an error occures, return non-zero, otherwise return zero.
*
*/
@@ -633,11 +635,12 @@
jz 1f /* LBA not supported */
/* Wahoo! Got LBA! */
- movb $0x1, %bh
+ movl $BIOSDISK_FLAG_LBA_EXTENSION, %edi
+ /* XXX Should use INT 13 AH=42h */
data32
jmp 2f
-1: xorb %bh, %bh /* Too bad, no LBA */
+1: xorl %edi, %edi /* Too bad, no LBA */
2: movb $0x8, %ah /* ask for disk info */
int $0x13
@@ -649,33 +652,35 @@
probe_success:
/*
- * form a dword representing all this gunk:
- * 4 bit BIOS extension (0 = none, 1 = LBA)
- * 12 bit cylinder
- * 8 bit head
- * 8 bit sector
+ * Store the information for CHS and BIOS extension to registers:
+ * 32 bit BIOS extension -> edi
+ * 32 bit cylinder -> ebx
+ * 32 bit head -> ecx
+ * 32 bit sector -> edx
*/
- movb %bh, %ah /* restore BIOS extensions bits */
-
#ifdef AWARD_INT13_EXTENSIONS
movb %dh, %al /* bits 10,11 of cylinder count */
andb $0xc0, %al
-#endif
shlw $2, %ax /* << 2 */
+#endif
movb %cl, %al /* bits 8,9 of cylinder count */
andb $0xc0, %al
shlw $2, %ax /* << 2 */
movb %ch, %al /* Lower 8 bits */
- shll $16, %eax /* << 16 */
+ movswl %ax, %ebx /* max cylinder */
+ incl %ebx /* num culinder */
#ifdef AWARD_INT13_EXTENSIONS
andb $0x3f, %dh /* mask off cylinder gunk */
#endif
- movb %dh, %ah /* max head */
+ movb %dh, %al /* max head */
+
andb $0x3f, %cl /* mask off cylinder gunk */
- movb %cl, %al /* max sector (and # sectors) */
+ movsbl %cl, %edx /* max sector (and # sectors) */
- movl %eax, %ebx /* save return value */
+ movsbl %al, %ecx
+ incl %ecx /* num head */
+
data32
jmp got_drive
@@ -684,18 +689,37 @@
* Urk. Call failed. It is not supported for floppies by old
* BIOSes, but it should work for all hard drives!!
*
- * Return a 0 here... presume there is no drive present. ????
+ * Return a 1 here... presume there is no drive present. ????
*/
- movl $0, %ebx /* not present value */
+ data32
+ call EXT_C(real_to_prot)
+ .code32
+
+ movl $1, %eax
+ popl %esi
+ popl %edi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %ebp
+ ret
+
+ .code16
+
got_drive:
data32
call EXT_C(real_to_prot) /* back to protected mode */
.code32
- /* set up return in correct register */
- movl %ebx, %eax
+ movl 0x0c(%ebp), %eax
+ movl %ebx, (%eax)
+ movl %ecx, 0x04(%eax)
+ movl %edx, 0x08(%eax)
+ movl %edi, 0x0c(%eax)
+
+ xorl %eax, %eax
popl %esi
popl %edi
diff -urN /home/okuji/work/grub/shared_src/boot.c grub/shared_src/boot.c
--- /home/okuji/work/grub/shared_src/boot.c Mon Mar 15 18:24:53 1999
+++ grub/shared_src/boot.c Tue Mar 16 04:43:30 1999
@@ -532,8 +532,18 @@
bi.bi_n_bios_used = 0; /* this field is apparently unused */
for (i = 0; i < N_BIOS_GEOM; i++)
- bi.bi_bios_geom[i] = get_diskinfo (i + 0x80);
-
+ {
+ struct geometry geom;
+
+ /* XXX Should check the return value. */
+ get_diskinfo (i + 0x80, &geom);
+ /* XXX If HEADS or SECTORS is greater than 255, then this will
+ break the geometry information. That is a drawback of BSD
+ but not of GRUB. */
+ bi.bi_bios_geom[i] = (((geom.cylinders - 1) << 16)
+ + (((geom.heads - 1) & 0xff) << 8)
+ + (geom.sectors & 0xff));
+ }
bi.bi_size = sizeof (struct bootinfo);
bi.bi_memsizes_valid = 1;
bi.bi_basemem = mbi.mem_lower;
diff -urN /home/okuji/work/grub/shared_src/cmdline.c grub/shared_src/cmdline.c
--- /home/okuji/work/grub/shared_src/cmdline.c Mon Mar 15 18:24:58 1999
+++ grub/shared_src/cmdline.c Tue Mar 16 01:12:57 1999
@@ -372,7 +372,8 @@
set_device (dest_dev) && open_partition () &&
devread (0, 0, SECTOR_SIZE, old_sect))
{
- int dest_drive = current_drive, dest_geom = buf_geom;
+ int dest_drive = current_drive;
+ struct geometry dest_geom = buf_geom;
int dest_sector = part_start, i;
#ifndef NO_DECOMPRESSION
@@ -466,11 +467,11 @@
if (!errnum
&& (biosdisk(BIOSDISK_WRITE,
- dest_drive, dest_geom,
+ dest_drive, &dest_geom,
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|| (write_stage2_sect
&& biosdisk(BIOSDISK_WRITE,
- current_drive, buf_geom,
+ current_drive, &buf_geom,
stage2_sect, 1, SCRATCHSEG))))
errnum = ERR_WRITE;
}
diff -urN /home/okuji/work/grub/shared_src/disk_io.c grub/shared_src/disk_io.c
--- /home/okuji/work/grub/shared_src/disk_io.c Mon Mar 15 18:25:05 1999
+++ grub/shared_src/disk_io.c Tue Mar 16 01:28:05 1999
@@ -78,7 +78,7 @@
/* disk buffer parameters */
int buf_drive = -1;
int buf_track;
-int buf_geom;
+struct geometry buf_geom;
/* filesystem common variables */
int filepos;
@@ -103,26 +103,24 @@
*/
if (buf_drive != drive)
{
- buf_geom = get_diskinfo (drive);
+ if (get_diskinfo (drive, &buf_geom))
+ {
+ errnum = ERR_NO_DISK;
+ return 0;
+ }
buf_drive = drive;
buf_track = -1;
}
- if (buf_geom == 0)
- {
- errnum = ERR_NO_DISK;
- return 0;
- }
-
/* Get first sector of track */
- soff = sector % SECTORS (buf_geom);
+ soff = sector % buf_geom.sectors;
track = sector - soff;
- num_sect = SECTORS (buf_geom) - soff;
+ num_sect = buf_geom.sectors - soff;
bufaddr = BUFFERADDR + (soff * SECTOR_SIZE) + byte_offset;
if (track != buf_track)
{
- int bios_err, read_start = track, read_len = SECTORS (buf_geom);
+ int bios_err, read_start = track, read_len = buf_geom.sectors;
/*
* If there's more than one read in this entire loop, then
@@ -136,7 +134,7 @@
bufaddr = BUFFERADDR + byte_offset;
}
- bios_err = biosdisk (BIOSDISK_READ, drive, buf_geom,
+ bios_err = biosdisk (BIOSDISK_READ, drive, &buf_geom,
read_start, read_len, BUFFERSEG);
if (bios_err)
{
@@ -151,7 +149,7 @@
* required sector(s) rather than failing completely.
*/
if (slen > num_sect
- || biosdisk (BIOSDISK_READ, drive, buf_geom,
+ || biosdisk (BIOSDISK_READ, drive, &buf_geom,
sector, slen, BUFFERSEG))
errnum = ERR_READ;
@@ -293,7 +291,7 @@
buf_track = -1;
- if (biosdisk (BIOSDISK_WRITE, saved_drive, buf_geom,
+ if (biosdisk (BIOSDISK_WRITE, saved_drive, &buf_geom,
0, 1, SCRATCHSEG))
{
errnum = ERR_WRITE;
@@ -406,7 +404,7 @@
bsd_evil_hack = 0;
current_slice = 0;
part_start = 0;
- part_length = SECTORS (buf_geom) * HEADS (buf_geom) * CYLINDERS (buf_geom);
+ part_length = buf_geom.sectors * buf_geom.heads * buf_geom.cylinders;
if (current_drive & 0x80)
{
@@ -900,6 +898,7 @@
{
/* disk completions */
int disk_no, i, j;
+ struct geometry geom;
printf (" Possible disks are: ");
@@ -909,7 +908,7 @@
{
disk_no = (i * 0x80) + j;
if ((disk_choice || disk_no == current_drive)
- && get_diskinfo (disk_no))
+ && ! get_diskinfo (disk_no, &geom))
printf (" %cd%d", (i ? 'h' : 'f'), j);
}
}
diff -urN /home/okuji/work/grub/shared_src/filesys.h grub/shared_src/filesys.h
--- /home/okuji/work/grub/shared_src/filesys.h Mon Mar 15 18:25:05 1999
+++ grub/shared_src/filesys.h Tue Mar 16 01:24:34 1999
@@ -21,10 +21,6 @@
#include "pc_slice.h"
-#define SECTORS(geom) ( (geom) & 0xFF )
-#define HEADS(geom) ( ( ( (geom) >> 8 ) & 0xFF ) + 1 )
-#define CYLINDERS(geom) ( ( ( (geom) >> 16 ) & 0x3FF ) + 1 )
-
/*
* Default to all functioning filesystems enabled
*/
diff -urN /home/okuji/work/grub/shared_src/shared.h grub/shared_src/shared.h
--- /home/okuji/work/grub/shared_src/shared.h Mon Mar 15 18:25:18 1999
+++ grub/shared_src/shared.h Tue Mar 16 04:29:41 1999
@@ -59,6 +59,8 @@
#define BIOSDISK_WRITE 0x1
#define BIOSDISK_ERROR_GEOMETRY 0x100
+#define BIOSDISK_FLAG_LBA_EXTENSION 0x00000001
+
/*
* This is the filesystem (not raw device) buffer.
* It is 32K in size, do not overrun!
@@ -304,6 +306,21 @@
extern int block_file;
#endif /* NO_BLOCK_FILES */
+/* The information for a disk geometry */
+struct geometry
+{
+ /* The number of cylinders */
+ unsigned long cylinders;
+ /* The number of heads */
+ unsigned long heads;
+ /* The number of sectors */
+ unsigned long sectors;
+ /* Flags */
+ unsigned long flags;
+};
+
+typedef struct geometry *geometry_t;
+
extern long part_start;
extern long part_length;
@@ -311,7 +328,7 @@
extern int buf_drive;
extern int buf_track;
-extern int buf_geom;
+extern struct geometry buf_geom;
/* these are the current file position and maximum file position */
extern int filepos;
@@ -418,8 +435,8 @@
void set_attrib (int attr);
/* Low-level disk I/O */
-int get_diskinfo (int drive);
-int biosdisk (int read, int drive, int geometry,
+int get_diskinfo (int drive, geometry_t geometry);
+int biosdisk (int read, int drive, geometry_t geometry,
int sector, int nsec, int segment);
void stop_floppy (void);
----------------------------------------------------------------------
OKUJI Yoshinori <[EMAIL PROTECTED]> ^o-o^
http://duff.kuicr.kyoto-u.ac.jp/~okuji (in English) m /