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>
|
||||
|
||||
* 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:
|
||||
* Bug fixes.
|
||||
* 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.
|
||||
|
||||
New in 0.5 - 1998-08-20, Erich Boleyn:
|
||||
|
|
|
@ -43,7 +43,6 @@ AC_SUBST(stage2debug)
|
|||
# Programs
|
||||
#
|
||||
|
||||
AC_PROG_INSTALL
|
||||
AC_CHECK_TOOL(CC, gcc)
|
||||
AC_CHECK_TOOL(LD, ld)
|
||||
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
|
||||
|
||||
* 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"
|
||||
* offset zero
|
||||
*
|
||||
* If it will fit into the BIOS geometry, it tries the INT 0x13
|
||||
* AH=<subfunction> interface, else if it is a hard disk, it will
|
||||
* try the hard disk LBA calls (not yet implemented). If these
|
||||
* won't work, or otherwise it is out of the translated area, then
|
||||
* it returns BIOS_GEOMETRY_ERROR.
|
||||
* Will try INT 0x13 LBA (AH=0x42/0x43) or standard (AH=0x2/0x3)
|
||||
* depending on probed geometry. For addresses out of the translated
|
||||
* area, it returns BIOS_GEOMETRY_ERROR.
|
||||
*/
|
||||
|
||||
ENTRY(biosdisk)
|
||||
|
@ -350,10 +348,56 @@ ENTRY(biosdisk)
|
|||
push %edx
|
||||
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:
|
||||
* 6 bit zero
|
||||
* 10 bit cylinder (bytes 2 & 3)
|
||||
* 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)
|
||||
*/
|
||||
|
@ -379,15 +423,27 @@ ENTRY(biosdisk)
|
|||
/* check cylinder offset, is there a geometry problem here? */
|
||||
movl 0x10(%ebp), %ebx
|
||||
shrl $16, %ebx
|
||||
andb $0xf, %bh /* mask out bios extension code */
|
||||
cmpl %ebx, %eax
|
||||
|
||||
/* if not, go on to standard read function */
|
||||
jle disk_use_standard_bios
|
||||
|
||||
/* XXX else we better use LBA or generate a geometry error */
|
||||
movl $BIOSDISK_ERROR_GEOMETRY, %eax
|
||||
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
|
||||
* INT 0x13/AH=<subfunc> interface.
|
||||
|
@ -396,9 +452,10 @@ disk_use_standard_bios:
|
|||
|
||||
shll $8, %edx /* get head number to %dh */
|
||||
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
|
||||
rorb $2, %cl
|
||||
shlb $6, %cl
|
||||
incb %al /* sector; sec starts from 1, not 0 */
|
||||
orb %al, %cl
|
||||
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
|
||||
after it is called */
|
||||
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 */
|
||||
movw 0x1c(%ebp), %bx /* segment */
|
||||
|
||||
|
@ -528,6 +586,7 @@ probe_loop:
|
|||
movb $1, %dh
|
||||
movb $79, %ch
|
||||
|
||||
xorb %bh, %bh /* no BIOS extensions */
|
||||
data32
|
||||
jmp probe_success
|
||||
|
||||
|
@ -535,7 +594,27 @@ probe_values:
|
|||
.byte 36, 18, 15, 9, 0
|
||||
|
||||
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
|
||||
|
||||
data32
|
||||
|
@ -546,18 +625,24 @@ hard_drive:
|
|||
|
||||
probe_success:
|
||||
/*
|
||||
* form a longword representing all this gunk:
|
||||
* 6 bit zero
|
||||
* 10 bit cylinder
|
||||
* form a dword representing all this gunk:
|
||||
* 4 bit BIOS extension (0 = none, 1 = LBA)
|
||||
* 12 bit cylinder
|
||||
* 8 bit head
|
||||
* 8 bit sector
|
||||
*/
|
||||
movb %cl, %al /* Upper two bits of cylinder count */
|
||||
andl $192,%eax
|
||||
addr32
|
||||
leal 0(,%eax,4),%eax /* << 2 */
|
||||
movb %bh, %ah /* restore BIOS extensions bits */
|
||||
|
||||
movb %dh, %al /* bits 10,11 of cylinder count */
|
||||
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 */
|
||||
sall $16,%eax /* << 16 */
|
||||
shll $16, %eax /* << 16 */
|
||||
|
||||
andb $0x3f, %ah /* mask of cylinder gunk */
|
||||
movb %dh, %ah /* max head */
|
||||
andb $0x3f, %cl /* mask of cylinder gunk */
|
||||
movb %cl, %al /* max sector (and # sectors) */
|
||||
|
|
|
@ -450,11 +450,11 @@ returnit:
|
|||
buf_track = -1;
|
||||
|
||||
if (!errnum
|
||||
&& (biosdisk(BIOSDISK_SUBFUNC_WRITE,
|
||||
&& (biosdisk(BIOSDISK_WRITE,
|
||||
dest_drive, dest_geom,
|
||||
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|
||||
|| (write_stage2_sect
|
||||
&& biosdisk(BIOSDISK_SUBFUNC_WRITE,
|
||||
&& biosdisk(BIOSDISK_WRITE,
|
||||
current_drive, buf_geom,
|
||||
stage2_sect, 1, SCRATCHSEG))))
|
||||
errnum = ERR_WRITE;
|
||||
|
|
|
@ -86,6 +86,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr)
|
|||
if (buf_drive != drive)
|
||||
{
|
||||
buf_geom = get_diskinfo (drive);
|
||||
printf ("buf_geom = 0x%x\n", buf_geom); /* FIXME */
|
||||
buf_drive = drive;
|
||||
buf_track = -1;
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr)
|
|||
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))
|
||||
{
|
||||
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.
|
||||
*/
|
||||
if (slen > num_sect
|
||||
|| biosdisk (BIOSDISK_SUBFUNC_READ, drive, buf_geom,
|
||||
|| biosdisk (BIOSDISK_READ, drive, buf_geom,
|
||||
sector, slen, BUFFERSEG))
|
||||
errnum = ERR_READ;
|
||||
|
||||
|
@ -270,7 +271,7 @@ make_saved_active (void)
|
|||
|
||||
buf_track = -1;
|
||||
|
||||
if (biosdisk (BIOSDISK_SUBFUNC_WRITE, saved_drive, buf_geom,
|
||||
if (biosdisk (BIOSDISK_WRITE, saved_drive, buf_geom,
|
||||
0, 1, SCRATCHSEG))
|
||||
{
|
||||
errnum = ERR_WRITE;
|
||||
|
|
|
@ -48,8 +48,8 @@
|
|||
/*
|
||||
* BIOS disk defines
|
||||
*/
|
||||
#define BIOSDISK_SUBFUNC_READ 0x2
|
||||
#define BIOSDISK_SUBFUNC_WRITE 0x3
|
||||
#define BIOSDISK_READ 0x0
|
||||
#define BIOSDISK_WRITE 0x1
|
||||
#define BIOSDISK_ERROR_GEOMETRY 0x100
|
||||
|
||||
/*
|
||||
|
@ -287,7 +287,7 @@ __attribute__ ((noreturn));
|
|||
|
||||
/* low-level disk I/O */
|
||||
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);
|
||||
void stop_floppy (void);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue