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

📄 head.s

📁 系统启动时检测内存状况的软件C代码
💻 S
📖 第 1 页 / 共 2 页
字号:
	pushl	$7 /* vector */	jmp	int_handvec8:	/* error code */	pushl	$8 /* vector */	jmp	int_handvec9:	pushl	$0 /* error code */	pushl	$9 /* vector */	jmp int_handvec10:	/* error code */	pushl	$10 /* vector */	jmp	int_handvec11:	/* error code */	pushl	$11 /* vector */	jmp	int_handvec12:	/* error code */	pushl	$12 /* vector */	jmp	int_handvec13:	/* error code */	pushl	$13 /* vector */	jmp	int_handvec14:	/* error code */	pushl	$14 /* vector */	jmp	int_handvec15:	pushl	$0 /* error code */	pushl	$15 /* vector */	jmp	int_handvec16:	pushl	$0 /* error code */	pushl	$16 /* vector */	jmp	int_handvec17:	/* error code */	pushl	$17 /* vector */	jmp	int_handvec18:	pushl	$0 /* error code */	pushl	$18 /* vector */	jmp	int_handvec19:	pushl	$0 /* error code */	pushl	$19 /* vector */	jmp	int_handint_hand:	pushl	%eax	pushl	%ebx	pushl	%ecx	pushl	%edx	pushl	%edi	pushl	%esi	pushl	%ebp	/* original stack pointer */	leal	20(%esp), %eax	pushl	%eax	pushl	%esp /* pointer to structure on the stack */	call	inter	addl	$8, %esp	popl	%ebp	popl	%esi	popl	%edi	popl	%edx	popl	%ecx	popl	%ebx	popl	%eax	iret/* * The interrupt descriptor table has room for 32 idt's */.align 4.word 0idt_descr:	.word 20*8-1	       # idt contains 32 entries	.long 0idt:	.fill 20,8,0	       # idt is uninitializedgdt_descr:	.word gdt_end - gdt - 1	.long 0.align 4.globl gdt, gdt_endgdt:	.quad 0x0000000000000000	/* NULL descriptor */	.quad 0x0000000000000000	/* not used */	.quad 0x00cf9a000000ffff	/* 0x10 main 4gb code at 0x000000 */	.quad 0x00cf92000000ffff	/* 0x18 main 4gb data at 0x000000 */	.word	0xFFFF				# 16bit 64KB - (0x10000*1 = 64KB)	.word	0				# base address = SETUPSEG	.byte	0x00, 0x9b			# code read/exec/accessed	.byte	0x00, 0x00			# granularity = bytes	.word	0xFFFF				# 16bit 64KB - (0x10000*1 = 64KB)	.word	0				# base address = SETUPSEG	.byte	0x00, 0x93			# data read/write/accessed	.byte	0x00, 0x00			# granularity = bytesgdt_end:.data.macro ptes64 start, count=64.quad \start + 0x0000000 + 0xE3.quad \start + 0x0200000 + 0xE3.quad \start + 0x0400000 + 0xE3.quad \start + 0x0600000 + 0xE3.quad \start + 0x0800000 + 0xE3.quad \start + 0x0A00000 + 0xE3.quad \start + 0x0C00000 + 0xE3.quad \start + 0x0E00000 + 0xE3.if \count-1ptes64 "(\start+0x01000000)",\count-1.endif.endm.macro maxdepth depth=1.if \depth-1maxdepth \depth-1.endif.endmmaxdepth.balign 4096.globl pd0pd0:	ptes64 0x0000000000000000.balign 4096.globl pd1pd1:	ptes64 0x0000000040000000.balign 4096.globl pd2pd2:	ptes64 0x0000000080000000.balign 4096.globl pd3pd3:	ptes64 0x00000000C0000000.balign 4096.globl pdppdp:	.long pd0 + 1	.long 0	.long pd1 + 1	.long 0	.long pd2 + 1	.long 0	.long pd3 + 1	.long 0.previous#define RSTART startup_32	.globl query_pcbiosquery_pcbios:	/* Save the caller save registers */	pushl	%ebx	pushl	%esi	pushl	%edi	pushl	%ebp	call	1f1:	popl	%ebx	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx	/* Compute the reloc address */	leal	RSTART@GOTOFF(%ebx), %esi	/* Fixup real code pointer */	movl	%esi, %eax	shrl	$4, %eax	movw	%ax, 2 + realptr@GOTOFF(%ebx)	/* Fixup protected code pointer */	leal	prot@GOTOFF(%ebx), %eax	movl	%eax, protptr@GOTOFF(%ebx)	/* Compute the gdt fixup */	movl	%esi, %eax	shll	$16, %eax	# Base low	movl	%esi, %ecx	shrl	$16, %ecx	andl	$0xff, %ecx	movl	%esi, %edx	andl	$0xff000000, %edx	orl	%edx, %ecx	/* Fixup the gdt */	andl	$0x0000ffff, REAL_CS + 0 + gdt@GOTOFF(%ebx)	orl	%eax,        REAL_CS + 0 + gdt@GOTOFF(%ebx)	andl	$0x00ffff00, REAL_CS + 4 + gdt@GOTOFF(%ebx)	orl	%ecx,        REAL_CS + 4 + gdt@GOTOFF(%ebx)	andl	$0x0000ffff, REAL_DS + 0 + gdt@GOTOFF(%ebx)	orl	%eax,        REAL_DS + 0 + gdt@GOTOFF(%ebx)	andl	$0x00ffff00, REAL_DS + 4 + gdt@GOTOFF(%ebx)	orl	%ecx,        REAL_DS + 4 + gdt@GOTOFF(%ebx)	/* Fixup the gdt_descr */	leal	gdt@GOTOFF(%ebx), %eax	movl	%eax, 2 + gdt_descr@GOTOFF(%ebx)	lidt	idt_real@GOTOFF(%ebx)	/* Don't disable the a20 line */	/* Load 16bit data segments, to ensure the segment limits are set */	movl	$REAL_DS, %eax	movl	%eax, %ds	movl	%eax, %es	movl	%eax, %ss	movl	%eax, %fs	movl	%eax, %gs	/* Compute the stack base */	leal	stack@GOTOFF(%ebx), %ecx	/* Compute the address of meminfo */	leal	mem_info@GOTOFF(%ebx), %edi	/* switch to 16bit mode */	ljmp	$REAL_CS, $1f - RSTART1:	.code16	/* Disable Paging and protected mode */	/* clear the PG & PE bits of CR0 */	movl	%cr0,%eax	andl	$~((1 << 31)|(1<<0)),%eax	movl	%eax,%cr0	/* make intersegment jmp to flush the processor pipeline	 * and reload %cs:%eip (to clear upper 16 bits of %eip).	 */	ljmp	*(realptr - RSTART)real:	/* we are in real mode now	 * set up the real mode segment registers : %ds, %ss, %es, %gs, %fs	 */	movw	%cs, %ax	movw	%ax, %ds	movw	%ax, %es	movw	%ax, %fs	movw	%ax, %gs	movw	%ax, %ss	/* Adjust the stack pointer */	movl	%ecx, %eax	shrl	$4, %eax	movw	%ax, %ss	subl	%ecx, %esp	/* Save my base pointer */	pushl	%ebx	/* Setup %ds to point to my data area */	shrl	$4, %edi	movl	%edi, %ds	/* Enable interrupts or BIOS's go crazy */	sti# Get memory size (extended mem, kB)#define SMAP	0x534d4150	xorl	%eax, %eax	movl	%eax, (E88)	movl	%eax, (E801)	movl	%eax, (E820NR)# Try three different memory detection schemes.  First, try# e820h, which lets us assemble a memory map, then try e801h,# which returns a 32-bit memory size, and finally 88h, which# returns 0-64m# method E820H:# the memory map from hell.  e820h returns memory classified into# a whole bunch of different types, and allows memory holes and# everything.  We scan through this memory map and build a list# of the first 32 memory areas, which we return at [E820MAP].# This is documented at http://www.teleport.com/~acpi/acpihtml/topic245.htmmeme820:	xorl	%ebx, %ebx			# continuation counter	movw	$E820MAP, %di			# point into the whitelist						# so we can have the bios						# directly write into it.jmpe820:	movl	$0x0000e820, %eax		# e820, upper word zeroed	movl	$SMAP, %edx			# ascii 'SMAP'	movl	$20, %ecx			# size of the e820rec	pushw	%ds				# data record.	popw	%es	int	$0x15				# make the call	jc	bail820				# fall to e801 if it fails	cmpl	$SMAP, %eax			# check the return is `SMAP'	jne	bail820				# fall to e801 if it fails#	cmpl	$1, 16(%di)			# is this usable memory?#	jne	again820	# If this is usable memory, we save it by simply advancing %di by	# sizeof(e820rec).	#good820:	movb	(E820NR), %al			# up to 32 entries	cmpb	$E820MAX, %al	jnl	bail820	incb	(E820NR)	movw	%di, %ax	addw	$E820ENTRY_SIZE, %ax	movw	%ax, %diagain820:	cmpl	$0, %ebx			# check to see if	jne	jmpe820				# %ebx is set to EOFbail820:# method E801H:# memory size is in 1k chunksizes, to avoid confusing loadlin.# we store the 0xe801 memory size in a completely different place,# because it will most likely be longer than 16 bits.meme801:	stc					# fix to work around buggy	xorw	%cx,%cx				# BIOSes which dont clear/set	xorw	%dx,%dx				# carry on pass/error of						# e801h memory size call						# or merely pass cx,dx though						# without changing them.	movw	$0xe801, %ax	int	$0x15	jc	mem88	cmpw	$0x0, %cx			# Kludge to handle BIOSes	jne	e801usecxdx			# which report their extended	cmpw	$0x0, %dx			# memory in AX/BX rather than	jne	e801usecxdx			# CX/DX.  The spec I have read	movw	%ax, %cx			# seems to indicate AX/BX	movw	%bx, %dx			# are more reasonable anyway...e801usecxdx:	andl	$0xffff, %edx			# clear sign extend	shll	$6, %edx			# and go from 64k to 1k chunks	movl	%edx, (E801)			# store extended memory size	andl	$0xffff, %ecx			# clear sign extend 	addl	%ecx, (E801)			# and add lower memory into						# total size.# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or# 64mb, depending on the bios) in ax.mem88:	movb	$0x88, %ah	int	$0x15	movw	%ax, (E88)#ifdef APM_OFF# check for APM BIOS	movw	$0x5300, %ax    # APM BIOS installation check	xorw	%bx, %bx	int	$0x15	jc	done_apm_bios   # error -> no APM BIOS	cmpw	$0x504d, %bx    # check for "PM" signature	jne	done_apm_bios   # no signature -> no APM BIOS	movw	$0x5304, %ax    # Disconnect first just in case	xorw	%bx, %bx	int	$0x15           # ignore return code	movw	$0x5301, %ax    # Real Mode connect	xorw	%bx, %bx	int	$0x15	jc	done_apm_bios   # error	movw	$0x5308, %ax    # Disable APM	mov	$0xffff, %bx	xorw	%cx, %cx	int	$0x15done_apm_bios:#endif	/* O.k. the BIOS query is done switch back to protected mode */	cli	/* Restore my saved variables */	popl	%ebx	/* Get an convinient %ds */	movw	%cs, %ax	movw	%ax, %ds	/* Load the global descriptor table */	addr32 lgdt	gdt_descr - RSTART	/* Turn on protected mode */	/* Set the PE bit in CR0 */	movl	%cr0,%eax	orl	$(1<<0),%eax	movl	%eax,%cr0	/* flush the prefetch queue, and relaod %cs:%eip */	data32 ljmp	*(protptr - RSTART)prot:	.code32	/* Reload other segment registers */	movl	$KERNEL_DS, %eax	movl	%eax, %ds	movl	%eax, %es	movl	%eax, %fs	movl	%eax, %gs	movl	%eax, %ss	/* Adjust the stack pointer */	leal	stack@GOTOFF(%ebx), %eax	addl	%eax, %esp	/* Restore the caller saved registers */	popl	%ebp	popl	%edi	popl	%esi	popl	%ebx	movl	$1, %eax	retrealptr:	.word	real - RSTART	.word	0x0000protptr:	.long	0	.long	KERNEL_CSidt_real:	.word	0x400 - 1			# idt limit ( 256 entries)	.word	0, 0				# idt base = 0L.datazerobss:	.long	1clear_display:	.long	1.previous.data.balign 16	.globl mem_infomem_info:	. = . + MEMINFO_SIZE.previous.bss.balign 16stack:	. = . + 4096stack_top:.previous

⌨️ 快捷键说明

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