⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 first.s

📁 LINUX lilo-22.7 源代码。
💻 S
字号:
#if 0;  first.S  -  LILO first stage boot loader with LBA32 support */Copyright 1992-1998 Werner Almesberger.Copyright 1999-2004 John Coffman.All rights reserved.Licensed under the terms contained in the file 'COPYING' in the source directory.#endif#define LILO_ASM#include "lilo.h"get common.s		/* as86 "include" will bypass the CPP */#define DEBUG 0#if VERSION_MINOR>=50# define DEBUG_NEW# undef VIDEO_ENABLE# define VIDEO_ENABLE 3# define VALIDATE !DEBUG	/* adds 0Dh bytes */# define SECOND_CHECK !DEBUG	/* adds  5h bytes */# define CYL1023 DEBUG		/* subs  8h bytes */# define GEOMETRIC !DEBUG	/* adds  1h byte  */# if DEBUG#  define DEBUG_LARGE# endif#else# define VALIDATE 1		/* adds 0Dh bytes */# define SECOND_CHECK 1		/* adds  5h bytes */# define CYL1023 0		/* subs  8h bytes */# define GEOMETRIC 1		/* adds  1h byte  */#endif!  VIDEO_ENABLE	for those systems that disable the video on boot!	= 0		first stage does not enable video!	= 1		use get vid mode/set vid mode to enable!	= 2		use VGA enable call to enable video!			(cannot use, as code gets too big)!	= 3		use direct mode set (mode 3, CGA, EGA, VGA)!	= 7		use direct mode set (mode 7, MDA)!#ifndef VIDEO_ENABLE# if VALIDATE==0#  define VIDEO_ENABLE 2# else#  define VIDEO_ENABLE 2# endif#endif! do not change the following -- it must correspond to the code in bsect.c#define RELOCATABLE -1	.text	.globl	_main	.org	0zero:_main:	cli			! NT 4 blows up if this is missing	jmp	startstage:	.byte	STAGE_FIRST	.org	4reloc:#if RELOCATABLE	.word	theend-zero	! size of the code & params#else	.word	0		! no size indication#endif	.org	6! Boot device parameters. They are set by the installer.sig:	.ascii	"LILO"vers:	.word	VERSIONmapstamp: .long 0		! map timestamplength	=  *-sig		! for the stage 1 vs stage 2 comparisonraid:	.long	0		! raid sector offsettstamp:	.long	0		! timestampmap_serial_no:	.long	0	! volume S/N containing map fileprompt:	.word	0		! indicates whether to always enter prompt				! contains many other flags, tood_dev:	.byte	0x80		! map file device coded_flag:	.byte	0		! disk addressing flagsd_addr:	.long	0		! disk addr of second stage index sectoredd_packet	=  0;;;	.word	16		! size of packet;;;	.word	1		! count of bytes to readedd_addr	=  4;;;	.word	map2		! where to read;;;	.word	*-*		! segment where to readedd_d_addr	=  8;;;	.long	1		! low address or CX,DX (geometric)				! start at sector 1 for search in geo mode;;;	.long	0		! hi address#if 0!  These locations are referenced as EX_OFF !					(they used to be at CODE_START_1)ext_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	/***************************************************/!	The following instruction MUST be!	first instruction after the CLI/JMP short!	at the start of the file; otherwise!	the boot sector relocation fails.!start:	mov	ax,#BOOTSEG	! use DS,ES,SS = 0x07C0/***************************************************/	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#ifdef DEBUG_NEW	push	ds	push	es	! just not enough space with debug turned on#endif#define JRC_DS_EQ_SS	cld			! do not forget to do this !!!	mov	ds,ax		! address data area	xor	bp,bp		! shorted addressing#if VIDEO_ENABLE! a BIOS has been found where the video interrupt (0x10) trashes DX!   so, we had better be very paranoid about DX!# if VIDEO_ENABLE==2	pusha			! protect DX# endif# if VIDEO_ENABLE > 2	mov	ax,#VIDEO_ENABLE	! set video mode 3 or 7# elif VIDEO_ENABLE==1	mov	ah,#15		! get video mode	int	0x10	cbw# else  /* VIDEO_ENABLE==2 */	mov	ax,#0x1200	! enable video (VGA)	mov	bl,#0x36	! (probably a nop on EGA or MDA)# endif	int	0x10		! video call# if VIDEO_ENABLE==2	popa			! restore DX# endif#endif#if (VIDEO_ENABLE&1) == 0	mov	al,#0x0d	! gimme a CR ...	call	display; the suspect call for trashing DX on one BIOS:	mov	al,#0x0a	! ... an LF ...	call	display#endif#if defined(DEBUG_NEW)	mov	ah,dl	call	bout		! code in AH#endif	mov	al,#0x4c	! ... an 'L' ...	call	displaylagain:	pusha			! preserve all the registers for restart	push	ds	pop	es		! use buffer at end of boot sector	cmp	dl,#EX_DL_MAG	! possible boot command line (chain.S)	jne	boot_in_dl	mov	dl,dh		! code passed in DH insteadboot_in_dl:	mov	bx,#map2	! buffer for volume search	mov	dh,[d_dev](bp)  ! map device to DH#if VALIDATE	mov	ax,dx		! copy device code to AL	and	ah,#0x80	! AH = 00 or 80	xor	al,ah		! hi-bits must be the same	js	use_installed	cmp	al,#MAX_BIOS_DEVICES	! limit the device code	jae	use_installed	! jump if DL is not valid#endif! map is on boot device for RAID1, and if so marked; viz.,	test	byte ptr [prompt](bp),#FLAG_MAP_ON_BOOT	jnz	use_boot	! as passed in from BIOS or MBR loaderuse_installed:	mov	dl,dh		! device code to DL	mov	esi,[map_serial_no](bp)	! to search for	or	esi,esi	jz	done_search	push	dx		! save flags	mov	ah,#8		! get number of hard disks	mov	dl,#0x80	push	bx		! paranoia	int	0x13	pop	bx	jc	error	movzx	cx,dl		! extend to word in CX#if GEOMETRIC	mov	dx,#0x80-1	! device 80, flags=0#else	mov	dx,#LBA32_FLAG*256+0x80-1	! device 80, flags=LBA32#endifvagain:	inc	dx	xor	eax,eax#if GEOMETRIC	inc	ax		! geometric addressing#endif	call	disk_read	! read 	cmp	esi,[PART_TABLE_OFFSET-6](bx)	je	vol_found	loop	vagain	pop	dx		! restore specified BIOS code				! AX and DX are identical at this pointvol_found:		! uses value in DX, stack may have extra valuedone_search:	use_boot:	push	bx		! save map2 for later	mov	dh,[d_flag](bp)	! get device flags to DH	mov	si,#d_addr	call	pread		! increments BX	mov	ah,#0x99	! possible error code	cmp	dword (bx-4),#EX_MAG_HL	! "LILO"	jne	error	pop	si		! point at #map2#if 1	push	#SETUP_STACKSIZE/16 + BOOTSEG + SECTOR_SIZE/16*2	pop	es#else	mov	ax,ds		! get segment	add	ax,#SETUP_STACKSIZE/16    !   + SECTOR_SIZE/16*2	mov	es,ax#endif	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	mov	cx,#length	! number of bytes to compare	mov	ah,#0x9A	! possible error code	repe	  cmpsb			! check Signature 1 & 2	jne	error	! check Signature 2#if SECOND_CHECK/* it would be nice to re-incorporate this check */	mov	al,#STAGE_SECOND	! do not touch AH (error code)	scasb	jne	error#endif! Start the second stage loader     DS=location of Params	push	es		! segment of second stage	push	bp		! BP==0	mov	al,#0x49	! display an 'I'	call	display	retf			! Jump to ES:BPdisk_error2:	mov	ah,#0x40	; signal seek error! no return from errorerror:#ifndef LCF_NO1STDIAG        mov	al,#32          ! display a space	call	display	call	bout#endif#ifndef DEBUG_LARGE	dec	byte [zero](bp)		!  CLI == 0xFA == 250	jz	zzz#ifndef DEBUG_NEW	mov	sp,#SETUP_STACKSIZE-4*2-8*2	! set the stack for First Stage#else	mov	sp,#SETUP_STACKSIZE-4*2-2*2-8*2	! set the stack for First Stage#endif	popa				! restore registers for restart	jmp	near lagain		! redo from start#endifzzz:#ifndef DEBUG_NEW	hlt#endif	jmp	zzz		! spin; wait for Ctrl-Alt-Del! packet read routinedisk_read:#ifndef JRC_DS_EQ_SS	push	ds#endif	pusha#ifndef JRC_DS_EQ_SS	push	ss	pop	ds#endif	push	bp		! BP==0	push	bp		! BP==0	push	eax		! low order disk address#ifdef DEBUG_LARGE	xchg	ax,dx	call	wout	xchg	ax,dx	call	dout		! print out disk address#endif	push	es		! memory segment ES	push	bx		! memory offset BX	push	#1		! sector count	push	#16		! size of packet = 16 bytes	mov	si,sp		! address of packet  DS:SI	push	bx	test	dh,#LINEAR_FLAG|LBA32_FLAG	jz	disk_geometric		test	dh,#LBA32_FLAG	jz	disk_convert	; it must be LINEAR	mov	bx,#0x55AA	;magic number	mov	ah,#0x41	int	0x13	jc	disk_convert	cmp	bx,#0xAA55	;changed?	jne	disk_convert	test	cl,#EDD_PACKET	;EDD packet calls supported	jnz	disk_edddisk_convert:	push	dx	push	es		! protect on floppies	mov	ah,#8		! get geometry	int	0x13	pop	esdisk_error3:			! transfer through on CF=1	jc	error		! disk_error12#if !CYL1023	push	cx	shr	cl,#6		;;;;	xchg	cl,ch	   ;CX is max cylinder number	mov	di,cx	   ;DI saves it	pop	cx#endif	shr	dx,#8	xchg	ax,dx		;AX <- DX	inc	ax		;AX is number of heads (256 allowed)	and	cx,#0x003f	;CX is number of sectors	mul	cx		; kills DX also	xchg	ax,bx	   	;save in BX	mov	ax,[edd_d_addr](si)	;low part of address	mov	dx,[edd_d_addr+2](si)	;hi part of address	cmp	dx,bx	jae	disk_error2	;prevent division error	div	bx		;AX is cyl, DX is head/sect#if CYL1023	cmp	ax,#1023#else	cmp	ax,di#endif	ja	disk_error2	;cyl is too big	shl	ah,#6		; save hi 2 bits	xchg	al,ah	xchg	ax,dx	div	cl		;AH = sec-1, AL = head	or	dl,ah	   ;form Cyl/Sec	mov	cx,dx	inc	cx		; sector is 1 based	pop	dx		! restore device code	mov	dh,al		! set head#	jmp	disk_read2disk_edd:	mov	ah,#0x42disk_int13:	pop	bx	mov	bp,#5disk_retry:	pusha	int	0x13#if 0	stc	mov	ah,#0x9C#endif	jnc	disk_okay	dec	bp		! does not alter CF, already 0	jz	disk_error3	! go to "jc" with CF=1 & ZF=1	xor	ax,ax		! reset the disk controller	int	0x13	popa			! reset AX,BX,CX,DX,SI	dec	bp		! fix up BP count	jmp	disk_retrydisk_geometric:	push	eax	pop	cx	pop	ax	mov	dh,ahdisk_read2:	mov	ax,#0x201	;read, count of 1	jmp	disk_int13disk_okay:; the pusha block is implicitly removed below;;;	mov	(si+2*16-1),ah	! set error code;   the error code is never checked	lea	sp,(si+16)	! do not touch carry; 	popa#ifndef JRC_DS_EQ_SS	pop	ds#endif	ret! Pointer Read -- read using pointer in DS:SIpread:	lodsd			! get address	or	eax,eax	jz	done	add	eax,[raid](bp)	! reloc is 0 on non-raid	call	disk_read		add	bh,#SECTOR_SIZE/256    	! next sectordone:	ret#if !defined(LCF_NO1STDIAG) || defined(DEBUG_NEW)bout:	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#endif; display - write byte in AL to console;	preserves all register contents; display: pusha		! make sure no register is changed	mov	bx,#7		!  BH=0, BL=07	mov	ah,#14	int	0x10	popa		! restore all the registers	ret#ifdef DEBUG_LARGEdout:	pushad	ror	eax,#16	call	wout	ror	eax,#16	call	wout	mov	al,#0x20	! space	call	display	popad	retwout:	push	ax	call	bout	! put out AH	pop	ax	push	ax	xchg	al,ah	call	bout	! put out AL (now in AH)	pop	ax	ret#endiftheend:!!   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, DRDOS, and LiLO volume S/N!	.org	0x1be		! spot for the partition tablep_table:	.blkb	16	.blkb	16	.blkb	16	.blkb	16#ifdef FIRST	.org	*-2	.long	FIRST		! boot block check#else	.word	0xAA55		! boot block signature#endif! Better be exactly 0x200map2	equ	*		! addressed as ES:[map2]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -