📄 first.s
字号:
#if 0; first.S - LILO first stage boot loader with LBA32 support */Copyright 1992-1998 Werner Almesberger.Copyright 1999-2002 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 0zero:_main: cli ! NT 4 blows up if this is missing jmp start nop;; .org 4reloc: .word theend-zero ! size of the code & params .org 6! Boot device parameters. They are set by the installer.sig: .ascii "LILO"stage: .word STAGE_FIRSTvers: .word VERSIONport: .byte 0 ! COM port (0 = unused, 1 = COM1, etc.)sparam: .byte 0 ! serial port parameters (0 = unused)raid: .long 0 ! raid sector offsettstamp: .long 0 ! timestamptimeout:.word 0 ! input timeoutdelay: .word 0 ! boot delaydataend: .word DATAEND>>4+0x20 ! allow for kernel command line (parmline)ms_len: .word 0 ! initial greeting messagems_cx: .word 0ms_dx: .word 0ms_al: .byte 0 ! (unused)#if 0d1_cx: .word 0 ! first descriptor sector addressd1_dx: .word 0d1_al: .byte 0 ! (unused)d2_addr: .blkb MAX_DESCR_SECS_asm*sa_size - sa_size#endifdc_cx: .word 0 ! default command-line sector addressdc_dx: .word 0dc_al: .byte 0 ! (unused)prompt: .byte 0 ! indicates whether to always enter prompt ! (also used as alignment byte)kt_cx: .word 0 ! keyboard translation tablekt_dx: .word 0kt_al: .byte 0d_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_1ext_si: .word 0 ! external interfaceext_es: .word 0 ! these locations are referenced in second.Sext_bx: .word 0 ! do not disturb the orderingext_dl: .byte 0 ! second.S will check this magic numberext_dh: .byte 0 ! not referenced, but must align stackext_stack:#endif start: call start2start2: pop ax ! get reloc source from old stack sub ax,#start2-zero mov di,cs shr ax,#4 ! make into paragraph offset 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 displaylagain: 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 mov ah,#0x99 ! possible error code#ifdef LCF_M386 cmp dword (bx-4),#EX_MAG_HL ! "LILO"#else cmp word (bx-4),#EX_MAG_L jne no2idx cmp word (bx-4+2),#EX_MAG_H#endif jne no2idx pop si ! point at #map2 int 0x12 ! get memory available shl ax,#6 ! convert to paragraphs sub ax,[dataend] ! allow for PARMLINE push ax pop es xor bx,bxsload: call pread ! read using map at DS:SI jnz sload ! into memory at ES:BX (auto increment)! Verify second stage loader signature mov si,#sig ! pointer to signature area mov di,si#ifdef LCF_M386 cmpsd ! check Signature 1 & 2#else cmpsw jne no2nd ! check Signature 1 cmpsw#endif jne no2nd ! check Signature 2 seg es cmp byte (di),#STAGE_SECOND jne no2nd cmpsw ! skip Stage & Flags cmpsw ! check VERSION;;; je rdone jne no2nd! Start the second stage loader DS=location of Paramsrdone: mov al,#0x49 ! display an 'I' call display push es push #0 retf! error exits belowno2nd: mov ah,#0x9Ano2idx: push cx ! display error 99 or 9A! no return from errorerror: pop cx ! pop return address to pread or errAH#ifndef LCF_NO1STDIAG mov al,#32 ! display a space call display call bout#endif xor ax,ax ! reset the FDC int 0x13 dec byte [zero] ! CLI == 0xFA == 250 jnz lagain ! redo from start#if 0zzz: hlt jmp zzz ! spin; wait for Ctrl-Alt-Del#else mov cx,#3<<4 ! delay 3 seconds, DX does not matter mov ah,#0x86 int 0x15 ! delay call int 0x18 ! exit to BIOS#endif! Pointer Read -- read using pointer in DS:SIpread: 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_doneuse_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_readrd_done: jc error ! error -> start over again add bh,#2 ! next sectordone: ret#ifndef LCF_NO1STDIAGbout: rol ax,4 ! bring hi-nibble to position call nout rol ax,4 ! bring lo-nibble to positionnout: and al,#0x0F ! display one nibble daa ! shorter conversion routine add al,#0xF0 adc al,#0x40 ! is now a hex char 0..9A..F#endifdisplay: push ax ! new display does not affect AX push bx ! nor does it change BX mov bx,#7 ! BH=0, BL=07 mov ah,#14 int 0x10 pop bx 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 tablep_table: .blkb 16 .blkb 16 .blkb 16 .blkb 16 .word 0xAA55 ! boot block signature;map2 equ *+BOOTSEG*16map2 equ * ! addressed as ES:[map2]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -