Kernel.c не выполняет полный код [ОС с нуля] - PullRequest
2 голосов
/ 28 октября 2019

Я новичок в операционных системах и пытаюсь собрать ОС с нуля (следуя инструкции ). Хотя я могу выполнить код, предоставленный автором. Но когда я добавляю свой пользовательский загрузчик (который, очевидно, занимает больше памяти и ожидает прерывания клавиатуры для загрузки ядра), а затем пытаюсь добавить драйверы, как указано в руководстве, мое ядро ​​не выполняет полный код (может или не может быть).

На самом деле у меня есть 5 операторов print в kernel.c (и все операторы работают нормально, когда я не добавляю драйвер), но как только я начинаю добавлять драйверы (даже если я не выполняю никакихфункция драйвера), код, кажется, избегает операторов print внизу.

Я попытался изменить смещение ядра, но, похоже, это не дает никакого эффекта.

kernel.c


void clear_screen() // clear the entire text screen
{
    char *vga = (char *)0xb8000;
    unsigned int i = 0;
    while (i < (80 * 25 * 2))
    {
        vga[i] = ' ';
        i++;
        vga[i] = COLOR;
        i++;
    }
}

unsigned int kprintf(char *message, unsigned int line) // the message and then the line #
{
    char *vga = (char *)0xb8000;
    unsigned int i = 0;

    i = (line * 80 * 2);

    while (*message != 0)
    {
        if (*message == '\n') 
        {
            line++;
            i = (line * 80 * 2);
            *message++;
        }
        else
        {
            vga[i] = *message;
            *message++;
            i++;
            vga[i] = COLOR;
            i++;
        }
    }

    return (1);
}


void main() // like main in a normal C program
{
    clear_screen();
    kprintf("Hi!\nThis is our Kernel\n", 2);
    kprintf("Our Team Members:\n", 12);
    kprintf("1. Aditya Garg \n",13);
    kprintf("2. Ayush Agarwal\n", 14);
    kprintf("3. Anup Aglawe \n", 15);
    kprintf("4. Anshuman yadav \n", 16);
    kprintf("5. Ujjaval shah \n", 17);
};

bootsect.asm

[org 0x7c00]
KERNEL_OFFSET equ 0x1000 

    mov [BOOT_DRIVE], dl 
    mov bp, 0x9000
    mov sp, bp
    call start1
    call load_kernel 
    call switch_to_pm 
    jmp $ 

%include "boot/print.asm"
%include "boot/print_hex.asm"
%include "boot/disk.asm"
%include "boot/gdt.asm"
%include "boot/32bit_print.asm"
%include "boot/switch_pm.asm"

[bits 16]
start1:
    mov ax, 0x0          
    mov ds, ax           
    mov es, ax           
    mov bx, 0x8000
    mov ax, 13;clearScreen 
    int 0x10       
    mov ah,2 ;big font
    int 0x10

    ;Position
    mov ah,0x02         
    mov bh,0x00         
    mov dh,0x06         
    mov dl,0x09         
    int 0x10
    mov si, start_os_intro              
    call Color_String        

    ;New Position
    mov ah,0x02
    mov bh,0x00
    mov dh,0x10
    mov dl,0x0a
    int 0x10
    mov si, press_key                    
    call RedColor_String       

    mov ax,0x00         
    int 0x16 

    mov al,2 ;change font             
    mov ah,0 ;clear screen             
    int 0x10  

    ret

start_os_intro db 'Welcome to DarkraiOS!',0
press_key db '>>Press any key<<',0        
; text db 'loading ', 0   


load_kernel:

    mov bx, KERNEL_OFFSET 
    mov dh, 1 
    mov dl, [BOOT_DRIVE]
    call disk_load
    ret

[bits 32]
BEGIN_PM:

    call KERNEL_OFFSET 
    jmp $ 


BOOT_DRIVE db 0 

times 510 - ($-$$) db 0
dw 0xaa55

Makefile

C_SOURCES = $(wildcard kernel/*.c drivers/*.c)
HEADERS = $(wildcard kernel/*.h drivers/*.h)
# Nice syntax for file extension replacement
OBJ = ${C_SOURCES:.c=.o}

# Change this if your cross-compiler is somewhere else
CC = i686-elf-gcc
GDB = i686-elf-gdb
# -g: Use debugging symbols in gcc
CFLAGS = -g

# First rule is run by default
os-image.bin: boot\bootsect.bin kernel.bin
    type $^ > os-image.bin

# '--oformat binary' deletes all symbols as a collateral, so we don't need
# to 'strip' them manually on this case
kernel.bin: boot/kernel_entry.o ${OBJ}
    i686-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary

# Used for debugging purposes
kernel.elf: boot\kernel_entry.o ${OBJ}
    i686-elf-ld -o $@ -Ttext 0x1000 $^ 

run: os-image.bin
    qemu-system-i386 -fda os-image.bin

# Open the connection to qemu and load our kernel-object file with symbols
debug: os-image.bin kernel.elf
    qemu-system-x86_64 -s -fda os-image.bin &
    ${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"

# Generic rules for wildcards
# To make an object, always compile from its .c
%.o: %.c ${HEADERS}
    ${CC} ${CFLAGS} -ffreestanding -c $< -o $@

%.o: %.asm
    nasm $< -f elf -o $@

%.bin: %.asm
    nasm $< -f bin -o $@

clean:
    rm -rf *.bin *.dis *.o os-image.bin *.elf
    rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o

Drivers ports.c

    unsigned char result;

    __asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
    return result;
}

void port_byte_out (unsigned short port, unsigned char data) {

    __asm__("out %%al, %%dx" : : "a" (data), "d" (port));
}

unsigned short port_word_in (unsigned short port) {
    unsigned short result;
    __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
    return result;
}

void port_word_out (unsigned short port, unsigned short data) {
    __asm__("out %%ax, %%dx" : : "a" (data), "d" (port));
}

Drivers / ports.h

unsigned char port_byte_in (unsigned short port);
void port_byte_out (unsigned short port, unsigned char data);
unsigned short port_word_in (unsigned short port);
void port_word_out (unsigned short port, unsigned short data);

Перед добавлением папки драйверов

После добавления папки драйверов (я не использую ни одну из функций драйвера)

PS- Если кто-нибудь попросит, я могу поделиться всем своим кодом.

1 Ответ

3 голосов
/ 28 октября 2019

На основании скриншота, на котором напечатана только часть меню, я могу предположить, что ваше ядро ​​(kernel.bin) не было полностью загружено в память. В load_kernel вы делаете:

load_kernel:    
    mov bx, KERNEL_OFFSET 
    mov dh, 1                ; <----- Number of sectors to read
    mov dl, [BOOT_DRIVE]
    call disk_load
    ret

Учебное пособие, которое вы используете, передает число секторов для чтения в DH . Это задокументировано в boot_sect_disk.asm как:

; load 'dh' sectors from drive 'dl' into ES:BX

Вам нужно увеличить это число, чтобы прочитать достаточно секторов для загрузки всего вашего ядра. Чтобы выяснить, сколько секторов для загрузки вы найдете размер kernel.bin, добавьте к нему 511, а затем разделите на 512. numsectors = (filesize + 511) / 512 вычисляет количество секторов в 512 байт, необходимое для загрузки файлаfilesize округлено до ближайшего 512-байтового сектора. Загрузите это значение в DH .

...