📄 second.s
字号:
#if 0/* second.S - LILO second stage boot loader */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 DEBUG*/#define INITRD_LATE#define RAID_NEW#define PIXADDRESS#define MEMORY_CHECK#define LOCK_BSS#define VAR_LOAD#define LILO_ASM#include "lilo.h"get common.s /* as86 "include" will bypass the CPP */#ifdef LCF_BUILTIN#define MAP Map#define MAP2 Map2#define DFLCMD Dflcmd#define DESCR Descr#define KEYTABLE Keytable#define PARMLINE Parmline#endif#ifdef DEBUG#define DEBUG_NEW 1#else/* the following gets changed to 0 for release: */#if VERSION_MINOR<50#define DEBUG_NEW 0#else#define DEBUG_NEW 1#ifndef MEMORY_CHECK#define MEMORY_CHECK#endif#endif /* VERSION_MINOR */#endif /* DEBUG */#ifdef LCF_M386#define BEG_FS#define SEG_FS seg fs#define END_FS/* get rid of the following to revert to old int 0x15/fn 0x88 mem scheme */#define HIGHMEM_MAX 0x38000000#else#define BEG_FS db 0x1e,0x2e,0x8e,0x1e,0x02,0x00/* push ds; \ seg cs; \ mov ds,firstseg */#define SEG_FS#define END_FS pop ds#endifLOADSEG = SYSSEG ! max kernel = 1024 sectors#define UI_MAGIC 0xff /* take input from keyboard */#ifdef MENUSTAGE_MENU = STAGE_FLAG_MENU#elseSTAGE_MENU = 0#endif#ifdef BITMAPSTAGE_BITMAP = STAGE_FLAG_BMP4 #if 0#ifndef LCF_NOSERIAL#define LCF_NOSERIAL#endif #endif#elseSTAGE_BITMAP = 0#endif#ifdef LCF_NOSERIALSTAGE_SERIAL = 0#elseSTAGE_SERIAL = STAGE_FLAG_SERIAL#endif .text .globl _main .org 0_main: jmp start#ifndef LCF_M386firstseg: dw 0#endif .org 6! Boot device parameters. They are set by the installer.sig: .ascii "LILO"stage: .word STAGE_SECOND|STAGE_SERIAL|STAGE_MENU|STAGE_BITMAPversion:.word VERSION;;; .org CODE_START_2start: cld ! only CLD in the code; there is no STD#ifdef LCF_M386 push ds pop fs ! address parameters from here#else seg cs mov firstseg,ds ! save DS here#endif#ifndef LCF_NOSERIAL;;; seg ss mov dx,par1_port+SSDIFF ! use a COM port ? ! watch out, loads par1_ser_param dec dl js nocom ! no -> go on xor ax,ax ! initialize the serial port xchg al,dh push ax push dx;;; or al,#0x06 ! stop bits = 2, nbits = 7 or 8 ! this OR is not needed yet (21.7) int 0x14 ! Communications Port INIT push #0x40 pop ds pop bx ! was DX shl bx,#1 mov dx,(bx) ! get the port address from the BIOS seg cs ! keep it mov slbase,dx pop bx ! special baud rate test -- was AX test bl,#0x04 ! stop bits == 2? cli ! do not disturb any code below jz stdbps ! standard BPS shr bx,#5 ! index divisor array seg cs mov bl,divisor(bx)spcbps: ! CLI: do not disturb ... push dx ! save base address add dx,#3 ! enable divisor latch access in al,dx or al,#0x80 out dx,al pop dx ! set new divisor push dx xchg ax,bx out dx,al inc dx mov al,ah out dx,al inc dx ! disable divisor latch access inc dx xchg ax,bx and al,#0x7f out dx,al pop dx ! restore base addressstdbps: ! CLI: redundant if fell in from above push dx add dx,#4 ! address Modem Control Reg.#if 0 in al,dx or al,#3 ! turn on DTR and RTS#else mov al,#3 ! turn on DTR and RTS#endif out dx,al pop dx sti ! done mov cx,#32 ! drain the queue (if any)drain: in al,dx loop drain add dx,#5 ! clear the status register in al,dx ! send "\r\nLI" to the serial port mov si,#serLI mov cx,#4ser1: seg cs lodsb call serdisp loop ser1 jmp comcom ! proceed with the rest of "LILO"serLI: .byte 13,10,0x4c,0x49 ! cr,lf,"LI"BAUD_BASE = 115200 ! divisor == 1divisor: .byte BAUD_BASE / 19200 ! must be same as bsect.c table .byte BAUD_BASE / 38400 .byte BAUD_BASE / 57600 .byte BAUD_BASE / 115200 .byte BAUD_BASE / 2400 .byte BAUD_BASE / 2400 .byte BAUD_BASE / 2400 .byte BAUD_BASE / 2400#endif /* LCF_NOSERIAL */nocom:#ifndef LCF_NODRAIN mov cx,#32 ! drain type-ahead buffer ?drkbd: mov ah,#1 ! is a key pressed ? int 0x16 jz comcom ! no -> done xor ah,ah ! get the key int 0x16 loop drkbd#endifcomcom: mov al,#0x4c ! display an 'L' call display push #0 ! get pointer to disk parameter table in DS:SI pop ds lds si,[0x78] ! 0x78 = 4*0x1E#ifndef LCF_XL_SECS cmp byte ptr (si+4),#9 ! okay ? ja dskok ! yes -> do not patch#endif push cs ! get pointer to new area in ES:DI pop es mov di,#dskprm mov cx,#6 ! copy 12 bytes rep movsw seg es ! patch number of sectors#ifndef LCF_XL_SECS mov byte ptr (di-8),#18#else mov byte ptr (di-8),#LCF_XL_SECS#endif push #0 pop ds cli ! paranoia mov [0x78],#dskprm mov [0x7a],es stidskok:#ifndef LCF_NOSERIAL seg cs ! clear the break flag mov byte ptr break,#0#endif call instto ! get timer interrupt;;; jmp restrt ! get going! Restart here after a boot errorrestrt: mov bx,cs ! adjust segment registers mov ds,bx mov es,bx#ifdef VAR_LOAD sub bx,#MAX_SETUPSECS*0x20+0x20 ! segment for setup code & ! bootsect mov cx,#INITSEG cmp bx,cx jbe restrt1 mov bx,cx ! BX is the smaller segment #restrt1: mov word ptr [map],#MAP mov [initseg],bx ! set up INITSEG (was 0x9000) lea cx,(bx+0x20) mov [setupseg],cx ! set up SETUPSEG (was 0x9020) mov cx,cs sub cx,bx ! subtract [initseg] shl cx,#4 ! get stack size mov ss,bx ! must lock with move to SP below#else mov cx,bx shl cx,#4 mov ax,#STACKSEG mov ss,ax#endif mov sp,cx ! data on the stack)#if DEBUG_NEW pusha mov bx,#msg_where call say mov ax,[initseg] call wout mov al,#32 ; space call display mov ax,[setupseg] call wout mov al,#32 ; space call display mov ax,cs call wout mov al,#32 ; space call display mov ax,ss call wout mov al,#0x3A ; colon call display mov ax,sp call wout call crlf popa#endif#ifndef LCF_M386 cmp word [sig],#EX_MAG_L ! check that this is really loaded at the ! right place ... "LI" jne crshbrn2 cmp word [sig+2],#EX_MAG_H ! "LO" jne crshbrn cmp word [mcmdbeg+6],#0x414d ! "MA" jne crshbrn cmp word [mcmdbeg+8],#0x4547 ! "GE"#else cmp dword [sig],#EX_MAG_HL ! "LILO" jne crshbrn cmp dword [mcmdbeg+6],#0x4547414d ; "MAGE" from BOOT_IMAGE#endif jne crshbrn cmp BYTE stage,#STAGE_SECOND jne crshbrn cmp WORD version,#VERSIONcrshbrn2: jne crshbrn mov cmdbeg,#acmdbeg ! probably unattended bootldsc: call kt_read ! read the KEYTABLE mov bx,#DESCR#ifdef RAID_NEW call raid_search#endif mov si,#KEYTABLE+256+mt_descrdescr_more:;; BEG_FS;; SEG_FS lodsw xchg cx,ax;; SEG_FS lodsw xchg dx,ax;; SEG_FS lodsb;; END_FS call cread bcs fdnok ! error -> retry add bh,#2 ! increment address cmp si,#KEYTABLE+256+mt_descr+sa_size*MAX_DESCR_SECS_asm jb descr_more mov si,#DESCR ! compute a checksum of the descriptor table mov di,#SECTOR_SIZE*MAX_DESCR_SECS-4#ifdef LCF_M386 push dword #CRC_POLY1#else push #CRC_POLY1>>16 push #CRC_POLY1&0xFFFF#endif call crc32 add di,si#ifdef LCF_M386 cmp eax,dword (di)#else cmp ax,word (di) jne chkerr cmp dx,word (di+2) #endif jz nochkerr! Checksum errorchkerr: mov bx,#msg_chkerr jmp zz ! go wait! Diecrshbrn: mov bx,#msg_sigerr ! signature not foundzz: call sayzzz: hlt ! wait for interrupt jmp zzz ! sit here forevernochkerr:#ifdef DEBUG pusha mov bx,#nochker_msg call say popa jmp nochkerr1nochker_msg: .ascii "Descriptor checksum okay\n" .byte 0nochkerr1:#endif#ifdef LCF_VIRTUAL; remove those items that have "vmdisable", if virtual boot call vmtest jnc virtual_done mov di,#DESCR0 ; point at first descriptorvir_loop: test byte ptr [id_name](di),#0xFF ; test for NUL name jz virtual_done test word ptr [id_flags](di),#FLAG_VMDISABLE jz vir_skip push di lea si,[id_size](di)vir_loop1: mov cx,#id_size rep movsb test byte ptr [id_name](di),#0xFF jnz vir_loop1 pop di jmp vir_loopvir_skip: add di,#id_size jmp vir_loopvirtual_done:#endif#if defined(MENU) || defined(BITMAP) xor bx,bx ! defaults are all zero mov [dimage],bx ! set default image to boot mov [abs_cx],bx ! upper left of scroll area ! means screen is not cleared#endif;;; call kt_read mov bx,#KEYTABLE+256 mov al,(bx+mt_flag) BEG_FS SEG_FS ! get possible FLAG_NOBD or byte ptr par1_prompt+SSDIFF,al END_FS#ifdef MENU call title_stuff#endif mov bx,#DFLCMD BEG_FS SEG_FS mov cx,par1_dflcmd+SSDIFF ;DFCMD_OFF SEG_FS mov dx,par1_dflcmd+2+SSDIFF SEG_FS mov al,par1_dflcmd+4+SSDIFF END_FS call cread jc fdnok ! error -> retry mov bx,#DFLCMD cmp word ptr (bx),#DC_MAGIC ! okay ? jne bdcmag ! no -> do not write#ifndef LCF_READONLY mov word ptr (bx),#DC_MGOFF ! erase the magic number call cmd_write ! write out the command line#endif jmp dokay ! continuebdcmag: mov byte ptr (bx+2),#0 ! disable the command line jmp dokay ! go onfdnok: #if 0 xor ax,ax ! reset FDC mov dl,al int 0x13#endif br ldsc ! retry! List all known boot imageslist: mov byte ptr (bx),#0 ! set EOL marker call crlf#ifdef MENU inc word [suppress] ! suppress console output#endif mov si,#DESCR0 ! list all images mov cx,#IMAGES xor dl,dl ! DL counts the imageslloop: testb (si),#0xff ! done ? jz ldone ! yes mov bx,si ! display the name call say add si,#MAX_IMAGE_NAME inc dl ! count the image test dl,#3 ! inside line -> go on jnz fill call crlf jmp imgdne ! next imagefill: push bx ! fill with spaces mov al,#0x20 call display pop bx inc bx cmp bx,si jbe fillimgdne: add si,#id_size-MAX_IMAGE_NAME loop lloop ! next imageldone: test dl,#3 ! already at BOL ? jz atbol ! yes -> no CRLF call crlfatbol: #ifdef MENU dec word [suppress]#endif br iloop ! done! Ready to process user inputdokay: mov bx,#ospc ! display 'O ' call say#ifdef HIGHMEM_MAX xor eax,eax mov dword ptr hma,eax#else xor ax,ax ! get the delay and disable further delays mov word ptr memlim,ax ! no memory limit#endif mov ospc,al ! disable the message mov word ptr vgaovr,#VGA_NOCOVR ! disable VGA override BEG_FS SEG_FS xchg ax,par1_delay+SSDIFF ;DSC_OFF-8+SSDIFF END_FS or old_del,ax ! remember delay mov nodfl,#iloop ! interactive prompt if falling through BEG_FS SEG_FS ! enter boot prompt ? test byte ptr par1_prompt+SSDIFF,#FLAG_PROMPT ;DSC_OFF+15+SSDIFF,#0 END_FS jnz extp ! yes -> check for external parameters mov nodfl,#bfirst ! boot first image if falling through call waitsh ! wait for a shifting key jc iloop ! key pressed -> enter interactive mode! Check for external parametersextp: BEG_FS SEG_FS ! external parameters ? cmp byte ptr EX_OFF+6,#EX_DL_MAG END_FS jne noex ! no -> go on BEG_FS SEG_FS ! clear flag mov byte ptr EX_OFF+6,#0 SEG_FS ! load the signature pointer les bx,EX_OFF END_FS#ifndef LCF_M386 seg es ! "LI" ? cmp word ptr (bx),#EX_MAG_L jne noex ! no -> go on seg es ! "LO" ? cmp word ptr (bx+2),#EX_MAG_H#else seg es cmp dword ptr (bx),#EX_MAG_HL ! "LILO"#endif jne noex ! no -> go on BEG_FS SEG_FS mov si,EX_OFF+4 ! pointer to the command line END_FS seg es cmp byte ptr (si),#0 ! empty ? je iloop ! yes -> enter interactive mode jmp niloop ! enter non-interactive mode! No external parameters after timeout -> boot first imagenoex: push cs ! restore ES pop es mov si,#DFLCMD+2 ! default command line ? cmp byte ptr (si),#0 jne niloop ! yes -> use it mov ax,nodfl ! no idea how to tell as86 to do jmp (addr) :-( jmp ax ! fall through! Command input processoriloop:#if defined(MENU) || defined(BITMAP) call menu_setup#endif#ifndef BITMAP BEG_FS SEG_FS ! message disabled ? cmp word ptr par1_msg_len+SSDIFF,#0 ;MSG_OFF+SSDIFF,#0 END_FS je nomsg ! yes -> skip this call crlf BEG_FS SEG_FS ! load the message file mov cx,par1_msg+SSDIFF ;MSG_OFF+SSDIFF+2 SEG_FS mov dx,par1_msg+2+SSDIFF SEG_FS mov al,par1_msg+4+SSDIFF END_FS mov bx,[map] call sread call loadfile push #SYSSEG pop ds xor bx,bx ! set the terminating NUL and disable further ! messages BEG_FS SEG_FS xchg bx,par1_msg_len+SSDIFF ;MSG_OFF+SSDIFF END_FS mov byte ptr (bx),#0 xor bx,bx ! display the message call say push cs ! restore segment registers pop ds push cs pop es#endifnomsg: mov cmdbeg,#acmdbeg ! probably unattended boot mov si,#usrinpm ! interactive modeniloop: ! ES may point to external params mov bx,#msg_p ! display boot prompt call say mov bx,#cmdline ! move cursor to the end of the lineclend: mov al,(bx) or al,al ! at end ? jz cledne ! yes -> go on push bx ! display the character call display pop bx inc bx ! next one jne clendcledne: mov byte ptr prechr,#32 ! character before command line is a space! Input loop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -