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

📄 floppyload.s

📁 linux下从网卡远程启动
💻 S
字号:
/* NOTE: this boot sector contains instructions that need at least an 80186. * Yes, as86 has a bug somewhere in the valid instruction set checks. * * SYS_SIZE is the number of clicks (16 bytes) to be loaded. */.equ	SYSSIZE, 8192	# 8192 * 16 bytes = 128kB maximum size of .ROM file/*	floppyload.S Copyright (C) 1991, 1992 Linus Torvalds *	modified by Drew Eckhardt *	modified by Bruce Evans (bde) * * floppyload.S is loaded at 0x0000:0x7c00 by the bios-startup routines. * * It then loads the system at SYSSEG<<4, using BIOS interrupts. * * The loader has been made as simple as possible, and continuous read errors * will result in a unbreakable loop. Reboot by hand. It loads pretty fast by * getting whole tracks at a time whenever possible. */.equ	BOOTSEG, 0x07C0			/* original address of boot-sector */.equ	SYSSEG, 0x1000			/* system loaded at SYSSEG<<4 */	.org	0	.text	.code16	jmp	$BOOTSEG, $go		/* reload cs:ip to match relocation addr */go: 	movw	$0x2000-12, %di		/* 0x2000 is arbitrary value >= length */					/* of bootsect + room for stack + 12 for */					/* saved disk parm block */	movw	$BOOTSEG, %ax	movw	%ax,%ds	movw	%ax,%es	movw	%ax,%ss			/* put stack at BOOTSEG:0x4000-12. */	movw	%di,%sp/* Many BIOS's default disk parameter tables will not recognize multi-sector * reads beyond the maximum sector number specified in the default diskette * parameter tables - this may mean 7 sectors in some cases. * * Since single sector reads are slow and out of the question, we must take care * of this by creating new parameter tables (for the first disk) in RAM.  We * will set the maximum sector count to 36 - the most we will encounter on an * ED 2.88.  High doesn't hurt.	Low does. * * Segments are as follows: ds=es=ss=cs - BOOTSEG */	xorw	%cx,%cx	movw	%cx,%es			/* access segment 0 */	movw	$0x78, %bx		/* 0:bx is parameter table address */	pushw	%ds			/* save ds *//* 0:bx is parameter table address */	ldsw	%es:(%bx),%si		/* loads ds and si */	movw	%ax,%es			/* ax is BOOTSECT (loaded above) */	movb	$6, %cl			/* copy 12 bytes */	cld	pushw	%di			/* keep a copy for later */	rep	movsw				/* ds:si is source, es:di is dest */	popw	%di	movb	$36,%es:4(%di)	movw	%cx,%ds			/* access segment 0 */	xchgw	%di,(%bx)	movw	%es,%si	xchgw	%si,2(%bx)	popw	%ds			/* restore ds */	movw	%di, dpoff		/* save old parameters */	movw	%si, dpseg		/* to restore just before finishing */	pushw	%ds	popw	%es			/* reload es *//* Note that es is already set up.  Also cx is 0 from rep movsw above. */	xorb	%ah,%ah			/* reset FDC */	xorb	%dl,%dl	int	$0x13/* Get disk drive parameters, specifically number of sectors/track. * * It seems that there is no BIOS call to get the number of sectors.  Guess * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read, * 15 if sector 15 can be read.	Otherwise guess 9. */	movw	$disksizes, %si		/* table of sizes to try */probe_loop: 	lodsb	cbtw				/* extend to word */	movw	%ax, sectors	cmpw	$disksizes+4, %si	jae	got_sectors		/* if all else fails, try 9 */	xchgw	%cx,%ax			/* cx = track and sector */	xorw	%dx,%dx			/* drive 0, head 0 */	movw	$0x0200, %bx		/* address after boot sector */					/*   (512 bytes from origin, es = cs) */	movw	$0x0201, %ax		/* service 2, 1 sector */	int	$0x13	jc	probe_loop		/* try next value */got_sectors: 	movw	$msg1end-msg1, %cx	movw	$msg1, %si	call	print_str/* ok, we've written the Loading... message, now we want to load the system */	pushw	%es			/* = ds */	movw	$SYSSEG, %ax	movw	%ax,%es			/* segment of SYSSEG<<4 */	pushw	%es	call	read_it/* This turns off the floppy drive motor, so that we enter the kernel in a * known state, and don't have to worry about it later. */	movw	$0x3f2, %dx	xorb	%al,%al	outb	%al,%dx	call	print_nl	pop	%es			/* = SYSSEG */	pop	%es			/* balance push/pop es */sigok: /* Restore original disk parameters */	movw	$0x78, %bx	movw	dpoff, %di	movw	dpseg, %si	xorw	%ax,%ax	movw	%ax,%ds	movw	%di,(%bx)	movw	%si,2(%bx)/* after that (everything loaded), we call to the .ROM file loaded. */	call	$SYSSEG, $0	int	$0x19		/* should try to boot machine *//* This routine loads the system at address SYSSEG<<4, making sure no 64kB * boundaries are crossed. We try to load it as fast as possible, loading whole * tracks whenever we can. * * in:	es - starting address segment (normally SYSSEG) */read_it: 	movw	$1,sread	movw	%es,%ax	testw	$0x0fff, %axdie:	jne	die			/* es must be at 64kB boundary */	xorw	%bx,%bx			/* bx is starting address within segment */rp_read: 	movw	%es,%ax	movw	%bx,%dx	movb	$4, %cl	shrw	%cl,%dx			/* bx is always divisible by 16 */	addw	%dx,%ax	cmpw	$SYSSEG+SYSSIZE, %ax	/* have we loaded all yet? */	jb	ok1_read	retok1_read: 	movw	sectors, %ax	subw	sread, %ax	movw	%ax,%cx	shlw	$9, %cx	addw	%bx,%cx	jnc	ok2_read	je	ok2_read	xorw	%ax,%ax	subw	%bx,%ax	shrw	$9, %axok2_read: 	call	read_track	movw	%ax,%cx	addw	sread, %ax	cmpw	sectors, %ax	jne	ok3_read	movw	$1, %ax	subw	head, %ax	jne	ok4_read	incw	trackok4_read: 	movw	%ax, head	xorw	%ax,%axok3_read: 	movw	%ax, sread	shlw	$9, %cx	addw	%cx,%bx	jnc	rp_read	movw	%es,%ax	addb	$0x10, %ah	movw	%ax,%es	xorw	%bx,%bx	jmp	rp_readread_track: 	pusha	pushw	%ax	pushw	%bx	pushw	%bp			/* just in case the BIOS is buggy */	movw	$0x0e2e, %ax		/* 0x2e = . */	movw	$0x0007, %bx	int	$0x10	popw	%bp	popw	%bx	popw	%ax	movw	track, %dx	movw	sread, %cx	incw	%cx	movb	%dl,%ch	movw	head, %dx	movb	%dl,%dh	andw	$0x0100, %dx	movb	$2, %ah	pushw	%dx			/* save for error dump */	pushw	%cx	pushw	%bx	pushw	%ax	int	$0x13	jc	bad_rt	addw	$8, %sp	popa	retbad_rt: pushw	%ax			/* save error code */	call	print_all		/* ah = error, al = read */	xorb	%ah,%ah	xorb	%dl,%dl	int	$0x13	addw	$10, %sp	popa	jmp	read_track/* print_all is for debugging purposes.	It will print out all of the registers. * The assumption is that this is called from a routine, with a stack frame like *	dx *	cx *	bx *	ax *	error *	ret <- sp */print_all: 	call	print_nl		/* nl for readability */	movw	$5, %cx			/* error code + 4 registers */	movw	%sp,%bpprint_loop: 	pushw	%cx			/* save count left */	cmpb	$5, %cl	jae	no_reg			/* see if register name is needed */	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */	movw	$0xe05+0x41-1, %ax	subb	%cl,%al	int	$0x10	movb	$0x58, %al		/* 'X' */	int	$0x10	movb	$0x3A, %al		/* ':' */	int	$0x10no_reg: 	addw	$2, %bp			/* next register */	call	print_hex		/* print it */	movb	$0x20, %al		/* print a space */	int	$0x10	popw	%cx	loop	print_loop	call	print_nl		/* nl for readability */	retprint_str: 	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */	movb	$0x0e, %ah		/* write char, tty mode */prloop: 	lodsb	int	$0x10	loop	prloop	retprint_nl: 	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */	movw	$0xe0d, %ax		/* CR */	int	$0x10	movb	$0xa, %al		/* LF */	int	$0x10	ret/* print_hex prints the word pointed to by ss:bp in hexadecimal. */print_hex: 	movw	(%bp),%dx		/* load word into dx */	movb	$4, %cl	movb	$0x0e, %ah		/* write char, tty mode */	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */	call	print_digit	call	print_digit	call	print_digit/* fall through */print_digit: 	rol	%cl,%dx			/* rotate so that lowest 4 bits are used */	movb	$0x0f, %al		/* mask for nybble */	andb	%dl,%al	addb	$0x90, %al		/* convert al to ascii hex (four instructions) */	daa	adcb	$0x40, %al	daa	int	$0x10	retsread:	.word 0				/* sectors read of current track */head:	.word 0				/* current head */track:	.word 0				/* current track */sectors: 	.word 0dpseg:	.word 0dpoff:	.word 0disksizes: 	.byte 36,18,15,9msg1: 	.ascii "Loading ROM image"msg1end: 	.org 510, 0/* The Etherboot loaders (which we loaded) store two words right below the * 0xAA55 signature.  We need not reserve any space for that, because this is * done after we finished our work. */	.word 0xAA55

⌨️ 快捷键说明

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