aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2000-06-22 21:43:23 +0000
committerhpa <hpa>2000-06-22 21:43:23 +0000
commitc8d71835d79232560d2bd056c607ecf3a6c0028c (patch)
tree7cdbf2749dc58b0cf119f0f65a4a13eca6a08913
parent11e5a33d234e0195abec35cfb0e00ea26e7a7320 (diff)
downloadsyslinux-c8d71835d79232560d2bd056c607ecf3a6c0028c.tar.gz
syslinux-c8d71835d79232560d2bd056c607ecf3a6c0028c.tar.xz
syslinux-c8d71835d79232560d2bd056c607ecf3a6c0028c.zip
The kernel command line always lives at 9xxxxh, as idiotic as that is.
-rw-r--r--Makefile7
-rw-r--r--ldlinux.asm42
-rw-r--r--mbr.asm208
3 files changed, 244 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index d1469073..41f664e5 100644
--- 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
diff --git a/ldlinux.asm b/ldlinux.asm
index 41c31ec6..917102e8 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -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
index 00000000..f3247cbb
--- /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