2010-01-14 4 views
9

Я написал простой загрузчик первого этапа, который отображает «Hello world», используя прерывание для bios. Теперь, как следующий очевидный шаг, чтобы написать второй этап, но где код для этого должен существовать и как загрузить его с первого этапа?Как загрузить загрузчик второго этапа с первого этапа?

Вот программа для первого этапа

[BITS 16] ;Tells the assembler that its a 16 bit code 
[ORG 0x7C00] ;Origin, tell the assembler that where the code will 
       ;be in memory after it is been loaded 

MOV SI, HelloString ;Store string pointer to SI 
CALL PrintString ;Call print string procedure 
JMP $  ;Infinite loop, hang it here. 


PrintCharacter: ;Procedure to print character on screen 
    ;Assume that ASCII value is in register AL 
MOV AH, 0x0E ;Tell BIOS that we need to print one charater on screen. 
MOV BH, 0x00 ;Page no. 
MOV BL, 0x07 ;Text attribute 0x07 is lightgrey font on black background 

INT 0x10 ;Call video interrupt 
RET  ;Return to calling procedure 



PrintString: ;Procedure to print string on screen 
    ;Assume that string starting pointer is in register SI 

next_character: ;Lable to fetch next character from string 
MOV AL, [SI] ;Get a byte from string and store in AL register 
INC SI  ;Increment SI pointer 
OR AL, AL ;Check if value in AL is zero (end of string) 
JZ exit_function ;If end then return 
CALL PrintCharacter ;Else print the character which is in AL register 
JMP next_character ;Fetch next character from string 
exit_function: ;End label 
RET  ;Return from procedure 


;Data 
HelloString db 'Hello World', 0 ;HelloWorld string ending with 0 

TIMES 510 - ($ - $$) db 0 ;Fill the rest of sector with 0 
DW 0xAA55   ;Add boot signature at the end of bootloader 
+0

Вы используете язык C? Любая другая важная информация, которую вы можете поделиться? –

+0

мы использовали инструкции для x86 для первой стадии, но мы планируем написать второй этап на языке более высокого уровня, например c .. где я храню этот двоичный код второй стадии и как загрузить его с загрузчика первого этапа – Xinus

+0

Возможный дубликат [Загрузка ядра от сборки (NASM)] (http://stackoverflow.com/questions/1551240/loading-kernel-from-assembly-nasm) –

ответ

6

На x86 вы могли бы сделать следующее (упрощенно):

  • Есть загрузчик загрузит н-й сектор диска/дискеты (где бы вы не загружались) в память и выполнять его (например, сегмент нагрузки/смещение и делать retf). Лучшей альтернативой является поиск файловой системы для определенного имени файла (например, KERNEL.BIN), но вам нужно будет узнать тип файловой системы (например, FAT12, если вы тестируете дискету).
  • Затем ядро ​​запускается в реальном режиме. Он устанавливает дескрипторы кода, GDT и т. Д., Активирует 32-битную адресацию (вы должны были услышать об «A20») и, наконец, входите в защищенный режим. Затем вам нужно далеко перейти к 32-битовому сегменту кода (файл ядра должен быть связан вместе таким образом, чтобы 32-разрядный код находился в абсолютном положении, например, со смещением 512, сразу после 16-разрядного реального режима) ,
  • 32-разрядная сборка ядра затем определяет EXTERN _mykernel (например) и вызывает этот символ.
  • Тогда вы можете начать писать свое ядро ​​как функцию C mykernel.

Хорошо, это был краткий обзор того, что я сделал несколько лет назад (с большим количеством копий & пасты из Интернета;). Если это не помогает, вот некоторые хорошие веб-ресурсы по разработке ОС:

Надежда, что помогает ^^

+1

Спасибо за первую ссылку – Xinus

1

Посмотрите на реализацию GRUB здесь (этап 1):

http://src.illumos.org/source/xref/illumos-gate/usr/src/grub/grub-0.97/stage1/stage1.S

Сначала заметили начальную точку в 0x7c00 и конечную подпись 0xaa55 для этого первого сектора. Изнутри разборки, и можно увидеть это:

349 copy_buffer: 
350 movw ABS(stage2_segment), %es 
351 
352 /* 
353 * We need to save %cx and %si because the startup code in 
354 * stage2 uses them without initializing them. 
355 */ 
356 pusha 
357 pushw %ds 
358 
359 movw $0x100, %cx 
360 movw %bx, %ds 
361 xorw %si, %si 
362 xorw %di, %di 
363 
364 cld 
365 
366 rep 
367 movsw 
368 
369 popw %ds 
370 popa 
371 
372 /* boot stage2 */ 
373 jmp *(stage2_address) 
374 
375 /* END OF MAIN LOOP */ 
376 

По существу, логика, чтобы скопировать код 2 этапа в другую часть памяти, и после этого скачка прямо там, и это «загрузочный stage2 ». Другими словами, «boot stage1» эффективно запускается из BIOS после того, как он загрузил сектор в память, тогда как stage2 - это то место, где вы прыгаете туда - это может быть где угодно.

+0

Как ассемблер знает, что все метки для кода, загруженного из диск теперь смещены везде, где вы загружались в ОЗУ? –

3

Minimal работоспособной пример NASM BIOS, который загружает этап 2 и переходит к нему

use16 
org 0x7C00 

    ; You should do further initializations here 
    ; like setup the stack and segment registers. 

    ; Load stage 2 to memory. 
    mov ah, 0x02 
    ; Number of sectors to read. 
    mov al, 1 
    ; This may not be necessary as many BIOS set it up as an initial state. 
    mov dl, 0x80 
    ; Cylinder number. 
    mov ch, 0 
    ; Head number. 
    mov dh, 0 
    ; Starting sector number. 2 because 1 was already loaded. 
    mov cl, 2 
    ; Where to load to. 
    mov bx, stage2 
    int 0x13 

    jmp stage2 

    ; Magic bytes.  
    times ((0x200 - 2) - ($ - $$)) db 0x00 
    dw 0xAA55 

stage2: 

    ; Print 'a'. 
    mov ax, 0x0E61 
    int 0x10 

    cli 
    hlt 

    ; Pad image to multiple of 512 bytes. 
    times ((0x400) - ($ - $$)) db 0x00 

компилировать и запускать:

nasm -f bin -o main.img main.asm 
qemu-system-i386 main.img 

Ожидаемый результат: a печатается на экране, а затем программа останавливается.

Протестировано на Ubuntu 14.04.

Пример Saner GAS с использованием сценария компоновщика и правильной инициализации (регистры сегментов, стек) on my GitHub.

+0

Если кто-нибудь может догадаться, почему downvote, пожалуйста, сделайте это, я смогу узнать и улучшить информацию. Я никогда не отвечаю. –

+0

А, я просматриваю активный список тегов 'bootloader', и я вижу, что мы встречаемся снова. Одно замечание, которое я сделаю, это то, что я, вероятно, закрыл бы этот вопрос как слишком широкий. Хотя вы предоставляете решение, вы утверждаете, что OP будет просто загружаться из следующего сектора после MBR. Хотя это решение, я думаю, что вышеперечисленное является более близким знаком в обсуждении других идей, таких как поиск файла для файловой системы. Этот ответ предполагает и многое другое - есть ли файловая система, содержащая 2-й этап? Какая файловая система? и т. д. –

+0

@MichaelPetch снова там :-) Согласился, что это хороший ответ. Это просто, что мне обычно нравится сначала запускать некоторые вещи, чтобы увидеть его красоту, и тогда это облегчает понимание более глубоких частей позже. –

Смежные вопросы