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

📄 boothead.s

📁 boot启动监视代码 boot启动监视代码
💻 S
📖 第 1 页 / 共 2 页
字号:
	int	0x16	jnz	getc		! Keypress?	xor	ax, ax		! No key	ret_getchar:	movb	ah, #0		! Read character from keyboard	int	0x16getc:	cmpb	al, #0x3D	! '=' character	jnz	noeq	movb	_eqscancode, ah	! Save scancode of '=' keynoeq:	cmpb	al, #0x0D	! Carriage return	jnz	nocr	movb	al, #0x0A	! Change to linefeednocr:	xorb	ah, ah		! ax = al	ret! int putchar(c);!	Write a character in teletype mode.  The putc and putk synonyms!	are for the kernel printk function that uses one of them.!	Newlines are automatically prepended by a carriage return.!.define _putchar, _putc, _putk_putchar:_putc:_putk:	mov	bx, sp	movb	al, 2(bx)	! al = character to be printed	testb	al, al		! 1.6.* printk prints null characters	jz	nulch		! that appear as blanks, so don't do it.	cmpb	al, #0x0A	! al = newline?	jnz	putc		! No	cmpb	wdirty, #0	! Yes, erase wheel and do a carriage return	jz	nodirt	movb	al, #0x20	! putc(' ');	call	putcnodirt:	movb	al, #0x0D	! putc('\r')	call	putc	movb	al, #0x0A	! Restore the '\n' and print itputc:	movb	ah, #14		! 14 = print character in teletype mode	mov	bx, #0x0001	! Page 0, foreground color	int	0x10		! Call BIOS VIDEO_IO	movb	wdirty, #0nulch:	ret! |/-\|/-\|/-\|/-\|/-\	(playtime)wheel:	push	si	mov	si, gp		! si = gp	lodsb	call	putc		! putc(*si++)	movb	al, #0x08	call	putc		! putc('\b')	cmp	si, #glyphs+4	jne	wmore	mov	si, #glyphswmore:	mov	gp, si		! gp= si == glyphs + 4 ? glyphs : si;	incb	wdirty	pop	si	ret.data	.align	2gp:	.data2	glyphsglyphs:	.ascii	"|/-\\"wdirty:	.data1	0.text! void reset_video(int color);!	Reset and clear the screen.! void set_cursor(column, row);!	Position the cursor at a specified column & row..define _reset_video, _set_cursor_reset_video:	mov	bx, sp	movb	al, #7		! Assume mode 7: 80x24 monochrome	cmp	2(bx), #0	! Or is color requested?	jz	clear	movb	al, #2		! Mode 2: 80x25 colorclear:	xorb	ah, ah		! Reset video	int	0x10	xor	dx, dx		! dl = column = 0, dh = row = 0	jmp	setcur_set_cursor:	mov	bx, sp	movb	dl, 2(bx)	! dl = column	movb	dh, 4(bx)	! dh = rowsetcur:	xorb	bh, bh		! Page 0	movb	ah, #0x02	! Set cursor position	int	0x10	ret! u32_t get_tick(void);!	Return the current value of the clock tick counter.  This counter!	increments 18.2 times per second.  Poll it to do delays.  Does not!	work on the original PC, but works on the PC/XT..define _get_tick_get_tick:	xorb	ah, ah		! Code for get tick count	int	0x1A	mov	ax, dx	mov	dx, cx		! dx:ax = cx:dx = tick count	ret! Functions used to obtain info about the hardware, like the type of video! and amount of memory.  Boot uses this information itself, but will also! pass them on to a pure 386 kernel, because one can't make BIOS calls from! protected mode.  The video type could probably be determined by the kernel! too by looking at the hardware, but there is a small chance on errors that! the monitor allows you to correct by setting variables..define		_get_video	! returns type of display.define		_get_ext_memsize  ! returns amount of extended memory in K.define		_get_low_memsize  ! returns amount of low memory in K.define		_get_processor	! returns processor type (86, 186, 286, 386)! u16_t get_video(void)!	Return type of display, in order: MDA, CGA, mono EGA, color EGA,!	mono VGA, color VGA._get_video:	mov	ax, #0x1A00	! Function 1A returns display code	int	0x10		! al = 1A if supported	cmpb	al, #0x1A	jnz	no_dc		! No display code function supported	mov	ax, #2	cmpb	bl, #5		! Is it a monochrome EGA?	jz	got_video	inc	ax	cmpb	bl, #4		! Is it a color EGA?	jz	got_video	inc	ax	cmpb	bl, #7		! Is it a monochrome VGA?	jz	got_video	inc	ax	cmpb	bl, #8		! Is it a color VGA?	jz	got_videono_dc:	movb	ah, #0x12	! Get information about the EGA	movb	bl, #0x10	int	0x10	cmpb	bl, #0x10	! Did it come back as 0x10? (No EGA)	jz	no_ega	mov	ax, #2	cmpb	bh, #1		! Is it monochrome?	jz	got_video	inc	ax	jmp	got_videono_ega:	int	0x11		! Get bit pattern for equipment	and	ax, #0x30	! Isolate color/mono field	sub	ax, #0x30	jz	got_video	! Is it an MDA?	mov	ax, #1		! No it's CGAgot_video:	ret! u16_t get_ext_memsize(void);!	Ask the BIOS how much extended memory there is._get_ext_memsize:	call	_get_processor	! Is this an old crate?	cmp	ax, #186	jbe	no_ext		! Don't try the next function, it crashed an XT	movb	ah, #0x88	clc			! Carry will stay clear if call exists	int	0x15		! Returns size (in K) in ax for AT's	jnb	got_ext_memsizeno_ext:	sub	ax, ax		! Error, probably a PCgot_ext_memsize:	ret! u16_t get_low_memsize(void);!	Ask the BIOS how much normal memory there is._get_low_memsize:	int	0x12		! Returns the size (in K) in ax	ret! u16_t get_processor(void);!	Decide processor type among 8088=8086, 80188=80186, 80286, 80386, 80486.!	Return 86, 186, 286, 386 or 486.!	Preserves all registers except the flags and the return register ax.! Method:!	8088=8086 and 80188=80186 push sp as new sp, 80286 and 80386 as old sp.!	All but 8088=8086 do shifts mod 32 or 16.!	386 stores 0 for the upper 8 bits of the GDT pointer in 16 bit mode,!	while 286 stores 0xFF.!	486 has an AC flag the 386 doesn't have.	o32 = 0x66		! 32 bit operand size prefix_get_processor:	push	bp	mov	bp, sp	push	sp		! see if pushed sp == sp	pop	ax	cmp	ax, sp	jz	new_processor	mov	cx, #0x0120	! see if shifts are mod 32	shlb	ch, cl		! zero tells if 86	mov	ax, #86	jz	got_processor	mov	ax, #186	jmp	got_processornew_processor:			! see if high bits are set in saved GDT	sub	sp, #6		! space for GDT ptr	.data1	0x0F		! Prefix for 286 instruction: sgdt -6(bp)	add	-6(bp), ax	! save 3 word GDT ptr (This is NOT an add!)	cmpb	-1(bp), #0	! top byte of GDT ptr is zero only for 386	mov	ax, #286	jnz	got_processor! 386 or 486	and	sp, #0xFFFC	! Align stack to avoid AC fault (needed?)	.data1	o32		! About to operate on a 32 bit object	pushf			! Push eflags	pop	ax	pop	dx		! dx:ax = eflags	mov	bx, ax	mov	cx, dx		! Save original eflags	xor	dx, #0x0004	! Flip the AC bit	push	dx	push	ax		! Push modified eflags value	.data1	o32	popf			! Load modified eflags register	.data1	o32	pushf	pop	ax	pop	dx		! Get it again	push	cx	push	bx	.data1	o32	popf			! Restore original eflags register	xor	dx, cx		! See if AC bit changed	test	dx, #0x0004	mov	ax, #386	! 386 if it didn't react to "flipping"	jz	got_processor	mov	ax, #486	! 486 if you can modify the AC bitgot_processor:	mov	sp, bp	pop	bp	ret! void _bootstrap(device, partoff, partseg)!	Call another bootstrap routine to boot MS-DOS for instance.  (No real!	need for that anymore, now that you can format floppies under Minix).!	The bootstrap must have been loaded at BOOTSEG from "device"..define _bootstrap_bootstrap:	mov	bx, sp	movb	dl, 2(bx)	! Device to boot from	lds	si, 4(bx)	! ds:si = partition table entry	xor	ax, ax	mov	es, ax		! Vector segment	mov	di, #BUFFER	! es:di = buffer in low core	mov	cx, #PENTRYSIZE	! cx = size of partition table entry	rep	movsb			! Copy the entry to low core	mov	si, #BUFFER	! es:si = partition table entry	mov	ds, ax		! Some bootstraps need zero segment registers	cli	mov	ss, ax	mov	sp, #BOOTOFF	! This should do it	sti	jmpf	BOOTOFF, 0	! Back to where the BIOS loads the boot code! To my surprise this code is so fast that floppy drive 0 was still running! (tries to boot floppy first), when Minix was started after a hard disk boot.stop_motor:	mov	dx, #0x03F2	! Motor drive control bits	movb	al, #0x0C	! Bits 4-7 for floppy 0-3 are off	outb			! Kill the motors	ret! void minix86(koff, kcs, kds, bootparams, paramsize);!	Call 8086 Minix or 386 Minix with an 8086 startoff..define _minix86_minix86:	call	stop_motor	! Turn off floppy drives	mov	bp, sp		! Pointer to arguments	mov	ax, #0x100	! Newer boot code	mov	si, 8(bp)	mov	di, ds		! di:si = boot parameters	mov	cx, 10(bp)	! # bytes of boot parameters	push	cx	push	si		! Kernel may find these on the stack too	mov	ds, 6(bp)	! Kernel data segment set	mov	es, 6(bp)	! Set es to kernel data too	cli			! Disable interrupts	jmpf	@2(bp)		! Finally out of this mess!! Minix is called with ax, di and si as expected, but also with segment! registers and stack compatible with the 386 call.! void minix386(koff, kcs, kds, bootparams, paramsize);!	Call 386 Minix with a 386 mode switch.  Code inspired by the Amoeba!	386 bootstrap by Leendert van Doorn..define _minix386_minix386:	call	stop_motor	! Turn off floppy drives	mov	bp, sp		! Pointer to arguments	mov	di, ds		! Monitor ds	mov	si, #gdt	! di:si = Global descriptor table	mov	bx, #gdt_desc	call	set_base	! Set base of gdt descriptor	mov	di, 6(bp)	! Kernel ds	xor	si, si		! di:si = Kernel data segment	mov	bx, #ds_desc	call	set_base	! Set base of kernel ds	mov	di, ss		! Monitor ss	xor	si, si		! di:si = Monitor stack segment	mov	bx, #ss_desc	call	set_base	! Minix starts with the stack of the monitor	mov	di, 4(bp)	! Kernel cs	xor	si, si		! di:si = Kernel text segment	mov	bx, #cs_desc	call	set_base	! Set base of kernel cs	xor	ax, ax	push	ax	push	10(bp)		! 32 bit size of parameters on stack	push	ax	push	8(bp)		! 32 bit address of parameters (ss relative)! Use the BIOS to kick us into protected mode.  This is the most portable! way to enable the A20 address line.  A real programmer would use cr0.	mov	si, #gdt	! es:si = global descriptor table	xor	bx, bx		! 8259's must be initialized by the kernel	movb	ah, #0x89	! Protected mode function code! Fake an interrupt stack frame as if called from the kernel entry point	cli			! No more interruptions	pushf			! Flags	push	4(bp)		! Kernel cs	push	2(bp)		! Kernel entry point	mov	ds, bx		! ds = vector segment	jmpf	@4*0x15		! "int 0x15"! The "interrupt" will return directly to the Minix kernel in 386 mode.  The! split is clean:  No 386 code here, and no 8086 code in the kernel.  The! boot parameters address and size are on the stack.  They may be retrieved! using the ss descriptor.set_base:	! Set the base of descriptor bx to the 8086 address di:si	mov	2(bx), di	! Base = segment	mov	cx, #4seg2abs:	shl	2(bx), #1	rclb	4(bx), #1	! Base = segment << 4	loop	seg2abs	add	2(bx), si	adcb	4(bx), #0	! Base = (segment << 4) + offset	ret.data	.align	2	UNSET	= 0	! Must be computed! Global descriptor table.gdt:null_desc:	! Null descriptor	.data2	0x0000, 0x0000	.data1	0x00, 0x00, 0x00, 0x00gdt_desc:	! Descriptor for this descriptor table	.data2	8*8-1, UNSET	.data1	UNSET, 0x00, 0x00, 0x00idt_desc:	! Interrupt descriptor table descriptor (no interrupts allowed)	.data2	0x0000, 0x0000	.data1	0x00, 0x00, 0x00, 0x00ds_desc:	! Kernel data segment descriptor (4Gb flat)	.data2	0xFFFF, UNSET	.data1	UNSET, 0x92, 0xCF, 0x00es_desc:	! Physical memory descriptor (4Gb flat)	.data2	0xFFFF, 0x0000	.data1	0x00, 0x92, 0xCF, 0x00ss_desc:	! Monitor data segment descriptor (64Kb flat)	.data2	0xFFFF, UNSET	.data1	UNSET, 0x92, 0x40, 0x00cs_desc:	! Kernel code segment descriptor (4Gb flat)	.data2	0xFFFF, UNSET	.data1	UNSET, 0x9A, 0xCF, 0x00bios_desc:	! BIOS segment descriptor (scratch for int 0x15)	.data2	UNSET, UNSET	.data1	UNSET, UNSET, UNSET, UNSET

⌨️ 快捷键说明

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