[patch] 2.3.41: 360/720k bootsect booting support..

From: Chris Noe (stiker@northlink.com)
Date: Sun Jan 30 2000 - 22:10:48 EST


AK's boocode updated to 2.3.41, sprinkled with a few more little
optimizations. Not compile tested though, so beware.

This should go straight into 2.5 if anyone besides nkbj tests it :)
<hint hint>

Chris Noe
(stiker@northlink.com)

diff -u --recursive linux-2.3.41/README linux/README
--- linux-2.3.41/README Sun Jan 9 01:15:48 2000
+++ linux/README Sun Jan 30 21:36:44 2000
@@ -197,10 +197,7 @@
 
    For some, this is on a floppy disk, in which case you can "cp
    /usr/src/linux/arch/i386/boot/zImage /dev/fd0" to make a bootable
- floppy. Please note that you can not boot a kernel by
- directly dumping it to a 720k double-density 3.5" floppy. In this
- case, it is highly recommended that you install LILO on your
- double-density boot floppy or switch to high-density floppies.
+ floppy.
 
    If you boot Linux from the hard drive, chances are you use LILO which
    uses the kernel image as specified in the file /etc/lilo.conf. The
diff -u --recursive linux-2.3.41/arch/i386/boot/bootsect.S linux/arch/i386/boot/bootsect.S
--- linux-2.3.41/arch/i386/boot/bootsect.S Sun Jan 30 21:41:45 2000
+++ linux/arch/i386/boot/bootsect.S Sun Jan 30 21:38:55 2000
@@ -5,8 +5,12 @@
  * modified by Bruce Evans (bde)
  * modified by Chris Noe (May 1999) (as86 -> gas)
  *
- * bootsect is loaded at 0x7c00 by the bios-startup routines, and moves
- * itself out of the way to address 0x90000, and jumps there.
+ * 360k/720k disk support: Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
+ *
+ * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
+ * addresses must be multiplied by 16 to obtain their respective linear
+ * addresses. To avoid confusion, linear addresses are written using leading
+ * hex while segment addresses are written as segment:offset.
  *
  * bde - should not jump blindly, there may be systems with only 512K low
  * memory. Use int 0x12 to get the top of memory, etc.
@@ -56,14 +60,12 @@
 .global _start
 _start:
 
-#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
- int $0x3
-#endif
+# First things first. Move ourself from 0x7C00 -> 0x90000 and jump there.
 
         movw $BOOTSEG, %ax
- movw %ax, %ds
+ movw %ax, %ds # %ds = BOOTSEG
         movw $INITSEG, %ax
- movw %ax, %es
+ movw %ax, %es # %ax = %es = INITSEG
         movw $256, %cx
         subw %si, %si
         subw %di, %di
@@ -82,7 +84,7 @@
                                         # length of bootsect + length of
                                         # setup + room for stack;
                                         # 12 is disk parm size.
- movw %ax, %ds # ax and es already contain INITSEG
+ movw %ax, %ds # %ax and %es already contain INITSEG
         movw %ax, %ss
         movw %di, %sp # put stack at INITSEG:0x4000-12.
 
@@ -98,66 +100,29 @@
 #
 # High doesn't hurt. Low does.
 #
-# Segments are as follows: ds = es = ss = cs - INITSEG, fs = 0,
-# and gs is unused.
+# Segments are as follows: %cs = %ds = %es = %ss = INITSEG, %fs = 0,
+# and %gs is unused.
 
- movw %cx, %fs # set fs to 0
- movw $0x78, %bx # fs:bx is parameter table address
+ movw %cx, %fs # %fs = 0
+ movw $0x78, %bx # %fs:%bx is parameter table address
         pushw %ds
- ldsw %fs:(%bx), %si # ds:si is source
+ ldsw %fs:(%bx), %si # %ds:%si is source
         movb $6, %cl # copy 12 bytes
- cld
- pushw %di # di = 0x4000-12.
- rep
- movsw
+ pushw %di # %di = 0x4000-12.
+ rep # don't worry about cld
+ movsw # already done above
         popw %di
         popw %ds
         movb $36, 0x4(%di) # patch sector count
         movw %di, %fs:(%bx)
         movw %es, %fs:2(%bx)
 
-# Load the setup-sectors directly after the bootblock.
-# Note that 'es' is already set up.
-# Also, cx = 0 from rep movsw above.
-
-load_setup:
- xorb %ah, %ah # reset FDC
- xorb %dl, %dl
- int $0x13
- xorw %dx, %dx # drive 0, head 0
- movb $0x02, %cl # sector 2, track 0
- movw $0x0200, %bx # address = 512, in INITSEG
- movb $0x02, %ah # service 2, "read sector(s)"
- movb setup_sects, %al # (assume all on head 0, track 0)
- int $0x13 # read it
- jnc ok_load_setup # ok - continue
-
- pushw %ax # dump error code
- call print_nl
- movw %sp, %bp
- call print_hex
- popw %ax
- jmp load_setup
-
-ok_load_setup:
 # Get disk drive parameters, specifically nr of sectors/track.
 
-#if 0
-
-# bde - the Phoenix BIOS manual says function 0x08 only works for fixed
-# disks. It doesn't work for one of my BIOS's (1987 Award). It was
-# fatal not to check the error code.
-
- xorb %dl, %dl
- movb $0x08, %ah # AH=8 is get drive parameters
- int $0x13
- xorb %ch, %ch
-
-#else
-
 # It seems that there is no BIOS call to get the number of sectors.
 # Guess 36 sectors if sector 36 can be read, 18 sectors if sector 18
 # can be read, 15 if sector 15 can be read. Otherwise guess 9.
+# Note that %cx = 0 from rep movsw above.
 
         movw $disksizes, %si # table of sizes to try
 probe_loop:
@@ -166,31 +131,56 @@
         movw %ax, sectors
         cmpw $disksizes+4, %si
         jae got_sectors # if all else fails, try 9
-
- xchgw %cx, %ax # cx = track and sector
+
+ xchgw %cx, %ax # %cx = track and sector
         xorw %dx, %dx # drive 0, head 0
- xorb %bl, %bl
- movb setup_sects, %bh
- incb %bh
- shlb %bh # address after setup (es = cs)
+ movw $0x0200, %bx # address = 512, in INITSEG (%es = %cs)
         movw $0x0201, %ax # service 2, 1 sector
         int $0x13
         jc probe_loop # try next value
-#endif
 
 got_sectors:
- movw $INITSEG, %ax
- movw %ax, %es # set up es
         movb $0x03, %ah # read cursor pos
         xorb %bh, %bh
         int $0x10
         movw $9, %cx
- movw $0x0007, %bx # page 0, attribute 7 (normal)
- movw $msg1, %bp
- movw $0x1301, %ax # write string, move cursor
+ movb $0x07, %bl # page 0, attribute 7 (normal)
+ # %bh is set above; int10 doesn't
+ # modify it
+ movw $msg1, %bp
+ movw $0x1301, %ax # write string, move cursor
         int $0x10 # tell the user we're loading..
- movw $SYSSEG, %ax # ok, we've written the message, now
- movw %ax, %es # we want to load system (at 0x10000)
+
+# Load the setup-sectors directly after the moved bootblock (at 0x90200).
+# We should know the drive geometry to do it, as setup may exceed first
+# cylinder (for 9-sector 360K and 720K floppies).
+
+ movw $0x0001, %ax # set sread (sector-to-read) to 1 as
+ movw $sread, %si # the boot sector has already been read)
+ movw %ax, (%si)
+
+ xorw %ax, %ax # reset FDC
+ xorb %dl, %dl
+ int $0x13
+ movw $0x0200, %bx # address = 512, in INITSEG
+next_step:
+ movb setup_sects, %al
+ movw sectors, %cx
+ subw (%si), %cx # (%si) = sread
+ cmpb %cl, %al
+ jbe no_cyl_crossing
+ movw sectors, %ax
+ subw (%si), %ax # (%si) = sread
+no_cyl_crossing:
+ call read_track
+ pushw %ax # save it
+ call set_next # set %bx properly; it uses ax,cx,dx
+ popw %ax # restore
+ subb %al, setup_sects # rest - for next step
+ jnz next_step
+
+ pushw $SYSSEG
+ popw %es # %es = SYSSEG
         call read_it
         call kill_motor
         call print_nl
@@ -200,72 +190,74 @@
 # Otherwise, one of /dev/fd0H2880 (2,32) or /dev/PS0 (2,28) or /dev/at0 (2,8)
 # depending on the number of sectors we pretend to know we have.
 
- movw %cs:root_dev, %ax
+# Segments are as follows: %cs = %ds = %ss = INITSEG,
+# %es = SYSSEG, %fs = 0, %gs is unused.
+
+ movw root_dev, %ax
         orw %ax, %ax
         jne root_defined
-
- movw %cs:sectors, %bx
+
+ movw sectors, %bx
         movw $0x0208, %ax # /dev/ps0 - 1.2Mb
         cmpw $15, %bx
         je root_defined
-
+
         movb $0x1c, %al # /dev/PS0 - 1.44Mb
         cmpw $18, %bx
         je root_defined
-
+
         movb $0x20, %al # /dev/fd0H2880 - 2.88Mb
         cmpw $36, %bx
         je root_defined
-
+
         movb $0, %al # /dev/fd0 - autodetect
 root_defined:
- movw %ax, %cs:root_dev
+ movw %ax, root_dev
 
 # After that (everything loaded), we jump to the setup-routine
 # loaded directly after the bootblock:
 
         ljmp $SETUPSEG, $0
 
-# This routine loads the system at address 0x10000, making sure
-# no 64kB boundaries are crossed. We try to load it as fast as
-# possible, loading whole tracks whenever we can.
-
-# es = starting address segment (normally 0x1000)
+# These variables are addressed via %si register as it gives shorter code.
 
 sread: .word 0 # sectors read of current track
 head: .word 0 # current head
 track: .word 0 # current track
 
+# This routine loads the system at address SYSSEG, making sure
+# no 64kB boundaries are crossed. We try to load it as fast as
+# possible, loading whole tracks whenever we can.
+
 read_it:
- movb setup_sects, %al
- incb %al
- movb %al, sread
- movw %es, %ax
+ movw %es, %ax # %es = SYSSEG when called
         testw $0x0fff, %ax
-die: jne die # es must be at 64kB boundary
-
- xorw %bx, %bx # bx is starting address within segment
+die: jne die # %es must be at 64kB boundary
+ xorw %bx, %bx # %bx is starting address within segment
 rp_read:
-#ifdef __BIG_KERNEL__
- bootsect_kludge = 0x220 # 0x200 (size of bootsector) + 0x20 (offset
- lcall bootsect_kludge # of bootsect_kludge in setup.S)
+#ifdef __BIG_KERNEL__ # look in setup.S for bootsect_kludge
+ bootsect_kludge = 0x220 # 0x200 + 0x20 which is the size of the
+ lcall bootsect_kludge # bootsector + bootsect_kludge offset
 #else
- movw %es, %ax
+ movw %es, %ax
         subw $SYSSEG, %ax
+ movw %bx, %cx
+ shr $4, %cx
+ add %cx, %ax # check offset
 #endif
- cmpw syssize, %ax # have we loaded all yet?
+ cmpw syssize, %ax # have we loaded everything yet?
         jbe ok1_read
 
         ret
 
 ok1_read:
         movw sectors, %ax
- subw sread, %ax
+ subw (%si), %ax # (%si) = sread
         movw %ax, %cx
         shlw $9, %cx
         addw %bx, %cx
         jnc ok2_read
-
+
         je ok2_read
 
         xorw %ax, %ax
@@ -273,60 +265,64 @@
         shrw $9, %ax
 ok2_read:
         call read_track
- movw %ax, %cx
- addw sread, %ax
- cmpw sectors, %ax
- jne ok3_read
-
- movw $1, %ax
- subw head, %ax
- jne ok4_read
-
- incw track
-ok4_read:
- movw %ax, head
- xorw %ax, %ax
-ok3_read:
- movw %ax, sread
- shlw $9, %cx
- addw %cx, %bx
- jnc rp_read
-
- movw %es, %ax
- addb $0x10, %ah
- movw %ax, %es
- xorw %bx, %bx
+ call set_next
         jmp rp_read
 
 read_track:
         pusha
         pusha
- movw $0xe2e, %ax # loading... message 2e = .
+ movw $0xe2e, %ax # print "." (0x2e) for each track read
         movw $7, %bx
          int $0x10
         popa
- movw track, %dx
- movw sread, %cx
+
+# Accessing head, track, sread via %si gives shorter code.
+
+ movw 4(%si), %dx # 4(%si) = track
+ movw (%si), %cx # (%si) = sread
         incw %cx
         movb %dl, %ch
- movw head, %dx
+ movw 2(%si), %dx # 2(%si) = head
         movb %dl, %dh
         andw $0x0100, %dx
         movb $2, %ah
- pushw %dx # save for error dump
+ pushw %dx # save for error dump
         pushw %cx
         pushw %bx
         pushw %ax
         int $0x13
         jc bad_rt
-
+
         addw $8, %sp
         popa
         ret
 
+set_next:
+ movw %ax, %cx
+ addw (%si), %ax # (%si) = sread
+ cmp sectors, %ax
+ jne ok3_set
+ movw $0x0001, %ax
+ xorw %ax, 2(%si) # change head
+ jne ok4_set
+ incw 4(%si) # next track
+ok4_set:
+ xorw %ax, %ax
+ok3_set:
+ movw %ax, (%si) # set sread
+ shlw $9, %cx
+ addw %cx, %bx
+ jnc set_next_fin
+ movw %es, %ax
+ addb $0x10, %ah
+ movw %ax, %es
+ xorw %bx, %bx
+set_next_fin:
+ ret
+
 bad_rt:
         pushw %ax # save error code
- call print_all # ah = error, al = read
+ call print_all # %ah = error, %al = read
         xorb %ah, %ah
         xorb %dl, %dl
         int $0x13
@@ -350,8 +346,8 @@
         movw $5, %cx # error code + 4 registers
         movw %sp, %bp
 print_loop:
- pushw %cx # save count left
- call print_nl # nl for readability
+ pushw %cx # save count remaining
+ call print_nl # <-- for readability
         cmpb $5, %cl
         jae no_reg # see if register name is needed
         
@@ -377,16 +373,16 @@
         ret
 
 # print_hex is for debugging purposes, and prints the word
-# pointed to by ss:bp in hexadecimal.
+# pointed to by %ss:%bp in hexadecimal.
 
 print_hex:
         movw $4, %cx # 4 hex digits
- movw (%bp), %dx # load word into dx
+ movw (%bp), %dx # load word into %dx
 print_digit:
         rolw $4, %dx # rotate to use low 4 bits
- movw $0xe0f, %ax # ah = request
- andb %dl, %al # al = mask for nybble
- addb $0x90, %al # convert al to ascii hex
+ movw $0xe0f, %ax # %ah = request
+ andb %dl, %al # %al = mask for nybble
+ addb $0x90, %al # convert %al to ascii hex
         daa # in only four instructions!
         adc $0x40, %al
         daa
@@ -397,6 +393,7 @@
 # This procedure turns off the floppy drive motor, so
 # that we enter the kernel in a known state, and
 # don't have to worry about it later.
+# NOTE: Doesn't save %ax or %dx; do it yourself if you need to.
 
 kill_motor:
         movw $0x3f2, %dx
@@ -409,7 +406,7 @@
 msg1: .byte 13, 10
                 .ascii "Loading"
 
-# XXX: This is a *very* snug fit.
+# XXX: This is a fairly snug fit.
 
 .org 497
 setup_sects: .byte SETUPSECS
diff -u --recursive linux-2.3.41/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- linux-2.3.41/arch/i386/boot/setup.S Thu Jan 6 18:58:02 2000
+++ linux/arch/i386/boot/setup.S Sun Jan 30 21:52:13 2000
@@ -210,8 +210,8 @@
 # Move rest of setup code/data to here
         movw $2048, %di # four sectors loaded by LILO
         subw %si, %si
- movw %cs, %ax # aka SETUPSEG
- movw %ax, %es
+ pushw %cs
+ popw %es # aka SETUPSEG
         movw $SYSSEG, %ax
         movw %ax, %ds
         rep

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jan 31 2000 - 21:00:27 EST