public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: Killing off the boot sector (was: [STATUS 2.5]  January 8, 2002)
  2003-01-08 18:05 [STATUS 2.5] January 8, 2002 Guillaume Boissiere
@ 2003-01-08 20:03 ` H. Peter Anvin
  2003-01-08 20:35   ` DervishD
  2003-01-08 21:23   ` John Bradford
  0 siblings, 2 replies; 6+ messages in thread
From: H. Peter Anvin @ 2003-01-08 20:03 UTC (permalink / raw)
  To: linux-kernel

Followup to:  <3E1C2208.6727.5370CB@localhost>
By author:    "Guillaume Boissiere" <boissiere@adiglobal.com>
In newsgroup: linux.dev.kernel
> 
> 179  nor  bugme-janitors@lists.osdl.org  OPEN   boot from 21
> sec/track floppy  
> 

Can we *please* kill off the stupid in-kernel boot sector?  The
probing method it uses to determine geometry is unreliable (doesn't
work on anything but true legacy floppies, not IDE, not USB, not
firewire); it generates these kinds of requests; doesn't handle
large-size kernels; hard-codes the use of address 0x90000 which isn't
available on all machines; and overall promotes what's fundamentally
bad practice.

People keep asking what's the harm in keeping it, and the answer is,
quite simply: "because people continue to try to use it."

Here is a patch that guts it to print an error message.  It's even
tested.

--- linux-2.5.54/arch/i386/boot/bootsect.S.dist	Wed Jan  8 11:35:52 2003
+++ linux-2.5.54/arch/i386/boot/bootsect.S	Wed Jan  8 11:52:16 2003
@@ -4,29 +4,13 @@
  *	modified by Drew Eckhardt
  *	modified by Bruce Evans (bde)
  *	modified by Chris Noe (May 1999) (as86 -> gas)
- *
- * 360k/720k disk support: Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
+ *	gutted by H. Peter Anvin (Jan 2003)
  *
  * 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.
- *
- * It then loads 'setup' directly after itself (0x90200), and the system
- * at 0x10000, using BIOS interrupts. 
- *
- * NOTE! currently system is at most (8*65536-4096) bytes long. This should 
- * be no problem, even in the future. I want to keep it simple. This 508 kB
- * kernel size should be enough, especially as this doesn't contain the
- * buffer cache as in minix (and especially now that the kernel is 
- * compressed :-)
- *
- * The loader has been made as simple as possible, and continuous
- * read errors will result in a unbreakable loop. Reboot by hand. It
- * loads pretty fast by getting whole tracks at a time whenever possible.
  */
 
 #include <asm/boot.h>
@@ -59,359 +43,47 @@
 .global _start
 _start:
 
-# First things first. Move ourself from 0x7C00 -> 0x90000 and jump there.
+	# Normalize the start address
+	jmpl	$BOOTSEG, $start2
 
-	movw	$BOOTSEG, %ax
-	movw	%ax, %ds		# %ds = BOOTSEG
-	movw	$INITSEG, %ax
-	movw	%ax, %es		# %ax = %es = INITSEG
-	movw	$256, %cx
-	subw	%si, %si
-	subw	%di, %di
-	cld
-	rep
-	movsw
-	ljmp	$INITSEG, $go
-
-# bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde).  We
-# wouldn't have to worry about this if we checked the top of memory.  Also
-# my BIOS can be configured to put the wini drive tables in high memory
-# instead of in the vector table.  The old stack might have clobbered the
-# drive table.
-
-go:	movw	$0x4000-12, %di		# 0x4000 is an arbitrary value >=
-					# length of bootsect + length of
-					# setup + room for stack;
-					# 12 is disk parm size.
-	movw	%ax, %ds		# %ax and %es already contain INITSEG
+start2:
+	movw	%cs, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
 	movw	%ax, %ss
-	movw	%di, %sp		# put stack at INITSEG:0x4000-12.
+	movw	$0x7c00, %sp
+	sti
+	cld
 
-# Many BIOS's default disk parameter tables will not recognize
-# multi-sector reads beyond the maximum sector number specified
-# in the default diskette parameter tables - this may mean 7
-# sectors in some cases.
-#
-# Since single sector reads are slow and out of the question,
-# we must take care of this by creating new parameter tables
-# (for the first disk) in RAM.  We will set the maximum sector
-# count to 36 - the most we will encounter on an ED 2.88.  
-#
-# High doesn't hurt.  Low does.
-#
-# Segments are as follows: %cs = %ds = %es = %ss = INITSEG, %fs = 0,
-# and %gs is unused.
-
-	movw	%cx, %fs		# %fs = 0
-	movw	$0x78, %bx		# %fs:%bx is parameter table address
-	pushw	%ds
-	ldsw	%fs:(%bx), %si		# %ds:%si is source
-	movb	$6, %cl			# copy 12 bytes
-	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)
-
-# Get disk drive parameters, specifically number of sectors/track.
-
-# 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	$bugger_off_msg, %si
 
-	movw	$disksizes, %si		# table of sizes to try
-probe_loop:
+msg_loop:
 	lodsb
-	cbtw				# extend to word
-	movw	%ax, sectors
-	cmpw	$disksizes+4, %si
-	jae	got_sectors		# If all else fails, try 9
-
-	xchgw	%cx, %ax		# %cx = track and sector
-	xorw	%dx, %dx		# drive 0, head 0
-	movw	$0x0200, %bx		# address = 512, in INITSEG (%es = %cs)
-	movw	$0x0201, %ax		# service 2, 1 sector
-	int	$0x13
-	jc	probe_loop		# try next value
-
-got_sectors:
-	movb	$0x03, %ah		# read cursor pos
-	xorb	%bh, %bh
-	int	$0x10
-	movw	$9, %cx
-	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..
-
-# 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)
-
-	call	kill_motor		# reset FDC
-	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
-
-# After that we check which root-device to use. If the device is
-# defined (!= 0), nothing is done and the given device is used.
-# 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.
-
-# 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	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, root_dev
-
-# After that (everything loaded), we jump to the setup-routine
-# loaded directly after the bootblock:
-
-	ljmp	$SETUPSEG, $0
-
-# 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:
-	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
-rp_read:
-#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
-	subw	$SYSSEG, %ax
-	movw	%bx, %cx
-	shr	$4, %cx
-	add	%cx, %ax		# check offset
-#endif
-	cmpw	syssize, %ax		# have we loaded everything yet?
-	jbe	ok1_read
-
-	ret
-
-ok1_read:
-	movw	sectors, %ax
-	subw	(%si), %ax		# (%si) = sread
-	movw	%ax, %cx
-	shlw	$9, %cx
-	addw	%bx, %cx
-	jnc	ok2_read
-
-	je	ok2_read
-
-	xorw	%ax, %ax
-	subw	%bx, %ax
-	shrw	$9, %ax
-ok2_read:
-	call	read_track
-	call	set_next
-	jmp	rp_read
-
-read_track:
-	pusha
-	pusha	
-	movw	$0xe2e, %ax 		# loading... message 2e = .
-	movw	$7, %bx
- 	int	$0x10
-	popa		
-
-# 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	2(%si), %dx		# 2(%si) = head
-	movb	%dl, %dh
-	andw	$0x0100, %dx
-	movb	$2, %ah
-	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
+	andb	%al, %al
+	jz	die
+	mov	$0xe, %ah
 	xorw	%bx, %bx
-set_next_fin:
-	ret
-
-bad_rt:
-	pushw	%ax			# save error code
-	call	print_all		# %ah = error, %al = read
-	xorb	%ah, %ah
-	xorb	%dl, %dl
-	int	$0x13
-	addw	$10, %sp
-	popa
-	jmp read_track
-
-# print_all is for debugging purposes.  
-#
-# it will print out all of the registers.  The assumption is that this is
-# called from a routine, with a stack frame like
-#
-#	%dx 
-#	%cx
-#	%bx
-#	%ax
-#	(error)
-#	ret <- %sp
- 
-print_all:
-	movw	$5, %cx			# error code + 4 registers
-	movw	%sp, %bp
-print_loop:
-	pushw	%cx			# save count remaining
-	call	print_nl		# <-- for readability
-	cmpb	$5, %cl
-	jae	no_reg			# see if register name is needed
-	
-	movw	$0xe05 + 'A' - 1, %ax
-	subb	%cl, %al
-	int	$0x10
-	movb	$'X', %al
 	int	$0x10
-	movb	$':', %al
-	int	$0x10
-no_reg:
-	addw	$2, %bp			# next register
-	call	print_hex		# print it
-	popw	%cx
-	loop	print_loop
-	ret
+	jmp	msg_loop
 
-print_nl:
-	movw	$0xe0d, %ax		# CR
-	int	$0x10
-	movb	$0xa, %al		# LF
-	int 	$0x10
-	ret
-
-# print_hex is for debugging purposes, and prints the word
-# pointed to by %ss:%bp in hexadecimal.
-
-print_hex:
-	movw	$4, %cx			# 4 hex digits
-	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
-	daa				# in only four instructions!
-	adc	$0x40, %al
-	daa
-	int	$0x10
-	loop	print_digit
-	ret
+die:
+	# Allow the user to press a key, then reboot
+	xorw	%ax, %ax
+	int	$0x16
+	int	$0x19
 
-# 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:
-#if 1
-	xorw	%ax, %ax		# reset FDC
-	xorb	%dl, %dl
-	int	$0x13
-#else
-	movw	$0x3f2, %dx
-	xorb	%al, %al
-	outb	%al, %dx
-#endif
-	ret
 
-sectors:	.word 0
-disksizes:	.byte 36, 18, 15, 9
-msg1:		.byte 13, 10
-		.ascii "Loading"
+bugger_off_msg:
+	.ascii	"Direct booting from floppy is no longer supported.\r\n"
+	.ascii	"Please use a boot loader program instead.\r\n"
+	.ascii	"\n"
+	.ascii	"Remove disk and press any key to reboot . . .\r\n"
+	.byte	0
+	
 
-# XXX: This is a fairly snug fit.
+	# Kernel attributes; used by setup
 
-.org 497
+	.org 497
 setup_sects:	.byte SETUPSECTS
 root_flags:	.word ROOT_RDONLY
 syssize:	.word SYSSIZE
--- linux-2.5.54/arch/i386/boot/tools/build.c.dist	Wed Jan  1 19:22:04 2003
+++ linux-2.5.54/arch/i386/boot/tools/build.c	Wed Jan  8 11:53:32 2003
@@ -150,13 +150,10 @@
 	sz = sb.st_size;
 	fprintf (stderr, "System is %d kB\n", sz/1024);
 	sys_size = (sz + 15) / 16;
-	/* 0x28000*16 = 2.5 MB, conservative estimate for the current maximum */
-	if (sys_size > (is_big_kernel ? 0x28000 : DEF_SYSSIZE))
+	/* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */
+	if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE))
 		die("System is too big. Try using %smodules.",
 			is_big_kernel ? "" : "bzImage or ");
-	if (sys_size > 0xefff)
-		fprintf(stderr,"warning: kernel is too big for standalone boot "
-		    "from floppy\n");
 	while (sz > 0) {
 		int l, n;
 

-- 
<hpa@transmeta.com> at work, <hpa@zytor.com> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt	<amsp@zytor.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Killing off the boot sector (was: [STATUS 2.5]  January 8, 2002)
  2003-01-08 20:03 ` Killing off the boot sector (was: [STATUS 2.5] January 8, 2002) H. Peter Anvin
@ 2003-01-08 20:35   ` DervishD
  2003-01-08 21:23   ` John Bradford
  1 sibling, 0 replies; 6+ messages in thread
From: DervishD @ 2003-01-08 20:35 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel

    Hi HPA :))

> Can we *please* kill off the stupid in-kernel boot sector?

    Yespleaseyespleaseyesplease... I posted a message here a long
time ago because I couldn't boot a raw kernel image with 2.4.x. Well,
it didn't work even with a emulated floppy image (El Torito, you
know)...

    I think that, with those good boot loaders out there, this piece
of code, that is architecture dependend, should be off-the kernel.

    IMHO, those saved bytes should be used to store another cool Tux
image or something like that XDDDDD

> People keep asking what's the harm in keeping it, and the answer is,
> quite simply: "because people continue to try to use it."

    Exact...

    You've got a very good and sensible idea ;)
    Raúl

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Killing off the boot sector (was: [STATUS 2.5]  January 8, 2002)
  2003-01-08 20:03 ` Killing off the boot sector (was: [STATUS 2.5] January 8, 2002) H. Peter Anvin
  2003-01-08 20:35   ` DervishD
@ 2003-01-08 21:23   ` John Bradford
  2003-01-09  0:06     ` H. Peter Anvin
  1 sibling, 1 reply; 6+ messages in thread
From: John Bradford @ 2003-01-08 21:23 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel

> Can we *please* kill off the stupid in-kernel boot sector?
> 
> Here is a patch that guts it to print an error message.  It's even
> tested.

> -# 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:
> -#if 1
> -	xorw	%ax, %ax		# reset FDC
> -	xorb	%dl, %dl
> -	int	$0x13
> -#else
> -	movw	$0x3f2, %dx
> -	xorb	%al, %al
> -	outb	%al, %dx
> -#endif
> -	ret

Shouldn't that part stay, incase somebody boots a machine from a
floppy, and leaves it running for hours?

> +	.ascii	"Direct booting from floppy is no longer supported.\r\n"
> +	.ascii	"Please use a boot loader program instead.\r\n"
> +	.ascii	"\n"
> +	.ascii	"Remove disk and press any key to reboot . . .\r\n"

Couldn't you put an ASCII penguin in there?  :-)

John.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Killing off the boot sector (was: [STATUS 2.5]  January 8, 2002)
  2003-01-08 21:23   ` John Bradford
@ 2003-01-09  0:06     ` H. Peter Anvin
  0 siblings, 0 replies; 6+ messages in thread
From: H. Peter Anvin @ 2003-01-09  0:06 UTC (permalink / raw)
  To: linux-kernel

Followup to:  <200301082123.h08LNXSY003383@darkstar.example.net>
By author:    John Bradford <john@grabjohn.com>
In newsgroup: linux.dev.kernel
> 
> Shouldn't that part stay, incase somebody boots a machine from a
> floppy, and leaves it running for hours?
> 

No; interrupts are enabled so the BIOS will time out the floppy and
turn off the motor if necessary.  The only reason Linux (sort of)
needs that code is because the kernel takes control away from the
BIOS.  I say "sort of" because it really only matters if the kernel
doesn't have a floppy driver.

	-hpa
-- 
<hpa@transmeta.com> at work, <hpa@zytor.com> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt	<amsp@zytor.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Killing off the boot sector (was: [STATUS 2.5]  January 8, 2002)
@ 2003-01-11 16:03 Mikael Pettersson
  2003-01-22  7:24 ` H. Peter Anvin
  0 siblings, 1 reply; 6+ messages in thread
From: Mikael Pettersson @ 2003-01-11 16:03 UTC (permalink / raw)
  To: hpa, linux-kernel

On 8 Jan 2003 12:03:27 -0800, H. Peter Anvin wrote:
>Can we *please* kill off the stupid in-kernel boot sector?  The
>probing method it uses to determine geometry is unreliable (doesn't
>work on anything but true legacy floppies, not IDE, not USB, not
>firewire); it generates these kinds of requests; doesn't handle
>large-size kernels; hard-codes the use of address 0x90000 which isn't
>available on all machines; and overall promotes what's fundamentally
>bad practice.
>
>People keep asking what's the harm in keeping it, and the answer is,
>quite simply: "because people continue to try to use it."

While I have no particular affection for the in-kernel boot loader,
I do care about being able to test new kernels with 'make bzdisk'
as a regular user, using raw (no file system) floppies.

Last time I checked, LILO required both a file system and root privs
(for FIBMAP). Would syslinux work better?

/Mikael

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Killing off the boot sector (was: [STATUS 2.5]  January 8, 2002)
  2003-01-11 16:03 Killing off the boot sector (was: [STATUS 2.5] January 8, 2002) Mikael Pettersson
@ 2003-01-22  7:24 ` H. Peter Anvin
  0 siblings, 0 replies; 6+ messages in thread
From: H. Peter Anvin @ 2003-01-22  7:24 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: linux-kernel

Mikael Pettersson wrote:
> 
> While I have no particular affection for the in-kernel boot loader,
> I do care about being able to test new kernels with 'make bzdisk'
> as a regular user, using raw (no file system) floppies.
> 
> Last time I checked, LILO required both a file system and root privs
> (for FIBMAP). Would syslinux work better?
> 

SYSLINUX will work if (a) you have write permission to the device and 
(b) the device is included in /etc/fstab with "user" permissions.

	-hpa




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-01-22  7:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-11 16:03 Killing off the boot sector (was: [STATUS 2.5] January 8, 2002) Mikael Pettersson
2003-01-22  7:24 ` H. Peter Anvin
  -- strict thread matches above, loose matches on Subject: below --
2003-01-08 18:05 [STATUS 2.5] January 8, 2002 Guillaume Boissiere
2003-01-08 20:03 ` Killing off the boot sector (was: [STATUS 2.5] January 8, 2002) H. Peter Anvin
2003-01-08 20:35   ` DervishD
2003-01-08 21:23   ` John Bradford
2003-01-09  0:06     ` H. Peter Anvin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox