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

📄 bootsect.s

📁 Memtest86 is thorough, stand alone memory test for Intel/AMD x86 architecture systems. BIOS based m
💻 S
字号:
/* *	 bootsect.s		Copyright (C) 1991, 1992 Linus Torvalds * * bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves * itself out of the way to address 0x90000, and jumps there. * * It then loads 'setup' directly after itself (0x90200), and the system * at 0x10000, using BIOS interrupts.  * * The loader has been made as simple as possible, and continuos * read errors will result in a unbreakable loop. Reboot by hand. It * loads pretty fast by getting whole tracks at a time whenever possible. * * 1-Jan-96 Modified by Chris Brady for use as a boot loader for MemTest-86. */#include "defs.h"ROOT_DEV = 0	.code16.section ".bootsect", "ax", @progbits_boot:# ld86 requires an entry symbol. This may as well be the usual one..globl	_main_main:	movw	$BOOTSEG, %ax	movw	%ax, %ds	movw	$INITSEG, %ax	movw	%ax, %es	movw	$256, %cx	subw	%si, %si	subw	%di, %di	cld	rep	movsw	ljmp	$INITSEG, $go - _bootgo:		movw	%cs, %ax	movw	$(0x4000-12), %dx	# 0x4000 is arbitrary value >= length of					# bootsect + length of setup + room for stack					# 12 is disk parm size# bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde).  We# wouldn't have to worry about this if we checked the top of memory.  Also# my BIOS can be configured to put the wini drive tables in high memory# instead of in the vector table.  The old stack might have clobbered the# drive table.	movw	%ax, %ds	movw	%ax, %es	movw	%ax, %ss		# put stack at INITSEG:0x4000-12.	movw	%dx, %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 18 - the most we will encounter on an HD 1.44.   * *	High doesn't hurt.  Low does. * *	Segments are as follows: ds=es=ss=cs - INITSEG, *		fs = 0, gs = parameter table segment */	pushw	$0	popw	%fs	movw	$0x78, %bx		# fs:bx is parameter table address	lgs	%fs:(%bx),%si		# gs:si is source	movw	%dx, %di		# es:di is destination	movw	$6, %cx			# copy 12 bytes	cld	rep	movsw %gs:(%si), (%di)	movw	%dx, %di	movb	$18, 4(%di)		# patch sector count	movw	%di, %fs:(%bx)	movw	%es, %fs:2(%bx)	movw	%cs, %ax	movw	%ax, %fs	movw	%ax, %gs	xorb	%ah, %ah		# reset FDC 	xorb	%dl, %dl	int	$0x13	# load the setup-sectors directly after the bootblock.# Note that 'es' is already set up.load_setup:	xorw	%dx, %dx			# drive 0, head 0	movw	$0x0002, %cx			# sector 2, track 0	movw	$0x0200, %bx			# address = 512, in INITSEG	movw	$(0x0200 + SETUPSECS), %ax	# service 2, nr of sectors						# (assume all on head 0, track 0)	int	$0x13				# read it	jnc	ok_load_setup			# ok - continue	pushw	%ax			# dump error code	call	print_nl	movw	%sp, %bp	call	print_hex	popw	%ax		xorb	%dl, %dl		# reset FDC	xorb	%ah, %ah	int	$0x13	jmp	load_setupok_load_setup:# Get disk drive parameters, specifically nr of sectors/track/* It seems that there is no BIOS call to get the number of sectors.  Guess * 18 sectors if sector 18 can be read, 15 if sector 15 can be read. * Otherwise guess 9 */	xorw	%dx, %dx			# drive 0, head 0	movw	$0x0012, %cx			# sector 18, track 0	movw	$(0x200+(SETUPSECS*0x200)), %bx	# address after setup (es = cs)	movw	$0x0201, %ax			# service 2, 1 sector	int	$0x13	jnc	got_sectors	movb	$0x0f, %cl			# sector 15	movw	$0x0201, %ax			# service 2, 1 sector	int	$0x13	jnc	got_sectors	movb	$0x09, %cl	got_sectors:	movw	%cx, %cs:sectors - _boot	movw	$INITSEG, %ax	movw	%ax, %es# Print some inane message	movb	$0x03, %ah		# read cursor pos	xorb	%bh, %bh	int	$0x10		movw	$9, %cx	movw	$0x0007, %bx		# page 0, attribute 7 (normal)	movw	$msg1 - _boot, %bp	movw	$0x1301, %ax		# write string, move cursor	int	$0x10	# ok, we've written the message, now# we want to load the system (at 0x10000)	movw	$TSTLOAD, %ax	movw	%ax, %es		# segment of 0x010000	call	read_it	call	kill_motor	call	print_nl# after that (everyting loaded), we jump to# the setup-routine loaded directly after# the bootblock:	ljmp	$SETUPSEG,$0# This routine loads the system at address 0x10000, 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 0x1000)#sread:	.word 1+SETUPSECS	# sectors read of current trackhead:	.word 0			# current headtrack:	.word 0			# current trackread_it:	movw	%es, %ax	testw	$0x0fff, %axdie:		jne	die		# es must be at 64kB boundary	xorw	%bx,%bx		# bx is starting address within segmentrp_read:	movw	%es, %ax	subw	$TSTLOAD, %ax	# have we loaded all yet?	cmpw	syssize - _boot, %ax	jbe	ok1_read	retok1_read:	movw	%cs:sectors - _boot, %ax	subw	sread - _boot, %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	add	sread - _boot, %ax	cmpw	%cs:sectors - _boot, %ax	jne	ok3_read	movw	$1, %ax	subw	head - _boot, %ax	jne	ok4_read	incw	track - _bootok4_read:	movw	%ax, head - _boot	xorw	%ax, %axok3_read:	movw	%ax, sread - _boot	shlw	$9, %cx	addw	%cx, %bx	jnc	rp_read	movw	%es, %ax	addb	$0x10, %ah	movw	%ax, %es	xorw	%bx, %bx	jmp	rp_read	read_track:	pusha	pusha	movw	$0xe2e, %ax 	# loading... message 2e = .	movw	$7, %bx	int	$0x10	popa		movw	track - _boot, %dx	movw	sread - _boot, %cx	incw	%cx	movb	%dl, %ch	movw	head - _boot, %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:	movw	$5, %cx		# error code + 4 registers	movw	%sp, %bpprint_loop:	pushw	%cx		# save count left	call	print_nl	# nl for readability	cmpb	5, %cl		# see if register name is needed	jae	no_reg	movw	$(0xe05	+ 'A' - 1), %ax	subb	%cl, %al	int	$0x10	movb	$'X', %al	int	$0x10	movb	$':', %al		int	$0x10no_reg:	addw	$2, %bp		# next register	call	print_hex	# print it	popw	%cx	loop	print_loop	ret	print_nl:	movw	$0xe0d, %ax	# CR	int	$0x10	movb	$0x0a, %al	# LF	int	$0x10	ret	/* *	print_hex is for debugging purposes, and prints the word *	pointed to by ss:bp in hexadecmial.*/print_hex:	movw	$4, %cx		# 4 hex digits	movw	(%bp), %dx	# load word into dxprint_digit:	rolw	$4, %dx		# rotate so that lowest 4 bits are used	movb	$0xe, %ah	movb	%dl, %al	# mask off so we have only next nibble	andb	$0xf, %al	addb	$'0', %al	# convert to 0-based digit	cmpb	$'9', %al	# check for overflow	jbe	good_digit	addb	$('A' - '0' - 10), %al	good_digit:	int	$0x10	loop	print_digit	ret/* * This procedure 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. */kill_motor:	pushw	%dx	movw	$0x3f2, %dx	xorb	%al, %al	outb	%al, %dx	popw	%dx	retsectors:	.word 0msg1:	.byte 13,10	.ascii "Loading".org 497setup_sects:	.byte SETUPSECS.org 500syssize:	.word _syssize.org 508root_dev:	.word ROOT_DEVboot_flag:	.word 0xAA55_eboot:

⌨️ 快捷键说明

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