(1)Bootsect.sブートエリアコード分析

マシンの電源がオンになったら、最初にCPUのCS:IPをCS = 0xF000、IP = 0xFFF0に設定します。これは、CPU開発者とBIOS開発者の間で締結された合意であり、システム全体を実行するための論理的な開始点です。

0xFFFF0は、BIOSコードが配置されているROM領域の先頭です。CS:IPがこれをポイントすると、BIOSの基本的なIOデバイスチェックが実行されます。BIOSチェックが完了すると、ブートデバイス(ディスクなど)が実行されます。 、CD-ROM、フロッピーディスクなど)ディスク0のトラック0の最初のセクターは、0x07C00でメモリにロードされます。最後に、BIOSは0x07C00にジャンプし、オペレーティングシステムのブートプログラムに制御を移します。この0x07C00はBIOSの合意であり、オペレーティングシステムのブート領域をディスクからその場所にコピーすることを自由に選択できることに注意してください。たとえば、Seabiosのソースコードhttps://git.seabios.org/cgit/seabios.git/tree/src/boot.cでは、このアドレスは直接ハードコードされています。
ここに画像の説明を挿入

そして、この0ディスクサーフェス0トラック1セクターはブート領域であり、このセクターの512バイトのコンテンツは、bootsect.sアセンブリコードのコンパイル後に取得されます。

次に、このコードが何をするか見てみましょう:

1つ目は、いくつかのセグメントのセグメントベース
アドレスを定義することです。BOOTSEG:BOOTセグメントアドレス
INITSEG:初期化アドレス。将来的には、ブート領域のコードがここで
SETUPSEG:セットアップ開始セグメントベースアドレス
SYSSEG:SYSセグメントベースにコピーされます。住所

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text

SETUPLEN = 4				! nr of setup-sectors
BOOTSEG  = 0x07c0			! original address of boot-sector
INITSEG  = 0x9000			! we move boot here - out of the way
SETUPSEG = 0x9020			! setup starts here
SYSSEG   = 0x1000			! system loaded at 0x10000 (65536).
ENDSEG   = SYSSEG + SYSSIZE		! where to stop loading

! ROOT_DEV:	0x000 - same type of floppy as boot.
!		0x301 - first partition on first drive etc
ROOT_DEV = 0x306

次に、startと入力します。

entry _start
_start:
	mov	ax,#BOOTSEG
	mov	ds,ax
	mov	ax,#INITSEG
	mov	es,ax
	mov	cx,#256
	sub	si,si
	sub	di,di
	rep
	movw
	jmpi	go,INITSEG
go:	···

このコードは主に、BOOTSEGセグメントの512バイトのブートコードをINITSEGが配置されているセグメントにコピーするためのものです。movw命令は一度に2バイトの内容をコピーするため、cxの初期値は256であることに注意してください。
そして最後にjmpi go,INITSEGINITSEGの値はCSに与えられ、goのオフセットはIPに与えられます。これは、上記でブートをセグメント0x9000にコピーする作業が完了したためです。2つのセグメント0x07c0と0x9000には2つの同一のブートコードがあります。CSセグメントへのINITSEGは0x9000の先頭に転送され、実行したい量をコンパイルしてIPに移動することは、CPUを直接作成し、その後jmpi go,INITSEGに続行するように指示することです。

go:	mov	ax,cs
	mov	ds,ax
	mov	es,ax
! put stack at 0x9ff00.
	mov	ss,ax
	mov	sp,#0xFF00		! arbitrary value >>512

! load the setup-sectors directly after the bootblock.
! Note that 'es' is already set up.

CSが0x9000セグメントになった後、ds、es、ssの3つのセグメントレジスタを次々に設定し、同時にspレジスタの値を設定し、スタックの最上位を0x9FF00に設定します。

load_setup:
	mov	dx,#0x0000		! drive 0, head 0
	mov	cx,#0x0002		! sector 2, track 0
	mov	bx,#0x0200		! address = 512, in INITSEG
	mov	ax,#0x0200+SETUPLEN	! service 2, nr of sectors
	int	0x13			! read it
	jnc	ok_load_setup		! ok - continue
	mov	dx,#0x0000
	mov	ax,#0x0000		! reset the diskette
	int	0x13
	j	load_setup

その後すぐに、0x13割り込みを使用して、ブートディスクの2番目のセクターを開始し、合計SETUPLEN(4)セクターの内容をes:0x020(つまり、0x90200)のアドレスに読み取ります。
読み取りが正しい場合は、にジャンプしますok_load_setup。そうでない場合、dx、axをリセット、load_setupをループで実行します。

ok_load_setup:

! Get disk drive parameters, specifically nr of sectors/track

	mov	dl,#0x00
	mov	ax,#0x0800		! AH=8 is get drive parameters
	int	0x13
	mov	ch,#0x00
	seg cs
	mov	sectors,cx
	mov	ax,#INITSEG
	mov	es,ax

! Print some inane message

	mov	ah,#0x03		! read cursor pos
	xor	bh,bh
	int	0x10
	
	mov	cx,#24
	mov	bx,#0x0007		! page 0, attribute 7 (normal)
	mov	bp,#msg1
	mov	ax,#0x1301		! write string, move cursor
	int	0x10

! ok, we've written the message, now
! we want to load the system (at 0x10000)

	mov	ax,#SYSSEG
	mov	es,ax		! segment of 0x010000
	call	read_it
	call	kill_motor

次のステップは、SYSTEMパーツをロードすることです。これも、0x13割り込みを使用して実行され、0x10000から始まるセグメントにSYSTEMパーツをロードします。同時に、0x10を使用して「Loadingsystem ...」のプロンプト文字列を出力します。

msg1:
	.byte 13,10
	.ascii "Loading system ..."
	.byte 13,10,13,10

システムを読み取った後、ルートファイルシステムなどのマシンデータを準備する必要があります。この部分は重要ではありません。

! After that we check which root-device to use. If the device is
! defined (!= 0), nothing is done and the given device is used.
! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
! on the number of sectors that the BIOS reports currently.

	seg cs
	mov	ax,root_dev
	cmp	ax,#0
	jne	root_defined
	seg cs
	mov	bx,sectors
	mov	ax,#0x0208		! /dev/ps0 - 1.2Mb
	cmp	bx,#15
	je	root_defined
	mov	ax,#0x021c		! /dev/PS0 - 1.44Mb
	cmp	bx,#18
	je	root_defined
undef_root:
	jmp undef_root
root_defined:
	seg cs
	mov	root_dev,ax

最後に、を使用しjmpi 0,SETUPSEGて、セットアップが配置されているコードセグメント、つまりCS = 0x90200、IP = 0ジャンプします。また、0x90200は、ブートディスクの最初のセクターから5番目のセクターまでです。

! after that (everyting loaded), we jump to
! the setup-routine loaded directly after
! the bootblock:

	jmpi	0,SETUPSEG

おすすめ

転載: blog.csdn.net/jmh1996/article/details/108809430