Add LBA support
This commit is contained in:
parent
17b6dcd892
commit
5223272174
8 changed files with 147 additions and 32 deletions
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
1999-03-03 Gordon Matzigkeit <gord@trick.fig.org>
|
||||||
|
|
||||||
|
* shared_src/asm.S (biosdisk): Use LBA mode if high nibble of
|
||||||
|
GEOMETRY is nonzero.
|
||||||
|
(get_diskinfo): Set high nibble of GEOMETRY (0xf0000000) to 1 if
|
||||||
|
LBA mode is detected.
|
||||||
|
|
||||||
|
1999-03-02 Gordon Matzigkeit <gord@trick.fig.org>
|
||||||
|
|
||||||
|
* shared_src/disk_io.c (make_saved_active): Use BIOSDISK_READ and
|
||||||
|
BIOSDISK_WRITE.
|
||||||
|
|
||||||
|
* shared_src/cmdline.c (enter_cmdline): Use BIOSDISK_WRITE.
|
||||||
|
|
||||||
|
* shared_src/shared.h (BIOSDISK_SUBFUNC_READ,
|
||||||
|
BIOSDISK_SUBFUNC_WRITE): Delete constants.
|
||||||
|
|
||||||
|
* shared_src/asm.S (biosdisk): Change subfunc argument to be
|
||||||
|
read=0, write=1.
|
||||||
|
|
||||||
|
* configure.in: Drop redundant AC_PROG_INSTALL. From OKUJI
|
||||||
|
Yoshinori.
|
||||||
|
|
||||||
1999-03-01 Gordon Matzigkeit <gord@trick.fig.org>
|
1999-03-01 Gordon Matzigkeit <gord@trick.fig.org>
|
||||||
|
|
||||||
* debian/rules (binary-arch): Properly install README.debian.
|
* debian/rules (binary-arch): Properly install README.debian.
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -3,6 +3,7 @@ NEWS - list of user-visible changes between releases of GRUB
|
||||||
New in 0.5.90 - 1999-03-01, Gordon Matzigkeit:
|
New in 0.5.90 - 1999-03-01, Gordon Matzigkeit:
|
||||||
* Bug fixes.
|
* Bug fixes.
|
||||||
* GRUB understands symlinks on ext2fs (but still not ffs).
|
* GRUB understands symlinks on ext2fs (but still not ffs).
|
||||||
|
* The GRUB stage2 uses LBA mode and AWARD extensions if they are supported.
|
||||||
* Many source code and build cleanups to comply with GNU standards.
|
* Many source code and build cleanups to comply with GNU standards.
|
||||||
|
|
||||||
New in 0.5 - 1998-08-20, Erich Boleyn:
|
New in 0.5 - 1998-08-20, Erich Boleyn:
|
||||||
|
|
|
@ -43,7 +43,6 @@ AC_SUBST(stage2debug)
|
||||||
# Programs
|
# Programs
|
||||||
#
|
#
|
||||||
|
|
||||||
AC_PROG_INSTALL
|
|
||||||
AC_CHECK_TOOL(CC, gcc)
|
AC_CHECK_TOOL(CC, gcc)
|
||||||
AC_CHECK_TOOL(LD, ld)
|
AC_CHECK_TOOL(LD, ld)
|
||||||
AC_CHECK_TOOL(OBJCOPY, objcopy)
|
AC_CHECK_TOOL(OBJCOPY, objcopy)
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
grub (0.5.91) unstable; urgency=low
|
||||||
|
|
||||||
|
* Added support for LBA mode and BIOS extensions.
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
grub (0.5.90) unstable; urgency=low
|
grub (0.5.90) unstable; urgency=low
|
||||||
|
|
||||||
* Beta-testing release.
|
* Beta-testing release.
|
||||||
|
|
129
shared_src/asm.S
129
shared_src/asm.S
|
@ -330,15 +330,13 @@ realcseg:
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* biosdisk(subfunc, drive, geometry, sector, nsec, segment)
|
* biosdisk(write, drive, geometry, sector, nsec, segment)
|
||||||
* Read/write "nsec" sectors from disk to real segment "segment"
|
* Read/write "nsec" sectors from disk to real segment "segment"
|
||||||
* offset zero
|
* offset zero
|
||||||
*
|
*
|
||||||
* If it will fit into the BIOS geometry, it tries the INT 0x13
|
* Will try INT 0x13 LBA (AH=0x42/0x43) or standard (AH=0x2/0x3)
|
||||||
* AH=<subfunction> interface, else if it is a hard disk, it will
|
* depending on probed geometry. For addresses out of the translated
|
||||||
* try the hard disk LBA calls (not yet implemented). If these
|
* area, it returns BIOS_GEOMETRY_ERROR.
|
||||||
* won't work, or otherwise it is out of the translated area, then
|
|
||||||
* it returns BIOS_GEOMETRY_ERROR.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ENTRY(biosdisk)
|
ENTRY(biosdisk)
|
||||||
|
@ -350,10 +348,56 @@ ENTRY(biosdisk)
|
||||||
push %edx
|
push %edx
|
||||||
push %esi
|
push %esi
|
||||||
|
|
||||||
|
/* Check whether we have LBA. */
|
||||||
|
movb 0x13(%ebp), %al
|
||||||
|
shrb $4, %al
|
||||||
|
jz disk_compute_args /* nope. */
|
||||||
|
|
||||||
|
/* set up disk address packet for extended calls (LBA mode) */
|
||||||
|
movl 0x14(%ebp), %eax /* absolute block number */
|
||||||
|
movl %eax, dap_block
|
||||||
|
xorl %eax, %eax
|
||||||
|
movl %eax, dap_block + 4
|
||||||
|
|
||||||
|
movb 0x18(%ebp), %al /* number of sectors */
|
||||||
|
movw %ax, dap_blocks
|
||||||
|
|
||||||
|
/* set up the buffer address */
|
||||||
|
xorl %eax, %eax
|
||||||
|
movw 0x1c(%ebp), %ax /* segment */
|
||||||
|
shll $4, %eax
|
||||||
|
movl %eax, dap_buffer
|
||||||
|
movl $disk_address_packet, %esi
|
||||||
|
|
||||||
|
xorb %bl, %bl
|
||||||
|
movb 0x8(%ebp), %bh /* read=0, write=1 */
|
||||||
|
addb $0x42, %bh /* convert to extended subfunction */
|
||||||
|
|
||||||
|
movb 0xc(%ebp), %dl /* drive */
|
||||||
|
|
||||||
|
call EXT_C(prot_to_real) /* enter real mode */
|
||||||
|
.code16
|
||||||
|
|
||||||
|
movw %bx, %ax
|
||||||
|
int $0x13 /* do the operation */
|
||||||
|
|
||||||
|
/* set success return value */
|
||||||
|
movb $0, %bl
|
||||||
|
|
||||||
|
/* did we actually succeed? */
|
||||||
|
data32
|
||||||
|
jnc disk_exit_16
|
||||||
|
|
||||||
|
data32
|
||||||
|
call EXT_C(real_to_prot) /* back to protected mode */
|
||||||
|
.code32
|
||||||
|
|
||||||
|
/* either failed, or a floppy, so try standard BIOS calls */
|
||||||
|
disk_compute_args:
|
||||||
/*
|
/*
|
||||||
* "geometry" is a longword representing the BIOS geometry:
|
* GEOMETRY is a longword representing the BIOS geometry:
|
||||||
* 6 bit zero
|
* 4 bit BIOS extension (0 = none, 1 = LBA)
|
||||||
* 10 bit cylinder (bytes 2 & 3)
|
* 12 bit cylinder (bytes 2 & 3)
|
||||||
* 8 bit head (byte 1)
|
* 8 bit head (byte 1)
|
||||||
* 8 bit sector (byte 0)
|
* 8 bit sector (byte 0)
|
||||||
*/
|
*/
|
||||||
|
@ -379,15 +423,27 @@ ENTRY(biosdisk)
|
||||||
/* check cylinder offset, is there a geometry problem here? */
|
/* check cylinder offset, is there a geometry problem here? */
|
||||||
movl 0x10(%ebp), %ebx
|
movl 0x10(%ebp), %ebx
|
||||||
shrl $16, %ebx
|
shrl $16, %ebx
|
||||||
|
andb $0xf, %bh /* mask out bios extension code */
|
||||||
cmpl %ebx, %eax
|
cmpl %ebx, %eax
|
||||||
|
|
||||||
/* if not, go on to standard read function */
|
/* if not, go on to standard read function */
|
||||||
jle disk_use_standard_bios
|
jle disk_use_standard_bios
|
||||||
|
|
||||||
/* XXX else we better use LBA or generate a geometry error */
|
|
||||||
movl $BIOSDISK_ERROR_GEOMETRY, %eax
|
movl $BIOSDISK_ERROR_GEOMETRY, %eax
|
||||||
jmp disk_exit_32
|
jmp disk_exit_32
|
||||||
|
|
||||||
|
disk_address_packet:
|
||||||
|
.align 4
|
||||||
|
.byte 0x20 /* length of packet */
|
||||||
|
.byte 0 /* reserved */
|
||||||
|
dap_blocks:
|
||||||
|
.word 0 /* number of blocks */
|
||||||
|
dap_buffer:
|
||||||
|
.long 0 /* buffer address */
|
||||||
|
dap_block:
|
||||||
|
.long 0 /* absolute block number */
|
||||||
|
.long 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This portion implements the BIOS standardized
|
* This portion implements the BIOS standardized
|
||||||
* INT 0x13/AH=<subfunc> interface.
|
* INT 0x13/AH=<subfunc> interface.
|
||||||
|
@ -396,9 +452,10 @@ disk_use_standard_bios:
|
||||||
|
|
||||||
shll $8, %edx /* get head number to %dh */
|
shll $8, %edx /* get head number to %dh */
|
||||||
xchgl %eax, %ecx /* cylinder to %cx, sector to %al */
|
xchgl %eax, %ecx /* cylinder to %cx, sector to %al */
|
||||||
/* cylinder; the highest 2 bits of cyl is in %cl */
|
/* FIXME: cylinder; bits 10,11 of cyl are in %dh */
|
||||||
|
/* cylinder; bits 8,9 of cyl are in %cl */
|
||||||
xchgb %ch, %cl
|
xchgb %ch, %cl
|
||||||
rorb $2, %cl
|
shlb $6, %cl
|
||||||
incb %al /* sector; sec starts from 1, not 0 */
|
incb %al /* sector; sec starts from 1, not 0 */
|
||||||
orb %al, %cl
|
orb %al, %cl
|
||||||
movb 0xc(%ebp), %dl /* drive */
|
movb 0xc(%ebp), %dl /* drive */
|
||||||
|
@ -406,7 +463,8 @@ disk_use_standard_bios:
|
||||||
/* prot_to_real will set %es to 0, so must set it ourselves
|
/* prot_to_real will set %es to 0, so must set it ourselves
|
||||||
after it is called */
|
after it is called */
|
||||||
movb 0x18(%ebp), %bl /* number of sectors */
|
movb 0x18(%ebp), %bl /* number of sectors */
|
||||||
movb 0x8(%ebp), %bh /* bios disk subfunction */
|
movb 0x8(%ebp), %bh /* read=0, write=1 */
|
||||||
|
addb $0x2, %bh /* convert to subfunction */
|
||||||
shll $16, %ebx /* shift num sect. and subfunction */
|
shll $16, %ebx /* shift num sect. and subfunction */
|
||||||
movw 0x1c(%ebp), %bx /* segment */
|
movw 0x1c(%ebp), %bx /* segment */
|
||||||
|
|
||||||
|
@ -528,6 +586,7 @@ probe_loop:
|
||||||
movb $1, %dh
|
movb $1, %dh
|
||||||
movb $79, %ch
|
movb $79, %ch
|
||||||
|
|
||||||
|
xorb %bh, %bh /* no BIOS extensions */
|
||||||
data32
|
data32
|
||||||
jmp probe_success
|
jmp probe_success
|
||||||
|
|
||||||
|
@ -535,7 +594,27 @@ probe_values:
|
||||||
.byte 36, 18, 15, 9, 0
|
.byte 36, 18, 15, 9, 0
|
||||||
|
|
||||||
hard_drive:
|
hard_drive:
|
||||||
movb $0x8, %ah /* ask for disk info */
|
/* Check for LBA. */
|
||||||
|
movb $0x41, %ah
|
||||||
|
movw $0x55aa, %bx
|
||||||
|
int $0x13 /* int 13 extensions install check */
|
||||||
|
|
||||||
|
data32
|
||||||
|
jc 1f /* invalid function */
|
||||||
|
cmpw $0xaa55, %bx
|
||||||
|
data32
|
||||||
|
jnz 1f /* failed magic */
|
||||||
|
|
||||||
|
andb $1, %cx
|
||||||
|
data32
|
||||||
|
jnz 1f /* LBA not supported */
|
||||||
|
|
||||||
|
/* Wahoo! Got LBA! */
|
||||||
|
movb $0x1, %bh
|
||||||
|
jmp 2f
|
||||||
|
|
||||||
|
1: xorb %bh, %bh /* Too bad, no LBA */
|
||||||
|
2: movb $0x8, %ah /* ask for disk info */
|
||||||
int $0x13
|
int $0x13
|
||||||
|
|
||||||
data32
|
data32
|
||||||
|
@ -546,18 +625,24 @@ hard_drive:
|
||||||
|
|
||||||
probe_success:
|
probe_success:
|
||||||
/*
|
/*
|
||||||
* form a longword representing all this gunk:
|
* form a dword representing all this gunk:
|
||||||
* 6 bit zero
|
* 4 bit BIOS extension (0 = none, 1 = LBA)
|
||||||
* 10 bit cylinder
|
* 12 bit cylinder
|
||||||
* 8 bit head
|
* 8 bit head
|
||||||
* 8 bit sector
|
* 8 bit sector
|
||||||
*/
|
*/
|
||||||
movb %cl, %al /* Upper two bits of cylinder count */
|
movb %bh, %ah /* restore BIOS extensions bits */
|
||||||
andl $192,%eax
|
|
||||||
addr32
|
movb %dh, %al /* bits 10,11 of cylinder count */
|
||||||
leal 0(,%eax,4),%eax /* << 2 */
|
andb $0xc0, %eax
|
||||||
|
shlw $2, %ax /* << 2 */
|
||||||
|
movb %cl, %al /* bits 8,9 of cylinder count */
|
||||||
|
andb $0xc0, %al
|
||||||
|
shlw $2, %ax /* << 2 */
|
||||||
movb %ch, %al /* Lower 8 bits */
|
movb %ch, %al /* Lower 8 bits */
|
||||||
sall $16,%eax /* << 16 */
|
shll $16, %eax /* << 16 */
|
||||||
|
|
||||||
|
andb $0x3f, %ah /* mask of cylinder gunk */
|
||||||
movb %dh, %ah /* max head */
|
movb %dh, %ah /* max head */
|
||||||
andb $0x3f, %cl /* mask of cylinder gunk */
|
andb $0x3f, %cl /* mask of cylinder gunk */
|
||||||
movb %cl, %al /* max sector (and # sectors) */
|
movb %cl, %al /* max sector (and # sectors) */
|
||||||
|
|
|
@ -450,11 +450,11 @@ returnit:
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
|
|
||||||
if (!errnum
|
if (!errnum
|
||||||
&& (biosdisk(BIOSDISK_SUBFUNC_WRITE,
|
&& (biosdisk(BIOSDISK_WRITE,
|
||||||
dest_drive, dest_geom,
|
dest_drive, dest_geom,
|
||||||
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|
||||||
|| (write_stage2_sect
|
|| (write_stage2_sect
|
||||||
&& biosdisk(BIOSDISK_SUBFUNC_WRITE,
|
&& biosdisk(BIOSDISK_WRITE,
|
||||||
current_drive, buf_geom,
|
current_drive, buf_geom,
|
||||||
stage2_sect, 1, SCRATCHSEG))))
|
stage2_sect, 1, SCRATCHSEG))))
|
||||||
errnum = ERR_WRITE;
|
errnum = ERR_WRITE;
|
||||||
|
|
|
@ -86,6 +86,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr)
|
||||||
if (buf_drive != drive)
|
if (buf_drive != drive)
|
||||||
{
|
{
|
||||||
buf_geom = get_diskinfo (drive);
|
buf_geom = get_diskinfo (drive);
|
||||||
|
printf ("buf_geom = 0x%x\n", buf_geom); /* FIXME */
|
||||||
buf_drive = drive;
|
buf_drive = drive;
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +119,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr)
|
||||||
bufaddr = BUFFERADDR + byte_offset;
|
bufaddr = BUFFERADDR + byte_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bios_err = biosdisk (BIOSDISK_SUBFUNC_READ, drive, buf_geom,
|
if (bios_err = biosdisk (BIOSDISK_READ, drive, buf_geom,
|
||||||
read_start, read_len, BUFFERSEG))
|
read_start, read_len, BUFFERSEG))
|
||||||
{
|
{
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
|
@ -132,7 +133,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr)
|
||||||
* required sector(s) rather than failing completely.
|
* required sector(s) rather than failing completely.
|
||||||
*/
|
*/
|
||||||
if (slen > num_sect
|
if (slen > num_sect
|
||||||
|| biosdisk (BIOSDISK_SUBFUNC_READ, drive, buf_geom,
|
|| biosdisk (BIOSDISK_READ, drive, buf_geom,
|
||||||
sector, slen, BUFFERSEG))
|
sector, slen, BUFFERSEG))
|
||||||
errnum = ERR_READ;
|
errnum = ERR_READ;
|
||||||
|
|
||||||
|
@ -270,7 +271,7 @@ make_saved_active (void)
|
||||||
|
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
|
|
||||||
if (biosdisk (BIOSDISK_SUBFUNC_WRITE, saved_drive, buf_geom,
|
if (biosdisk (BIOSDISK_WRITE, saved_drive, buf_geom,
|
||||||
0, 1, SCRATCHSEG))
|
0, 1, SCRATCHSEG))
|
||||||
{
|
{
|
||||||
errnum = ERR_WRITE;
|
errnum = ERR_WRITE;
|
||||||
|
|
|
@ -48,8 +48,8 @@
|
||||||
/*
|
/*
|
||||||
* BIOS disk defines
|
* BIOS disk defines
|
||||||
*/
|
*/
|
||||||
#define BIOSDISK_SUBFUNC_READ 0x2
|
#define BIOSDISK_READ 0x0
|
||||||
#define BIOSDISK_SUBFUNC_WRITE 0x3
|
#define BIOSDISK_WRITE 0x1
|
||||||
#define BIOSDISK_ERROR_GEOMETRY 0x100
|
#define BIOSDISK_ERROR_GEOMETRY 0x100
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -287,7 +287,7 @@ __attribute__ ((noreturn));
|
||||||
|
|
||||||
/* low-level disk I/O */
|
/* low-level disk I/O */
|
||||||
int get_diskinfo (int drive);
|
int get_diskinfo (int drive);
|
||||||
int biosdisk (int subfunc, int drive, int geometry,
|
int biosdisk (int read, int drive, int geometry,
|
||||||
int sector, int nsec, int segment);
|
int sector, int nsec, int segment);
|
||||||
void stop_floppy (void);
|
void stop_floppy (void);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue