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 /

Reply via email to