2013-10-24 5 views
3

Так что я ударил стену через четыре дня. Я работаю с OSDev tut и два дня искал высокий и низкий. Я все пробовал. Сначала я понял, что глупо, что я пытался собрать 64, и именно поэтому я получил «..relocation, усеченный, чтобы соответствовать: rva32 против ..». Я перешел на Cygwin 32, и теперь я не вижу главного в своем ядре.Смешивание и проблемы ядра

Извините, если это глупо, я пытаюсь работать над этим в перерывах между занятиями и я сожжен

boot.asm скомпилирован с >>> NASM -f эльфа boot.asm -o boot.o

MBALIGN  equ 1<<0     ; align loaded modules on page boundaries 
MEMINFO  equ 1<<1     ; provide memory map 
FLAGS  equ MBALIGN | MEMINFO  ; this is the Multiboot 'flag' field 
MAGIC  equ 0x1BADB002    ; 'magic number' lets bootloader find the header 
CHECKSUM equ -(MAGIC + FLAGS)  ; checksum of above, to prove we are multiboot 

section .multiboot 
align 4 
    dd MAGIC 
    dd FLAGS 
    dd CHECKSUM 

section .bootstrap_stack 
align 4 
stack_bottom: 
times 16384 db 0 
stack_top: 

section .text 
global _start 
_start: 

    mov esp, stack_top 

    call kernel_main 

    cli 
.hang: 
    hlt 
    jmp .hang 

ядро ​​скомпилировано с >>> г ++ -c -o kernel.cpp kernel.o -ffreestanding -O2 -Wall -Wextra -fno-исключения -fno-RTTI

#include <stddef.h> 
#include <stdint.h> 

/* Hardware text mode color constants. */ 
enum vga_color 
{ 
    COLOR_BLACK = 0, 
    COLOR_BLUE = 1, 
    COLOR_GREEN = 2, 
    COLOR_CYAN = 3, 
    COLOR_RED = 4, 
    COLOR_MAGENTA = 5, 
    COLOR_BROWN = 6, 
    COLOR_LIGHT_GREY = 7, 
    COLOR_DARK_GREY = 8, 
    COLOR_LIGHT_BLUE = 9, 
    COLOR_LIGHT_GREEN = 10, 
    COLOR_LIGHT_CYAN = 11, 
    COLOR_LIGHT_RED = 12, 
    COLOR_LIGHT_MAGENTA = 13, 
    COLOR_LIGHT_BROWN = 14, 
    COLOR_WHITE = 15, 
}; 

uint8_t make_color(enum vga_color fg, enum vga_color bg) 
{ 
    return fg | bg << 4; 
} 

uint16_t make_vgaentry(char c, uint8_t color) 
{ 
    uint16_t c16 = c; 
    uint16_t color16 = color; 
    return c16 | color16 << 8; 
} 

size_t strlen(const char* str) 
{ 
    size_t ret = 0; 
    while (str[ret] != 0) 
     ret++; 
    return ret; 
} 

static const size_t VGA_WIDTH = 80; 
static const size_t VGA_HEIGHT = 24; 

size_t terminal_row; 
size_t terminal_column; 
uint8_t terminal_color; 
uint16_t* terminal_buffer; 

void terminal_initialize() 
{ 
    terminal_row = 0; 
    terminal_column = 0; 
    terminal_color = make_color(COLOR_LIGHT_GREY, COLOR_BLACK); 
    terminal_buffer = (uint16_t*) 0xB8000; 
    for (size_t y = 0; y < VGA_HEIGHT; y++) 
    { 
     for (size_t x = 0; x < VGA_WIDTH; x++) 
     { 
      const size_t index = y * VGA_WIDTH + x; 
      terminal_buffer[index] = make_vgaentry(' ', terminal_color); 
     } 
    } 
} 

void terminal_setcolor(uint8_t color) 
{ 
    terminal_color = color; 
} 

void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) 
{ 
    const size_t index = y * VGA_WIDTH + x; 
    terminal_buffer[index] = make_vgaentry(c, color); 
} 

void terminal_putchar(char c) 
{ 
    terminal_putentryat(c, terminal_color, terminal_column, terminal_row); 
    if (++terminal_column == VGA_WIDTH) 
    { 
     terminal_column = 0; 
     if (++terminal_row == VGA_HEIGHT) 
     { 
      terminal_row = 0; 
     } 
    } 
} 

void terminal_writestring(const char* data) 
{ 
    size_t datalen = strlen(data); 
    for (size_t i = 0; i < datalen; i++) 
     terminal_putchar(data[i]); 
} 

extern "C" 
{ 
    void kernel_main() 
    { 
     terminal_initialize(); 
     /* Since there is no support for newlines in terminal_putchar yet, \n will 
      produce some VGA specific character instead. This is normal. */ 
     terminal_writestring("Hello, kernel World!\n"); 
    } 
} 

линкер вызов >> > g ++ -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib -f нет-исключения boot.o kernel.o -lgcc

ENTRY(_start) 

SECTIONS 
{ 
    /* Begin @ 1 MB*/ 
    . = 1M; 

    /* multiboot header -> text */ 
    .text BLOCK(4K) : ALIGN(4K) 
    { 
     *(.multiboot) 
     *(.text) 
    } 

    /* Read only data */ 
    .rodata BLOCK(4K) : ALIGN(4K) 
    { 
     *(.rodata) 
    } 

    /* Read-write data */ 
    .data BLOCK(4K) : ALIGN(4K) 
    { 
     *(.data) 
    } 

    /* Read, write, and stack */ 
    .bss BLOCK(4K) : ALIGN(4K) 
    { 
     *(COMMON) 
     *(.bss) 
     *(.bootstrap_stack) 
    } 

    /* Additional Here */ 
} 

Может быть, я просто сожжен, и я не вижу что-то простое, но именно поэтому я здесь

ответ

0

По умолчанию GCC добавляет SO- так называемые «файлы запуска» в ваш объектный файл, что делает невозможным его загрузку. Чтобы отключить их, добавьте -nostartfiles в список аргументов g++. Кроме того, C++ требует кучу других вещей, созданных для того, чтобы он даже загрузился!

Пожалуйста, см: http://wiki.osdev.org/C++

1

Я знаю, этот вопрос более старый, но есть несколько вещей, чтобы узнать от проблем, с которыми сталкиваются. Предполагая 32-битную компиляцию, есть несколько проблем, и, вероятно, одна из них может привести к вашим проблемам.

При компоновке Вы определили, что .bootstrap_stack будет размещен в .bss раздел:

.bss BLOCK(4K) : ALIGN(4K) 
{ 
    *(COMMON) 
    *(.bss) 
    *(.bootstrap_stack) 
} 

В boot.asm вы определяете стек с:

section .bootstrap_stack 
align 4 
stack_bottom: 
    times 16384 db 0 
stack_top: 

Это штраф, но вы не должны пытаться помещать инициализированные данные в .bss, а раздел, который вы добавляете, должен иметь nobits, alloc и write атрибуты, которые должны быть совместимы с типичным сегментом BSS. Это может выглядеть примерно так:

section .bootstrap_stack nobits alloc write 
align 4 
stack_bottom: 
    resb 16384   ; Reserves but doesn't initialize 16384 bytes 
stack_top: 

Внесение этих изменений будет создан правильный стек (16k в размере) в BSS сегмента, и избежать ассемблер и компоновщик предупреждения.

В вашем boot.asm вы делаете call kernel_main. Это нормально, но поскольку он не находится внутри boot.asm, вы должны сообщить ассемблеру (NASM), что это внешняя метка.В верхней части boot.asm вы должны добавить:

extern kernel_main 

Самый большой потенциальной проблемой использования GCC является то, что он поместит 4k раздел с .note.gnu.build-id после ваших заголовков ELF. Это почти гарантирует, что ваш section .multiboot будет размещен за точкой 8k вашего двоичного файла ELF и заставит многозагрузочный загрузчик (например, GRUB) сказать вам, что он не может найти многозадачный заголовок в вашем файле. Чтобы обойти это, вам нужно связать свой последний двоичный код ядра (myos.bin) с опцией компоновщика -Wl,--build-id=none. Вы также должны прямо указать NASM для генерации 32-битного ELF объект с -f elf32 и GCC с -m32 вариантов. Ваши компиляции и команды будет выглядеть примерно так:

nasm -f elf32 boot.asm -o boot.o 
g++ -m32 -c kernel.cpp -o kernel.o -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti 
g++ -m32 -Wl,--build-id=none -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib -fno-exceptions boot.o kernel.o -lgcc 

компилировать и компоновать с отладочной, вы можете сделать это:

nasm -f elf32 -g -F dwarf boot.asm -o boot.o 
g++ -g -m32 -c kernel.cpp -o kernel.o -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti 
g++ -g -m32 -Wl,--build-id=none -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib -fno-exceptions boot.o kernel.o -lgcc 

Вы должны также прислушаться к advice из OSDev Wiki, чтобы построить с кросс-компилятор, а не собственный компилятор, адаптированный к вашей среде хоста. В долгосрочной перспективе это может избежать некоторых трудно найти ошибки.

Пересмотренный boot.asm может выглядеть следующим образом:

extern kernel_main 

MBALIGN  equ 1<<0     ; align loaded modules on page boundaries 
MEMINFO  equ 1<<1     ; provide memory map 
FLAGS  equ MBALIGN | MEMINFO  ; this is the Multiboot 'flag' field 
MAGIC  equ 0x1BADB002    ; 'magic number' lets bootloader find the header 
CHECKSUM equ -(MAGIC + FLAGS)  ; checksum of above, to prove we are multiboot 

section .multiboot 
align 4 
    dd MAGIC 
    dd FLAGS 
    dd CHECKSUM 

section .bootstrap_stack nobits alloc write 
align 4 
stack_bottom: 
    resb 16384    ; Reserves but doesn't initialize 16384 bytes 
stack_top: 

section .text 
global _start 
_start: 

    mov esp, stack_top 

    call kernel_main 

    cli 
.hang: 
    hlt 
    jmp .hang 
Смежные вопросы