Задать вопрос

Почему от добавления функций помимо main() в начало кода ядро перестает работать?

Причем если добавить в конец, то все нормально, но кому нужна функция в конце?

Makefile
all:
	nasm -f bin bootloader.asm -o bootloader
	i686-elf-gcc -ffreestanding -m16 -c kernel.c -o kernel.o -Wall -Wextra
	i686-elf-ld -Ttext 0x7E00 --oformat binary kernel.o -o kernel -e main
	dd if=/dev/zero of=install.img bs=512 count=2880
	dd if=bootloader of=install.img conv=notrunc
	dd if=kernel of=install.img seek=1 conv=notrunc
clean:
	rm install.img bootloader kernel kernel.o
dump:
	cat bootloader.asm kernel.c Makefile std.h vga.h
run:
	qemu-system-i386 -fda install.img


kernel.c
void main() {
    // Print to the screen using BIOS interrupt
    asm volatile (
            "mov $0x0E, %%ah;"        // Teletype Output function
            "mov $'H', %%al;"          // Print 'H'
            "int $0x10;"               // BIOS interrupt
            "mov $'e', %%al;"          // Print 'e'
            "int $0x10;"
            "mov $'l', %%al;"          // Print 'l'
            "int $0x10;"
            "mov $'l', %%al;"          // Print 'l'
            "int $0x10;"
            "mov $'o', %%al;"          // Print 'o'
            "int $0x10;"
            :
            :
            : "%ax", "%bx"
        );

    // Halt the CPU (end of program)
    asm volatile ("hlt");
}


bootloader.asm
[BITS 16]
ORG 0x7C00

START:
    ; Clear registers
    XOR AX, AX
    MOV DS, AX           ; Data Segment to 0x0000
    MOV ES, AX           ; Extra Segment to 0x0000

    ; Set 80x25 text mode using VESA BIOS
    MOV AX, 0x0003       ; Function: Set Video Mode (80x25 Text)
    INT 0x10

    ; Load kernel from second sector
	MOV AH, 0x02         ; Function: Read Sectors
	MOV AL, 0x01         ; Number of sectors to read
	MOV CH, 0x00         ; Cylinder 0
	MOV CL, 0x02         ; Sector 2 (second sector of disk)
	MOV DH, 0x00         ; Head 0
	MOV DL, 0x00         ; Drive 0 (floppy disk)
	MOV BX, 0x7E00       ; Load address for the kernel
	INT 0x13

    JC load_error        ; Jump if carry flag is set (error)

    ; Jump to the kernel's entry point
    JMP 0x0000:0x7E00

load_error:
    ; Display error message (simple loop, no proper string handling)
    MOV AH, 0x0E         ; Teletype Output
    MOV AL, 'E'          ; Error message
    INT 0x10
    MOV AL, 'R'
    INT 0x10
    MOV AL, 'R'
    INT 0x10
    MOV AL, 'O'
    INT 0x10
    MOV AL, 'R'
    INT 0x10
    MOV AL, '!'
    INT 0x10
    HLT                  ; Halt on error

times 510-($-$$) DB 0    ; Fill remaining space with zeroes
DW 0xAA55               ; Boot sector signature


Простите, до форматирования пока руки не дошли.

Если например добавить void myFunc () {} в начало кода, то:
6745ede760028574131421.png

А если в конец то:
6745ee0488491890515748.png

С include файлами таже проблема. (за исключением stdbool.h и им подобые)
  • Вопрос задан
  • 159 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Почему от добавления функций помимо main() в начало кода ядро перестает работать?

смотри: ты собираешь образ kernel следующей командой:
i686-elf-ld -Ttext 0x7E00 --oformat binary kernel.o -o kernel -e main

а запускаешь следующей:
; Jump to the kernel's entry point
    JMP 0x0000:0x7E00

как по-твоему здесь используется информация о точке входа -e main?

Ответ
никак, выполнение всегда начинается с начала образа kernel, куда выполняет переход начальный загрузчик; что там будет, то и начнёт выполняться. Эта информация даже никуда не записывается, потому что файл формата binary -- это тупо склеенные вместе загружаемые сегменты, там нет места для метаинформации. Если бы ты собирал ELF, то этот адрес был бы записан в поле e_entry заголовка ELF.

Если не модифицировать загрузчик, то образ ядра должен начинаться с кода точки входа, в твоём случае -- с кода main(). Чтобы поместить нужный код в нужное место собранного образа обычно используют скрипт линковщика.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы