* [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