]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Intwrapped biosdisk
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 4 Apr 2010 16:43:26 +0000 (18:43 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 4 Apr 2010 16:43:26 +0000 (18:43 +0200)
conf/i386-pc.rmk
disk/i386/pc/biosdisk.c
include/grub/i386/pc/biosdisk.h
include/grub/i386/pc/init.h
kern/i386/pc/startup.S

index bef17a25b0b58c0b78624a9b4015633fb1650113..39554594cf8d58348d06370d9c4eeaa9779a47de 100644 (file)
@@ -54,8 +54,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \
        kern/env.c \
        term/i386/pc/console.c term/i386/vga_common.c \
        symlist.c
-kernel_img_HEADERS += machine/biosdisk.h machine/pxe.h i386/pit.h \
-       machine/init.h machine/int.h
+kernel_img_HEADERS += machine/pxe.h i386/pit.h machine/int.h
 kernel_img_CFLAGS = $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
 kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
index 4fc29023b776e9cce126f50f85a759f70e2cda01..71b516422c2f42257b4b9e72c0e269af4b707755 100644 (file)
@@ -83,6 +83,166 @@ grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
   return (regs.eax >> 8) & 0xff;
 }
 
+/*
+ *   Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
+ *   NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
+ *   return non-zero, otherwise zero.
+ */
+static int 
+grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
+                          int soff, int nsec, int segment)
+{
+  int ret, i;
+
+  /* Try 3 times.  */
+  for (i = 0; i < 3; i++)
+    {
+      struct grub_bios_int_registers regs;
+
+      /* set up CHS information */
+      /* set %ch to low eight bits of cylinder */
+      regs.ecx = (coff << 8) & 0xff00;
+      /* set bits 6-7 of %cl to high two bits of cylinder */
+      regs.ecx |= (coff >> 2) & 0xc0;
+      /* set bits 0-5 of %cl to sector */
+      regs.ecx |= soff & 0x3f;
+
+      /* set %dh to head and %dl to drive */  
+      regs.edx = (drive & 0xff) | ((hoff << 8) & 0xff00);
+      /* set %ah to AH */
+      regs.eax = (ah << 8) & 0xff00;
+      /* set %al to NSEC */
+      regs.eax |= nsec & 0xff;
+
+      regs.ebx = 0;
+      regs.es = segment;
+
+      regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+
+      grub_bios_interrupt (0x13, &regs);
+      /* check if successful */
+      if (!(regs.flags & GRUB_CPU_INT_FLAGS_CARRY))
+       return 0;
+
+      /* save return value */
+      ret = regs.eax >> 8;
+
+      /* if fail, reset the disk system */
+      regs.eax = 0;
+      regs.edx = (drive & 0xff);
+      regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+      grub_bios_interrupt (0x13, &regs);
+    }
+  return ret;
+}
+
+/*
+ *   Check if LBA is supported for DRIVE. If it is supported, then return
+ *   the major version of extensions, otherwise zero.
+ */
+static int
+grub_biosdisk_check_int13_extensions (int drive)
+{
+  struct grub_bios_int_registers regs;
+
+  regs.edx = drive & 0xff;
+  regs.eax = 0x4100;
+  regs.ebx = 0x55aa;
+  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+  grub_bios_interrupt (0x13, &regs);
+  
+  if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
+    return 0;
+
+  if ((regs.ebx & 0xffff) != 0xaa55)
+    return 0;
+
+  /* check if AH=0x42 is supported */
+  if (!(regs.ecx & 1))
+    return 0;
+
+  return (regs.eax >> 8) & 0xff;
+}
+
+/*
+ *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
+ *   error occurs, then return non-zero, otherwise zero.
+ */
+static int 
+grub_biosdisk_get_diskinfo_standard (int drive,
+                                    unsigned long *cylinders,
+                                    unsigned long *heads,
+                                    unsigned long *sectors)
+{
+  struct grub_bios_int_registers regs;
+
+  regs.eax = 0x0800;
+  regs.edx = drive & 0xff;
+
+  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+  grub_bios_interrupt (0x13, &regs);
+
+  /* Check if unsuccessful. Ignore return value if carry isn't set to 
+     workaround some buggy BIOSes. */
+  if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0))
+    return (regs.eax & 0xff00) >> 8;
+
+  /* bogus BIOSes may not return an error number */  
+  /* 0 sectors means no disk */
+  if (!(regs.ecx & 0x3f))
+    /* XXX 0x60 is one of the unused error numbers */
+    return 0x60;
+
+  /* the number of heads is counted from zero */
+  *heads = ((regs.edx >> 8) & 0xff) + 1;
+  *cylinders = (((regs.ecx >> 8) & 0xff) | ((regs.ecx << 2) & 0x0300)) + 1;
+  *sectors = regs.ecx & 0x3f;
+  return 0;
+}
+
+static int
+grub_biosdisk_get_diskinfo_real (int drive, void *drp, grub_uint16_t ax)
+{
+  struct grub_bios_int_registers regs;
+
+  regs.eax = ax;
+
+  /* compute the address of drive parameters */
+  regs.esi = ((grub_addr_t) drp) & 0xf;
+  regs.ds = ((grub_addr_t) drp) >> 4;
+  regs.edx = drive & 0xff;
+
+  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+  grub_bios_interrupt (0x13, &regs);
+
+  /* Check if unsuccessful. Ignore return value if carry isn't set to 
+     workaround some buggy BIOSes. */
+  if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0))
+    return (regs.eax & 0xff00) >> 8;
+
+  return 0;
+}
+
+/*
+ *   Return the cdrom information of DRIVE in CDRP. If an error occurs,
+ *   then return non-zero, otherwise zero.
+ */
+static int
+grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
+{
+  return grub_biosdisk_get_diskinfo_real (drive, cdrp, 0x4b01);
+}
+
+/*
+ *   Return the geometry of DRIVE in a drive parameters, DRP. If an error
+ *   occurs, then return non-zero, otherwise zero.
+ */
+static int
+grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
+{
+  return grub_biosdisk_get_diskinfo_real (drive, drp, 0x4800);
+}
+
 static int
 grub_biosdisk_get_drive (const char *name)
 {
index 83d833cade26e83be7d5727d896fb7217d211885..69a240a2e3d285a876abfbcefed9a4c5297cb0d5 100644 (file)
@@ -106,18 +106,6 @@ struct grub_biosdisk_dap
   grub_uint64_t block;
 } __attribute__ ((packed));
 
-int EXPORT_FUNC(grub_biosdisk_rw_standard) (int ah, int drive, int coff, int hoff,
-                              int soff, int nsec, int segment);
-int EXPORT_FUNC(grub_biosdisk_check_int13_extensions) (int drive);
-int EXPORT_FUNC(grub_biosdisk_get_diskinfo_int13_extensions) (int drive,
-           void *drp);
-int EXPORT_FUNC(grub_biosdisk_get_cdinfo_int13_extensions) (int drive,
-           void *cdrp);
-int EXPORT_FUNC(grub_biosdisk_get_diskinfo_standard) (int drive,
-                                        unsigned long *cylinders,
-                                        unsigned long *heads,
-                                        unsigned long *sectors);
-
 void grub_biosdisk_init (void);
 void grub_biosdisk_fini (void);
 
index 2be80e7730c6b86512a097b0d47bd54c68495136..30130d189b9498e17a86629353587dcd0d8f8461 100644 (file)
@@ -33,7 +33,7 @@ grub_uint32_t grub_get_eisa_mmap (void);
 
 /* Get a memory map entry. Return next continuation value. Zero means
    the end.  */
-grub_uint32_t EXPORT_FUNC(grub_get_mmap_entry) (struct grub_machine_mmap_entry *entry,
+grub_uint32_t grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
                                   grub_uint32_t cont);
 
 /* Turn on/off Gate A20.  */
index 4c7c74ec777e98e808de4210bc3f7c9b5f1fb54e..6733e12bc7ff1aa3695c8cd53865889f3a67937c 100644 (file)
@@ -505,263 +505,6 @@ FUNCTION(grub_chainloader_real_boot)
 
 #include "../loader.S"
 
-/*
- *   int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
- *                                  int soff, int nsec, int segment)
- *
- *   Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
- *   NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
- *   return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_rw_standard)
-       pushl   %ebp
-       movl    %esp, %ebp
-
-       pushl   %ebx
-       pushl   %edi
-       pushl   %esi
-
-       /* set up CHS information */
-
-       /* set %ch to low eight bits of cylinder */
-       xchgb   %cl, %ch
-       /* set bits 6-7 of %cl to high two bits of cylinder */
-       shlb    $6, %cl
-       /* set bits 0-5 of %cl to sector */
-       addb    0xc(%ebp), %cl
-       /* set %dh to head */
-       movb    0x8(%ebp), %dh
-       /* set %ah to AH */
-       movb    %al, %ah
-       /* set %al to NSEC */
-       movb    0x10(%ebp), %al
-       /* save %ax in %di */
-       movw    %ax, %di
-       /* save SEGMENT in %bx */
-       movw    0x14(%ebp), %bx
-
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movw    %bx, %es
-       xorw    %bx, %bx
-       movw    $3, %si         /* attempt at least three times */
-
-1:
-       movw    %di, %ax
-       int     $0x13           /* do the operation */
-       jnc     2f              /* check if successful */
-
-       movb    %ah, %bl        /* save return value */
-       /* if fail, reset the disk system */
-       xorw    %ax, %ax
-       int     $0x13
-
-       decw    %si
-       cmpw    $0, %si
-       je      2f
-       xorb    %bl, %bl
-       jmp     1b              /* retry */
-2:
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %esi
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-
-       ret     $(4 * 4)
-
-
-/*
- *   int grub_biosdisk_check_int13_extensions (int drive)
- *
- *   Check if LBA is supported for DRIVE. If it is supported, then return
- *   the major version of extensions, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_check_int13_extensions)
-       pushl   %ebp
-       pushl   %ebx
-
-       /* drive */
-       movb    %al, %dl
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movb    $0x41, %ah
-       movw    $0x55aa, %bx
-       int     $0x13           /* do the operation */
-
-       /* check the result */
-       jc      1f
-       cmpw    $0xaa55, %bx
-       jne     1f
-
-       movb    %ah, %bl        /* save the major version into %bl */
-
-       /* check if AH=0x42 is supported */
-       andw    $1, %cx
-       jnz     2f
-
-1:
-       xorb    %bl, %bl
-2:
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %ebx
-       popl    %ebp
-
-       ret
-
-
-/*
- *   int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
- *
- *   Return the cdrom information of DRIVE in CDRP. If an error occurs,
- *   then return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions)
-       movw    $0x4B01, %cx
-       jmp     1f
-
-/*
- *   int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
- *
- *   Return the geometry of DRIVE in a drive parameters, DRP. If an error
- *   occurs, then return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
-       movb    $0x48, %ch
-1:
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-
-       /* compute the address of drive parameters */
-       movw    %dx, %si
-       andl    $0xf, %esi
-       shrl    $4, %edx
-       movw    %dx, %bx        /* save the segment into %bx */
-       /* drive */
-       movb    %al, %dl
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movw    %cx, %ax
-       movw    %bx, %ds
-       int     $0x13           /* do the operation */
-       jc      noclean
-       /* Clean return value if carry isn't set to workaround
-       some buggy BIOSes.  */
-       xor     %ax, %ax
-noclean:
-       movb    %ah, %bl        /* save return value in %bl */
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %esi
-       popl    %ebx
-       popl    %ebp
-
-       ret
-
-
-/*
- *   int grub_biosdisk_get_diskinfo_standard (int drive,
- *                                            unsigned long *cylinders,
- *                                            unsigned long *heads,
- *                                            unsigned long *sectors)
- *
- *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
- *   error occurs, then return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_get_diskinfo_standard)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-
-       /* push CYLINDERS */
-       pushl   %edx
-       /* push HEADS */
-       pushl   %ecx
-       /* SECTORS is on the stack */
-
-       /* drive */
-       movb    %al, %dl
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movb    $0x8, %ah
-       int     $0x13           /* do the operation */
-       jc      noclean2
-       /* Clean return value if carry isn't set to workaround
-       some buggy BIOSes.  */
-       xor     %ax, %ax
-noclean2:
-       /* check if successful */
-       testb   %ah, %ah
-       jnz     1f
-       /* bogus BIOSes may not return an error number */
-       testb   $0x3f, %cl      /* 0 sectors means no disk */
-       jnz     1f              /* if non-zero, then succeed */
-       /* XXX 0x60 is one of the unused error numbers */
-       movb    $0x60, %ah
-1:
-       movb    %ah, %bl        /* save return value in %bl */
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       /* pop HEADS */
-       popl    %edi
-       movb    %dh, %al
-       incl    %eax    /* the number of heads is counted from zero */
-       movl    %eax, (%edi)
-
-       /* pop CYLINDERS */
-       popl    %edi
-       movb    %ch, %al
-       movb    %cl, %ah
-       shrb    $6, %ah /* the number of cylinders is counted from zero */
-       incl    %eax
-       movl    %eax, (%edi)
-
-       /* SECTORS */
-       movl    0x10(%esp), %edi
-       andb    $0x3f, %cl
-       movzbl  %cl, %eax
-       movl    %eax, (%edi)
-
-       xorl    %eax, %eax
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-
-       ret     $4
-
-
 /*
  *
  * grub_get_memsize(i) :  return the memory size in KB. i == 0 for conventional