о linux v0.01 bootsect.S - PullRequest
       24

о linux v0.01 bootsect.S

1 голос
/ 02 октября 2011

В последнее время я смотрю на исходный код linux 0.01, так как bootsect.S в 2.6.11 и более поздних версиях бесполезен, и это хорошее место для начала изучения кода 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.

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 (системный код содержит boot / head.S и init / main.c в соответствии с Makefile)

  • загрузка временных gdt и idt с lgdt и lidt

  • разрешить A20 доступ к физической памяти 16 МБ.

  • установить бит 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 связаны между собой как двоичный файл системы, который загрузочный сектор загружает в память.

У меня вопрос: если системный код (запись head.S / startup_32) загружен в 0x10000, то почему бы не перейти к 0x10000, а к 0x000000? Разве не странно переходить к 0x0, так как там нет загруженного кода ??

Ниже приведена ссылка для скачивания исходного кода: https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B1F0m2rUn8BYMjQ4ZDQxZTUtODI5My00MGZiLTgwZDQtM2ZiZWQ2ZWQxYzIx

1 Ответ

1 голос
/ 02 октября 2011

Вот ответ:

| 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 с ES = 0, DI = 0 (пункт назначения) и DS = 0x1000, SI = 0 (источник), то есть он перемещает материал с 0x10000 (= DS * 0x10 + SI) на 0 (= ES * 0x10 +DI).

...