gpt4 book ai didi

linux - 关于 linux v0.01 bootsect.S

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:10:01 28 4
gpt4 key购买 nike

最近在看linux 0.01的源码,由于2.6.11及以上版本的bootsect.S没用,是学习linux代码的好起点,所以选择trace第一个版本Linux。 :P

我在 bootsect.S 中有一些问题。以下是bootsect.S linux v 0.01中的部分代码。

P.S 第一个版本的汇编代码使用的是 intel 语法而不是 at&t。

mov   ax,#0x0001  | protected mode (PE) bit
lmsw ax | This is it!
jmpi 0,8 | jmp offset 0 of segment 8 (cs) which is the second entry of the gdt.

广东话:

.word    0,0,0,0        | dummy
.word 0x07FF | 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 | base address=0
.word 0x9A00 | code read/exec
.word 0x00C0 | granularity=4096, 386

.word 0x07FF | 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 | base address=0
.word 0x9200 | data read/write
.word 0x00C0 | granularity=4096, 386

开机过程大概是这样的:

  • 将引导加载程序代码从 0x7c00 移至 0x9000

  • 跳转到 0x9000

  • 设置段寄存器。

  • 加载系统代码到0x10000(根据Makefile,系统代码包含boot/head.S和init/main.c)

  • 用 lgdt 和 lidt 加载临时 gdt 和 idt

  • 启用A20访问16mb物理内存。

  • 设置cr0 PE位进入保护模式

  • 跳转到0x000000

以下是系统的Makefile:

tools/system:   
boot/head.o init/main.o \
$(ARCHIVES) $(LIBS)
$(LD) $(LDFLAGS) boot/head.o init/main.o \
$(ARCHIVES) \
$(LIBS) \

-o tools/system > System.map

似乎 head.S 和 main.c 作为系统二进制链接在一起,bootsect 将其加载到内存中。

我的问题是,如果系统代码(哪个条目是 head.S/startup_32 )加载到 0x10000 中,为什么不跳转到 0x10000 而不是跳转到 0x000000?跳转到 0x0 是不是很奇怪,因为那里没有加载代码??

以下是源码下载链接: https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B1F0m2rUn8BYMjQ4ZDQxZTUtODI5My00MGZiLTgwZDQtM2ZiZWQ2ZWQxYzIx

最佳答案

答案如下:

| It then loads the system at 0x10000, using BIOS interrupts. Thereafter
| it disables all interrupts, moves the system down to 0x0000, ...

这是它附带的代码:

        cli                     | no interrupts allowed !

| first we move the system to it's rightful place

mov ax,#0x0000
cld | 'direction'=0, movs moves forward
do_move:
mov es,ax | destination segment
add ax,#0x1000
cmp ax,#0x9000
jz end_move
mov ds,ax | source segment
sub di,di
sub si,si
mov cx,#0x8000
rep
movsw
j do_move

如果你仔细看代码,你会注意到它确实开始执行 REP MOVSW with ES=0,DI=0 (destination) and DS=0x1000,SI=0 (source),也就是说,它移动从 0x10000(=DS*0x10+SI) 到 0(=ES*0x10+DI) 的东西。

关于linux - 关于 linux v0.01 bootsect.S,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7626861/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com