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

📄 bootf.asm

📁 John Fine的OS模型// 源代码// C & ASM// 英文
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	stosd				;{1H}
	mov	ax, (1024-3)*2
	xchg	ax, cx
	rep stosw
	mov	ax, 0xD007		;0FF800000 page tbl pointer
	stosd				;{1F}
	mov	ah, 0xE0		;Page directory self pointer
	stosd				;{1G}
	mov	al, 0
	mov	CR3, eax		;Set up page directory
	mov	eax, CR0		;Turn on paging and protected mode
	or	eax, 0x80000001
	mov	CR0, eax
	mov	cl, flat_data		;Setup ds and es
	push	cx			;{5}
	pop	ds
	mov	es, cx
	jmp dword 8:0xFF800000		;Go
	
read_sectors:
; Input:
;	EAX = LBN
;	DI  = sector count
;	ES = segment
; Output:
;	EBX high half cleared
;	DL = drive #
;	EDX high half cleared
;	ESI = 0
; Clobbered:
;	BX, CX, DH

	push	eax
	push	di
	push	es

.10:	push	eax		;LBN

	cdq			;edx = 0
	movzx	ebx, byte [boot+BB_sec]
	div	ebx		;EAX=track ;EDX=sector-1
	mov	cx, dx		;CL=sector-1 ;CH=0
	sub	bl, dl		;BX = max transfer before end of track
	cmp	di, bx		;Do we want more than that?
	ja	.20		;Yes, do just this much now
	mov	bx, di		;No, do it all now
.20:	mov	esi, ebx	;Save count for this transfer.

	inc	cx		;CL=Sector number
	xor	dx, dx
	mov	bl, [boot+BB_head]
	div	ebx		;EAX=cylinder ;EDX=head

	mov	dh, dl		;Head
	mov	dl, [boot]	;Drive
	xchg	ch, al		;CH=Low 8 bits of cylinder number; AL=0
	shr	ax, 2		;AL[6:7]=High two bits of cylinder
	or	cl, al		;CX = Cylinder and sector

	mov	ax, si		;Sector count
	mov	ah, 2		;Read
	xor	bx, bx
	push	ax
	int	13h
	pop	ax
	jnc	.30

	int	13h		;If at second you don't succeed, give up
	jc near	disk_error

.30:	pop	eax
	add	eax, esi	;Advance LBN

	push	si
	shl	si, 5
	mov	bx, es
	add	bx, si		;Advance segment
	mov	es, bx
	pop	si

	sub	di, si
	ja	.10

	pop	es
	pop	di
	pop	eax
	xor	si, si
	ret	

file_name db 'KERNEL  BIN'

gdt	start_gdt		;{9}

flat_code	desc	0, 0xFFBFF, D_CODE+D_READ+D_BIG+D_BIG_LIM

flat_data	desc	0, 0xFFFFF, D_DATA+D_WRITE+D_BIG+D_BIG_LIM

	end_gdt

	resb 0x1FE+$$-$
	db	0x55, 0xAA		;Standard end of boot sector
;_____________________________________________________________________________
;
;  Build/Install instructions:
;
;  *)  NASM -f obj bootf.asm
;
;  *)  JLOC bootf.lnk bootf.bin
;
;  *)  Start with a formatted floppy.
;
;  *)  PARTCOPY bootf.bin 0 3 -f0 0
;      This step overwrites the JMP at the start of the floppy with a JMP $+3E
;      With many formatters, that matches the JMP that the formatter put there
;      and makes no difference.  In most other cases it is safe to overwrite
;      the JMP.  If you want to preserve a different JMP, change the first
;      "resb" in bootp.asm to adjust the address of "start".
;
;  *)  PARTCOPY bootf.bin 3E 1C2 -f0 3E
;      This step copies the rest of bootp.bin to the floppy at offset 3E,
;      skipping the parameters set up by format, so the diskette will still be
;      useable as a DOS diskette.
;
;  *)  Copy some protected mode image to the file C:\KERNEL.BIN.
;
;  *)  Boot the floppy.
;_____________________________________________________________________________
;
;   I left out most of the error handling (what do you expect for 1B1 bytes).
; For errors which it does detect, it just beeps once and hangs.  Errors (and
; unsupported conditions) which it doesn't even try to detect include:
;   a)  Not running on a 386 or better
;   b)  Active partition is not a FAT16 partition
;   c)  Root directory is more than 608Kb long.
;   d)  TEST.BIN more than 4Mb long
;   e)  Total RAM less than 1MB plus actual size of TEST.BIN
; Errors which it does check for include:
;   a)  C-bit set after any int 13h
;   b)  No active partition
;   c)  No "TEST.BIN" in the root directory
; 
;    If this were a partition boot, you probably could leave out the code of
; reading the MBR, and finding and reading partition boot.  Then you could
; add a few error checks.  As a test boot used from a floppy, it needs to
; do that extra work and you just shouldn't use it if the basic conditions
; aren't valid.  As part of a large multi-boot (another example I hope to
; document) it could be bigger than one sector.
;_____________________________________________________________________________
;
; {} Documentation connected to specific source code sections:
;
;{0}  I wasn't sure what to assume about the CPU state when the BIOS (or
; earlier boot) transfers control here.  Probably interrupts are disabled and
; DS=0;  But I didn't assume that.  Assuming that could save a couple bytes
; of code.
;
;{1}  Memory use:
;  {A} The boot itself is at 0:7C00
;  {B} The top of the stack is 0:800
;  {C} The directory and FAT are both read in and accessed starting at 800:0
;  {D} The image is read in, then copied to 1MB (physical)
;  {E} The page tables are built at 9C000 physical
;  {F} The image is mapped to FFF80000 linear
;  {G} The page tables are mapped to FFFC0000 linear
;  {H} The first 4Mb is mapped linear = physical
;
;{2}  Most of this code runs in "big real mode".  That allows the code to make
;  int 13h (and other) BIOS calls, but also to access extended memory directly.
;
;{3}  I left out most error checks, and just beep once for the errors that are
; checked.  That makes this code suitable for learning about pmode booting and
; for test use by pmode kernel developers.  To package with an OS as end-user
; boot code, you need to either take out some of this code or load from
; some larger place, and add some real error messages.
;
;{4}  One way you might want to reduce the work of the boot is to leave the job
; of enabling A20 to the kernel startup code:
;  {A}  Don't enable A20 here.
;  {B}  Load the image at 2Mb instead of at 1Mb.  (Only odd Megabytes are
;       unusable when A20 is disabled).
;  {C}  "shr eax,1" to convert 4Mb to 2Mb.
; Note that the current version has a minimum memory requirement of 1Mb plus
; size of the image.  This change would require 2Mb plus the size of the image.
;
;{5}  The first version of this code changed the value of segment registers
; directly after switching to pmode.  It worked on all but one machine that I
; tested it on (a 386).  On that machine, on the second switch to protected
; mode, the first segment register loaded got the right selector but a bad
; descriptor.  I have read that you need a JMP after to switching to pmode, but
; successfully written MANY programs without that JMP and seen many more
; written by others.  I guess there is a case in which a delay is required (the
; usual "flush the prefetch queue" theory doesn't fit the observed facts
; because I fixed the problem by changing "mov ds,cx" to "push cx", "pop ds";
; They each take only two bytes in the prefetch queue.
;   Further testing has shown that on a 386 you may need more than a short
; instruction worth of delay after switching back to real mode.  Any memory or
; I/O read is enough, so I rearranged the code to have at least one such read
; between a change of CR0 bit 0 and a write to an sreg.  The "jmp short $+2"
; that others recommend would work because it forces a true fetch access (on
; a 386 at least).  I don't use it because I don't want to waste two bytes in
; boot code.
; 
;
;{6}  Most of this code doesn't care whether interrupts are enabled or not, so
; I never enable them after the initial cli.  BIOS's correctly enable
; interrupts DURING the processing of int 13h, if they need interrupts.
; Unfortunately, some BIOSs also enable interrupts on exit from int 13h.
; Interrupts must be disable for the switch to pmode, so another cli is
; required.
;
;{7}  Only the low half of edi is used by read_sectors, so the high half
; doesn't need to be saved and restored across that use.
;
;{8}  I call int 8 (IRQ 0) many times.  This is done in case the code was
; loaded from floppy.  It tricks the BIOS into turning the floppy motor off.
; I don't like to start my pmode tests with the floppy motor on.
;
;{9}  The first entry in a GDT is never used by the CPU.  A zero selector is
; defined as being safe to put into a segment register without loading a
; descriptor from the GDT (You can't access memory through it).  I generally
; use the first 6 bytes of the GDT as a self pointer.  Once you are used to
; this convention, it makes code more readable.  The macros in gdt.inc set it
; up.
;_____________________________________________________________________________

⌨️ 快捷键说明

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