Created
March 28, 2014 20:44
-
-
Save iori-yja/9842600 to your computer and use it in GitHub Desktop.
first.S code from LILO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if 0 | |
; first.S - LILO first stage boot loader with LBA32 support */ | |
Copyright 1992-1998 Werner Almesberger. | |
Copyright 1999-2001 John Coffman. | |
All rights reserved. | |
Licensed under the terms contained in the file 'COPYING' in the | |
source directory. | |
#endif | |
#define JRC_NOCOMPACT | |
#define DELL_DIRTY_HACK | |
#define LILO_ASM | |
#include "lilo.h" | |
get common.s /* as86 "include" will bypass the CPP */ | |
.text | |
.globl _main | |
.org 0 | |
_main: | |
zero: | |
cli | |
call start | |
reloc: .word theend-zero ! size of the code & params | |
.org 6 | |
! Boot device parameters. They are set by the installer. | |
.ascii "LILO" | |
.word STAGE_FIRST | |
.word VERSION | |
#if 0 | |
.blkb BPB_OFFSET_asm | |
main2: cli ! NT 4 blows up if this is missing | |
jmpi start,BOOTSEG | |
#endif | |
port: .byte 0 ! COM port (0 = unused, 1 = COM1, etc.) | |
sparam: .byte 0 ! serial port parameters (0 = unused) | |
raid: .long 0 ! raid sector offset | |
tstamp: .long 0 ! timestamp | |
timeout:.word 0 ! input timeout | |
delay: .word 0 ! boot delay | |
ms_len: .word 0 ! initial greeting message | |
ms_cx: .word 0 | |
ms_dx: .word 0 | |
ms_al: .byte 0 ! (unused) | |
d1_cx: .word 0 ! first descriptor sector address | |
d1_dx: .word 0 | |
d1_al: .byte 0 ! (unused) | |
d2_addr: .blkb MAX_DESCR_SECS_asm*sa_size - sa_size | |
dc_cx: .word 0 ! default command-line sector address | |
dc_dx: .word 0 | |
dc_al: .byte 0 ! (unused) | |
prompt: .byte 0 ! indicates whether to always enter prompt | |
! (also used as alignment byte) | |
kt_cx: .word 0 ! keyboard translation table | |
kt_dx: .word 0 | |
kt_al: .byte 0 | |
d_addr: .word 0 ! second stage sector map of addresses | |
.word 0 | |
.byte 0 | |
.word 0,0 ! terminate the chain | |
;;; .org CODE_START_1 | |
#if 0 | |
! These locations are referenced as EX_OFF and must be at CODE_START_1 | |
ext_si: .word 0 ! external interface | |
ext_es: .word 0 ! these locations are referenced in second.S | |
ext_bx: .word 0 ! do not disturb the ordering | |
ext_dl: .byte 0 ! second.S will check this magic number | |
ext_dh: .byte 0 ! not referenced, but must align stack | |
ext_stack: | |
#endif | |
start: | |
#if 1 | |
pop di ! get reloc source from old stack | |
;;; lea bp,(di+display-reloc) | |
mov ax,cs | |
shr di,#4 ! make into paragraph offset | |
#else | |
pop ax ! get reloc source from old stack | |
mov di,cs | |
shr ax,#4 ! make into paragraph offset | |
#endif | |
add ax,di ! relocate the segment | |
mov ss,ax | |
mov sp,#SETUP_STACKSIZE ! set the stack for First Stage | |
sti ! now it is safe | |
push dx ! set ext_dl (and ext_dh, which is not used) | |
push bx ! WATCH the order of pushes | |
push es ! set ext_es | |
push si ! set ext_si | |
#define JRC_DS_EQ_SS | |
cld ! do not forget to do this !!! | |
mov ds,ax ! address data area | |
mov es,ax ! address data area | |
#ifdef DELL_DIRTY_HACK | |
#if 0 | |
mov ah,#15 ! get video mode | |
int 0x10 | |
cbw | |
#else | |
mov ax,#0x1200 ! enable video (VGA) | |
mov bl,#0x36 ! (probably a nop on EGA or MDA) | |
#endif | |
int 0x10 ! set video mode | |
#endif | |
mov al,#0x0d ! gimme a CR ... | |
call display | |
mov al,#0x0a ! ... an LF ... | |
call display | |
mov al,#0x4c ! ... an 'L' ... | |
call display | |
lagain: | |
mov si,#d_addr ! ready to load the second stage loader | |
mov bx,#map2 ! read second stage map to ES:BX | |
push bx ! save for later in SI | |
call pread ! read using pointer in DS:SI | |
pop si ! point at #map2 | |
int 0x12 ! get memory available | |
shl ax,#6 ! convert to paragraphs | |
sub ax,#DATAEND>>4+0x20 ! allow for PARMLINE | |
push ax | |
pop es | |
xor bx,bx | |
sload: call pread ! read using map at DS:SI | |
jnz sload ! into memory at ES:BX (auto increment) | |
rdone: mov al,#0x49 ! display an 'I' | |
call display | |
! Start the second stage loader DS=location of Params | |
push es | |
;;; push #0 | |
push bx ! display clobbered BH to zero!!! | |
retf | |
pread: lodsw ! get CX | |
xchg cx,ax | |
lodsb | |
test al,#LINEAR_FLAG|LBA32_FLAG | |
jnz use_linear | |
dec si | |
lodsw | |
mov dx,ax | |
or ax,cx | |
jz done | |
lodsb | |
mov ah,#2 ! read command | |
int 0x13 ! BIOS read | |
jmp rd_done | |
use_linear: | |
xchg dx,ax ! was mov dl,al | |
lodsw | |
test dl,#LBA32_FLAG | |
jnz is_lba | |
xor ah,ah ! was LINEAR, zero the hi-nibble (was count) | |
is_lba: | |
xchg ax,di | |
test dl,#RAID_REL_FLAG | |
jz skip_reloc | |
add cx,raid ! **** RAID ***** | |
adc di,raid+2 ! **** RAID ***** | |
skip_reloc: | |
call lba_read | |
rd_done: | |
jc error ! error -> start over again | |
add bh,#2 ! next sector | |
done: ret | |
error: | |
#ifndef LCF_NO1STDIAG | |
mov al,#32 ! display a space | |
call display | |
;;; ! display error code in AH | |
call bout | |
#endif | |
xor ax,ax ! reset the FDC | |
;;; mov dl,al | |
int 0x13 | |
pop ax ! pop return address to pread | |
jmp lagain ! redo from start | |
#ifndef LCF_NO1STDIAG | |
bout: rol ax,4 ! bring hi-nibble to position | |
call nout | |
rol ax,4 ! bring lo-nibble to position | |
nout: and al,#0x0F ! display one nibble | |
#if 0 | |
add al,#0x30 | |
cmp al,#0x3A ! a..f converts to letter | |
jb nokay | |
add al,#7 ! make a letter A..F | |
nokay: ! fall through | |
#else | |
daa ! shorter conversion routine | |
add al,#0xF0 | |
adc al,#0x40 ! is now a hex char 0..9A..F | |
#endif | |
#endif | |
display: push ax ! new display does not affect AX | |
xor bh,bh ! display on screen | |
mov ah,#14 | |
int 0x10 | |
pop ax | |
ret ! side effect, BH=0 | |
#include "read.S" | |
theend: | |
! | |
! If 'first' loads as the MBR, then there must be space for the partition | |
! table. If 'first' loads as the boot record of some partition, then | |
! the space reserved below is not used. But we must reserve the area | |
! as a hedge against the first case. | |
! | |
! | |
.org MAX_BOOT_SIZE ! | |
.word 0,0,0,0 ! space for NT and DRDOS dirty hacks | |
!!! .org 0x1be ! spot for the partition table | |
p_table: | |
.blkb 16 | |
.blkb 16 | |
.blkb 16 | |
.blkb 16 | |
.word 0xAA55 ! boot block signature | |
map2 equ *+BOOTSEG*16 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment