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

📄 boothead.s

📁 MINIX2.0操作系统源码 MINIX2.0操作系统源码
💻 S
📖 第 1 页 / 共 2 页
字号:
_peekchar:
	movb	ah, #0x01	! Keyboard status
	int	0x16
	jnz	getc		! Keypress?
	mov	ax, #-1		! No key
	ret
_getchar:
	xorb	ah, ah		! Read character from keyboard
	int	0x16
getc:	cmpb	al, #0x0D	! Carriage return?
	jnz	nocr
	movb	al, #0x0A	! Change to linefeed
nocr:	xorb	ah, ah		! ax = al
	ret

! int putchar(int 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 preceded 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 adds a trailing null
	jz	nulch
	cmpb	al, #0x0A	! al = newline?
	jnz	putc
	movb	al, #0x0D
	call	putc		! putc('\r')
	movb	al, #0x0A	! Restore the '\n' and print it
putc:	movb	ah, #0x0E	! Print character in teletype mode
	mov	bx, #0x0001	! Page 0, foreground color
	int	0x10		! Call BIOS VIDEO_IO
nulch:	ret

! void reset_video(unsigned mode);
!	Reset and clear the screen.
.define _reset_video
_reset_video:
	mov	bx, sp
	mov	ax, 2(bx)	! Video mode
	mov	cur_vid_mode, ax
	testb	ah, ah
	jnz	xvesa		! VESA extended mode?
	int	0x10		! Reset video (ah = 0)
	jmp	setcur
xvesa:	mov	bx, ax		! bx = extended mode
	mov	ax, #0x4F02	! Reset video
	int	0x10
setcur:	xor	dx, dx		! dl = column = 0, dh = row = 0
	xorb	bh, bh		! Page 0
	movb	ah, #0x02	! Set cursor position
	int	0x10
	ret

restore_video:			! To restore the video mode on exit
	mov	ax, old_vid_mode
	cmp	ax, cur_vid_mode
	je	vidok
	push	ax
	call	_reset_video
	pop	ax
vidok:	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_bus		! returns type of system bus
.define _get_video		! returns type of display
.define _get_memsize		! returns amount of low memory in K
.define _get_ext_memsize	! returns amount of extended memory in K

! u16_t get_bus(void)
!	Return type of system bus, in order: XT, AT, MCA.
_get_bus:
	call	_getprocessor
	xor	dx, dx		! Assume XT
	cmp	ax, #286	! An AT has at least a 286
	jb	got_bus
	inc	dx		! Assume AT
	movb	ah, #0xC0	! Code for get configuration
	int	0x15
	jc	got_bus		! Carry clear and ah = 00 if supported
	testb	ah, ah
	jne	got_bus
	eseg
	movb	al, 5(bx)	! Load feature byte #1
	inc	dx		! Assume MCA
	testb	al, #0x02	! Test bit 1 - "bus is Micro Channel"
	jnz	got_bus
	dec	dx		! Assume AT
	testb	al, #0x40	! Test bit 6 - "2nd 8259 installed"
	jnz	got_bus
	dec	dx		! It is an XT
got_bus:
	push	ds
	pop	es		! Restore es
	mov	ax, dx		! Return bus code
	ret

! 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_video

no_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_video

no_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 CGA

got_video:
	ret

! u16_t get_memsize(void);
!	Ask the BIOS how much normal memory there is.

_get_memsize:
	int	0x12		! Returns the size (in K) in ax
	ret

! u32_t get_ext_memsize(void);
!	Ask the BIOS how much extended memory there is.

_get_ext_memsize:
	call	_getprocessor
	cmp	ax, #286	! Only 286s and above have extended memory
	jb	no_ext
	movb	ah, #0x88	! Code for get extended memory size
	clc			! Carry will stay clear if call exists
	int	0x15		! Returns size (in K) in ax for AT's
	jnc	got_ext
no_ext:	xor	ax, ax		! Error, no extended memory
got_ext:
	xor	dx, dx
	ret

! Functions to leave the boot monitor.
.define _bootstrap		! Call another bootstrap
.define _minix			! Call Minix

! void _bootstrap(int device, struct part_entry *entry)
!	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".
_bootstrap:
	call	restore_video
	mov	bx, sp
	movb	dl, 2(bx)	! Device to boot from
	mov	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

! u32_t minix(u32_t koff, u32_t kcs, u32_t kds,
!					char *bootparams, size_t paramsize);
!	Call Minix.
_minix:
	push	bp
	mov	bp, sp		! Pointer to arguments

	mov	dx, #0x03F2	! Floppy motor drive control bits
	movb	al, #0x0C	! Bits 4-7 for floppy 0-3 are off
	outb	dx		! Kill the motors
	push	ds
	mov	ax, #0x0040	! BIOS data segment
	mov	ds, ax
	andb	0x003F, #0xF0	! Clear diskette motor status bits of BIOS
	pop	ds
	cli			! No more interruptions

	test	_k_flags, #K_I386 ! Switch to 386 mode?
	jnz	minix386

! Call Minix in real mode.
minix86:
	push	18(bp)		! # bytes of boot parameters
	push	16(bp)		! address of boot parameters

	test	_k_flags, #K_RET ! Can the kernel return?
	jz	noret86
	push	cs
	mov	ax, #ret86
	push	ax		! Monitor far return address
noret86:

	mov	ax, 8(bp)
	mov	dx, 10(bp)
	call	abs2seg
	push	dx		! Kernel code segment
	push	4(bp)		! Kernel code offset
	mov	ax, 12(bp)
	mov	dx, 14(bp)
	call	abs2seg
	mov	ds, dx		! Kernel data segment
	mov	es, dx		! Set es to kernel data too
	retf			! Make a far call to the kernel

! Call Minix in 386 mode.
minix386:
  cseg	mov	cs_real-2, cs	! Patch CS and DS into the instructions that
  cseg	mov	ds_real-2, ds	! reload them when switching back to real mode

	mov	dx, ds		! Monitor ds
	mov	ax, #p_gdt	! dx:ax = Global descriptor table
	call	seg2abs
	mov	p_gdt_desc+2, ax
	movb	p_gdt_desc+4, dl ! Set base of global descriptor table

	mov	ax, 12(bp)
	mov	dx, 14(bp)	! Kernel ds (absolute address)
	mov	p_ds_desc+2, ax
	movb	p_ds_desc+4, dl ! Set base of kernel data segment

	mov	dx, ss		! Monitor ss
	xor	ax, ax		! dx:ax = Monitor stack segment
	call	seg2abs		! Minix starts with the stack of the monitor
	mov	p_ss_desc+2, ax
	movb	p_ss_desc+4, dl

	mov	ax, 8(bp)
	mov	dx, 10(bp)	! Kernel cs (absolute address)
	mov	p_cs_desc+2, ax
	movb	p_cs_desc+4, dl

	mov	dx, cs		! Monitor cs
	xor	ax, ax		! dx:ax = Monitor code segment
	call	seg2abs
	mov	p_mcs_desc+2, ax
	movb	p_mcs_desc+4, dl

	push	#MCS_SELECTOR
	push	#bios13		! Far address to BIOS int 13 support

	push	#0
	push	18(bp)		! 32 bit size of parameters on stack
	push	#0
	push	16(bp)		! 32 bit address of parameters (ss relative)

	test	_k_flags, #K_RET ! Can the kernel return?
	jz	noret386
	push	#MCS_SELECTOR
	push	#ret386		! Monitor far return address
noret386:

	push	#0
	push	#CS_SELECTOR
	push	6(bp)
	push	4(bp)		! 32 bit far address to kernel entry point

	call	real2prot	! Switch to protected mode
	mov	ax, #DS_SELECTOR ! Kernel data
	mov	ds, ax
	mov	ax, #ES_SELECTOR ! Flat 4 Gb
	mov	es, ax
	.data1	o32		! Make a far call to the kernel
	retf

! Minix-86 returns here on a halt or reboot.
ret86:
	mov	8(bp), ax
	mov	10(bp), dx	! Return value
	jmp	return

! Minix-386 returns here on a halt or reboot.
ret386:
	.data1	o32
	mov	8(bp), ax	! Return value
	call	prot2real	! Switch to real mode

return:
	mov	sp, bp		! Pop parameters
	sti			! Can take interrupts again
	call	_get_video	! MDA, CGA, EGA, ...
	movb	dh, #24		! dh = row 24
	cmp	ax, #2		! At least EGA?
	jb	is25		! Otherwise 25 rows
	push	ds
	mov	ax, #0x0040	! BIOS data segment
	mov	ds, ax
	movb	dh, 0x0084	! Number of rows on display minus one
	pop	ds
is25:
	xorb	dl, dl		! dl = column 0
	xorb	bh, bh		! Page 0
	movb	ah, #0x02	! Set cursor position
	int	0x10
	mov	cur_vid_mode, #-1  ! Minix may have messed things up

	mov	ax, 8(bp)
	mov	dx, 10(bp)	! dx-ax = return value from the kernel
	pop	bp
	ret			! Continue as if nothing happened

! Support function for Minix-386 to make a BIOS int 13 call (disk I/O).
.define bios13
bios13:
	mov	bp, sp
	call	prot2real

	mov	ax, 8(bp)	! Load parameters
	mov	bx, 10(bp)
	mov	cx, 12(bp)
	mov	dx, 14(bp)
	mov	es, 16(bp)
	sti			! Enable interrupts
	int	0x13		! Make the BIOS call
	cli			! Disable interrupts
	mov	8(bp), ax	! Save results
	mov	10(bp), bx
	mov	12(bp), cx
	mov	14(bp), dx
	mov	16(bp), es

	call	real2prot
	mov	ax, #DS_SELECTOR ! Kernel data
	mov	ds, ax
	.data1	o32
	retf			! Return to the kernel

! Switch from real to protected mode.
real2prot:
	lgdt	p_gdt_desc	! Global descriptor table
	.data1	0x0F,0x20,0xC0	! mov	eax, cr0
	.data1	o32
	mov	msw, ax		! Save cr0
	orb	al, #0x01	! Set PE (protection enable) bit
	.data1	0x0F,0x22,0xC0	! mov	cr0, eax
	jmpf	cs_prot, MCS_SELECTOR ! Set code segment selector
cs_prot:
	mov	ax, #SS_SELECTOR ! Set data selectors
	mov	ds, ax
	mov	es, ax
	mov	ss, ax

	movb	ah, #0xDF	! Code for A20 enable
	jmp	gate_A20

! Switch from protected to real mode.
prot2real:
	lidt	p_idt_desc	! Real mode interrupt vectors
	.data1	o32
	mov	ax, msw		! Saved cr0
	.data1	0x0F,0x22,0xC0	! mov	cr0, eax
	jmpf	cs_real, 0xDEAD	! Reload cs register
cs_real:
	mov	ax, #0xBEEF
ds_real:
	mov	ds, ax		! Reload data segment registers
	mov	es, ax
	mov	ss, ax

	movb	ah, #0xDD	! Code for A20 disable
	!jmp	gate_A20

! Enable (ah = 0xDF) or disable (ah = 0xDD) the A20 address line.
gate_A20:
	call	kb_wait
	movb	al, #0xD1	! Tell keyboard that a command is coming
	outb	0x64
	call	kb_wait
	movb	al, ah		! Enable or disable code
	outb	0x60
	call	kb_wait
	mov	ax, #25		! 25 microsec delay for slow keyboard chip
0:	out	0xED		! Write to an unused port (1us)
	dec	ax
	jne	0b
	ret
kb_wait:
	inb	0x64
	testb	al, #0x02	! Keyboard input buffer full?
	jnz	kb_wait		! If so, wait
	ret

.data
	.align	2

! Global descriptor tables.
	UNSET	= 0		! Must be computed

! For "Extended Memory Block Move".
x_gdt:
x_null_desc:
	! Null descriptor
	.data2	0x0000, 0x0000
	.data1	0x00, 0x00, 0x00, 0x00
x_gdt_desc:
	! Descriptor for this descriptor table
	.data2	6*8-1, UNSET
	.data1	UNSET, 0x00, 0x00, 0x00
x_src_desc:
	! Source segment descriptor
	.data2	0xFFFF, UNSET
	.data1	UNSET, 0x92, 0x00, 0x00
x_dst_desc:
	! Destination segment descriptor
	.data2	0xFFFF, UNSET
	.data1	UNSET, 0x92, 0x00, 0x00
x_bios_desc:
	! BIOS segment descriptor (scratch for int 0x15)
	.data2	UNSET, UNSET
	.data1	UNSET, UNSET, UNSET, UNSET
x_ss_desc:
	! BIOS stack segment descriptor (scratch for int 0x15)
	.data2	UNSET, UNSET
	.data1	UNSET, UNSET, UNSET, UNSET

! Protected mode descriptor table.
p_gdt:
p_null_desc:
	! Null descriptor
	.data2	0x0000, 0x0000
	.data1	0x00, 0x00, 0x00, 0x00
p_gdt_desc:
	! Descriptor for this descriptor table
	.data2	8*8-1, UNSET
	.data1	UNSET, 0x00, 0x00, 0x00
p_idt_desc:
	! Real mode interrupt descriptor table descriptor
	.data2	0x03FF, 0x0000
	.data1	0x00, 0x00, 0x00, 0x00
p_ds_desc:
	! Kernel data segment descriptor (4 Gb flat)
	.data2	0xFFFF, UNSET
	.data1	UNSET, 0x92, 0xCF, 0x00
p_es_desc:
	! Physical memory descriptor (4 Gb flat)
	.data2	0xFFFF, 0x0000
	.data1	0x00, 0x92, 0xCF, 0x00
p_ss_desc:
	! Monitor data segment descriptor (64 kb flat)
	.data2	0xFFFF, UNSET
	.data1	UNSET, 0x92, 0x00, 0x00
p_cs_desc:
	! Kernel code segment descriptor (4 Gb flat)
	.data2	0xFFFF, UNSET
	.data1	UNSET, 0x9A, 0xCF, 0x00
p_mcs_desc:
	! Monitor code segment descriptor (64 kb flat)
	.data2	0xFFFF, UNSET
	.data1	UNSET, 0x9A, 0x00, 0x00

.bss
	.comm	old_vid_mode, 2		! Video mode at startup
	.comm	cur_vid_mode, 2		! Current video mode
	.comm	msw, 4			! Saved machine status word (cr0)

⌨️ 快捷键说明

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