2014-01-06 51 views
0

[此代碼適用於32位x86 Intel彙編器。此外,請嘗試遵守Xcode 5使用的彙編語法。彙編語言並不是我的特長,我想盡量避免由於我不理解代碼而導致的愚蠢錯誤。]跳轉到x86中的64位值

我想寫一個啓動加載器。我的內核入口點位於0xFFFFFFFF之上(因爲此內核內核文件是以64位模式構建的)。現在,我的彙編代碼下面的代碼段,從我的引導裝載程序的源代碼採取:

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// startprog(phyaddr, arg) 
// Start the program on protected mode where phyaddr is the entry point. 
// Passes arg to the program in %eax. 
// 
_startprog: 
    push %ebp 
    mov  %esp, %ebp 

    mov  0xc(%ebp), %eax // argument to program 
    mov  0x8(%ebp), %ecx // entry offset 
    mov  $0x28, %ebx  // segment 
    push %ebx 
    push %ecx 

    // set up %ds and %es 

    mov  $0x20, %ebx 
    movw %bx, %ds 
    movw %bx, %es 

    lret 

此代碼是由C調用一個指向內核的入口點和參數指針。問題是,上面的代碼假定入口點的地址適合32位指針。但是,我的內核的入口點不適合32位指針;它佔用了它原生大小指針的所有64位(如果你想知道,我不能簡單地在32位模式下重建我的內核,否則我不會問這個問題)。在32位程序集中跳轉到64位地址的最佳方式是什麼?

謝謝。 (這裏是sources for my kernelsources for my boot loader,如果需要的話)。

回答

3

首先,您需要切換到Long Mode(64位模式)引導程序裏面,只有然後可以跳轉到內核。原因是指令指針(IP)在實模式中只有16位寬,在虛擬受保護地址模式下只有32位寬,除了長模式外,高32/48位被屏蔽。

周圍有很多「Bootloader中的長模式」代碼, this OSDev article on entering it without intermediate 32-bit mode。希望有所幫助。

如果你的內核不支持在長時間模式下被調用,你唯一的選擇是將它加載到4 GiB以下,因爲在上面的地址中不能運行任何32位代碼。沒有看源代碼(對不起,現在是凌晨1點26分,我需要明天工作),有些內核支持在它們的最終操作模式設置之前運行,例如,它們的入口地址爲& 0x00FFFFFF或其他。 (例如,MirBSD內核具有VMA和LMA 0xD0100120,但預計跳轉到0x00100120,並且稍後設置分頁本身以將自己映射到高。

+0

這一切都很好,除了我的內核不支持被調用在我看來,它需要在32位保護模式,因爲它切換到長模式本身。 – wjk

+0

事實證明,我的內核預計將被加載在一個低地址。想想那個,直到你指出來,謝謝! – wjk