《Linux0.11源码解读》理解(二) 加载setup、加载system

现在CPU开始执行bootsect,它的作用是挪动bootset并设置栈, 并把第二部分setup、第三部分system程序陆续加载到内存中。把放到合理的内存位置需要先对内存进行规划。

根据上一节,boostsect当前所在内存位置是0x07c0,大小为512byte,现在要将其挪动到内存的0x9000(INITSET)。除此以外,还要将位于硬盘上的4个(SETUPLEN)扇区的setup程序加载到内存的0x9020(SETUPSEG);最后要将system程序(内核)加载到内存的0x1000(SYSSEG),并指定了其末尾位置(ENDSEG)。

SYSSIZE = 0x3000
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

注意,这里的INITSET,SETUPSEG,SYSSEG会被ds(数据段基址)载入,因此在实模式下的实际加载内存位置是0x90000,0x90200(bootsect占据的512字节内存末尾正是0x90000+0x200,说明bootsect和setup在内存里紧挨着),0x10000。

如何将已位于内存的bootsect挪动位置

通过ds:si和es:di指定源地址和目的地址,cx指定重复操作的次数,movw每次复制2字节一共是512字节。然后jmpi段间跳转将cs:ip设置为0x9000:go以让程序从go标签继续。

cs已被更新为0x9000,同样将其赋予ds、es,并设置栈顶为0x9ff00,为后续栈操作做好准备。

	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:	mov	ax,cs
	mov	ds,ax
	mov	es,ax
; put stack at 0x9ff00.
	mov	ss,ax
	mov	sp,#0xFF00		; arbitrary value >>512

如何将setup加载到指定位置

答案仍是调用BIOS的0x13中断,只不过和上一节课0x19中断不同的是,0x13的参数由我们bootsect的程序来指定,其中包括指定硬盘0盘面0磁头、2扇区0磁道、偏移地址512(0x200)、ah中断所属的功能号0x02,al待读setup的扇区数是4。最后调用int 0x13,通过cf标志是否为0判断0x13执行是否成功:失败并则重试,成功则无条件跳转到ok_load_setup。

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
	jmp	load_setup

如何将system加载到指定位置

核心代码就这几行,其作用是把从硬盘第 6 个扇区开始往后的 240 个扇区,加载到内存 0x10000 处,和之前的从硬盘复制到内存类似,read_it归根到底也用到了0x13。其原理都是通过磁盘控制器访问磁盘,要给出柱面,磁头,扇区等信息。详细read_it参考:https://blog.csdn.net/kunkliu/article/details/126294876

ok_load_setup:
    ...
    mov ax,#SYSSEG
    mov es,ax       ; segment of 0x10000
    call read_it
    ...
    jmpi 0,0x9020

 现在所有操作系统代码都已加载内存,给一张来自于《Linux0.11源码解读》的内存图景:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值