The kernel command line always lives at 9xxxxh, as idiotic as that is.
authorhpa <hpa>
Thu, 22 Jun 2000 21:43:23 +0000 (21:43 +0000)
committerhpa <hpa>
Thu, 22 Jun 2000 21:43:23 +0000 (21:43 +0000)
Makefile
ldlinux.asm
mbr.asm [new file with mode: 0644]

index d146907..41f664e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,8 +33,8 @@ VERSION = $(shell cat version)
 # want to recompile the installers (ITARGET).
 #
 SOURCES = ldlinux.asm syslinux.asm syslinux.c copybs.asm \
-         pxelinux.asm pxe.inc
-BTARGET = bootsect.bin ldlinux.sys ldlinux.bin ldlinux.lst pxelinux.bin
+         pxelinux.asm pxe.inc mbr.asm
+BTARGET = bootsect.bin ldlinux.sys ldlinux.bin ldlinux.lst pxelinux.bin mbr.bin
 ITARGET = syslinux.com syslinux copybs.com
 DOCS    = COPYING NEWS README TODO *.doc
 OTHER   = Makefile bin2c.pl now.pl genstupid.pl keytab-lilo.pl version \
@@ -69,6 +69,9 @@ bootsect.bin: ldlinux.bin
 ldlinux.sys: ldlinux.bin
        dd if=ldlinux.bin of=ldlinux.sys  bs=512 skip=1
 
+mbr.bin: mbr.asm
+       $(NASM) -f bin -l mbr.lst -o mbr.bin mbr.asm
+
 syslinux.com: syslinux.asm bootsect.bin ldlinux.sys stupid.inc
        $(NASM) -f bin -l syslinux.lst -o syslinux.com syslinux.asm
 
index 41c31ec..917102e 100644 (file)
@@ -40,7 +40,7 @@ BAUD_DIVISOR  equ 115200              ; Serial port parameter
 ;
 %define        version_str     VERSION         ; Must be 4 characters long!
 %define date           DATE_STR        ; Defined from the Makefile
-%define        year            '1999'
+%define        year            '2000'
 ;
 ; Debgging stuff
 ;
@@ -105,9 +105,15 @@ setup_entry        equ $
                endstruc
 
 ;
+; Kernel command line signature
+;
+CMD_MAGIC      equ 0A33Fh              ; Command line magic
+
+;
 ; Magic number of su_header field
 ;
 HEADER_ID       equ 'HdrS'             ; HdrS (in littleendian hex)
+
 ;
 ; Flags for the su_loadflags field
 ;
@@ -1844,8 +1850,6 @@ got_highmem:
 ;
 ; Construct the command line (append options have already been copied)
 ;
-               mov word [es:kern_cmd_magic],0A33Fh     ; Command line magic no
-               mov word [es:kern_cmd_offset],cmd_line_here
                mov di,[CmdLinePtr]
                 mov si,boot_image              ; BOOT_IMAGE=
                 mov cx,boot_image_len
@@ -2087,9 +2091,31 @@ high_load_done:
 ; and the real mode stuff to 90000h.  We assume that all bzImage kernels are
 ; capable of starting their setup from a different address.
 ;
-               test byte [LoadFlags],LOAD_HIGH
                mov bx,real_mode_seg            ; Real mode segment
+;
+; Copy command line.  Unfortunately, the kernel boot protocol requires
+; the command line to exist in the 9xxxxh range even if the rest of the
+; setup doesn't.
+;
+               mov fs,bx                       ; FS -> real_mode_seg
+               mov ax,9000h
+               mov es,ax
+               mov si,cmd_line_here
+               mov di,si
+               mov [fs:kern_cmd_magic],word CMD_MAGIC ; Store magic
+               mov [fs:kern_cmd_offset],di     ; Store pointer
+
+               mov cx,[CmdLineLen]
+               add cx,byte 3
+               shr cx,2                        ; Convert to dwords
+               fs rep movsd
+
+               test byte [LoadFlags],LOAD_HIGH
+               ; Note bx -> real_mode_seg still
                jnz in_proper_place             ; If high load, we're done
+
+;
+; Loading low; we can't assume it's safe to run in place.
 ;
 ; Copy real_mode stuff up to 90000h
 ;
@@ -2104,12 +2130,6 @@ high_load_done:
                xor si,si
                xor di,di
                fs rep movsd                    ; Copy setup + boot sector
-               mov si,cmd_line_here
-               mov di,si
-               mov cx,[CmdLineLen]
-               add cx,byte 3
-               shr cx,2                        ; Convert to dwords
-               fs rep movsd
 ;
 ; Some kernels in the 1.2 ballpark but pre-bzImage have more than 4
 ; setup sectors, but the boot protocol had not yet been defined.  They
@@ -2126,7 +2146,7 @@ high_load_done:
                shl cx,7                        ; Sectors -> dwords
                xor eax,eax
                rep stosd                       ; Clear region
-
+;
                mov ecx,[KernelSize]
                add ecx,3                       ; Round upwards
                shr ecx,2                       ; Bytes -> dwords
diff --git a/mbr.asm b/mbr.asm
new file mode 100644 (file)
index 0000000..f3247cb
--- /dev/null
+++ b/mbr.asm
@@ -0,0 +1,208 @@
+; -*- fundamental -*- (asm-mode sucks)
+; $Id$
+; -----------------------------------------------------------------------
+;   
+;   Copyright 2000 H. Peter Anvin - All Rights Reserved
+;
+;   This program is free software; you can redistribute it and/or modify
+;   it under the terms of the GNU General Public License as published by
+;   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+;   USA; either version 2 of the License, or (at your option) any later
+;   version; incorporated herein by reference.
+;
+; -----------------------------------------------------------------------
+
+;
+; mbr.asm
+;
+; Simple Master Boot Record, including support for EBIOS extensions.
+;
+; The MBR lives in front of the boot sector, and is responsible for
+; loading the boot sector of the active partition.  The EBIOS support is needed
+; if the active partition starts beyond cylinder 1024.
+;
+; This MBR determines all geometry info at runtime.  It uses only the linear
+; block field in the partition table.  It does, however, pass the partition table
+; information unchanged to the target OS.
+;
+; This MBR should be "8086-clean", i.e. not require a 386.
+;
+
+;
+; Note: The MBR is actually loaded at 0:7C00h, but we quickly move it down to
+; 0600h.
+;
+
+               org 0600h
+_start:                cli
+               xor ax,ax
+               mov ds,ax
+               mov es,ax
+               mov ss,ax
+               mov sp,7C00h
+               sti
+               cld
+               mov si,sp               ; Start address
+               mov di,0600h            ; Destination address
+               mov cx,512/2
+               rep movsw
+
+;
+; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h.
+; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same
+; thing, use a far jump to canonicalize the address.
+;
+
+               jmp 0:next              ; Jump to copy at 0600h
+                               
+next:
+               mov [DriveNo], dl               ; Drive number stored in DL
+;
+; Check for CHS parameters.  This doesn't work on floppy disks,
+; but for an MBR we don't care.
+;
+               mov ah,08h                      ; Get drive parameters
+               int 13h
+               mov [Heads],dh
+               mov dh,cl
+               and dh,3Fh                      ; Max sector number
+               dec dh                          ; Sector count
+               mov [Sectors],dh
+               mov dx,cx
+               xchg dh,dl
+               mov cl,6
+               shr dh,cl
+               mov [Cylinders],dx
+
+;
+; Now look for one (and only one) active partition.
+;
+               mov si,PartitionTable
+               xor ax,ax
+               mov cx,4
+checkpartloop:
+               test byte [si],80h
+               jz .notactive
+               inc ax
+               mov di,si
+.notactive:    add si,byte 16
+               loop checkpartloop
+
+               cmp ax,byte 1                   ; Better be only one
+               jnz not_one_partition
+
+;
+; Now we have the active partition partition information in DS:DI.
+; Check to see if we support EBIOS.
+;
+               mov dl,[DriveNo]
+               mov ax,4100h
+               mov bx,055AAh
+               xor cx,cx
+               xor dh,dh
+               stc
+               int 13h
+               jc no_ebios
+               cmp bx,0AA55h
+               jne no_ebios
+               test cl,1                       ; LBA device access
+               jz no_ebios
+;
+; We have EBIOS.  Load the boot sector using LBA.
+;
+               push di
+               mov si,dapa
+               mov bx,[di+8]                   ; Copy the block address
+               mov [si+8],bx
+               mov bx,[di+10]
+               mov [si+10],bx
+               mov dl,[DriveNo]
+               mov ah,42h                      ; Extended Read
+               jmp short common_tail
+;
+; No EBIOS.  Load the boot sector using CHS.
+;
+no_ebios:
+               push di
+               mov ax,[di+8]
+               mov dx,[di+10]
+               div word [Sectors]
+               inc dx
+               mov cx,dx                       ; Sector #
+               xor dx,dx
+               div word [Heads]
+               ; DX = head #, AX = cylinder #
+               mov ch,al
+               shr ax,1
+               shr ax,1
+               and al,0C0h
+               or cl,al
+               mov dh,dl                       ; Head #
+               mov dl,[DriveNo]
+               mov bx,7C00h
+               mov ah,02h                      ; Read
+common_tail:
+               int 13h
+               jc disk_error
+               pop di
+;
+; Verify that we have a boot sector, jump
+;
+               test word [7C00h+510],0AA55h
+               jne missing_os
+               cli
+               jmp 7C00h                       ; Jump to boot sector
+
+not_one_partition:
+               ja too_many_os
+missing_os:
+               mov si,missing_os_msg
+               jmp short die
+too_many_os:
+disk_error:
+               mov si,bad_disk_msg
+die:
+.msgloop:
+               lodsb
+               xor al,al
+               jz .now
+               mov ah,0Eh                      ; TTY output
+               mov bx,0007h
+               int 10h
+               jmp short .msgloop
+.now:
+               jmp short .now
+
+               align 4, db 0                   ; Begin data area
+
+;
+; EBIOS disk address packet
+;
+dapa:
+               dw 16                           ; Packet size
+.count:                dw 1                            ; Block count
+.off:          dw 7C00h                        ; Offset of buffer
+.seg:          dw 0                            ; Segment of buffer
+.lba:          dd 0                            ; LBA (LSW)
+               dd 0                            ; LBA (MSW)
+
+; CHS information
+Heads:         dw 0
+Sectors:       dw 0
+Cylinders:     dw 0
+
+; Error messages
+missing_os_msg db 'Missing operating system', 13, 10, 0
+bad_disk_msg   db 'Operating system loading error', 13, 10, 0
+
+;
+; Total MBR size: 446 bytes
+; (End-of-boot-sector signature also needed.)
+;
+               times 446-($-$$) db 0
+PartitionTable equ $                           ; Start of partition table
+
+;
+; BSS data; put at 800h
+;
+DriveNo                equ 0800h