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

📄 head.s

📁 最早的linux操作系统源代码(3)
💻 S
字号:
/* *  head.s contains the 32-bit startup code. * * NOTE!!! Startup happens at absolute address 0x00000000, which is also where * the page directory will exist. The startup code will be overwritten by * the page directory. */.text.globl idt,gdt,pg_dirpg_dir:.globl startup_32startup_32:	movl $0x10,%eax	mov %ax,%ds	mov %ax,%es	mov %ax,%fs	mov %ax,%gs	lss stack_start,%esp	call setup_idt	call setup_gdt	movl $0x10,%eax		# reload all the segment registers	mov %ax,%ds		# after changing gdt. CS was already	mov %ax,%es		# reloaded in 'setup_gdt'	mov %ax,%fs	mov %ax,%gs	lss stack_start,%esp	xorl %eax,%eax1:	incl %eax		# check that A20 really IS enabled	movl %eax,0x000000	cmpl %eax,0x100000	je 1b	movl %cr0,%eax		# check math chip	andl $0x80000011,%eax	# Save PG,ET,PE	testl $0x10,%eax	jne 1f			# ET is set - 387 is present	orl $4,%eax		# else set emulate bit1:	movl %eax,%cr0	jmp after_page_tables/* *  setup_idt * *  sets up a idt with 256 entries pointing to *  ignore_int, interrupt gates. It then loads *  idt. Everything that wants to install itself *  in the idt-table may do so themselves. Interrupts *  are enabled elsewhere, when we can be relatively *  sure everything is ok. This routine will be over- *  written by the page tables. */setup_idt:	lea ignore_int,%edx	movl $0x00080000,%eax	movw %dx,%ax		/* selector = 0x0008 = cs */	movw $0x8E00,%dx	/* interrupt gate - dpl=0, present */	lea idt,%edi	mov $256,%ecxrp_sidt:	movl %eax,(%edi)	movl %edx,4(%edi)	addl $8,%edi	dec %ecx	jne rp_sidt	lidt idt_descr	ret/* *  setup_gdt * *  This routines sets up a new gdt and loads it. *  Only two entries are currently built, the same *  ones that were built in init.s. The routine *  is VERY complicated at two whole lines, so this *  rather long comment is certainly needed :-). *  This routine will beoverwritten by the page tables. */setup_gdt:	lgdt gdt_descr	ret.org 0x1000pg0:.org 0x2000pg1:.org 0x3000pg2:		# This is not used yet, but if you		# want to expand past 8 Mb, you'll have		# to use it..org 0x4000after_page_tables:	pushl $0		# These are the parameters to main :-)	pushl $0	pushl $0	pushl $L6		# return address for main, if it decides to.	pushl $main	jmp setup_pagingL6:	jmp L6			# main should never return here, but				# just in case, we know what happens./* This is the default interrupt "handler" :-) */.align 2ignore_int:	incb 0xb8000+160		# put something on the screen	movb $2,0xb8000+161		# so that we know something	iret				# happened/* * Setup_paging * * This routine sets up paging by setting the page bit * in cr0. The page tables are set up, identity-mapping * the first 8MB. The pager assumes that no illegal * addresses are produced (ie >4Mb on a 4Mb machine). * * NOTE! Although all physical memory should be identity * mapped by this routine, only the kernel page functions * use the >1Mb addresses directly. All "normal" functions * use just the lower 1Mb, or the local data space, which * will be mapped to some other place - mm keeps track of * that. * * For those with more memory than 8 Mb - tough luck. I've * not got it, why should you :-) The source is here. Change * it. (Seriously - it shouldn't be too difficult. Mostly * change some constants etc. I left it at 8Mb, as my machine * even cannot be extended past that (ok, but it was cheap :-) * I've tried to show which constants to change by having * some kind of marker at them (search for "8Mb"), but I * won't guarantee that's all :-( ) */.align 2setup_paging:	movl $1024*3,%ecx	xorl %eax,%eax	xorl %edi,%edi			/* pg_dir is at 0x000 */	cld;rep;stosl	movl $pg0+7,pg_dir		/* set present bit/user r/w */	movl $pg1+7,pg_dir+4		/*  --------- " " --------- */	movl $pg1+4092,%edi	movl $0x7ff007,%eax		/*  8Mb - 4096 + 7 (r/w user,p) */	std1:	stosl			/* fill pages backwards - more efficient :-) */	subl $0x1000,%eax	jge 1b	xorl %eax,%eax		/* pg_dir is at 0x0000 */	movl %eax,%cr3		/* cr3 - page directory start */	movl %cr0,%eax	orl $0x80000000,%eax	movl %eax,%cr0		/* set paging (PG) bit */	ret			/* this also flushes prefetch-queue */.align 2.word 0idt_descr:	.word 256*8-1		# idt contains 256 entries	.long idt.align 2.word 0gdt_descr:	.word 256*8-1		# so does gdt (not that that's any	.long gdt		# magic number, but it works for me :^)	.align 8 idt:	.fill 256,8,0		# idt is uninitializedgdt:	.quad 0x0000000000000000	/* NULL descriptor */	.quad 0x00c09a00000007ff	/* 8Mb */	.quad 0x00c09200000007ff	/* 8Mb */	.quad 0x0000000000000000	/* TEMPORARY - don't use */	.fill 252,8,0			/* space for LDT's and TSS's etc */

⌨️ 快捷键说明

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