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

📄 second.s

📁 linux 的引导程序源码The Microsoft&reg Windows&reg Software Development Kit (SDK) provides the documentation
💻 S
📖 第 1 页 / 共 5 页
字号:
cwrite:#ifdef RAID_NEW	BEG_FS	SEG_FS	test	byte ptr par1_prompt+SSDIFF,#FLAG_RAID_NOWRITE ; no writes?	END_FS	jnz	cwok		; jump if no writing allowed	BEG_FS	SEG_FS	test	byte ptr par1_prompt+SSDIFF,#FLAG_RAID	; is it a RAID write	END_FS	jnz	cmd_raid_wrt#endif        mov     byte ptr (dsk_wrflag),#1        ! flag write operation        call    cread        mov     byte ptr (dsk_wrflag),#0        ! flag read operation	jnc	cwok		! no error - returncnok:	push	ax		! leave no traces	push	bx	mov	al,#87		! "W"	push	ax		! display clobbers AH	call	display	pop	ax	mov	al,ah		! error code	call	bout	call	crlf		! leave space	pop	bx	pop	ax        stc                     ! flag error  JRCcwok:#if DEBUG_NEW	pushf	call	pause	popf#endif	ret			! done#ifdef RAID_NEW;  We know it is RAID, so CHS is not in effectcmd_raid_wrt:	mov	di,#raid_tt	; point at RAID translation table        xor     ah,ah           ;will be zero for LINEAR        xchg    al,dh           ;AX is possible address 	test	dl,#LBA32_FLAG	;test for pure LINEAR	*****	jz	lnwrt		;jump if pure LINEAR	*****        test    dl,#LBA32_NOCOUNT        jz      lnwrt        mov     ah,dh           ;former count is really hi-nibblelnwrt:			; address is AX:CX, DH=1, DL=device+flags, ES:BX=buffer        mov     dh,#1           ;set count to 1	push	ax		push	cx	push	di	mov     byte ptr (dsk_wrflag),#1        ! flag write operation#if DEBUG_NEW	pusha	push	ax			! save high order	push	cx			! save low order	push	dx	mov	bx,#cmdwr	call	say	pop	ax	call	bout			! device+flags	mov	bx,#rs_reloc	call	say	call	dout	call	crlf	popa#endif	call	lnread	mov	byte ptr (dsk_wrflag),#0	! flag read operation	pop	di	pop	cx	jc	cmdwerr	pop	ax	mov	dh,(di)			! get next raid device	or	dh,dh	jz	cwok	and	dl,#0xFF-DEV_MASK		! save flags	or	dl,dh	add	cx,(di+1)		! apply low order translation	adc	ax,(di+3)		! apply high order translation	add	di,#5	jmp	lnwrtcmdwerr:	pop	cx			! was AX	jmp	cnok			! write dumb error message#if DEBUG_NEWcmdwr:	.ascii	"RAID: write to device "	.byte	0#endif#endif#endifkt_read:		; KEYTABLE read	call	kt_set		; set for KEYTABLE i/o	call	cread	jc	keyerr	mov	si,#KEYTABLE	! compute a checksum of the keytable	mov	di,#SECTOR_SIZE - 8	! skip the last 4+4 bytes#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	keyerr	cmp	dx,word (di+2)	#endif	jz	nokeyerr! Checksum errorkeyerr:	mov	bx,#msg_chkkey	br	zz		! go waitnokeyerr:	ret! Sector read!  trashes CX and DIcread:          test    dl,#LINEAR_FLAG|LBA32_FLAG        jnz     use_linear        push    ax              ;save the count	mov	ah,#2		;read command        call    dsk_do_rw       ; int 0x13 with retries        pop     cx              ;Carry Set means error on read        mov     al,cl           ;count in AL, error code in AH        retuse_linear:        mov     ah,hinib        ;will be zero for LINEAR        xchg    al,dh           ;AX is possible address 	test	dl,#LBA32_FLAG	;test for LBA32/LINEAR	*****	jz	lnread		;pure LINEAR		*****        test    dl,#LBA32_NOCOUNT        jz      lnread        mov     ah,dh           ;former count is really hi-nibble        mov     hinib,ah        mov     dh,#1           ;set count to 1lnread:        xchg    di,ax           ;hi-address to DI        mov     al,dh           ;count to AL	test	dl,#RAID_REL_FLAG		; ******	jz	ln_do_read			; ******	BEG_FS	SEG_FS	add	cx,par1_raid_offset+SSDIFF	; ***** RAID ******	SEG_FS	adc	di,par1_raid_offset+2+SSDIFF	; ***** RAID ******	END_FSln_do_read:        call    lba_read        mov     al,cl           ;count returned in AL, error code in AH        ret                     ;Carry Set means error on read#ifdef LCF_VIRTUAL; vmtest -- return Carry=1 if in virtual (VMware) mode;	    return Carry=0 if in real mode;vmtest:	pushad			; save all extended registers	smsw	ax	rcr	al,1		; PE bit in AL to Carry	jc	vm_ret		; exit if virtual mode#if DEBUG_NEW	mov	ah,#2		! get keyboard flags	int	0x16	and	al,#0x50	! Caps, Scroll Lock flags	cmp	al,#0x40	je	vm_vir		! Caps only means virtual boot simulated#endif;;  VMware(R) test for virtual mode;	mov	eax,#0x564D5868	! EAX: in = 'VMXh'   out = version	xor	ebx,ebx		! EBX:               out = 'VMXh' under vmware	mov	edi,eax	mov	dx,#0x5658	!  DX: in = 'VX'	mov	ecx,#10		! ECX: in = VMXGetVersion	in	eax,dx	cmp	ebx,edi		! test for vmware	clc			; NOT vmware if Carry==0	jne	vm_ret		! not vmware	inc	eax		; carry is not affected by INC	jz	vm_ret		; invalid version number == 0xFFFFFFFFvm_vir:	stc			; signal virtual modevm_ret:	popad		; restore all the extended registers	ret#endif#ifdef RAID_NEW; raid_search -- search for other raid disks which parallel this one;;  enter with DS:BX pointing to buffer to use (DESCR) for searches;         and with ES=DS=CS;;  side effect is to set up the raid translation table for writes;;raid_search:	push	es#if DEBUG_NEW	mov	byte ptr raid_nn,#0	;set number of raid disks to 0	call	crlf#endif	BEG_FS	SEG_FS	mov	dl,par1_keytab+sa_device+SSDIFF	; get map file drive; enable matching RAID boot blocks by clearing the DEFEAT flag	SEG_FS	and	byte ptr par1_prompt+SSDIFF,#0xFF-FLAG_RAID_DEFEAT	SEG_FS	test	byte ptr par1_prompt+SSDIFF,#FLAG_RAID	END_FS#if DEBUG_NEW#ifdef LCF_M386	jz	near rs_ret#else	beq	rs_ret#endif#else	jz	rs_ret#endif	and	dx,#0xF0		; save LINEAR/LBA32/LBA32_NOCOUNT#if 0	cmp	dl,#0x80		; must be 0x80 for this to be raid#if DEBUG_NEW#ifdef LCF_M386	jne	near rs_ret#else	bne	rs_ret#endif#else	jne	rs_ret#endif#endif	mov	bp,#16			; test 16 bios devices	push	#raid_tt		; set pointerrs_next:	push	ds	pop	es	mov	cx,#1#if DEBUG_NEW	pusha	push	dx	mov	bx,#rs_test	call	say	pop	ax	call	bout	popa#endif	push	dx			; protect LBA32/LINEAR flags	and	dx,#DEV_MASK		; mask flag bits; clear DH, too (0x008F)	mov	al,cl			; read 1 sector	call	cread			; read the boot sector (MBR)					; no RAID relocation will happen					; because we use CHS addressing	pop	dx	jc	rs_done	pop	di	call	raid_compare		; watch out for DI - raid ptr in					; the stack#ifdef RAID_NEW	push	bx	mov	cx,#4	lea	si,(bx+PART_TABLE_OFFSET)	add	bh,#SECTOR_SIZE>>8rs_chk_pri:#if 0	cmp	byte ptr (si+4),#0xFD	; check for raid partition	jne	rs_chk_pri_next#endif	cmp	byte ptr (si+4),#0	; check for empty entry	je	rs_chk_pri_next	push	cx	push	di#if DEBUG_NEW	push	bx	mov	bx,#rsckpar	call	say	mov	al,#5	sub	al,cl	call	nout	pop	bx#endif	mov	al,#1	mov	cx,(si+8)	mov	di,(si+8+2)	call	lba_read	pop	di	call	raid_compare	pop	cxrs_chk_pri_next:	add	si,#16			; next partition table entry	loop	rs_chk_pri	pop	bx	push	di#endif  /* CHECK_PRI_TOO */	inc	dl			; move to next drive	dec	bp	jnz	rs_next			; try next device coders_done:	pop	di	mov	byte ptr (di),#0		; mark zero on end#if DEBUG_NEW	pusha	call	crlf	mov	bx,#rs_found	call	say	mov	si,#raid_nn	lodsb	call	nout	mov	bx,#rs_found2	call	sayrs_debug1:	mov	bx,#rs_dev	call	say	lodsb	call	bout	mov	bx,#rs_reloc	call	say#ifdef LCF_M386	lodsd	push	eax	call	dout#else	lodsw	push	ax	lodsw	call	wout	pop	ax	call	wout#endif	call	crlf	test	byte ptr (si),#0xFF	jnz	rs_debug1	call	pause	popa#endifrs_ret:	pop	es	ret; raid compare;  ;   enter with  DI = raid pointer ;   DS:BX  points at the buffer that was read;     DL is device code;raid_compare:	push	es	push	si	push	di	mov	si,bx			; compare what is read	xor	di,di			; to our first stage loader#ifdef LCF_M386	push	fs	pop	es#else	seg	cs	mov	es,firstseg#endif	mov	cx,#par1_raid_offset-par1_cli	; signature	repe		cmpsb	jne	rs_skip2	add	si,#8	add	di,#8			; skip raid_reloc & timestamp	mov	cx,#par1_size - par1_raid_offset - 8	repe		cmpsbrs_skip2:#if DEBUG_NEW	pushf	pusha	mov	bx,#rs_nomatch	jne	rs_nm	mov	bx,#rs_matchrs_nm:	call	say	popa	popf#endif	jne	rs_skip; we found two boot records that are identical#if DEBUG_NEW	inc	raid_nn#endif#ifdef LCF_M386	mov	eax,(bx+par1_raid_offset)#else	mov	ax,(bx+par1_raid_offset)	mov	cx,(bx+par1_raid_offset+2)#endif#ifdef LCF_M386	seg	fs	sub	eax,par1_raid_offset#else	seg	es			; ES == FS	sub	ax,par1_raid_offset	seg	es	sbb	cx,par1_raid_offset+2	push	ax	or	ax,cx		; do the zero test	pop	ax#endif	jnz	rs_insert	seg	es		; ES == FS	cmp	dl,par1_dflcmd+sa_device#if DEBUG_NEW	jne	rs_insert	pusha	mov	bx,#rs_omitted	call	say	popa	jmp	rs_skip#else	je	rs_skip#endifrs_insert:	pop	di	mov	(di),dl				; save device#ifdef LCF_M386	mov	(di+1),eax			; save offset#else	mov	(di+1),ax			; save offset lo	mov	(di+1+2),cx			; save offset hi#endif	add	di,#5	push	dirs_skip:	pop	di	pop	si	pop	es	ret#if DEBUG_NEWraid_nn:	.byte	0	; must precede raid_tt for printout#endifraid_tt:	.blkb	5*16	; format is    drive:      .byte				;              translate:  .long		.byte   0#if DEBUG_NEWrs_test:	.ascii	"RAID: Testing"rs_dev:		.ascii	" device "		.byte	0rs_nomatch:	.ascii	" no"rs_match:	.ascii	" match"		.byte	10,0rs_omitted:	.ascii	"    omitted"		.byte	10,0rs_found:	.ascii	"RAID: found "		.byte	0rs_found2:	.ascii	" matching MBR(s)"		.byte	10,0rs_reloc:	.ascii	"  reloc "		.byte	0rsckpar:	.ascii	"  Checking partition "		.byte	0#endif#endif#if 1; crc32 -- calculate CRC-32 checksum;;	call:;		push	dword #POLYNOMIAL;;		ES:SI	char string pointer;		DI	count of characters;;		call	crc32;;    CRC-32 is returned in EAX  or  DX:AX;		the arguments are popped from the stack;crc32:		push	bp		mov	bp,sp		push	si		push	di		push	bx		push	cx#ifdef LCF_M386		mov	eax,#-1		; initialize CRC#else		mov	ax,#-1		cwd#endif		inc	dicrc32a:		dec	di		jz	crc32d		mov	cx,#8		; count 8 bits		seg es		mov	bl,(si)		; get next character		inc	sicrc32b:		shl	bx,#1		; get hi bit of char in BH#ifdef LCF_M386		shl	eax,#1		; shift hi bit out of CRC#else		shl	ax,#1		rcl	dx,#1#endif		adc	bh,#0		; add carry to BH		shr	bh,#1		; put bit in carry		jnc	crc32c		; skip the xor#ifdef LCF_M386		xor	eax,(bp+4)	; xor in the polynomial#else		xor	ax,(bp+4)		xor	dx,(bp+6)#endifcrc32c:		loop	crc32b		; loop back for 8 bits		jmp	crc32acrc32d:		#ifdef LCF_M386		not	eax		; finialize CRC#else		not	ax		not	dx#endif		pop	cx		pop	bx		pop	di		pop	si				leave		ret	4#endif#ifdef HIGHMEM_MAX; enter with BX == Ramdisk size (in 4k pages);rd_setup:	push	bx		; save Ramdisk size in pages	mov	eax,hma		; user specified?	or	eax,eax#ifdef LCF_INITRDLOW	jnz	rd_have_hma#else		/* ifndef LCF_INITRDLOW */	jnz	near rd_have_hma	BEG_FS	SEG_FS	test	byte ptr par1_prompt+SSDIFF,#FLAG_LARGEMEM	END_FS	jz	near no_e801; try the E820 memory map first	xor	edx,edx			; flag nothing found	xor	ebx,ebx	jmp	e8goe8go2:	or	ebx,ebx			; test for end	jz	e8go5e8go:	push	edx			; save best prospect	mov	eax,#0xe820	mov	edx,#0x534d4150	;'SMAP'	mov	ecx,#20	mov	di,#memmap	int	0x15			; get memory map	pop	edx			; restore what we have found so far	jc	no_e820	cmp	eax,#0x534d4150	;'SMAP'	jne	no_e820	cmp	ecx,#20	jne	no_e820	mov	eax,memmap	; get start	mov	ecx,memmap+4	; get high part	cmp	word memmap+16,#1	; available?	jne	e8no1			; go on to next	or	ecx,ecx	jnz	e8go2	cmp	eax,#0x100000	; compare to 1Mb	ja	e8go2	add	eax,memmap+8	; get final address	adc	ecx,memmap+12	;	shrd	eax,ecx,#10	; convert to 1k blocks (legacy)	cmp	eax,#4*1024	; compare to 4Mb	jb	no_e820	xchg	eax,edx		; save in edx	jmp	e8go2e8no1:	shrd	eax,ecx,#10	; convert to 1k blocks	cmp	eax,#1024	; compare to 1Mb	jb	e8go2		; loop if too small	cmp	eax,edx		; check against HMA	jae	e8go2	xchg	eax,edx		; compensate for buggy BIOS	jmp	e8go2		; remember in EDX & loope8go5:	or	edx,edx		; find anything?	jz	no_e820	xchg	eax,edx	jmp	rd_have_hmano_e820:; above failed, try the older E801 block count interface	xor	cx,cx		; some BIOSs are buggy	xor	dx,dx	mov	ax,#0xe801	; call	stc	int	0x15	jc	no_e801	or	cx,cx	jz	e801cx	mov	ax,cxe801cx:	or	dx,dx	jz	e801dx	mov	bx,dxe801dx:		movzx	ebx,bx	movzx	eax,ax	shl	ebx,6		; convert to 1k	add	eax,#1024	; add 1M to address	add	eax,ebx	jmp	rd_have_hma#endif	/* ifndef LCF_INITRDLOW */no_e801:; above two methods failed, try the old 0x88 function	mov	ah,#0x88	; get count of extended memory blocks	int	0x15	movzx	eax,ax		; extend to dword	add	eax,#1024	; add in base 1M;rd_have_hm

⌨️ 快捷键说明

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