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

📄 l.s

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 S
字号:
/* * Memory and machine-specific definitions.  Used in C and assembler. *//* * Sizes */#define	BI2BY		8			/* bits per byte */#define BI2WD		32			/* bits per word */#define	BY2WD		4			/* bytes per word */#define	BY2PG		4096			/* bytes per page */#define	WD2PG		(BY2PG/BY2WD)		/* words per page */#define	PGSHIFT		12			/* log(BY2PG) */#define PGROUND(s)	(((s)+(BY2PG-1))&~(BY2PG-1))#define	MAXMACH		1			/* max # cpus system can run *//* * Time */#define	HZ		(20)			/* clock frequency */#define	MS2HZ		(1000/HZ)		/* millisec per clock tick */#define	TK2SEC(t)	((t)/HZ)		/* ticks to seconds */#define	TK2MS(t)	((((ulong)(t))*1000)/HZ)	/* ticks to milliseconds */#define	MS2TK(t)	((((ulong)(t))*HZ)/1000)	/* milliseconds to ticks *//* * Fundamental addresses *//* *  Address spaces * *  User is at 0-2GB *  Kernel is at 2GB-4GB * *  To avoid an extra page map, both the user stack (USTKTOP) and *  the temporary user stack (TSTKTOP) should be in the the same *  4 meg. */#define	UZERO		0			/* base of user address space */#define	UTZERO		(UZERO+BY2PG)		/* first address in user text */#define	KZERO		0x80000000		/* base of kernel address space */#define	KTZERO		KZERO			/* first address in kernel text */#define	USERADDR	0xC0000000		/* struct User */#define	UREGADDR	(USERADDR+BY2PG-4*19)	#define	TSTKTOP		USERADDR		/* end of new stack in sysexec */#define TSTKSIZ 10#define	USTKTOP		(TSTKTOP-TSTKSIZ*BY2PG)	/* byte just beyond user stack */#define	USTKSIZE	(16*1024*1024 - TSTKSIZ*BY2PG)	/* size of user stack */#define ROMBIOS		(KZERO|0xF0000)#define	MACHSIZE	4096#define isphys(x) (((ulong)x)&KZERO)/* *  known 80386 segments (in GDT) and their selectors */#define	NULLSEG	0	/* null segment */#define	KDSEG	1	/* kernel data/stack */#define	KESEG	2	/* kernel executable */	#define	UDSEG	3	/* user data/stack */#define	UESEG	4	/* user executable */#define TSSSEG	5	/* task segment */#define SELGDT	(0<<3)	/* selector is in gdt */#define	SELLDT	(1<<3)	/* selector is in ldt */#define SELECTOR(i, t, p)	(((i)<<3) | (t) | (p))#define NULLSEL	SELECTOR(NULLSEG, SELGDT, 0)#define KESEL	SELECTOR(KESEG, SELGDT, 0)#define KDSEL	SELECTOR(KDSEG, SELGDT, 0)#define UESEL	SELECTOR(UESEG, SELGDT, 3)#define UDSEL	SELECTOR(UDSEG, SELGDT, 3)#define TSSSEL	SELECTOR(TSSSEG, SELGDT, 0)/* *  fields in segment descriptors */#define SEGDATA	(0x10<<8)	/* data/stack segment */#define SEGEXEC	(0x18<<8)	/* executable segment */#define	SEGTSS	(0x9<<8)	/* TSS segment */#define SEGCG	(0x0C<<8)	/* call gate */#define	SEGIG	(0x0E<<8)	/* interrupt gate */#define SEGTG	(0x0F<<8)	/* task gate */#define SEGTYPE	(0x1F<<8)#define SEGP	(1<<15)		/* segment present */#define SEGPL(x) ((x)<<13)	/* priority level */#define SEGB	(1<<22)		/* granularity 1==4k (for expand-down) */#define SEGG	(1<<23)		/* granularity 1==4k (for other) */#define SEGE	(1<<10)		/* expand down */#define SEGW	(1<<9)		/* writable (for data/stack) */#define	SEGR	(1<<9)		/* readable (for code) */#define SEGD	(1<<22)		/* default 1==32bit (for code) *//* *  virtual MMU */#define PTEMAPMEM	(1024*1024)	/* ??? */	#define SEGMAPSIZE	16		/* ??? */#define	PTEPERTAB	(PTEMAPMEM/BY2PG)	/* ??? */#define PPN(x)		((x)&~(BY2PG-1))/* *  physical MMU */#define	PTEVALID	(1<<0)#define	PTEUNCACHED	0		/* everything is uncached */#define PTEWRITE	(1<<1)#define	PTERONLY	(0<<1)#define	PTEKERNEL	(0<<2)#define	PTEUSER		(1<<2)/* *  flag register bits that we care about */#define IFLAG	0x200#define OP16	BYTE	$0x66/* *	about to walk all over ms/dos - turn off interrupts */TEXT	origin(SB),$0	CLI#ifdef BOOT/* *	This part of l.s is used only in the boot kernel. *	It assumes that we are in real address mode, i.e., *	that we look like an 8086. *//* *	relocate everything to a half meg and jump there *	- looks wierd because it is being assembled by a 32 bit *	  assembler for a 16 bit world */	MOVL	$0,BX	INCL	BX	SHLL	$15,BX	MOVL	BX,CX	MOVW	BX,ES	MOVL	$0,SI	MOVL	SI,DI	CLD; REP; MOVSL/*	JMPFAR	0X8000:$lowcore(SB) /**/	 BYTE	$0xEA	 WORD	$lowcore(SB)	 WORD	$0X8000TEXT	lowcore(SB),$0/* *	now that we're in low core, update the DS */	MOVW	BX,DS/* * 	goto protected mode *//*	MOVL	tgdtptr(SB),GDTR /**/	 BYTE	$0x0f	 BYTE	$0x01	 BYTE	$0x16	 WORD	$tgdtptr(SB)	MOVL	CR0,AX	ORL	$1,AX	MOVL	AX,CR0/* *	clear prefetch queue (wierd code to avoid optimizations) */	CLC	JCC	flush	MOVL	AX,AXflush:/* *	set all segs *//*	MOVW	$SELECTOR(1, SELGDT, 0),AX	/**/	 BYTE	$0xc7	 BYTE	$0xc0	 WORD	$SELECTOR(1, SELGDT, 0)	MOVW	AX,DS	MOVW	AX,SS	MOVW	AX,ES	MOVW	AX,FS	MOVW	AX,GS/*	JMPFAR	SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/	 BYTE	$0x66	 BYTE	$0xEA	 LONG	$mode32bit-KZERO(SB)	 WORD	$SELECTOR(2, SELGDT, 0)TEXT	mode32bit(SB),$0#endif BOOT	/*	 * Clear BSS	 */	LEAL	edata-KZERO(SB),SI	MOVL	SI,DI	ADDL	$4,DI	MOVL	$0,AX	MOVL	AX,(SI)	LEAL	end-KZERO(SB),CX	SUBL	DI,CX	SHRL	$2,CX	CLD; REP; MOVSL	/*	 *  make a bottom level page table page that maps the first	 *  16 meg of physical memory	 */	LEAL	tpt-KZERO(SB),AX	/* get phys addr of temporary page table */	ADDL	$(BY2PG-1),AX		/* must be page alligned */	ANDL	$(~(BY2PG-1)),AX	/* ... */	MOVL	$(4*1024),CX		/* pte's per page */	MOVL	$((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BXsetpte:	MOVL	BX,-4(AX)(CX*4)	SUBL	$(1<<PGSHIFT),BX	LOOP	setpte	/*	 *  make a top level page table page that maps the first	 *  16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg	 */	MOVL	AX,BX	ADDL	$(4*BY2PG),AX	ADDL	$(PTEVALID|PTEKERNEL|PTEWRITE),BX	MOVL	BX,0(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)	ADDL	$BY2PG,BX	MOVL	BX,4(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX)	ADDL	$BY2PG,BX	MOVL	BX,8(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX)	ADDL	$BY2PG,BX	MOVL	BX,12(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX)	/*	 *  point processor to top level page & turn on paging	 */	MOVL	AX,CR3	MOVL	CR0,AX	ORL	$0X80000000,AX	ANDL	$~(0x8|0x2),AX	/* TS=0, MP=0 */	MOVL	AX,CR0	/*	 *  use a jump to an absolute location to get the PC into	 *  KZERO.	 */	LEAL	tokzero(SB),AX	JMP*	AXTEXT	tokzero(SB),$0	/*	 *  stack and mach	 */	MOVL	$mach0(SB),SP	MOVL	SP,m(SB)	MOVL	$0,0(SP)	ADDL	$(MACHSIZE-4),SP	/* start stack under machine struct */	MOVL	$0, u(SB)	/*	 *  clear flags	 */	MOVL	$0,AX	PUSHL	AX	POPFL	CALL	main(SB)loop:	JMP	loopGLOBL	mach0+0(SB), $MACHSIZEGLOBL	u(SB), $4GLOBL	m(SB), $4GLOBL	tpt(SB), $(BY2PG*6)/* *  gdt to get us to 32-bit/segmented/unpaged mode */TEXT	tgdt(SB),$0	/* null descriptor */	LONG	$0	LONG	$0	/* data segment descriptor for 4 gigabytes (PL 0) */	LONG	$(0xFFFF)	LONG	$(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)	/* exec segment descriptor for 4 gigabytes (PL 0) */	LONG	$(0xFFFF)	LONG	$(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)/* *  pointer to initial gdt */TEXT	tgdtptr(SB),$0	WORD	$(3*8)	LONG	$tgdt-KZERO(SB)/* *  input a byte */TEXT	inb(SB),$0	MOVL	p+0(FP),DX	XORL	AX,AX	INB	RET/* *  output a byte */TEXT	outb(SB),$0	MOVL	p+0(FP),DX	MOVL	b+4(FP),AX	OUTB	RET/* *  input a string of shorts from a port */TEXT	inss(SB),$0	MOVL	p+0(FP),DX	MOVL	a+4(FP),DI	MOVL	c+8(FP),CX	CLD; REP; OP16; INSL	RET/* *  output a string of shorts to a port */TEXT	outss(SB),$0	MOVL	p+0(FP),DX	MOVL	a+4(FP),SI	MOVL	c+8(FP),CX	CLD; REP; OP16; OUTSL	RET/* *  test and set */TEXT	tas(SB),$0	MOVL	$0xdeadead,AX	MOVL	l+0(FP),BX	XCHGL	AX,(BX)	RET/* *  routines to load/read various system registers */GLOBL	idtptr(SB),$6TEXT	putidt(SB),$0		/* interrupt descriptor table */	MOVL	t+0(FP),AX	MOVL	AX,idtptr+2(SB)	MOVL	l+4(FP),AX	MOVW	AX,idtptr(SB)	MOVL	idtptr(SB),IDTR	RETGLOBL	gdtptr(SB),$6TEXT	putgdt(SB),$0		/* global descriptor table */	MOVL	t+0(FP),AX	MOVL	AX,gdtptr+2(SB)	MOVL	l+4(FP),AX	MOVW	AX,gdtptr(SB)	MOVL	gdtptr(SB),GDTR	RETTEXT	putcr3(SB),$0		/* top level page table pointer */	MOVL	t+0(FP),AX	MOVL	AX,CR3	RETTEXT	puttr(SB),$0		/* task register */	MOVL	t+0(FP),AX	MOVW	AX,TASK	RETTEXT	getcr0(SB),$0		/* coprocessor bits */	MOVL	CR0,AX	RETTEXT	getcr2(SB),$0		/* fault address */	MOVL	CR2,AX	RET#define	FPOFF\	WAIT;\	MOVL	CR0,AX;\	ORL	$0x4,AX		/* EM=1 */;\	MOVL	AX,CR0#define	FPON\	MOVL	CR0,AX;\	ANDL	$~0x4,AX	/* EM=0 */;\	MOVL	AX,CR0	TEXT	fpoff(SB),$0		/* turn off floating point */	FPOFF	RETTEXT	fpinit(SB),$0		/* turn on & init the floating point */	FPON	FINIT	WAIT	PUSHW	$0x0330	FLDCW	0(SP)		/* ignore underflow/precision, signal others */	POPW	AX	WAIT	RETTEXT	fpsave(SB),$0		/* save floating point state and turn off */	MOVL	p+0(FP),AX	WAIT	FSAVE	0(AX)	FPOFF	RETTEXT	fprestore(SB),$0	/* turn on floating point and restore regs */	FPON	MOVL	p+0(FP),AX	FRSTOR	0(AX)	WAIT	RETTEXT	fpstatus(SB),$0		/* get floating point status */	FSTSW	AX	RET/* *  special traps */TEXT	intr0(SB),$0	PUSHL	$0	PUSHL	$0	JMP	intrcommonTEXT	intr1(SB),$0	PUSHL	$0	PUSHL	$1	JMP	intrcommonTEXT	intr2(SB),$0	PUSHL	$0	PUSHL	$2	JMP	intrcommonTEXT	intr3(SB),$0	PUSHL	$0	PUSHL	$3	JMP	intrcommonTEXT	intr4(SB),$0	PUSHL	$0	PUSHL	$4	JMP	intrcommonTEXT	intr5(SB),$0	PUSHL	$0	PUSHL	$5	JMP	intrcommonTEXT	intr6(SB),$0	PUSHL	$0	PUSHL	$6	JMP	intrcommonTEXT	intr7(SB),$0	PUSHL	$0	PUSHL	$7	JMP	intrcommonTEXT	intr8(SB),$0	PUSHL	$8	JMP	intrscommonTEXT	intr9(SB),$0	PUSHL	$0	PUSHL	$9	JMP	intrcommonTEXT	intr10(SB),$0	PUSHL	$10	JMP	intrscommonTEXT	intr11(SB),$0	PUSHL	$11	JMP	intrscommonTEXT	intr12(SB),$0	PUSHL	$12	JMP	intrscommonTEXT	intr13(SB),$0	PUSHL	$13	JMP	intrscommonTEXT	intr14(SB),$0	PUSHL	$14	JMP	intrscommonTEXT	intr15(SB),$0	PUSHL	$0	PUSHL	$15	JMP	intrcommonTEXT	intr16(SB),$0	PUSHL	$0	PUSHL	$16	JMP	intrcommonTEXT	intr24(SB),$0	PUSHL	$0	PUSHL	$24	JMP	intrcommonTEXT	intr25(SB),$0	PUSHL	$0	PUSHL	$25	JMP	intrcommonTEXT	intr26(SB),$0	PUSHL	$0	PUSHL	$26	JMP	intrcommonTEXT	intr27(SB),$0	PUSHL	$0	PUSHL	$27	JMP	intrcommonTEXT	intr28(SB),$0	PUSHL	$0	PUSHL	$28	JMP	intrcommonTEXT	intr29(SB),$0	PUSHL	$0	PUSHL	$29	JMP	intrcommonTEXT	intr30(SB),$0	PUSHL	$0	PUSHL	$30	JMP	intrcommonTEXT	intr31(SB),$0	PUSHL	$0	PUSHL	$31	JMP	intrcommonTEXT	intr32(SB),$0	PUSHL	$0	PUSHL	$16	JMP	intrcommonTEXT	intr33(SB),$0	PUSHL	$0	PUSHL	$33	JMP	intrcommonTEXT	intr34(SB),$0	PUSHL	$0	PUSHL	$34	JMP	intrcommonTEXT	intr35(SB),$0	PUSHL	$0	PUSHL	$35	JMP	intrcommonTEXT	intr36(SB),$0	PUSHL	$0	PUSHL	$36	JMP	intrcommonTEXT	intr37(SB),$0	PUSHL	$0	PUSHL	$37	JMP	intrcommonTEXT	intr38(SB),$0	PUSHL	$0	PUSHL	$38	JMP	intrcommonTEXT	intr39(SB),$0	PUSHL	$0	PUSHL	$39	JMP	intrcommonTEXT	intr64(SB),$0	PUSHL	$0	PUSHL	$64	JMP	intrcommonTEXT	intrbad(SB),$0	PUSHL	$0	PUSHL	$0x1ff	JMP	intrcommonintrcommon:	PUSHL	DS	PUSHL	ES	PUSHL	FS	PUSHL	GS	PUSHAL	MOVL	$(KDSEL),AX	MOVW	AX,DS	MOVW	AX,ES	LEAL	0(SP),AX	PUSHL	AX	CALL	trap(SB)	POPL	AX	POPAL	POPL	GS	POPL	FS	POPL	ES	POPL	DS	ADDL	$8,SP	/* error code and trap type */	IRETLintrscommon:	PUSHL	DS	PUSHL	ES	PUSHL	FS	PUSHL	GS	PUSHAL	MOVL	$(KDSEL),AX	MOVW	AX,DS	MOVW	AX,ES	LEAL	0(SP),AX	PUSHL	AX	CALL	trap(SB)	POPL	AX	POPAL	POPL	GS	POPL	FS	POPL	ES	POPL	DS	ADDL	$8,SP	/* error code and trap type */	IRETL/* *  interrupt level is interrupts on or off */TEXT	spllo(SB),$0	PUSHFL	POPL	AX	STI	RETTEXT	splhi(SB),$0	PUSHFL	POPL	AX	CLI	RETTEXT	splx(SB),$0	MOVL	s+0(FP),AX	PUSHL	AX	POPFL	RET/* *  do nothing whatsoever till interrupt happens */TEXT	idle(SB),$0	HLT	RET/* *  label consists of a stack pointer and a PC */TEXT	gotolabel(SB),$0	MOVL	l+0(FP),AX	MOVL	0(AX),SP	/* restore sp */	MOVL	4(AX),AX	/* put return pc on the stack */	MOVL	AX,0(SP)	MOVL	$1,AX		/* return 1 */	RETTEXT	setlabel(SB),$0	MOVL	l+0(FP),AX	MOVL	SP,0(AX)	/* store sp */	MOVL	0(SP),BX	/* store return pc */	MOVL	BX,4(AX)	MOVL	$0,AX		/* return 0 */	RET/* *  Used to get to the first process. *  Set up an interrupt return frame and IRET to user level. */TEXT	touser(SB),$0	PUSHL	$(UDSEL)		/* old ss */	PUSHL	$(USTKTOP)		/* old sp */	PUSHFL				/* old flags */	PUSHL	$(UESEL)		/* old cs */	PUSHL	$(UTZERO+32)		/* old pc */	MOVL	$(UDSEL),AX	MOVW	AX,DS	MOVW	AX,ES	MOVW	AX,GS	MOVW	AX,FS	IRETL/* *  set configuration register */TEXT	config(SB),$0	MOVL	l+0(FP),AX	MOVL	$0x3F3,DX	OUTB	OUTB	RET

⌨️ 快捷键说明

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