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

📄 locore.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 3 页
字号:
/*- * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	from: @(#)locore.s	7.3 (Berkeley) 5/13/91 *	from NetBSD: Id: locore.s,v 1.12 1993/05/27 16:44:13 cgd Exp * *      @(#)locore.s	8.3 (Berkeley) 9/23/93 *//* * locore.s:	4BSD machine support for the Intel 386 *		Preliminary version *		Written by William F. Jolitz, 386BSD Project */#include "assym.s"#include "machine/psl.h"#include "machine/pte.h"#include "errno.h"#include "machine/trap.h"#include "machine/specialreg.h"#ifdef cgd_notdef#include "machine/cputypes.h"#endif#define	KDSEL		0x10/* * Note: This version greatly munged to avoid various assembler errors * that may be fixed in newer versions of gas. Perhaps newer versions * will have more pleasant appearance. */	.set	IDXSHIFT,10	.set	SYSTEM,0xFE000000	# virtual address of system start	/*note: gas copys sign bit (e.g. arithmetic >>), can't do SYSTEM>>22! */	.set	SYSPDROFF,0x3F8		# Page dir index of System Base#define	NOP	inb $0x84, %al ; inb $0x84, %al #define	ALIGN32	.align 2	/* 2^2  = 4 *//* * PTmap is recursive pagemap at top of virtual address space. * Within PTmap, the page directory can be found (third indirection). */	.set	PDRPDROFF,0x3F7		# Page dir index of Page dir	.globl	_PTmap, _PTD, _PTDpde, _Sysmap	.set	_PTmap,0xFDC00000	.set	_PTD,0xFDFF7000	.set	_Sysmap,0xFDFF8000	.set	_PTDpde,0xFDFF7000+4*PDRPDROFF/* * APTmap, APTD is the alternate recursive pagemap. * It's used when modifying another process's page tables. */	.set	APDRPDROFF,0x3FE		# Page dir index of Page dir	.globl	_APTmap, _APTD, _APTDpde	.set	_APTmap,0xFF800000	.set	_APTD,0xFFBFE000	.set	_APTDpde,0xFDFF7000+4*APDRPDROFF/* * Access to each processes kernel stack is via a region of * per-process address space (at the beginning), immediatly above * the user process stack. */	.set	_kstack, USRSTACK	.globl	_kstack	.set	PPDROFF,0x3F6	.set	PPTEOFF,0x400-UPAGES	# 0x3FE#define	ENTRY(name) \	.globl _/**/name; _/**/name:#define	ALTENTRY(name) \	.globl _/**/name; _/**/name:/* * Initialization */	.data	.globl	_cpu,_cold,_boothowto,_bootdev,_cyloffset,_atdevbase,_atdevphys_cpu:	.long	0		# are we 386, 386sx, or 486_cold:	.long	1		# cold till we are not_atdevbase:	.long	0	# location of start of iomem in virtual_atdevphys:	.long	0	# location of device mapping ptes (phys)	.globl	_IdlePTD, _KPTphys_IdlePTD:	.long	0_KPTphys:	.long	0	.space 512tmpstk:	.text	.globl	startstart:	movw	$0x1234,%ax	movw	%ax,0x472	# warm boot	jmp	1f	.space	0x500		# skip over warm boot shit	/*	 * pass parameters on stack (howto, bootdev, unit, cyloffset)	 * note: 0(%esp) is return address of boot	 * ( if we want to hold onto /boot, it's physical %esp up to _end)	 */ 1:	movl	4(%esp),%eax	movl	%eax,_boothowto-SYSTEM	movl	8(%esp),%eax	movl	%eax,_bootdev-SYSTEM	movl	12(%esp),%eax	movl	%eax, _cyloffset-SYSTEM#ifdef cgd_notdef	/* find out our CPU type. */        pushfl        popl    %eax        movl    %eax, %ecx        xorl    $0x40000, %eax        pushl   %eax        popfl        pushfl        popl    %eax        xorl    %ecx, %eax        shrl    $18, %eax        andl    $1, %eax        push    %ecx        popfl              cmpl    $0, %eax        jne     1f        movl    $CPU_386, _cpu-SYSTEM	jmp	2f1:      movl    $CPU_486, _cpu-SYSTEM2:#endif#ifdef garbage	/* count up memory */	xorl	%eax,%eax		# start with base memory at 0x0	#movl	$ 0xA0000/NBPG,%ecx	# look every 4K up to 640K	movl	$ 0xA0,%ecx		# look every 4K up to 640K1:	movl	0(%eax),%ebx		# save location to check	movl	$0xa55a5aa5,0(%eax)	# write test pattern	/* flush stupid cache here! (with bcopy (0,0,512*1024) ) */	cmpl	$0xa55a5aa5,0(%eax)	# does not check yet for rollover	jne	2f	movl	%ebx,0(%eax)		# restore memory	addl	$ NBPG,%eax	loop	1b2:	shrl	$12,%eax	movl	%eax,_Maxmem-SYSTEM	movl	$0x100000,%eax		# next, talley remaining memory	#movl	$((0xFFF000-0x100000)/NBPG),%ecx	movl	$(0xFFF-0x100),%ecx1:	movl	0(%eax),%ebx		# save location to check	movl	$0xa55a5aa5,0(%eax)	# write test pattern	cmpl	$0xa55a5aa5,0(%eax)	# does not check yet for rollover	jne	2f	movl	%ebx,0(%eax)		# restore memory	addl	$ NBPG,%eax	loop	1b2:	shrl	$12,%eax	movl	%eax,_Maxmem-SYSTEM#endif/* find end of kernel image */	movl	$_end-SYSTEM,%ecx	addl	$ NBPG-1,%ecx	andl	$~(NBPG-1),%ecx	movl	%ecx,%esi/* clear bss and memory for bootstrap pagetables. */	movl	$_edata-SYSTEM,%edi	subl	%edi,%ecx	addl	$(UPAGES+5)*NBPG,%ecx/* * Virtual address space of kernel: * *	text | data | bss | page dir | proc0 kernel stack | usr stk map | Sysmap *			     0               1       2       3             4 */	xorl	%eax,%eax	# pattern	cld	rep	stosb	movl	%esi,_IdlePTD-SYSTEM /*physical address of Idle Address space */	movl	$ tmpstk-SYSTEM,%esp	# bootstrap stack end location#define	fillkpt		\1:	movl	%eax,0(%ebx)	; \	addl	$ NBPG,%eax	; /* increment physical address */ \	addl	$4,%ebx		; /* next pte */ \	loop	1b		;/* * Map Kernel * N.B. don't bother with making kernel text RO, as 386 * ignores R/W AND U/S bits on kernel access (only v works) ! * * First step - build page tables */	movl	%esi,%ecx		# this much memory,	shrl	$ PGSHIFT,%ecx		# for this many pte s	addl	$ UPAGES+4,%ecx		# including our early context	movl	$ PG_V,%eax		#  having these bits set,	lea	(4*NBPG)(%esi),%ebx	#   physical address of KPT in proc 0,	movl	%ebx,_KPTphys-SYSTEM	#    in the kernel page table,	fillkpt/* map I/O memory map */	movl	$0x100-0xa0,%ecx	# for this many pte s,	movl	$(0xa0000|PG_V|PG_UW),%eax # having these bits set,(perhaps URW?) XXX 06 Aug 92	movl	%ebx,_atdevphys-SYSTEM	#   remember phys addr of ptes	fillkpt /* map proc 0's kernel stack into user page table page */	movl	$ UPAGES,%ecx		# for this many pte s,	lea	(1*NBPG)(%esi),%eax	# physical address in proc 0	lea	(SYSTEM)(%eax),%edx	movl	%edx,_proc0paddr-SYSTEM  # remember VA for 0th process init	orl	$ PG_V|PG_URKW,%eax	#  having these bits set,	lea	(3*NBPG)(%esi),%ebx	# physical address of stack pt in proc 0	addl	$(PPTEOFF*4),%ebx	fillkpt/* * Construct a page table directory * (of page directory elements - pde's) */	/* install a pde for temporary double map of bottom of VA */	lea	(4*NBPG)(%esi),%eax	# physical address of kernel page table	orl     $ PG_V|PG_UW,%eax	# pde entry is valid XXX 06 Aug 92	movl	%eax,(%esi)		# which is where temp maps!	/* kernel pde's */	movl	$ 3,%ecx		# for this many pde s,	lea	(SYSPDROFF*4)(%esi), %ebx	# offset of pde for kernel	fillkpt	/* install a pde recursively mapping page directory as a page table! */	movl	%esi,%eax		# phys address of ptd in proc 0	orl	$ PG_V|PG_UW,%eax	# pde entry is valid XXX 06 Aug 92	movl	%eax, PDRPDROFF*4(%esi)	# which is where PTmap maps!	/* install a pde to map kernel stack for proc 0 */	lea	(3*NBPG)(%esi),%eax	# physical address of pt in proc 0	orl	$ PG_V,%eax		# pde entry is valid	movl	%eax,PPDROFF*4(%esi)	# which is where kernel stack maps!	/* load base of page directory, and enable mapping */	movl	%esi,%eax		# phys address of ptd in proc 0 	orl	$ I386_CR3PAT,%eax	movl	%eax,%cr3		# load ptd addr into mmu	movl	%cr0,%eax		# get control word	orl	$0x80000001,%eax	# and let s page!	movl	%eax,%cr0		# NOW!	pushl	$begin				# jump to high mem!	retbegin: /* now running relocated at SYSTEM where the system is linked to run */	.globl _Crtat	movl	_Crtat,%eax	subl	$0xfe0a0000,%eax	movl	_atdevphys,%edx	# get pte PA	subl	_KPTphys,%edx	# remove base of ptes, now have phys offset	shll	$ PGSHIFT-2,%edx  # corresponding to virt offset	addl	$ SYSTEM,%edx	# add virtual base	movl	%edx, _atdevbase	addl	%eax,%edx	movl	%edx,_Crtat	/* set up bootstrap stack */	movl	$ _kstack+UPAGES*NBPG-4*12,%esp	# bootstrap stack end location	xorl	%eax,%eax		# mark end of frames	movl	%eax,%ebp	movl	_proc0paddr, %eax	movl	%esi, PCB_CR3(%eax)	lea	7*NBPG(%esi),%esi	# skip past stack.	pushl	%esi		call	_init386		# wire 386 chip for unix operation		movl	$0,_PTD	call 	_main	popl	%esi	.globl	__ucodesel,__udatasel	movzwl	__ucodesel,%eax	movzwl	__udatasel,%ecx	# build outer stack frame	pushl	%ecx		# user ss	pushl	$ USRSTACK	# user esp	pushl	%eax		# user cs	pushl	$0		# user ip	movw	%cx,%ds	movw	%cx,%es	movw	%ax,%fs		# double map cs to fs	movw	%cx,%gs		# and ds to gs	lret	# goto user!	pushl	$lretmsg1	/* "should never get here!" */	call	_paniclretmsg1:	.asciz	"lret: toinit\n"	.set	exec,59	.set	exit,1	.globl	_icode	.globl	_szicode#define	LCALL(x,y)	.byte 0x9a ; .long y; .word x/* * Icode is copied out to process 1 to exec /etc/init. * If the exec fails, process 1 exits. */_icode:	# pushl	$argv-_icode	# gas fucks up again	movl	$argv,%eax	subl	$_icode,%eax	pushl	%eax	# pushl	$init-_icode	movl	$init,%eax	subl	$_icode,%eax	pushl	%eax	pushl	%eax	# dummy out rta	movl	%esp,%ebp	movl	$exec,%eax	LCALL(0x7,0x0)	pushl	%eax	movl	$exit,%eax	pushl	%eax	# dummy out rta	LCALL(0x7,0x0)init:	.asciz	"/sbin/init"	.align	2argv:	.long	init+6-_icode		# argv[0] = "init" ("/sbin/init" + 6)	.long	eicode-_icode		# argv[1] follows icode after copyout	.long	0eicode:_szicode:	.long	_szicode-_icode	.globl	_sigcode,_szsigcode_sigcode:	movl	12(%esp),%eax	# unsure if call will dec stack 1st	call	%eax	xorl	%eax,%eax	# smaller movl $103,%eax	movb	$103,%al	# sigreturn()	LCALL(0x7,0)		# enter kernel with args on stack	hlt			# never gets here_szsigcode:	.long	_szsigcode-_sigcode	/*	 * Support routines for GCC	 */	.globl ___udivsi3	ALIGN32___udivsi3:	movl 4(%esp),%eax	xorl %edx,%edx	divl 8(%esp)	ret	.globl ___divsi3	ALIGN32___divsi3:	movl 4(%esp),%eax	#xorl %edx,%edx		/* not needed - cltd sign extends into %edx */	cltd	idivl 8(%esp)	ret	/*	 * I/O bus instructions via C	 */	.globl	_inb	ALIGN32_inb:	movl	4(%esp),%edx	subl	%eax,%eax	# clr eax	NOP	inb	%dx,%al	ret	.globl	_inw	ALIGN32_inw:	movl	4(%esp),%edx	subl	%eax,%eax	# clr eax	NOP	inw	%dx,%ax	ret	.globl	_rtcin	ALIGN32_rtcin:	movl	4(%esp),%eax	outb	%al,$0x70	subl	%eax,%eax	# clr eax	inb	$0x71,%al	# Compaq SystemPro 	ret	.globl	_outb	ALIGN32_outb:	movl	4(%esp),%edx	NOP	movl	8(%esp),%eax	outb	%al,%dx	NOP	ret	.globl	_outw	ALIGN32_outw:	movl	4(%esp),%edx	NOP	movl	8(%esp),%eax	outw	%ax,%dx	NOP	ret	/*	 * void bzero(void *base, u_int cnt)	 */	.globl _bzero	ALIGN32_bzero:	pushl	%edi	movl	8(%esp),%edi	movl	12(%esp),%ecx	xorl	%eax,%eax	shrl	$2,%ecx		cld	rep	stosl	movl	12(%esp),%ecx	andl	$3,%ecx	rep	stosb	popl	%edi	ret	/*	 * fillw (pat,base,cnt)	 */	.globl _fillw	ALIGN32_fillw:	pushl	%edi	movl	8(%esp),%eax	movl	12(%esp),%edi	movw	%ax, %cx	rorl	$16, %eax	movw	%cx, %ax	cld	movl	16(%esp),%ecx	shrl	%ecx	rep	stosl	movl	16(%esp),%ecx	andl	$1, %ecx	rep	stosw	popl	%edi	ret	.globl _bcopyb	ALIGN32_bcopyb:	pushl	%esi	pushl	%edi	movl	12(%esp),%esi	movl	16(%esp),%edi	movl	20(%esp),%ecx	cld	rep	movsb	popl	%edi	popl	%esi	xorl	%eax,%eax	ret	/*	 * (ov)bcopy (src,dst,cnt)	 *  ws@tools.de     (Wolfgang Solfrank, TooLs GmbH) +49-228-985800	 */	.globl	_bcopy,_ovbcopy	ALIGN32_ovbcopy:_bcopy:	pushl	%esi	pushl	%edi	movl	12(%esp),%esi	movl	16(%esp),%edi	movl	20(%esp),%ecx	cmpl	%esi,%edi	/* potentially overlapping? */	jnb	1f	cld			/* nope, copy forwards. */	shrl	$2,%ecx		/* copy by words */	rep	movsl	movl	20(%esp),%ecx	andl	$3,%ecx		/* any bytes left? */	rep	movsb	popl	%edi	popl	%esi	xorl	%eax,%eax	ret	ALIGN321:	addl	%ecx,%edi	/* copy backwards. */	addl	%ecx,%esi	std

⌨️ 快捷键说明

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