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

📄 setup.s

📁 底层驱动开发
💻 S
📖 第 1 页 / 共 2 页
字号:
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)# Then check for an APM BIOS...						# %ds points to the bootsector	movw	$0, 0x40			# version = 0 means no APM BIOS	movw	$0x05300, %ax			# APM BIOS installation check	xorw	%bx, %bx	int	$0x15	jc	done_apm_bios			# Nope, no APM BIOS		cmpw	$0x0504d, %bx			# Check for "PM" signature	jne	done_apm_bios			# No signature, no APM BIOS	andw	$0x02, %cx			# Is 32 bit supported?	je	done_apm_bios			# No 32-bit, no (good) APM BIOS	movw	$0x05304, %ax			# Disconnect first just in case	xorw	%bx, %bx	int	$0x15				# ignore return code	movw	$0x05303, %ax			# 32 bit connect	xorl	%ebx, %ebx	xorw	%cx, %cx			# paranoia :-)	xorw	%dx, %dx			#   ...	xorl	%esi, %esi			#   ...	xorw	%di, %di			#   ...	int	$0x15	jc	no_32_apm_bios			# Ack, error. 	movw	%ax,  (66)			# BIOS code segment	movl	%ebx, (68)			# BIOS entry point offset	movw	%cx,  (72)			# BIOS 16 bit code segment	movw	%dx,  (74)			# BIOS data segment	movl	%esi, (78)			# BIOS code segment lengths	movw	%di,  (82)			# BIOS data segment length# Redo the installation check as the 32 bit connect# modifies the flags returned on some BIOSs	movw	$0x05300, %ax			# APM BIOS installation check	xorw	%bx, %bx	xorw	%cx, %cx			# paranoia	int	$0x15	jc	apm_disconnect			# error -> shouldn't happen	cmpw	$0x0504d, %bx			# check for "PM" signature	jne	apm_disconnect			# no sig -> shouldn't happen	movw	%ax, (64)			# record the APM BIOS version	movw	%cx, (76)			# and flags	jmp	done_apm_biosapm_disconnect:					# Tidy up	movw	$0x05304, %ax			# Disconnect	xorw	%bx, %bx	int	$0x15				# ignore return code	jmp	done_apm_biosno_32_apm_bios:	andw	$0xfffd, (76)			# remove 32 bit support bitdone_apm_bios:#endif#include "edd.S"# Now we want to move to protected mode ...	cmpw	$0, %cs:realmode_swtch	jz	rmodeswtch_normal	lcall	*%cs:realmode_swtch	jmp	rmodeswtch_endrmodeswtch_normal:        pushw	%cs	call	default_switchrmodeswtch_end:# we get the code32 start address and modify the below 'jmpi'# (loader may have changed it)	movl	%cs:code32_start, %eax	movl	%eax, %cs:code32# Now we move the system to its rightful place ... but we check if we have a# big-kernel. In that case we *must* not move it ...	testb	$LOADED_HIGH, %cs:loadflags	jz	do_move0			# .. then we have a normal low						# loaded zImage						# .. or else we have a high						# loaded bzImage	jmp	end_move			# ... and we skip movingdo_move0:	movw	$0x100, %ax			# start of destination segment	movw	%cs, %bp			# aka SETUPSEG	subw	$DELTA_INITSEG, %bp		# aka INITSEG	movw	%cs:start_sys_seg, %bx		# start of source segment	clddo_move:	movw	%ax, %es			# destination segment	incb	%ah				# instead of add ax,#0x100	movw	%bx, %ds			# source segment	addw	$0x100, %bx	subw	%di, %di	subw	%si, %si	movw 	$0x800, %cx	rep	movsw	cmpw	%bp, %bx			# assume start_sys_seg > 0x200,						# so we will perhaps read one						# page more than needed, but						# never overwrite INITSEG						# because destination is a						# minimum one page below source	jb	do_moveend_move:# then we load the segment descriptors	movw	%cs, %ax			# aka SETUPSEG	movw	%ax, %ds		# Check whether we need to be downward compatible with version <=201	cmpl	$0, cmd_line_ptr	jne	end_move_self		# loader uses version >=202 features	cmpb	$0x20, type_of_loader	je	end_move_self		# bootsect loader, we know of it# Boot loader doesnt support boot protocol version 2.02.# If we have our code not at 0x90000, we need to move it there now.# We also then need to move the params behind it (commandline)# Because we would overwrite the code on the current IP, we move# it in two steps, jumping high after the first one.	movw	%cs, %ax	cmpw	$SETUPSEG, %ax	je	end_move_self	cli					# make sure we really have						# interrupts disabled !						# because after this the stack						# should not be used	subw	$DELTA_INITSEG, %ax		# aka INITSEG	movw	%ss, %dx	cmpw	%ax, %dx	jb	move_self_1	addw	$INITSEG, %dx	subw	%ax, %dx			# this will go into %ss after						# the movemove_self_1:	movw	%ax, %ds	movw	$INITSEG, %ax			# real INITSEG	movw	%ax, %es	movw	%cs:setup_move_size, %cx	std					# we have to move up, so we use						# direction down because the						# areas may overlap	movw	%cx, %di	decw	%di	movw	%di, %si	subw	$move_self_here+0x200, %cx	rep	movsb	ljmp	$SETUPSEG, $move_self_heremove_self_here:	movw	$move_self_here+0x200, %cx	rep	movsb	movw	$SETUPSEG, %ax	movw	%ax, %ds	movw	%dx, %ssend_move_self:					# now we are at the right place## Enable A20.  This is at the very best an annoying procedure.# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.# AMD Elan bug fix by Robert Schwebel.##if defined(CONFIG_X86_ELAN)	movb $0x02, %al			# alternate A20 gate	outb %al, $0x92			# this works on SC410/SC520a20_elan_wait:	call a20_test	jz a20_elan_wait	jmp a20_done#endifA20_TEST_LOOPS		=  32		# Iterations per waitA20_ENABLE_LOOPS	= 255		# Total loops to try		#ifndef CONFIG_X86_VOYAGERa20_try_loop:	# First, see if we are on a system with no A20 gate.a20_none:	call	a20_test	jnz	a20_done	# Next, try the BIOS (INT 0x15, AX=0x2401)a20_bios:	movw	$0x2401, %ax	pushfl					# Be paranoid about flags	int	$0x15	popfl	call	a20_test	jnz	a20_done	# Try enabling A20 through the keyboard controller#endif /* CONFIG_X86_VOYAGER */a20_kbc:	call	empty_8042#ifndef CONFIG_X86_VOYAGER	call	a20_test			# Just in case the BIOS worked	jnz	a20_done			# but had a delayed reaction.#endif	movb	$0xD1, %al			# command write	outb	%al, $0x64	call	empty_8042	movb	$0xDF, %al			# A20 on	outb	%al, $0x60	call	empty_8042#ifndef CONFIG_X86_VOYAGER	# Wait until a20 really *is* enabled; it can take a fair amount of	# time on certain systems; Toshiba Tecras are known to have this	# problem.a20_kbc_wait:	xorw	%cx, %cxa20_kbc_wait_loop:	call	a20_test	jnz	a20_done	loop	a20_kbc_wait_loop	# Final attempt: use "configuration port A"a20_fast:	inb	$0x92, %al			# Configuration Port A	orb	$0x02, %al			# "fast A20" version	andb	$0xFE, %al			# don't accidentally reset	outb	%al, $0x92	# Wait for configuration port A to take effecta20_fast_wait:	xorw	%cx, %cxa20_fast_wait_loop:	call	a20_test	jnz	a20_done	loop	a20_fast_wait_loop	# A20 is still not responding.  Try frobbing it again.	# 	decb	(a20_tries)	jnz	a20_try_loop		movw	$a20_err_msg, %si	call	prtstra20_die:	hlt	jmp	a20_diea20_tries:	.byte	A20_ENABLE_LOOPSa20_err_msg:	.ascii	"linux: fatal error: A20 gate not responding!"	.byte	13, 10, 0	# If we get here, all is gooda20_done:#endif /* CONFIG_X86_VOYAGER */# set up gdt and idt	lidt	idt_48				# load idt with 0,0	xorl	%eax, %eax			# Compute gdt_base	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)	shll	$4, %eax	addl	$gdt, %eax	movl	%eax, (gdt_48+2)	lgdt	gdt_48				# load gdt with whatever is						# appropriate# make sure any possible coprocessor is properly reset..	xorw	%ax, %ax	outb	%al, $0xf0	call	delay	outb	%al, $0xf1	call	delay# well, that went ok, I hope. Now we mask all interrupts - the rest# is done in init_IRQ().	movb	$0xFF, %al			# mask all interrupts for now	outb	%al, $0xA1	call	delay		movb	$0xFB, %al			# mask all irq's but irq2 which	outb	%al, $0x21			# is cascaded# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't# need no steenking BIOS anyway (except for the initial loading :-).# The BIOS-routine wants lots of unnecessary data, and it's less# "interesting" anyway. This is how REAL programmers do it.## Well, now's the time to actually move into protected mode. To make# things as simple as possible, we do no register set-up or anything,# we let the gnu-compiled 32-bit programs do that. We just jump to# absolute address 0x1000 (or the loader supplied one),# in 32-bit protected mode.## Note that the short jump isn't strictly needed, although there are# reasons why it might be a good idea. It won't hurt in any case.	movw	$1, %ax				# protected mode (PE) bit	lmsw	%ax				# This is it!	jmp	flush_instrflush_instr:	xorw	%bx, %bx			# Flag to indicate a boot	xorl	%esi, %esi			# Pointer to real-mode code	movw	%cs, %si	subw	$DELTA_INITSEG, %si	shll	$4, %esi			# Convert to 32-bit pointer# jump to startup_32 in arch/i386/boot/compressed/head.S#	# NOTE: For high loaded big kernels we need a#	jmpi    0x100000,__BOOT_CS##	but we yet haven't reloaded the CS register, so the default size #	of the target offset still is 16 bit.#	However, using an operand prefix (0x66), the CPU will properly#	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference#	Manual, Mixing 16-bit and 32-bit code, page 16-6)	.byte 0x66, 0xea			# prefix + jmpi-opcodecode32:	.long	0x1000				# will be set to 0x100000						# for big kernels	.word	__BOOT_CS# Here's a bunch of information about your current kernel..kernel_version:	.ascii	UTS_RELEASE		.ascii	" ("		.ascii	LINUX_COMPILE_BY		.ascii	"@"		.ascii	LINUX_COMPILE_HOST		.ascii	") "		.ascii	UTS_VERSION		.byte	0# This is the default real mode switch routine.# to be called just before protected mode transitiondefault_switch:	cli					# no interrupts allowed !	movb	$0x80, %al			# disable NMI for bootup						# sequence	outb	%al, $0x70	lret#ifndef CONFIG_X86_VOYAGER# This routine tests whether or not A20 is enabled.  If so, it# exits with zf = 0.## The memory address used, 0x200, is the int $0x80 vector, which# should be safe.A20_TEST_ADDR = 4*0x80a20_test:	pushw	%cx	pushw	%ax	xorw	%cx, %cx	movw	%cx, %fs			# Low memory	decw	%cx	movw	%cx, %gs			# High memory area	movw	$A20_TEST_LOOPS, %cx	movw	%fs:(A20_TEST_ADDR), %ax	pushw	%axa20_test_wait:	incw	%ax	movw	%ax, %fs:(A20_TEST_ADDR)	call	delay				# Serialize and make delay constant	cmpw	%gs:(A20_TEST_ADDR+0x10), %ax	loope	a20_test_wait	popw	%fs:(A20_TEST_ADDR)	popw	%ax	popw	%cx	ret	#endif /* CONFIG_X86_VOYAGER */# This routine checks that the keyboard command queue is empty# (after emptying the output buffers)## Some machines have delusions that the keyboard buffer is always full# with no keyboard attached...## If there is no keyboard controller, we will usually get 0xff# to all the reads.  With each IO taking a microsecond and# a timeout of 100,000 iterations, this can take about half a# second ("delay" == outb to port 0x80). That should be ok,# and should also be plenty of time for a real keyboard controller# to empty.#empty_8042:	pushl	%ecx	movl	$100000, %ecxempty_8042_loop:	decl	%ecx	jz	empty_8042_end_loop	call	delay	inb	$0x64, %al			# 8042 status port	testb	$1, %al				# output buffer?	jz	no_output	call	delay	inb	$0x60, %al			# read it	jmp	empty_8042_loopno_output:	testb	$2, %al				# is input buffer full?	jnz	empty_8042_loop			# yes - loopempty_8042_end_loop:	popl	%ecx	ret# Read the cmos clock. Return the seconds in algettime:	pushw	%cx	movb	$0x02, %ah	int	$0x1a	movb	%dh, %al			# %dh contains the seconds	andb	$0x0f, %al	movb	%dh, %ah	movb	$0x04, %cl	shrb	%cl, %ah	aad	popw	%cx	ret# Delay is needed after doing I/Odelay:	outb	%al,$0x80	ret# Descriptor tables## NOTE: The intel manual says gdt should be sixteen bytes aligned for# efficiency reasons.  However, there are machines which are known not# to boot with misaligned GDTs, so alter this at your peril!  If you alter# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two# empty GDT entries (one for NULL and one reserved).## NOTE:	On some CPUs, the GDT must be 8 byte aligned.  This is# true for the Voyager Quad CPU card which will not boot without# This directive.  16 byte aligment is recommended by intel.#	.align 16gdt:	.fill GDT_ENTRY_BOOT_CS,8,0	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)	.word	0				# base address = 0	.word	0x9A00				# code read/exec	.word	0x00CF				# granularity = 4096, 386						#  (+5th nibble of limit)	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)	.word	0				# base address = 0	.word	0x9200				# data read/write	.word	0x00CF				# granularity = 4096, 386						#  (+5th nibble of limit)gdt_end:	.align	4		.word	0				# alignment byteidt_48:	.word	0				# idt limit = 0	.word	0, 0				# idt base = 0L	.word	0				# alignment bytegdt_48:	.word	gdt_end - gdt - 1		# gdt limit	.word	0, 0				# gdt base (filled in later)# Include video setup & detection code#include "video.S"# Setup signature -- must be lastsetup_sig1:	.word	SIG1setup_sig2:	.word	SIG2# After this point, there is some free space which is used by the video mode# handling code to store the temporary mode table (not used by the kernel).modelist:.textendtext:.dataenddata:.bssendbss:

⌨️ 快捷键说明

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