2013-10-24 36 views
3

所以我四天後就撞上了牆。我正在使用OSDev tut,並且搜索了兩天的高和低。我已經嘗試了一切。首先,我意識到愚蠢的我正在嘗試64編譯,這就是爲什麼我得到了「..relocation被截斷爲適合:rva32對..」。我轉到了Cygwin 32,現在我無法在我的內核中看到main。鏈接器和內核困境

很抱歉,如果這是愚蠢的,我想這個在課間工作,我燒

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 

內核編譯>>> G ++ -c kernel.cpp -o kernel.o -ffreestanding -02 -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 -freestanding -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

默認情況下,海灣合作委員會增加了所謂稱爲「啓動文件」到您的目標文件,使其無法啓動。要禁用它們,請將-nostartfiles附加到參數列表g++。此外,C++還需要創建一堆其他內容才能啓動!

請參閱: http://wiki.osdev.org/C++

1

我知道這個問題是一個較舊的一個,但也有幾件事情,從遇到的問題中汲取教訓。假設32位編譯,有幾個問題,並可能有一個gotchya可能導致你的問題。

當鏈接已指定的.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,allocwrite屬性設置爲與典型的BSS段兼容。它可能看起來像:

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

進行這些更改將設立在BSS段適當堆棧(大小16K),並避免彙編器和鏈接器警告。

在你的boot.asm你做call kernel_main。這很好,但由於它不在boot.asm之內,所以應該告訴彙編程序(NASM)它是外部標籤。在boot.asm頂部,你應該加上:

extern kernel_main 

使用GCC最大的潛在問題是,它將會把與.note.gnu.build-id 4k的部分您的ELF頭後。這幾乎可以保證您的section .multiboot將放置在ELF二進制文件的8k點之外,並且會導致多重引導加載程序(如GRUB)告訴您無法在文件中找到多引導標題。爲了解決這個問題,你需要鏈接你的最終內核二進制文件(myos.bin)和鏈接器選項-Wl,--build-id=none。您還應明確告知NASM生成一個32位ELF對象-f elf32GCC-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 

你也應該聽從OSDev維基的advice建立一個交叉編譯器,而不是根據您的主機環境定製的本機編譯器。從長遠來看,這可以避免一些難以發現的錯誤。

修訂的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