Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于linux v0.01 bootssect.S_Linux_Assembly_Bootloader - Fatal编程技术网

关于linux v0.01 bootssect.S

关于linux v0.01 bootssect.S,linux,assembly,bootloader,Linux,Assembly,Bootloader,最近我在看linux 0.01源代码,因为2.6.11和更高版本中的bootssect.S是无用的,它是开始学习linux代码的好地方,因此我选择跟踪linux的第一个版本:P 我在S节有一些问题。下面是bootssect.slinuxv0.01中的一些代码 另外,第一版汇编代码使用的是英特尔语法,而不是at&t mov ax,#0x0001 | protected mode (PE) bit lmsw ax | This is it! jmpi 0,8 | jmp

最近我在看linux 0.01源代码,因为2.6.11和更高版本中的bootssect.S是无用的,它是开始学习linux代码的好地方,因此我选择跟踪linux的第一个版本:P

我在S节有一些问题。下面是bootssect.slinuxv0.01中的一些代码

另外,第一版汇编代码使用的是英特尔语法,而不是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.
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

以下是系统的生成文件:

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作为系统二进制文件链接在一起,bootssect将其加载到内存中

我的问题是,如果系统代码(哪个条目是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
如果仔细观察代码,您会注意到它确实开始使用ES=0,DI=0(目标)和DS=0x1000,SI=0(源)执行REP MOVSW,也就是说,它将内容从0x10000(=DS*0x10+SI)移动到0(=ES*0x10+DI)。

答案如下:

| 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

如果仔细看代码,您会注意到它确实开始使用ES=0,DI=0(目的地)和DS=0x1000,SI=0(源代码)执行REP MOVSW,也就是说,它将内容从0x10000(=DS*0x10+SI)移动到0(=ES*0x10+DI)。

到源代码的链接会很好:)我在文章中添加了一个下载链接。回复:)链接到源代码会很好:)我在帖子中添加了一个下载链接。答复:)