public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [i386 BOOT CODE] kernel bootable again
@ 2005-09-13 13:46 Pascal Bellard
  2005-09-13 19:04 ` Frank Sorenson
  0 siblings, 1 reply; 12+ messages in thread
From: Pascal Bellard @ 2005-09-13 13:46 UTC (permalink / raw)
  To: Riley; +Cc: Linux-Kernel

[-- Attachment #1: Type: text/plain, Size: 869 bytes --]

Hello,

Please find attached a patch to build i386/x86_64 kernel directly
bootable. It may be usefull for rescue floppies and installation
floppies.

System sector count is updated by tools/bluid.c at offset 495. The
system could be up to 32 Mb long.

-- support any drive geometry --

Disk geometry detection assumes that no error raises on first track.
First track is read sector by sector and the first error determinates
the sectors per track count. Next, reads are performed track by track.
Tested on floppy H2/S18 and harddisk H16/S63. Should work on
every exotic drive supporting Int13h CHS.

-- cmdline support --

If ram_size (offset 504) bit 13 is set, the kernel cmdline
is load from the sector following the kernel image.

If Ctrl, Alt, Shift or CapsLock is pressed the kernel cmdline is
prompted until Enter key. BackSpace is supported.

Regards,

-pascal

[-- Attachment #2: linux-2_6_13-bootblock_u.DEFANGED-1 --]
[-- Type: application/DEFANGED-1, Size: 34289 bytes --]

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-13 13:46 [i386 BOOT CODE] kernel bootable again Pascal Bellard
@ 2005-09-13 19:04 ` Frank Sorenson
  2005-09-13 19:42   ` H. Peter Anvin
  2005-09-14  9:52   ` Pascal Bellard
  0 siblings, 2 replies; 12+ messages in thread
From: Frank Sorenson @ 2005-09-13 19:04 UTC (permalink / raw)
  To: pascal.bellard; +Cc: Riley, Linux-Kernel, H. Peter Anvin

[-- Attachment #1: Type: text/plain, Size: 1726 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Pascal Bellard wrote:
> Hello,
> 
> Please find attached a patch to build i386/x86_64 kernel directly
> bootable. It may be usefull for rescue floppies and installation
> floppies.

Pascal,

In commit f8eeaaf4180334a8e5c3582fe62a5f8176a8c124, build.c has already
changed, and I don't believe it's very compatible with this change.

See
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f8eeaaf4180334a8e5c3582fe62a5f8176a8c124

Also, we'll need to see comments from H. Peter Anvin on this patch.
CC'ing him.


> System sector count is updated by tools/bluid.c at offset 495. The
> system could be up to 32 Mb long.
> 
> -- support any drive geometry --
> 
> Disk geometry detection assumes that no error raises on first track.
> First track is read sector by sector and the first error determinates
> the sectors per track count. Next, reads are performed track by track.
> Tested on floppy H2/S18 and harddisk H16/S63. Should work on
> every exotic drive supporting Int13h CHS.
> 
> -- cmdline support --
> 
> If ram_size (offset 504) bit 13 is set, the kernel cmdline
> is load from the sector following the kernel image.
> 
> If Ctrl, Alt, Shift or CapsLock is pressed the kernel cmdline is
> prompted until Enter key. BackSpace is supported.
> 
> Regards,
> 
> -pascal

Frank
- --
Frank Sorenson - KD7TZK
Systems Manager, Computer Science Department
Brigham Young University
frank@tuxrocks.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iD8DBQFDJyKhaI0dwg4A47wRAjMoAJ9laL5kvIzkbJAxigSJahqkdnmx8gCg6dOy
V6ML9fJQjmfjcdxNGnbSuZ0=
=7P9o
-----END PGP SIGNATURE-----

[-- Attachment #2: linux-2_6_13-bootblock.patch --]
[-- Type: text/x-patch, Size: 34289 bytes --]

diff -purN linux-2.6.13/arch/i386/boot/bootsect.S linux-2.6.13-bootblock/arch/i386/boot/bootsect.S
--- linux-2.6.13/arch/i386/boot/bootsect.S	2005-09-12 10:37:52.000000000 +0200
+++ linux-2.6.13-bootblock/arch/i386/boot/bootsect.S	2005-09-12 10:40:19.000000000 +0200
@@ -4,20 +4,31 @@
  *	modified by Drew Eckhardt
  *	modified by Bruce Evans (bde)
  *	modified by Chris Noe (May 1999) (as86 -> gas)
- *	gutted by H. Peter Anvin (Jan 2003)
+ *
+ *      rewritten to support up to 32Mb kernel, cmdline
+ *      and any disk geometry by <pascal.bellard@ads-lu.com>
  *
  * 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. 
+ *
+ * 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>
 
 SETUPSECTS	= 4			/* default nr of setup-sectors */
 BOOTSEG		= 0x07C0		/* original address of boot-sector */
-INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
+INITSEG		= DEF_INITSEG		/* we load boot here - out of the way */
 SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
 SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
 SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
@@ -25,6 +36,12 @@ SYSSIZE		= DEF_SYSSIZE		/* system size: 
 ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
 SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
 
+/* some extra features */
+#define DISPLAY_KERNEL_VERSION		as soon as possible
+#define	EDIT_CMDLINE			on hotkey
+#define	LOAD_CMDLINE			according to bit ramsize.13
+#define EXTRA_DEVICES			to fill root_device
+
 #ifndef SVGA_MODE
 #define SVGA_MODE ASK_VGA
 #endif
@@ -42,57 +59,470 @@ SWAP_DEV	= 0			/* SWAP_DEV is now writte
 
 .global _start
 _start:
+	cld				# assume nothing
+	movw	$INITSEG, %ax
+	movw	%ax, %es		# %ax = %es = INITSEG
+#if MOVE_BOOTSECTOR
+# First things first. Move ourself from 0x7C00 -> 0x90000 and jump there.
+	movw	$BOOTSEG, %cx
+	movw	%cx, %ds		# %ds = BOOTSEG
+	movb	$1, %ch			# %cx = 256
+	subw	%si, %si
+	subw	%di, %di
+	rep
+	movsw
+	ljmp	$INITSEG, $go
+go:	
+#else
+	xorw	%cx, %cx		# %cx = 0
+#endif
 
-	# Normalize the start address
-	jmpl	$BOOTSEG, $start2
+# 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.
+
+	movw	$0x4000-12, %di		# 0x4000 is an arbitrary value >=
+					# length of bootsect + length of
+					# setup + room for stack;
+					# 12 is disk parm size.
+					# gdt will heat 48 more bytes.
+	movw	%ax, %ss		# %ax and %es already contain INITSEG
+	movw	%di, %sp		# put stack at INITSEG:0x4000-12.
+
+# 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 can set the maximum sector
+# count to 36 - the most we will encounter on an ED 2.88.  
+#
+# High doesn't hurt.  Low does.  Let's use the max: 63
+#
+# Segments are as follows: %es = %ss = INITSEG,
+# %fs and %gs are unused.
+
+	movw	$0x78, %bx		# %ds:%bx is parameter table address
+	movw	%cx, %ds		# %ds = 0
+	ldsw	(%bx), %si		# %ds:%si is source
+	movb	$6, %cl			# copy 12 bytes
+	rep				# don't worry about cld
+	movsw				# already done above
+	movw	%cx, %ds		# %ds = 0
+	movw	%sp, (%bx)		# %sp = 0x4000-12
+	movw	%es, 2(%bx)
+	pushw	%es
+	popw	%ds			# now %ds = %es = %ss = INITSEG
+	movb	$63, 0x4-12(%di)	# patch sector count, %di = 0x4000
+
+	cli
+	cbw				# %ax = 0 : geometry unknown yet
+	xorb	%dh, %dh		# head 0, current drive
+	incw	%cx			# cylinder 0, sector 1
+	movw	%cx, %di		# read 1 sector
+	call	read_first_sector	# read bootsector again to have
+					# access to data segment
+
+#ifndef	DISPLAY_KERNEL_VERSION
+	movw	$msg1, %si
+	call	puts
+#endif
 
-start2:
-	movw	%cs, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-	movw	$0x7c00, %sp
-	sti
-	cld
+# Load the setup-sectors directly after the moved bootblock (at 0x90200).
 
-	movw	$bugger_off_msg, %si
+	movb	setup_sects, %al
+#ifdef CHECK_SETUP_SIZE
+	orb	%al, %al
+	jne	setup_size_ok
+	movb	$SETUPSECTS, %al
+setup_size_ok:	
+#endif
+	cbw
+	xchg	%ax, %di
+	call	read_sectors		# read setup
+
+#ifdef	DISPLAY_KERNEL_VERSION
+#define kernel_version	0xE
+	movw	$0x200,%si
+	addw	kernel_version(%si),%si	# starting protocol 2.00, Kernel 1.3.73
+	call	puts			# show which kernel we are loading
+#endif
 
-msg_loop:
-	lodsb
-	andb	%al, %al
-	jz	die
-	movb	$0xe, %ah
-	movw	$7, %bx
-	int	$0x10
-	jmp	msg_loop
+# 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.
+
+#ifdef __BIG_KERNEL__
+type_of_loader	=	528
+	movw	$24, %cx		# allocate 48 bytes in stack
+init_gdt:
+	push	$0			#   initialized with 0
+	loop	init_gdt
+	movw	%sp, %si		# for bootsect_gdt
+	movw	$0x9300+(SYSSEG/4096), %ax	# source = SYSSEG
+	cwd
+	movw	%ax, 20(%si)		# bootsect_src_base+2
+	movb	$0x10-1, %al		# destination = 0x100000
+	movw	%ax, 28(%si)		# bootsect_dst_base+2
+	movw	%dx, 16(%si)		# bootsect_src = 64Kb
+	movw	%dx, 24(%si)		# bootsect_dst = 64Kb
+	movb	%dl, type_of_loader	# loader type = 0xFF
+syslp:
+	movw	$SYSSEG, %ax
+	movw	%ax, %es
+	movw	$128,%di		# 64Kb in sectors
+	subw	%di, sys_sects
+	pushf
+	jnc	not_last
+	addw	sys_sects, %di
+not_last:
+	call	read_sectors
+	incw	28(%si)			# bootsect_dst_base+2
+	movw	$0x8000, %cx		# full 64K
+	movb	$0x87, %ah
+	push	%ss
+	pop	%es			# gdt in es:si
+	int	$0x15
+	popf
+	ja	syslp
+#else
+	movw	$SYSSEG, %ax
+	movw	%ax, %es
+syslp:
+	movw	$128*32,%ax		# 64Kb in paragraphs
+	subw	%ax, syssize
+	pushf
+	jnc	not_last
+	addw	syssize, %ax
+not_last:
+	movb	$5, %cl			# paragraphs -> sectors
+	shrw	%cl, %ax
+	xchg	%ax, %di
+	call	read_sectors
+	popf
+	ja	syslp
+#endif
 
-die:
-	# Allow the user to press a key, then reboot
-	xorw	%ax, %ax
-	int	$0x16
-	int	$0x19
+# 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.
+
+
+	movw	root_dev, %ax
+	orw	%ax, %ax
+	jnz	root_defined
+
+	movw	$floppy_table,%si
+scan_floppy_table:
+	lodsw
+	cmpb	limits, %ah
+	je	set_root
+	jno	scan_floppy_table
+set_root:
+	movb	$2, %ah
+	addb	%dl, %al		# add current (floppy) drive
+	movw	%ax, root_dev
+root_defined:
+
+#if defined(LOAD_CMDLINE) || defined(EDIT_CMDLINE)
+#define BUFFER	0x7F00
+	movw	$BUFFER, %si
+	movw	%si, (%si)		# default : no cmdline
+#endif
 
-	# int 0x19 should never return.  In case it does anyway,
-	# invoke the BIOS reset code...
-	ljmp	$0xf000,$0xfff0
+#ifdef	LOAD_CMDLINE
+	testb	$0x20,ram_size+1	# bit 11 to 13 where unused
+					# now bit 13 means: load cmdline
+	jz	nocmd
+	movw	$BUFFER/16+INITSEG, %ax
+	movw	%ax, %es
+	movw	$1, %di			# cmdline = 512 bytes max
+	call	read_sectors
+nocmd:
+#endif
 
+#define RSHFT   0x01
+#define LSHFT   0x02
+#define CTRL    0x04
+#define ALT     0x08
+#define SCRLCK  0x10
+#define NUMLCK  0x20
+#define CAPSLCK 0x40
+#define INSERT  0x80
+
+#ifdef	EDIT_CMDLINE
+# The cmdline can be entered and modifed on hot key.
+# Only characters before the cursor are passed to the kernel.
+	movb	$2, %ah			# get keyboard status
+	int	$0x16
+	testb	$RSHFT|LSHFT|CTRL|ALT|CAPSLCK, %al
+	jz	nocmdline
+	pushw	%si
+	call	puts			# set %ah and %bx
+cmdlp:
+# if 1
+	movb	$32, %al		# clear end of line
+	int	$0x10			#  with Space
+	movb	$8, %al			#   and BackSpace
+	int	$0x10
+# endif
+	decw	%si
+cmdget:
+	cbw				# %ah = 0, get keyboard character
+	int	$0x16
+	cmpb	$8, %al			# BackSpace ?
+	je	cmdbs
+	cbw
+	movw	%ax, (%si)		# store end of string too
+	incw	%si
+	incw	%si
+cmdbs:
+	cmpw	$BUFFER, %si		# lower limit is checked
+	je	cmdget			#   but upper limit not
+	call	putc
+	cmpb	$13, %al		# Enter ?
+	jne	cmdlp
+	popw	%si
+nocmdline:
+#endif
 
-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
+#if defined(LOAD_CMDLINE) || defined(EDIT_CMDLINE)
+#if 1
+cmd_line_magic	=	0x20
+cmd_line_offset	=	0x22
+	movw	$0xA33F, cmd_line_magic
+	movw	%si, cmd_line_offset
+#else
+# protocol >= 2.02, starting Kernel 2.4.0-test3-pre3
+cmd_line_ptr	=	0x228
+	movzx	%si, %eax
+	addl	$INITSEG*16, %eax
+	movl	%eax, cmd_line_ptr
+#endif
+emptycmdline:
+#endif
+	
+# 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.
+
+#if 1
+kill_motor:
+	xorw	%ax, %ax		# reset FDC
+	int	$0x13
+#else
+kill_motor:
+	movw	$0x3f2, %dx
+	xorb	%al, %al
+	outb	%al, %dx
+#endif
 
+	call	print_nl
 
-	# Kernel attributes; used by setup
+# After that (everything loaded), we jump to the setup-routine
+# loaded directly after the bootblock:
+# Segments are as follows: %ds = %ss = INITSEG
+
+	ljmp	$SETUPSEG, $0
+
+# read_sectors reads %di sectors into %es:0 buffer.
+# %es:0 is updated to the next memory location.
+# First, sectors are read sector by sector until
+# sector per track count is known. Then they are
+# read track by track.
+# Assume no error on first track.
+
+#define TRACK_BY_TRACK	load as fast as possible !
+#define SHOW_REGS	show int13 status & parameters
+
+check_limits:
+        cmpb    %al, %cl		# max sector known ?
+        ja	next_head		#   no -> store it
+        cmpb    %ah, %dh		# max head known ?
+        ja	next_track		#   no -> store it
+	pusha				# save context
+#ifdef SHOW_REGS
+	pushw	%es			# print %es (named EX)
+	pushw	%dx			# print %dx
+	pushw	%cx			# print %cx
+	xorw	%cx, %cx
+	pushw	%cx			# print %bx
+# ifdef TRACK_BY_TRACK
+	movb	$2, %bh
+# endif
+	pushw	%bx			# print %ax
+	movb	$6,%cl
+	jmp	print_all		# print %bp (status)
+print_loop:
+	movb	$0x6 + 'A' - 1, %al
+	subb	%cl, %al
+	movw	$regs, %si		# caller %si is saved
+	call	putcs			# putc(%al) + puts(%si)
+# it will print out all of the registers.
+	popw	%bp			# load word into %bp
+print_all:
+	pushw	%cx			# save count remaining
+	movb	$4, %cl			# 4 hex digits
+print_digit:
+	rolw	$4, %bp			# rotate to use low 4 bits
+	movb	$0x0f, %al
+	andw	%bp, %ax		# %al = mask for nybble
+	addb	$0x90, %al		# convert %al to ascii hex
+	daa				# in only four instructions!
+	adcb	$0x40, %al
+	daa
+	call	putc			# set %ah and %bx
+	loop	print_digit
+	movb	$0x20, %al		# SPACE
+	int	$0x10
+	popw	%cx
+	loop	print_loop
+	xchg	%ax, %cx		# %ah = 0
+#else
+	cbw				# %ah = 0
+#endif
+        int     $0x13			# reset controler
+	popa				# restore context
+read_sectorslp:
+read_first_sector:
+        pushw   %di			# sector count
+        pushw   %ax			# limits
+        pushw   %dx
+        pushw   %cx
+	xorw	%bx, %bx
+#ifdef TRACK_BY_TRACK
+	subb	%cl, %al		# sectors remaining in track
+	ja	tolastsect
+	movb	$1, %al			# 1 sector mini
+tolastsect:
+	cbw
+	cmpw	%di, %ax
+	jb	more1trk
+	movw	%di, %ax		# sectors to read
+more1trk:
+	push	%ax
+	movb	$2, %ah			# cmd: read chs
+#else
+        movw    $0x201, %ax		# sector by sector
+	push	%ax
+#endif
+        int     $0x13
+	xchg	%ax, %bp		# status
+        popw    %bx			# %ax 
+        popw    %cx
+        popw    %dx
+        popw    %ax			# limits
+        popw    %di			# sector count
+	jc	check_limits
+next_sector:
+#ifdef TRACK_BY_TRACK
+	subw	%bx,%di			# update sector counter
+	addw	%bx,%cx			# next sector
+	shlw	$5,%bx			# sectors -> paragraghs
+	movw	%es, %bp
+	addw	%bx, %bp
+#else
+	decw	%di			# update sector counter
+	incw	%cx			# next sector
+	movw	%es, %bp
+	addw	$32, %bp		# sector size in paragraghs
+#endif
+	movw	%bp, %es		# next location
+        cmpb    %al,%cl			# reach sector limit ?
+        jne     bdendlp
+next_head:
+        movb    %cl,%al
+        incb    %dh			# next head
+        movb    $1,%cl			# first sector
+        cmpb    %ah,%dh			# reach head limit ?
+        jne     bdendlp
+next_track:
+        movb    %dh,%ah
+        movb    $0,%dh			# first head
+# NOTE : support 256 cylinders max
+        incb    %ch			# next cylinder
+bdendlp:
+curdrive =	_start
+curdx	=	_start
+curcx	=	_start+2
+limits	=	_start+4
+	movw	%dx, curdx		# save disk state
+	movw	%cx, curcx
+	movw	%ax, limits
+read_sectors:
+	movw	curdx, %dx		# restore disk state
+	movw	curcx, %cx
+#   al is last sector+1
+#   ah is last head+1
+	movw	limits, %ax
+	orw	%di,%di
+        jne	read_sectorslp
+	movb	$0x2e, %al 		# loading... message 2e = .
+putc:
+	movb	$0xe, %ah
+	movw	$7, %bx			#   one dot each 64k
+ 	int	$0x10
+return:
+	ret
+
+print_nl:
+	
+	movb	$0xd, %al		# CR
+	call	putc
+	movb	$0xa, %al		# LF
+	jmp	putc
+
+puts:
+	call	print_nl		# set %ah and %bx
+putslp:
+	lodsb
+	orb	%al,%al			# end of string is \0
+	jz	return
+putcs:
+	int	$0x10
+	jmp	putslp
 
-	.org 497
+floppy_table:
+#ifdef EXTRA_DEVICES		
+		.byte	16,9			# /dev/fd0u720
+		.byte	12,10			# /dev/fd0u800
+		.byte	80,11			# /dev/fd0u880
+		.byte	125,20			# /dev/fd0u1600
+		.byte	44,21			# /dev/fd0u1680
+		.byte	96,22			# /dev/fd0u1760
+		.byte	116,23			# /dev/fd0u1840
+		.byte	100,24			# /dev/fd0u1920
+		.byte	105,40			# /dev/fd0u3200
+		.byte	109,44			# /dev/fd0u3520
+		.byte	113,48			# /dev/fd0u3840
+#endif		
+		.byte	8,15			# /dev/fd0h1200 - /dev/ps0
+		.byte	28,18			# /dev/fd0u1440 - /dev/PS0
+		.byte	32,36			# /dev/fd0u2880 - /dev/fd0H2880
+		.byte	0,128			# /dev/fd0 - default: autodetect
+
+regs:		.asciz	"X:"
+
+#ifndef	DISPLAY_KERNEL_VERSION
+msg1:		.asciz	"Loading"
+#endif		
+
+tail:
+		.space	495+start-tail		
+
+#.org 495
+sys_sects:	.word SYSSIZE / 32		# size max is now 32Mb
+#.org 497
 setup_sects:	.byte SETUPSECTS
 root_flags:	.word ROOT_RDONLY
-syssize:	.word SYSSIZE
+syssize:	.word SYSSIZE % 0x10000		# size max was 1Mb
 swap_dev:	.word SWAP_DEV
-ram_size:	.word RAMDISK
+ram_size:	.word RAMDISK			# ramdisk size, ramdisk flags and cmdline flag
 vid_mode:	.word SVGA_MODE
 root_dev:	.word ROOT_DEV
 boot_flag:	.word 0xAA55
diff -purN linux-2.6.13/arch/i386/boot/tools/build.c linux-2.6.13-bootblock/arch/i386/boot/tools/build.c
--- linux-2.6.13/arch/i386/boot/tools/build.c	2005-09-12 10:38:52.000000000 +0200
+++ linux-2.6.13-bootblock/arch/i386/boot/tools/build.c	2005-09-12 10:46:25.000000000 +0200
@@ -168,10 +168,13 @@ int main(int argc, char ** argv)
 	}
 	close(fd);
 
-	if (lseek(1, 497, SEEK_SET) != 497)		    /* Write sizes to the bootsector */
+	if (lseek(1, 495, SEEK_SET) != 495)		    /* Write sizes to the bootsector */
 		die("Output: seek failed");
-	buf[0] = setup_sectors;
-	if (write(1, buf, 1) != 1)
+	sz = (sb.st_size + 511) / 512;
+	buf[0] = (sz & 0xff);
+	buf[1] = ((sz >> 8) & 0xff);
+	buf[2] = setup_sectors;
+	if (write(1, buf, 3) != 3)
 		die("Write of setup sector count failed");
 	if (lseek(1, 500, SEEK_SET) != 500)
 		die("Output: seek failed");
diff -purN linux-2.6.13/arch/i386/kernel/setup.c linux-2.6.13-bootblock/arch/i386/kernel/setup.c
--- linux-2.6.13/arch/i386/kernel/setup.c	2005-09-12 10:38:53.000000000 +0200
+++ linux-2.6.13-bootblock/arch/i386/kernel/setup.c	2005-09-12 10:57:01.000000000 +0200
@@ -156,6 +156,7 @@ unsigned long saved_videomode;
 #define RAMDISK_IMAGE_START_MASK  	0x07FF
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_LOAD_FLAG		0x4000	
+#define CMDLINE_LOAD_FLAG		0x2000	
 
 static char command_line[COMMAND_LINE_SIZE];
 
diff -purN linux-2.6.13/arch/x86_64/boot/bootsect.S linux-2.6.13-bootblock/arch/x86_64/boot/bootsect.S
--- linux-2.6.13/arch/x86_64/boot/bootsect.S	2005-09-12 10:37:58.000000000 +0200
+++ linux-2.6.13-bootblock/arch/x86_64/boot/bootsect.S	2005-09-12 10:58:07.000000000 +0200
@@ -4,20 +4,31 @@
  *	modified by Drew Eckhardt
  *	modified by Bruce Evans (bde)
  *	modified by Chris Noe (May 1999) (as86 -> gas)
- *	gutted by H. Peter Anvin (Jan 2003)
+ *
+ *      rewritten to support up to 32Mb kernel, cmdline
+ *      and any disk geometry by <pascal.bellard@ads-lu.com>
  *
  * 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. 
+ *
+ * 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>
 
 SETUPSECTS	= 4			/* default nr of setup-sectors */
 BOOTSEG		= 0x07C0		/* original address of boot-sector */
-INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
+INITSEG		= DEF_INITSEG		/* we load boot here - out of the way */
 SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
 SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
 SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
@@ -25,6 +36,12 @@ SYSSIZE		= DEF_SYSSIZE		/* system size: 
 ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
 SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
 
+/* some extra features */
+#define DISPLAY_KERNEL_VERSION		as soon as possible
+#define	EDIT_CMDLINE			on hotkey
+#define	LOAD_CMDLINE			according to bit ramsize.13
+#define EXTRA_DEVICES			to fill root_device
+
 #ifndef SVGA_MODE
 #define SVGA_MODE ASK_VGA
 #endif
@@ -42,57 +59,470 @@ SWAP_DEV	= 0			/* SWAP_DEV is now writte
 
 .global _start
 _start:
+	cld				# assume nothing
+	movw	$INITSEG, %ax
+	movw	%ax, %es		# %ax = %es = INITSEG
+#if MOVE_BOOTSECTOR
+# First things first. Move ourself from 0x7C00 -> 0x90000 and jump there.
+	movw	$BOOTSEG, %cx
+	movw	%cx, %ds		# %ds = BOOTSEG
+	movb	$1, %ch			# %cx = 256
+	subw	%si, %si
+	subw	%di, %di
+	rep
+	movsw
+	ljmp	$INITSEG, $go
+go:	
+#else
+	xorw	%cx, %cx		# %cx = 0
+#endif
 
-	# Normalize the start address
-	jmpl	$BOOTSEG, $start2
+# 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.
+
+	movw	$0x4000-12, %di		# 0x4000 is an arbitrary value >=
+					# length of bootsect + length of
+					# setup + room for stack;
+					# 12 is disk parm size.
+					# gdt will heat 48 more bytes.
+	movw	%ax, %ss		# %ax and %es already contain INITSEG
+	movw	%di, %sp		# put stack at INITSEG:0x4000-12.
+
+# 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 can set the maximum sector
+# count to 36 - the most we will encounter on an ED 2.88.  
+#
+# High doesn't hurt.  Low does.  Let's use the max: 63
+#
+# Segments are as follows: %es = %ss = INITSEG,
+# %fs and %gs are unused.
+
+	movw	$0x78, %bx		# %ds:%bx is parameter table address
+	movw	%cx, %ds		# %ds = 0
+	ldsw	(%bx), %si		# %ds:%si is source
+	movb	$6, %cl			# copy 12 bytes
+	rep				# don't worry about cld
+	movsw				# already done above
+	movw	%cx, %ds		# %ds = 0
+	movw	%sp, (%bx)		# %sp = 0x4000-12
+	movw	%es, 2(%bx)
+	pushw	%es
+	popw	%ds			# now %ds = %es = %ss = INITSEG
+	movb	$63, 0x4-12(%di)	# patch sector count, %di = 0x4000
+
+	cli
+	cbw				# %ax = 0 : geometry unknown yet
+	xorb	%dh, %dh		# head 0, current drive
+	incw	%cx			# cylinder 0, sector 1
+	movw	%cx, %di		# read 1 sector
+	call	read_first_sector	# read bootsector again to have
+					# access to data segment
+
+#ifndef	DISPLAY_KERNEL_VERSION
+	movw	$msg1, %si
+	call	puts
+#endif
 
-start2:
-	movw	%cs, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-	movw	$0x7c00, %sp
-	sti
-	cld
+# Load the setup-sectors directly after the moved bootblock (at 0x90200).
 
-	movw	$bugger_off_msg, %si
+	movb	setup_sects, %al
+#ifdef CHECK_SETUP_SIZE
+	orb	%al, %al
+	jne	setup_size_ok
+	movb	$SETUPSECTS, %al
+setup_size_ok:	
+#endif
+	cbw
+	xchg	%ax, %di
+	call	read_sectors		# read setup
+
+#ifdef	DISPLAY_KERNEL_VERSION
+#define kernel_version	0xE
+	movw	$0x200,%si
+	addw	kernel_version(%si),%si	# starting protocol 2.00, Kernel 1.3.73
+	call	puts			# show which kernel we are loading
+#endif
 
-msg_loop:
-	lodsb
-	andb	%al, %al
-	jz	die
-	movb	$0xe, %ah
-	movw	$7, %bx
-	int	$0x10
-	jmp	msg_loop
+# 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.
+
+#ifdef __BIG_KERNEL__
+type_of_loader	=	528
+	movw	$24, %cx		# allocate 48 bytes in stack
+init_gdt:
+	push	$0			#   initialized with 0
+	loop	init_gdt
+	movw	%sp, %si		# for bootsect_gdt
+	movw	$0x9300+(SYSSEG/4096), %ax	# source = SYSSEG
+	cwd
+	movw	%ax, 20(%si)		# bootsect_src_base+2
+	movb	$0x10-1, %al		# destination = 0x100000
+	movw	%ax, 28(%si)		# bootsect_dst_base+2
+	movw	%dx, 16(%si)		# bootsect_src = 64Kb
+	movw	%dx, 24(%si)		# bootsect_dst = 64Kb
+	movb	%dl, type_of_loader	# loader type = 0xFF
+syslp:
+	movw	$SYSSEG, %ax
+	movw	%ax, %es
+	movw	$128,%di		# 64Kb in sectors
+	subw	%di, sys_sects
+	pushf
+	jnc	not_last
+	addw	sys_sects, %di
+not_last:
+	call	read_sectors
+	incw	28(%si)			# bootsect_dst_base+2
+	movw	$0x8000, %cx		# full 64K
+	movb	$0x87, %ah
+	push	%ss
+	pop	%es			# gdt in es:si
+	int	$0x15
+	popf
+	ja	syslp
+#else
+	movw	$SYSSEG, %ax
+	movw	%ax, %es
+syslp:
+	movw	$128*32,%ax		# 64Kb in paragraphs
+	subw	%ax, syssize
+	pushf
+	jnc	not_last
+	addw	syssize, %ax
+not_last:
+	movb	$5, %cl			# paragraphs -> sectors
+	shrw	%cl, %ax
+	xchg	%ax, %di
+	call	read_sectors
+	popf
+	ja	syslp
+#endif
 
-die:
-	# Allow the user to press a key, then reboot
-	xorw	%ax, %ax
-	int	$0x16
-	int	$0x19
+# 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.
+
+
+	movw	root_dev, %ax
+	orw	%ax, %ax
+	jnz	root_defined
+
+	movw	$floppy_table,%si
+scan_floppy_table:
+	lodsw
+	cmpb	limits, %ah
+	je	set_root
+	jno	scan_floppy_table
+set_root:
+	movb	$2, %ah
+	addb	%dl, %al		# add current (floppy) drive
+	movw	%ax, root_dev
+root_defined:
+
+#if defined(LOAD_CMDLINE) || defined(EDIT_CMDLINE)
+#define BUFFER	0x7F00
+	movw	$BUFFER, %si
+	movw	%si, (%si)		# default : no cmdline
+#endif
 
-	# int 0x19 should never return.  In case it does anyway,
-	# invoke the BIOS reset code...
-	ljmp	$0xf000,$0xfff0
+#ifdef	LOAD_CMDLINE
+	testb	$0x20,ram_size+1	# bit 11 to 13 where unused
+					# now bit 13 means: load cmdline
+	jz	nocmd
+	movw	$BUFFER/16+INITSEG, %ax
+	movw	%ax, %es
+	movw	$1, %di			# cmdline = 512 bytes max
+	call	read_sectors
+nocmd:
+#endif
 
+#define RSHFT   0x01
+#define LSHFT   0x02
+#define CTRL    0x04
+#define ALT     0x08
+#define SCRLCK  0x10
+#define NUMLCK  0x20
+#define CAPSLCK 0x40
+#define INSERT  0x80
+
+#ifdef	EDIT_CMDLINE
+# The cmdline can be entered and modifed on hot key.
+# Only characters before the cursor are passed to the kernel.
+	movb	$2, %ah			# get keyboard status
+	int	$0x16
+	testb	$RSHFT|LSHFT|CTRL|ALT|CAPSLCK, %al
+	jz	nocmdline
+	pushw	%si
+	call	puts			# set %ah and %bx
+cmdlp:
+# if 1
+	movb	$32, %al		# clear end of line
+	int	$0x10			#  with Space
+	movb	$8, %al			#   and BackSpace
+	int	$0x10
+# endif
+	decw	%si
+cmdget:
+	cbw				# %ah = 0, get keyboard character
+	int	$0x16
+	cmpb	$8, %al			# BackSpace ?
+	je	cmdbs
+	cbw
+	movw	%ax, (%si)		# store end of string too
+	incw	%si
+	incw	%si
+cmdbs:
+	cmpw	$BUFFER, %si		# lower limit is checked
+	je	cmdget			#   but upper limit not
+	call	putc
+	cmpb	$13, %al		# Enter ?
+	jne	cmdlp
+	popw	%si
+nocmdline:
+#endif
 
-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
+#if defined(LOAD_CMDLINE) || defined(EDIT_CMDLINE)
+#if 1
+cmd_line_magic	=	0x20
+cmd_line_offset	=	0x22
+	movw	$0xA33F, cmd_line_magic
+	movw	%si, cmd_line_offset
+#else
+# protocol >= 2.02, starting Kernel 2.4.0-test3-pre3
+cmd_line_ptr	=	0x228
+	movzx	%si, %eax
+	addl	$INITSEG*16, %eax
+	movl	%eax, cmd_line_ptr
+#endif
+emptycmdline:
+#endif
+	
+# 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.
+
+#if 1
+kill_motor:
+	xorw	%ax, %ax		# reset FDC
+	int	$0x13
+#else
+kill_motor:
+	movw	$0x3f2, %dx
+	xorb	%al, %al
+	outb	%al, %dx
+#endif
 
+	call	print_nl
 
-	# Kernel attributes; used by setup
+# After that (everything loaded), we jump to the setup-routine
+# loaded directly after the bootblock:
+# Segments are as follows: %ds = %ss = INITSEG
+
+	ljmp	$SETUPSEG, $0
+
+# read_sectors reads %di sectors into %es:0 buffer.
+# %es:0 is updated to the next memory location.
+# First, sectors are read sector by sector until
+# sector per track count is known. Then they are
+# read track by track.
+# Assume no error on first track.
+
+#define TRACK_BY_TRACK	load as fast as possible !
+#define SHOW_REGS	show int13 status & parameters
+
+check_limits:
+        cmpb    %al, %cl		# max sector known ?
+        ja	next_head		#   no -> store it
+        cmpb    %ah, %dh		# max head known ?
+        ja	next_track		#   no -> store it
+	pusha				# save context
+#ifdef SHOW_REGS
+	pushw	%es			# print %es (named EX)
+	pushw	%dx			# print %dx
+	pushw	%cx			# print %cx
+	xorw	%cx, %cx
+	pushw	%cx			# print %bx
+# ifdef TRACK_BY_TRACK
+	movb	$2, %bh
+# endif
+	pushw	%bx			# print %ax
+	movb	$6,%cl
+	jmp	print_all		# print %bp (status)
+print_loop:
+	movb	$0x6 + 'A' - 1, %al
+	subb	%cl, %al
+	movw	$regs, %si		# caller %si is saved
+	call	putcs			# putc(%al) + puts(%si)
+# it will print out all of the registers.
+	popw	%bp			# load word into %bp
+print_all:
+	pushw	%cx			# save count remaining
+	movb	$4, %cl			# 4 hex digits
+print_digit:
+	rolw	$4, %bp			# rotate to use low 4 bits
+	movb	$0x0f, %al
+	andw	%bp, %ax		# %al = mask for nybble
+	addb	$0x90, %al		# convert %al to ascii hex
+	daa				# in only four instructions!
+	adcb	$0x40, %al
+	daa
+	call	putc			# set %ah and %bx
+	loop	print_digit
+	movb	$0x20, %al		# SPACE
+	int	$0x10
+	popw	%cx
+	loop	print_loop
+	xchg	%ax, %cx		# %ah = 0
+#else
+	cbw				# %ah = 0
+#endif
+        int     $0x13			# reset controler
+	popa				# restore context
+read_sectorslp:
+read_first_sector:
+        pushw   %di			# sector count
+        pushw   %ax			# limits
+        pushw   %dx
+        pushw   %cx
+	xorw	%bx, %bx
+#ifdef TRACK_BY_TRACK
+	subb	%cl, %al		# sectors remaining in track
+	ja	tolastsect
+	movb	$1, %al			# 1 sector mini
+tolastsect:
+	cbw
+	cmpw	%di, %ax
+	jb	more1trk
+	movw	%di, %ax		# sectors to read
+more1trk:
+	push	%ax
+	movb	$2, %ah			# cmd: read chs
+#else
+        movw    $0x201, %ax		# sector by sector
+	push	%ax
+#endif
+        int     $0x13
+	xchg	%ax, %bp		# status
+        popw    %bx			# %ax 
+        popw    %cx
+        popw    %dx
+        popw    %ax			# limits
+        popw    %di			# sector count
+	jc	check_limits
+next_sector:
+#ifdef TRACK_BY_TRACK
+	subw	%bx,%di			# update sector counter
+	addw	%bx,%cx			# next sector
+	shlw	$5,%bx			# sectors -> paragraghs
+	movw	%es, %bp
+	addw	%bx, %bp
+#else
+	decw	%di			# update sector counter
+	incw	%cx			# next sector
+	movw	%es, %bp
+	addw	$32, %bp		# sector size in paragraghs
+#endif
+	movw	%bp, %es		# next location
+        cmpb    %al,%cl			# reach sector limit ?
+        jne     bdendlp
+next_head:
+        movb    %cl,%al
+        incb    %dh			# next head
+        movb    $1,%cl			# first sector
+        cmpb    %ah,%dh			# reach head limit ?
+        jne     bdendlp
+next_track:
+        movb    %dh,%ah
+        movb    $0,%dh			# first head
+# NOTE : support 256 cylinders max
+        incb    %ch			# next cylinder
+bdendlp:
+curdrive =	_start
+curdx	=	_start
+curcx	=	_start+2
+limits	=	_start+4
+	movw	%dx, curdx		# save disk state
+	movw	%cx, curcx
+	movw	%ax, limits
+read_sectors:
+	movw	curdx, %dx		# restore disk state
+	movw	curcx, %cx
+#   al is last sector+1
+#   ah is last head+1
+	movw	limits, %ax
+	orw	%di,%di
+        jne	read_sectorslp
+	movb	$0x2e, %al 		# loading... message 2e = .
+putc:
+	movb	$0xe, %ah
+	movw	$7, %bx			#   one dot each 64k
+ 	int	$0x10
+return:
+	ret
+
+print_nl:
+	
+	movb	$0xd, %al		# CR
+	call	putc
+	movb	$0xa, %al		# LF
+	jmp	putc
+
+puts:
+	call	print_nl		# set %ah and %bx
+putslp:
+	lodsb
+	orb	%al,%al			# end of string is \0
+	jz	return
+putcs:
+	int	$0x10
+	jmp	putslp
 
-	.org 497
+floppy_table:
+#ifdef EXTRA_DEVICES		
+		.byte	16,9			# /dev/fd0u720
+		.byte	12,10			# /dev/fd0u800
+		.byte	80,11			# /dev/fd0u880
+		.byte	125,20			# /dev/fd0u1600
+		.byte	44,21			# /dev/fd0u1680
+		.byte	96,22			# /dev/fd0u1760
+		.byte	116,23			# /dev/fd0u1840
+		.byte	100,24			# /dev/fd0u1920
+		.byte	105,40			# /dev/fd0u3200
+		.byte	109,44			# /dev/fd0u3520
+		.byte	113,48			# /dev/fd0u3840
+#endif		
+		.byte	8,15			# /dev/fd0h1200 - /dev/ps0
+		.byte	28,18			# /dev/fd0u1440 - /dev/PS0
+		.byte	32,36			# /dev/fd0u2880 - /dev/fd0H2880
+		.byte	0,128			# /dev/fd0 - default: autodetect
+
+regs:		.asciz	"X:"
+
+#ifndef	DISPLAY_KERNEL_VERSION
+msg1:		.asciz	"Loading"
+#endif		
+
+tail:
+		.space	495+start-tail		
+
+#.org 495
+sys_sects:	.word SYSSIZE / 32		# size max is now 32Mb
+#.org 497
 setup_sects:	.byte SETUPSECTS
 root_flags:	.word ROOT_RDONLY
-syssize:	.word SYSSIZE
+syssize:	.word SYSSIZE % 0x10000		# size max was 1Mb
 swap_dev:	.word SWAP_DEV
-ram_size:	.word RAMDISK
+ram_size:	.word RAMDISK			# ramdisk size, ramdisk flags and cmdline flag
 vid_mode:	.word SVGA_MODE
 root_dev:	.word ROOT_DEV
 boot_flag:	.word 0xAA55
diff -purN linux-2.6.13/arch/x86_64/boot/tools/build.c linux-2.6.13-bootblock/arch/x86_64/boot/tools/build.c
--- linux-2.6.13/arch/x86_64/boot/tools/build.c	2005-09-12 10:38:57.000000000 +0200
+++ linux-2.6.13-bootblock/arch/x86_64/boot/tools/build.c	2005-09-12 11:00:44.000000000 +0200
@@ -169,10 +169,13 @@ int main(int argc, char ** argv)
 	}
 	close(fd);
 
-	if (lseek(1, 497, SEEK_SET) != 497)		    /* Write sizes to the bootsector */
+	if (lseek(1, 495, SEEK_SET) != 495)		    /* Write sizes to the bootsector */
 		die("Output: seek failed");
-	buf[0] = setup_sectors;
-	if (write(1, buf, 1) != 1)
+	sz = (sb.st_size + 511) / 512;
+	buf[0] = (sz & 0xff);
+	buf[1] = ((sz >> 8) & 0xff);
+	buf[2] = setup_sectors;
+	if (write(1, buf, 3) != 3)
 		die("Write of setup sector count failed");
 	if (lseek(1, 500, SEEK_SET) != 500)
 		die("Output: seek failed");
diff -purN linux-2.6.13/Documentation/i386/boot.txt linux-2.6.13-bootblock/Documentation/i386/boot.txt
--- linux-2.6.13/Documentation/i386/boot.txt	2005-09-12 10:36:50.000000000 +0200
+++ linux-2.6.13-bootblock/Documentation/i386/boot.txt	2005-09-12 12:22:43.000000000 +0200
@@ -103,6 +103,7 @@ The header looks like:
 Offset	Proto	Name		Meaning
 /Size
 
+01EF/2	N/A	sys_sects	DO NOT USE - for bootsect.S use only
 01F1/1	ALL	setup_sects	The size of the setup in sectors
 01F2/2	ALL	root_flags	If set, the root is mounted readonly
 01F4/2	ALL	syssize		DO NOT USE - for bootsect.S use only
diff -purN linux-2.6.13/Documentation/ramdisk.txt linux-2.6.13-bootblock/Documentation/ramdisk.txt
--- linux-2.6.13/Documentation/ramdisk.txt	2005-09-12 10:35:39.000000000 +0200
+++ linux-2.6.13-bootblock/Documentation/ramdisk.txt	2005-09-12 10:55:35.000000000 +0200
@@ -63,12 +63,14 @@ to 2 MB (2^11) of where to find the RAM 
 14 indicates that a RAM disk is to be loaded, and bit 15 indicates whether a
 prompt/wait sequence is to be given before trying to read the RAM disk. Since
 the RAM disk dynamically grows as data is being written into it, a size field
-is not required. Bits 11 to 13 are not currently used and may as well be zero.
+is not required. Bit 13 indicates that a cmdline is to be loaded by the kernel
+bootblock, Bits 11 to 12 are not currently used and may as well be zero.
 These numbers are no magical secrets, as seen below:
 
 ./arch/i386/kernel/setup.c:#define RAMDISK_IMAGE_START_MASK     0x07FF
 ./arch/i386/kernel/setup.c:#define RAMDISK_PROMPT_FLAG          0x8000
 ./arch/i386/kernel/setup.c:#define RAMDISK_LOAD_FLAG            0x4000
+./arch/i386/kernel/setup.c:#define CMDLINE_LOAD_FLAG            0x2000
 
 Consider a typical two floppy disk setup, where you will have the 
 kernel on disk one, and have already put a RAM disk image onto disk #2.
@@ -159,6 +161,8 @@ users may wish to combine steps (d) and 
 Changelog:
 ----------
 
+09-05 :		Reserve CMDLINE_LOAD bit.
+
 10-22-04 :	Updated to reflect changes in command line options, remove
 		obsolete references, general cleanup.
 		James Nelson (james4765@gmail.com)

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-13 19:04 ` Frank Sorenson
@ 2005-09-13 19:42   ` H. Peter Anvin
  2005-09-14  9:42     ` Pascal Bellard
  2005-09-14  9:52   ` Pascal Bellard
  1 sibling, 1 reply; 12+ messages in thread
From: H. Peter Anvin @ 2005-09-13 19:42 UTC (permalink / raw)
  To: Frank Sorenson; +Cc: pascal.bellard, Riley, Linux-Kernel

Frank Sorenson wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Pascal Bellard wrote:
> 
>>Hello,
>>
>>Please find attached a patch to build i386/x86_64 kernel directly
>>bootable. It may be usefull for rescue floppies and installation
>>floppies.
> 
> 
> Pascal,
> 
> In commit f8eeaaf4180334a8e5c3582fe62a5f8176a8c124, build.c has already
> changed, and I don't believe it's very compatible with this change.
> 
> See
> http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f8eeaaf4180334a8e5c3582fe62a5f8176a8c124
> 
> Also, we'll need to see comments from H. Peter Anvin on this patch.
> CC'ing him.
> 

Geometry detection by looking for error returns is fundamentally broken. 
  Way too many non-traditional floppies (USB, IDE...) do not handle this 
at all, they will return successfully, with the data being the data from 
a sector from another track, and thus you end up with aliasing and a 
corrupt boot.  You can do it with fingerprinting, but that's complex and 
error-prone.

In short, this made sense in 1991, but it hasn't made sense for a very 
long time now.  Resurrecting bootsect.S is *NOT* a good idea.

	-hpa

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-13 19:42   ` H. Peter Anvin
@ 2005-09-14  9:42     ` Pascal Bellard
  2005-09-14  9:55       ` Martin Mares
                         ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Pascal Bellard @ 2005-09-14  9:42 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Frank Sorenson, pascal.bellard, riley, linux-kernel

> Frank Sorenson wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Pascal Bellard wrote:
>>
>>>Hello,
>>>
>>>Please find attached a patch to build i386/x86_64 kernel directly
>>>bootable. It may be usefull for rescue floppies and installation
>>>floppies.
>>
>>
>> Pascal,
>>
>> In commit f8eeaaf4180334a8e5c3582fe62a5f8176a8c124, build.c has already
>> changed, and I don't believe it's very compatible with this change.
>>
>> See
>> http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f8eeaaf4180334a8e5c3582fe62a5f8176a8c124
>>
>> Also, we'll need to see comments from H. Peter Anvin on this patch.
>> CC'ing him.
>>
>
> Geometry detection by looking for error returns is fundamentally broken.
>   Way too many non-traditional floppies (USB, IDE...) do not handle this
> at all, they will return successfully, with the data being the data from
> a sector from another track, and thus you end up with aliasing and a
> corrupt boot.  You can do it with fingerprinting, but that's complex and
> error-prone.
>
The bootblock code is 497 bytes long. It must as simple as possible.
Complex algorithms like fingerprinting can't be used.

Geometry detection works with usual floppies. This patch goal is to
support them like < 2.6 bootblocks did and fix 1M limitation and
special formatting like 1.68M floppies.

Geometry detection may work with non-traditional floppies but is not
designed to.

BTW, if this kind of floppies doesn't handle error, it's a bug in the
firmware, but not in bootblock code !

> In short, this made sense in 1991, but it hasn't made sense for a very
> long time now.  Resurrecting bootsect.S is *NOT* a good idea.
>
1.44M floppies are told dead for more than 10 years. In 2005 most of
computers are sold with these drives. Sometime I have to boot with
a floppy when nothing works (blush).

Kernel code is always growing. The bootblock spares filesystem and
external kernel loader overhead.

While linux kernel has a floppy driver the bootblock is usefull.

Now two solutions:

- without this patch = linux kernel are never directly bootable
- with this patch = linux kernel is directly bootable with some
  devices.

What is the better idea ?

-pascal

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-13 19:04 ` Frank Sorenson
  2005-09-13 19:42   ` H. Peter Anvin
@ 2005-09-14  9:52   ` Pascal Bellard
  1 sibling, 0 replies; 12+ messages in thread
From: Pascal Bellard @ 2005-09-14  9:52 UTC (permalink / raw)
  To: Frank Sorenson; +Cc: riley, linux-kernel, H. Peter Anvin

[-- Attachment #1: Type: text/plain, Size: 672 bytes --]

Frank,

I have built a new patch based on linux-2.6.13-git12 to avoid build.c
conflict.

Regards,

-pascal

> Pascal Bellard wrote:
>> Hello,
>>
>> Please find attached a patch to build i386/x86_64 kernel directly
>> bootable. It may be usefull for rescue floppies and installation
>> floppies.
>
> Pascal,
>
> In commit f8eeaaf4180334a8e5c3582fe62a5f8176a8c124, build.c has already
> changed, and I don't believe it's very compatible with this change.
>
> See
> http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f8eeaaf4180334a8e5c3582fe62a5f8176a8c124
>
> Also, we'll need to see comments from H. Peter Anvin on this patch.
> CC'ing him.



[-- Attachment #2: linux-2_6_13-git12-bootblock_u.DEFANGED-14 --]
[-- Type: application/DEFANGED-14, Size: 32124 bytes --]

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-14  9:42     ` Pascal Bellard
@ 2005-09-14  9:55       ` Martin Mares
  2005-09-14 16:38       ` H. Peter Anvin
  2005-09-17 15:26       ` Giuseppe Bilotta
  2 siblings, 0 replies; 12+ messages in thread
From: Martin Mares @ 2005-09-14  9:55 UTC (permalink / raw)
  To: Pascal Bellard; +Cc: H. Peter Anvin, Frank Sorenson, riley, linux-kernel

Hello!

> Now two solutions:
> 
> - without this patch = linux kernel are never directly bootable
> - with this patch = linux kernel is directly bootable with some
>   devices.
> 
> What is the better idea ?

The first, as long as nobody really needs direct booting. Code bloat.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
The first myth of management is that it exists.

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-14  9:42     ` Pascal Bellard
  2005-09-14  9:55       ` Martin Mares
@ 2005-09-14 16:38       ` H. Peter Anvin
  2005-09-17 15:26       ` Giuseppe Bilotta
  2 siblings, 0 replies; 12+ messages in thread
From: H. Peter Anvin @ 2005-09-14 16:38 UTC (permalink / raw)
  To: pascal.bellard; +Cc: Frank Sorenson, riley, linux-kernel

Pascal Bellard wrote:
> 
> Now two solutions:
> 
> - without this patch = linux kernel are never directly bootable
> - with this patch = linux kernel is directly bootable with some
>   devices.
> 
> What is the better idea ?
> 

The former, based on the *huge* number of emails of "it doesn't work on 
my platform" we kept getting, and getting, and getting.

It would be another matter if it was a high-value feature, but it's not.

	-hpa

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-14  9:42     ` Pascal Bellard
  2005-09-14  9:55       ` Martin Mares
  2005-09-14 16:38       ` H. Peter Anvin
@ 2005-09-17 15:26       ` Giuseppe Bilotta
  2005-09-17 15:56         ` Jesper Juhl
  2 siblings, 1 reply; 12+ messages in thread
From: Giuseppe Bilotta @ 2005-09-17 15:26 UTC (permalink / raw)
  To: linux-kernel

On Wed, 14 Sep 2005 11:42:12 +0200 (CEST), Pascal Bellard wrote:

> The bootblock code is 497 bytes long. It must as simple as possible.
> Complex algorithms like fingerprinting can't be used.
> 
> Geometry detection works with usual floppies. This patch goal is to
> support them like < 2.6 bootblocks did and fix 1M limitation and
> special formatting like 1.68M floppies.
> 
> Geometry detection may work with non-traditional floppies but is not
> designed to.

This is probably a stupid suggestion, but here it goes anyway: the
kernel has to be written on disk by something, right?

So if the "something" knows (or can get to know) the sector/tracks
layout of the disk it's writing the kernel onto, it could store this
information in the bootblock (is there space for that?). The bootblock
code would then just read this info and use it.

Of course, this would mean that making a kernel-bootable floppy
wouldn't be as simple as cp'ing the kernel image to /dev/fdwhatever,
but if a script/program designed to do this was included with the
kernel source (it wouldn't be too big ...) ...

-- 
Giuseppe "Oblomov" Bilotta

"Da grande lotterò per la pace"
"A me me la compra il mio babbo"
(Altan)
("When I grow up, I will fight for peace"
 "I'll have my daddy buy it for me")


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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-17 15:26       ` Giuseppe Bilotta
@ 2005-09-17 15:56         ` Jesper Juhl
  2005-09-17 16:19           ` Giuseppe Bilotta
  0 siblings, 1 reply; 12+ messages in thread
From: Jesper Juhl @ 2005-09-17 15:56 UTC (permalink / raw)
  To: Giuseppe Bilotta; +Cc: linux-kernel

On 9/17/05, Giuseppe Bilotta <bilotta78@hotpop.com> wrote:
> On Wed, 14 Sep 2005 11:42:12 +0200 (CEST), Pascal Bellard wrote:
> 
> > The bootblock code is 497 bytes long. It must as simple as possible.
> > Complex algorithms like fingerprinting can't be used.
> >
> > Geometry detection works with usual floppies. This patch goal is to
> > support them like < 2.6 bootblocks did and fix 1M limitation and
> > special formatting like 1.68M floppies.
> >
> > Geometry detection may work with non-traditional floppies but is not
> > designed to.
> 
> This is probably a stupid suggestion, but here it goes anyway: the
> kernel has to be written on disk by something, right?
> 
> So if the "something" knows (or can get to know) the sector/tracks
> layout of the disk it's writing the kernel onto, it could store this
> information in the bootblock (is there space for that?). The bootblock
> code would then just read this info and use it.
> 
> Of course, this would mean that making a kernel-bootable floppy
> wouldn't be as simple as cp'ing the kernel image to /dev/fdwhatever,
> but if a script/program designed to do this was included with the
> kernel source (it wouldn't be too big ...) ...
> 
I may be missing something here, but if you are going to do something
like that, then why not just use a real bootloader instead?

-- 
Jesper Juhl <jesper.juhl@gmail.com>
Don't top-post  http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please      http://www.expita.com/nomime.html

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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-17 15:56         ` Jesper Juhl
@ 2005-09-17 16:19           ` Giuseppe Bilotta
  2005-09-19  2:13             ` Coywolf Qi Hunt
  0 siblings, 1 reply; 12+ messages in thread
From: Giuseppe Bilotta @ 2005-09-17 16:19 UTC (permalink / raw)
  To: linux-kernel

On Sat, 17 Sep 2005 17:56:08 +0200, Jesper Juhl wrote:

>> This is probably a stupid suggestion, but here it goes anyway: the
>> kernel has to be written on disk by something, right?
>> 
>> So if the "something" knows (or can get to know) the sector/tracks
>> layout of the disk it's writing the kernel onto, it could store this
>> information in the bootblock (is there space for that?). The bootblock
>> code would then just read this info and use it.
>> 
>> Of course, this would mean that making a kernel-bootable floppy
>> wouldn't be as simple as cp'ing the kernel image to /dev/fdwhatever,
>> but if a script/program designed to do this was included with the
>> kernel source (it wouldn't be too big ...) ...
>> 
> I may be missing something here, but if you are going to do something
> like that, then why not just use a real bootloader instead?

I'm not too much into this stuff, I don't even know the technical 
differences betwen booting from kernel-on-floppy or from a bootloader. 
My proposal was just to work around the "what's the track layout" 
issue in the kernel-on-floppy direct boot. Maybe you could see it like 
a delayed bootloader process ... don't know.

But as I mentioned, it was probably just a stupid suggestion :)

-- 
Giuseppe "Oblomov" Bilotta

Axiom I of the Giuseppe Bilotta
theory of IT:
Anything is better than MS


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

* Re: [i386 BOOT CODE] kernel bootable again
  2005-09-17 16:19           ` Giuseppe Bilotta
@ 2005-09-19  2:13             ` Coywolf Qi Hunt
  0 siblings, 0 replies; 12+ messages in thread
From: Coywolf Qi Hunt @ 2005-09-19  2:13 UTC (permalink / raw)
  To: Giuseppe Bilotta; +Cc: linux-kernel

On 9/18/05, Giuseppe Bilotta <bilotta78@hotpop.com> wrote:
> On Sat, 17 Sep 2005 17:56:08 +0200, Jesper Juhl wrote:
> 
> >> This is probably a stupid suggestion, but here it goes anyway: the
> >> kernel has to be written on disk by something, right?
> >>
> >> So if the "something" knows (or can get to know) the sector/tracks
> >> layout of the disk it's writing the kernel onto, it could store this
> >> information in the bootblock (is there space for that?). The bootblock
> >> code would then just read this info and use it.
> >>
> >> Of course, this would mean that making a kernel-bootable floppy
> >> wouldn't be as simple as cp'ing the kernel image to /dev/fdwhatever,
> >> but if a script/program designed to do this was included with the
> >> kernel source (it wouldn't be too big ...) ...
> >>
> > I may be missing something here, but if you are going to do something
> > like that, then why not just use a real bootloader instead?
> 
> I'm not too much into this stuff, I don't even know the technical
> differences betwen booting from kernel-on-floppy or from a bootloader.
> My proposal was just to work around the "what's the track layout"
> issue in the kernel-on-floppy direct boot. Maybe you could see it like

Actually, DOS/Windows works that way. FAT filesystem stores the number
of sectors per track in its boot sector.

> a delayed bootloader process ... don't know.
> 
> But as I mentioned, it was probably just a stupid suggestion :)

You are too humble. It's not you, but linux bootsect.S stupid IMHO. ;)
-- 
Coywolf Qi Hunt
http://sosdg.org/~coywolf/

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

* Re: [i386 BOOT CODE] kernel bootable again
@ 2005-09-20 17:13 Etienne Lorrain
  0 siblings, 0 replies; 12+ messages in thread
From: Etienne Lorrain @ 2005-09-20 17:13 UTC (permalink / raw)
  To: linux-kernel

>>>> So if the "something" knows (or can get to know) the sector/tracks
>>>> layout of the disk it's writing the kernel onto, it could store this
>>>> information in the bootblock (is there space for that?). The bootblock
>>>> code would then just read this info and use it.
>
> Actually, DOS/Windows works that way. FAT filesystem stores the number
> of sectors per track in its boot sector.

  Gujin installer creates the filesystem (and the partition table if
 needed), the MBR with the disk geometry, and chain a simple bootloader
 or a menu based bootloader on the created FAT filesystem when told to
 do so.

  So if you just want to put a kernel and initrd on a floppy, and the
 floppy is big enough, you just do:
$ mkdir tmp
$ cd tmp
$ wget http://heanet.dl.sourceforge.net/sourceforge/gujin/install-1.2.tar.gz
$ tar xvzf install-1.2.tar.gz
$ ./instboot tiny.bin /dev/fd0
$ mcopy /boot/vmlinuz-2.6.13 a:
$ mcopy /boot/initrd-2.6.13 a:
  And you reboot with the floppy still inside the drive.

  If you want to put them on your USB thumb drive, and your PC can
 boot USB flash drives as a floppy (lot of BIOS bugs there), you
 just change the line (double check that your USB key is /dev/sda):
$ ./instboot tiny.bin /dev/fd0
  by:
$ ./instboot tiny.bin /dev/sda --disk=BIOS:0x00 --geometry=/dev/sda

  I personnally better like a partition table on my USB drives, so
 I am more used to erase manually the partition table:
$ dd if=/dev/null of=/dev/sda bs=512 count=64 # blank the head of the disk
 and then type:
$ ./instboot boot.bin /dev/sda --disk=BIOS:0x00 --geometry=/dev/sda \
     --mbr-device=/dev/sda --partition_index=1

  When booted from this key, the PC will boot the kernel named vmlinuz*
 and load the initrd/initramfs named initrd* (tiny.bin does not contain
 the graphic menu management).

  I will not say that I tested it lately, but you may also want to put
 your kernel and initrd on a bootable CDROM - without having the usual
 Gujin menu - then you just do:
$ mkdir tmpdir
$ cp /boot/vmlinuz-2.6.13 tmpdir
$ cp /boot/initrd-2.6.13 tmpdir
$ ./instboot tiny.bin tmpdir/tiny.bcd
$ mkisofs -untranslated-filenames -no-emul-boot -boot-load-size 4 \
    -b tiny.bcd tmpdir -o boot.iso
$ cdrecord boot.iso

  It is usually better (and will work for all those configuration)
 to put the kernel and its initrd inside a directory named "/boot",
 but I am highjicking a thread so want to keep it simple...

  Etienne.


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

end of thread, other threads:[~2005-09-20 17:13 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-13 13:46 [i386 BOOT CODE] kernel bootable again Pascal Bellard
2005-09-13 19:04 ` Frank Sorenson
2005-09-13 19:42   ` H. Peter Anvin
2005-09-14  9:42     ` Pascal Bellard
2005-09-14  9:55       ` Martin Mares
2005-09-14 16:38       ` H. Peter Anvin
2005-09-17 15:26       ` Giuseppe Bilotta
2005-09-17 15:56         ` Jesper Juhl
2005-09-17 16:19           ` Giuseppe Bilotta
2005-09-19  2:13             ` Coywolf Qi Hunt
2005-09-14  9:52   ` Pascal Bellard
  -- strict thread matches above, loose matches on Subject: below --
2005-09-20 17:13 Etienne Lorrain

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