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

📄 first-dos.s

📁 linux下从网卡远程启动
💻 S
📖 第 1 页 / 共 4 页
字号:
	movsb				; check	sti; Output some debugging messages by simply calling the interrupt vectors; which we just created.#ifdef DRV_DEBUG	mov	ax,CON(0x4A06)	int	0x2F	mov	si,CON(consz)	call	prnstr			; print out amount of conventional	mov	ax,dx			; memory	mov	cl,CON(12)	shr	ax,cl	call	prnwrd	mov	ax,dx	mov	cl,CON(4)	shl	ax,cl	call	prnwrd	mov	si,CON(bytes)	call	prnstr	mov	ax,CON(0x8800)	int	0x15	push	ax	mov	si,CON(extsz)	call	prnstr			; print out amount of extended memory	mov	cl,CON(6)	shr	ax,cl	call	prnwrd	pop	ax	mov	cl,CON(10)	shl	ax,cl	call	prnwrd	mov	si,CON(bytes)	call	prnstr#endif#ifndef	FREEDOS; The boot sector had to be placed into a temporary memory area to; avoid overwriting any bootrom structures. However, a call back; to the bootrom is no longer possible, so we can move the bootblock; where it belongs.	push	ds	mov	ax,CON(TEMP_SEGMENT)	mov	ds,ax	xor	ax,ax	mov	es,ax	xor	si,si	mov	di,CON(BOOT_OFFSET)	mov	cx,CON(SECT_SIZE)	rep	movsb				; move it	pop	ds; Finally call the boot sector#else; Finally call kernel.sys#endif	/* FREEDOS */#ifdef ASM_DEBUG	mov	si,CON(debug2)	call	prnstr#endif#ifdef	FREEDOS	mov	bl,LOC(drvid)		; FreeDOS gets boot drive from bl, 0=A#else	mov	dl,LOC(drvid)		; boot block may expect this#endif#ifdef ASM_FREEZE_AFTER_INITlop:	JMP(lop)#else#ifdef	FREEDOS	jmp	FDKSEG:0		; FreeDOS kernel.sys entry point#else	jmp	0:BOOT_OFFSET#endif	/* FREEDOS */#endif;====================================================================;; Setup DOS drive parameter block (DPB) for floppy disk drive. The; DPB is required to activate the floppy disk drive after the ramdisk; has been turned off.; Input:  none; Output: none; Registers changed: AX, BX, CX, DXsetdpb:	push	es	push	si	push	di	mov	dl,LOC(drvid)	cmp	dl,CON(0x80)		; can only restore floppy drives	jae	setdp8; First get the drive parameters from the BIOS	mov	LOC(dpb_phys),dl	; set physical drive ID	mov	ah,CON(0x08)		; get drive parameters from BIOS	int	0x13	jc	setdp8	xor	ah,ah	mov	al,ch			; set max number of cylinders	inc	ax	mov	LOC(dpb_cyls),ax	mov	si,CON(dpb_bpb_cur)	mov	al,cl			; set max number of sectors per track	mov	[si+BPB_SPT],ax	mov	al,dh	inc	ax			; set max number of heads	mov	[si+BPB_HEADS],ax; Determine DOS disk parameters by drive type	cmp	bl,CON(5)	jb	setdp1			; check for invalid drive type	mov	bl,CON(4)setdp1:	xor	bh,bh	dec	bx	push	bx	shl	bx,CON(1)	shl	bx,CON(1)		; compute address into drive para-	add	bx,CON(drvtab)		; meter table	xor	ah,ah	mov	al,[bx+0]		; get # of entries in root dir	mov	[si+BPB_DIR],al	mov	al,[bx+1]		; get # of sectors per FAT	mov	[si+BPB_SPF],ax	mov	al,[bx+2]		; get # of sectors per cluster	mov	[si+BPB_SPC],al	mov	al,[bx+3]		; get media ID	mov	[si+BPB_MEDIA_ID],al	pop	bx	mov	al,[bx+typtab]		; get drive type	mov	LOC(dpb_type),al; Determine number of bytes per sector	SEGES	mov	cl,[di+3]		; get shift value from BIOS media	mov	ax,CON(128)		; parameter table	shl	ax,cl			; shift base value	mov	[si+BPB_BPS],ax	JMP(setdp4)setdp8:	JMP(setdp9)			; needed for short jumps; Determine total number of sectorssetdp4:	mov	ax,[si+BPB_SPT]	mul	WLOC(dpb_cyls)	or	dx,dx			; should not overflow	jnz	setdp8#ifdef	USE_AS86	cmp	[si+BPB_HEADS],BCON(2)#endif#ifdef	USE_NASM	cmp	word [si+BPB_HEADS],BCON(2)#endif	jb	setdp3	shl	ax,CON(1)	jc	setdp8setdp3:	mov	[si+BPB_TOT_SECTS],ax; Determine if the drive can detect disk changes	mov	ah,CON(0x15)	mov	dl,LOC(drvid)	int	0x13			; get DASD type from BIOS	mov	bl,ah	mov	ax,CON(DPB_F_DEFAULT)	jc	setdp2	cmp	bl,CON(0x02)		; check if drive detects disk changes	jne	setdp2	or	ax,CON(DPB_F_DOOR)setdp2:	mov	LOC(dpb_flags),ax	; set flags; Thats it	inc	BLOC(dpb_valid)		; increment valid flagsetdp9:	pop	di	pop	si	pop	es	ret;====================================================================;; Find a load record in the boot header. The ID number of the load; record is in AL, and ES:DI points to requested load record, or is; the NULL pointer if load record not found.;; Changed registers: AX, DI, ESfndldr:	push	cx	mov	ch,al	les	di,LOC(header)		; examine boot image header	SEGES	mov	al,[di+BOOT_HD_LENGTH]	; get length of image header	call	getlen	add	di,ax			; get the pointer to first load recordfndl1:	SEGES	cmp	ch,[di+BOOT_LD_TAG1]	; is it the desired one ?	je	fndl3	SEGES	mov	al,[di+BOOT_LD_FLAGS]	; no, so check if its the last record	test	al,CON(BOOT_FLAG_EOF)	jnz	fndl2	SEGES	mov 	al,[di+BOOT_LD_LENGTH]	; no, get the address of the next one	call	getlen	add	di,ax	JMP(fndl1)fndl2:	xor	ax,ax			; couldnt find the desired record	mov	es,ax	mov	di,axfndl3:	pop	cx	ret;====================================================================;; Compute the length of a load record address from a length byte; in AL. Return the offset in AX.;; Changed registers: AXgetlen:	push	cx	mov 	ah,al	mov 	cl,CON(4)	shr	ah,cl	and	ax,CON(0x0f0f)		; compute the total length in	add	al,ah			; bytes from the length of the	xor	ah,ah			; record and that of the vendor	shl	ax,1			; information.	shl	ax,1	pop	cx	ret;====================================================================; Print a string in DS:SI onto the console;; Changed registers: ALprnstr:	push	si	cldprns1:	lodsb				; loop over all characters of	or	al,al			; string	jz	prns2	push	bx	mov	ah,CON(0x0E)		; print it	mov	bl,CON(0x07)	xor	bh,bh	int	0x10	pop	bx	JMP(prns1)prns2:	pop	si	ret#ifdef DRV_DEBUG;====================================================================;; Print hexadecimal values (in AX or AL) or characters onto the console;; Changed registers: AXprnwrd:	push	ax	mov	al,ah	call	prnbyt			; print the upper byte	pop	axprnbyt:	push	ax	shr	al,1			; prepare upper nibble	shr	al,1	shr	al,1	shr	al,1	call	prnnib			; print it	pop	axprnnib:	and	al,CON(0x0F)		; prepare lower nibble	add	al,CON(0x30)	cmp	al,CON(0x39)		; convert it into hex	jle	prnchr	add	al,CON(7)prnchr:	push	bx	mov	ah,CON(0x0E)		; print it	mov	bl,CON(0x07)	xor	bh,bh	int	0x10	pop	bx	ret#endif;====================================================================;; String and constants definitions; Startup signaturesigmsg:	db	0x0D, 0x0A	STRDECL('DOS Net Boot Image Loader ')	STRDECL(VERSION)	db	' '	STRDECL(VENDOR_MAGIC)	db	0x0D, 0x0A	STRDECL(COPYRIGHT)	db	0x0D, 0x0Acrlf:	db	0x0D, 0x0A	db	0; Magic numbers for boot record and bootp entrybmagic:	dd	BOOT_MAGIC		; boot image magic numbervmagic:	STRDECL(VENDOR_MAGIC)		; vendor magic ID	db	0			; end of vendor magic IDpmagic:	db	BOOTP_MAGIC_RFC		; bootp magic ID for RFC 1048	db	BOOTP_MAGIC_CMU		; bootp magic ID for CMU	db	BOOTP_MAGIC_STA		; bootp magic ID for Stanford	db	0; Specifications for different types of disk drives. The order is:; # dir entries, # sects per FAT, # sects per cluster, media IDdrvtab:	db	112, 2, 2, 0xfd		; 360kB disk	db	224, 7, 1, 0xf9		; 1.2MB disk	db	112, 3, 2, 0xf9		; 720kB disk	db	224, 9, 1, 0xf0		; 1.44 MB disktyptab:	db	DPB_T_360		; type values for drive parameter block	db	DPB_T_1200	db	DPB_T_720	db	DPB_T_1440; Error messagesrecerr:	STRDECL('Error in load record data')	db	0x0D, 0x0A	db	0bmerr:	STRDECL('Invalid boot header magic number')	db	0x0D, 0x0A	db	0vmerr:	STRDECL('Invalid vendor magic ID')	db	0x0D, 0x0A	db	0rderr:	STRDECL('Error while accessing ramdisk')	db	0x0D, 0x0A	db	0dskerr:	STRDECL('Wrong ramdisk image')	db	0x0D, 0x0A	db	0btperr:	STRDECL('BOOTP record invalid')	db	0x0D, 0x0A	db	0; Debug messages#ifdef ASM_DEBUGdebug1:	STRDECL('Making driver resident')	db	0x0D, 0x0A	db	0debug2:#ifdef ASM_FREEZE_AFTER_INIT	STRDECL('Freezing;')#else	STRDECL('Calling boot block')#endif	db	0x0D, 0x0A	db	0#endif#ifdef DRV_DEBUGconsz:	STRDECL('RAMDISK: reporting conventional memory size: ')	db	0extsz:	STRDECL('RAMDISK: reporting extended memory size: ')	db	0bytes:	STRDECL(' bytes')	db	0x0D,0x0A	db	0#endif;====================================================================;; Variable definitionsheader:	dd	0			; pointer to boot header from boot rombootp:	dd	0			; pointer to bootp block from boot romresseg:	dw	0			; segment of resident sectionoldDS:	dw	0			; old DS from boot romoldES:	dw	0			; old ES from boot romoldBP:	dw	0			; old BP from boot romoldSI:	dw	0			; old SI from boot romoldDI:	dw	0			; old DI from boot rom;====================================================================;; Start of resident section. This will be placed at the end of the; low 640kB RAM area.;;====================================================================;	ALIGN(16)			; has to be paragraph alignedstart_resident:				; indicate start of resident section;====================================================================;; New interrupt 2Fh routine. This routine gets called by IO.SYS; in order to determine the maximum amount of memory usable to; DOS. This only works with DOS versions 5.0 and higher. The DOS; function which gets installed into the interrupt 2Fh vector; does not call the old vector (i.e. it does not daisy-chain),; and therefore we can redirect 2Fh without a problem even when; considering to remove the ram disk lateron.;; NOTE THAT THIS INTERRUPT HAS TO BE THE FIRST ROUTINE IN THE; RESIDENT SECTION!;; Input:  AX     -  Magic ID;         DX     -  segment following last usable byte; Output: DX     -  new segment  following last usable byte; Registers changed: DXint2F:	JMP(int2F1)			; this has to be a relative jump	nop	STRDECL('RPL')			; magic ID string for DOSint2F1:	cmp	ax,CON(0x4A06)		; check for magic ID	jne	int2F9	push	cx	mov	dx,CON(start_resident)	; determine last usable segment	mov	cl,CON(4)		; from segment and offset of	shr	dx,cl			; the resident section	pop	cx	push	ax	push	cs	pop	ax	add	dx,ax			; add offset to segment	dec	dx	pop	ax	iretint2F9:	SEGCS	jmp	far [old2Fh]		; jump to old interrupt routine;====================================================================;; New interrupt F8h routine. It can be used to retrieve several; values from the resident driver.; Input:  AX  -  function code; Output: depends on function:;; Installation check (AX = 0x9C00);         AX     -  contains 0x009C;; Return ramdisk size and address (AX = 0x9C01);         BX:DX  -  address of ramdisk;         CX     -  size of ramdisk in kb;; Return size and address of BOOTP block (AX = 0x9C02);         BX:DX  -  address of BOOTP block;         CX     -  size of BOOTP block;; Return miscellaneous values for handling the ramdisk (AX = 0x9C03);         AX     -  XMS handle for ram disk;         BX:DX  -  address of old interrupt vector table;         CL     -  ramdisk id;; Remove ramdisk (AX = 0x9C04);         AL     -  non-zero if error;; Registers changed: depends on functionintF8:	cmp	ah,CON(0x9C)		; check for magic ID	jne	intF89	cmp	al,CON(01)		; check for function number	jne	intF81	SEGCS	mov	bx,LOC(rdaddr+2)	; return ramdisk address	SEGCS	mov	dx,LOC(rdaddr+0)	SEGCS	mov	cx,LOC(rdsize)		; return ramdisk size	iretintF81:	cmp	al,CON(0x02)	jne	intF82

⌨️ 快捷键说明

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