- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
最近在看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 是不是很奇怪,因为那里没有加载代码??
最佳答案
答案如下:
| 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/
最近在看linux 0.01的源码,由于2.6.11及以上版本的bootsect.S没用,是学习linux代码的好起点,所以选择trace第一个版本Linux。 :P 我在 bootsect.S 中有
我正在研究x86系统启动的过程这是启动流程: BIOS 将 bootsect 从磁盘 MBR 加载到 0x7c00 内存地址 boosect 将自身复制到 0x90000 内存地址并跳转到 0x900
我是一名优秀的程序员,十分优秀!