2010-07-22 24 views
3

Je suivais les tutoriels these pour créer un noyau simple que je chargerais ensuite en utilisant GRUB. Les instructions pour la compilation n'ont pas fonctionné (ld n'a pas pu trouver l'option -T) et quand j'ai finalement obtenu un fichier compilé, c'était au format Macho. Quelles sont les bonnes étapes à suivre lors de la compilation de ces fichiers sur Mac.
Modifier:
J'ai compilé le code sur une machine virtuelle Ubuntu et j'ai donc le fichier kernel.bin. Maintenant, comment puis-je créer une image amorçable qui exécute le noyau?Compilation du noyau dans un fichier binaire sur mac

Répondre

3

Vous ne pouvez pas faire cela directement sur un Mac, car les Mac utilisent EFI comme chargeur de démarrage (sorte de). Votre meilleur pari pour ce genre de choses est d'aller télécharger Sun VirtualBox et faire une machine virtuelle Linux - cela a l'avantage supplémentaire que vous pouvez prendre des instantanés, donc si les choses vont en forme de poire, vous pouvez toujours revenir en arrière arriver à écrire les routines d'E/S).

0

J'ai utilisé rEFIt pour rendre les chargeurs de démarrage pour Windows et Linux compatibles (ou pas si méchants) avec le bootloader Mac.

Si vous voulez un environnement Mac VM, j'ai entendu Q est bon et j'ai personnellement utilisé VMWare Fusion.

+1

Comment le bootloader ne me permet-il pas d'utiliser des scripts de liens? Je pense que cela a quelque chose à voir avec Mac en utilisant le linker BSD au lieu du linker GNU. Je ne veux pas graver et exécuter le système d'exploitation sur mon Mac, je veux juste le compiler dans une image amorçable. – None

4

Il y a quelques choses que vous devrez faire pour que cela fonctionne. Premièrement, vous devez vous assurer que nasm, gcc et ld créent des binaires macho i386. Cela signifie que vous devez passer -f macho à nasm, -m32 à gcc, et -arch i386 à ld sinon vous aurez des binaires macho x86_64. Deuxièmement, GRUB ne prend pas en charge les binaires macho - il vient seulement avec un support prêt à l'emploi pour les formats binaires ELF. Mais ce n'est pas un problème - vous pouvez dire à GRUB exactement ce qu'il faut faire pour démarrer votre noyau macho en utilisant l'en-tête multiboot.

En particulier, vous devez régler le 16 bit de FLAGS dans l'en-tête multiboot:

FLAGS 1<<16 | whateverelse 

Cela indiquera Grub de prendre les informations sur l'endroit où charger le noyau de vous au lieu d'essayer de comprendre cela automatiquement.

Vous devez maintenant indiquer cette information à GRUB. En particulier, il y a 4 champs Grub (ou tout bootloader multiboot compatible) a besoin pour charger un noyau dans tout format binaire:

  • header_addr: L'emplacement physique de la mémoire de votre noyau attend d'être situé à . Définissez-le égal à l'adresse de la section .text. (Astuce: Placez une étiquette juste après .text et référez-vous-y simplement ici)
  • load_addr: L'adresse que GRUB doit commencer à charger à partir du disque. Dans le cas de macho, .text est la première adresse, donc nous avons aussi mis à l'emplacement .text
  • load_end_addr: où GRUB devrait arrêter le chargement. Habituellement, quelque chose comme stack+STACKSIZE fonctionnerait.
  • bss_end_addr: où se trouve la fin de la section BSS. En macho, c'est juste là à la fin, donc le réglage égal à load_end_addr fonctionnera.
  • entry_addr: Le point d'entrée de votre code noyau. Sur OS X, la valeur par défaut est start mais, selon ce guide, elle est loader.

Mon exemple de code pour ceci:

global start   ; making entry point visible to linker 
extern _kmain   ; kmain is defined elsewhere 

; setting up the Multiboot header - see GRUB docs for details 
MODULEALIGN equ 1<<0     ; align loaded modules on page boundaries 
MEMINFO  equ 1<<1     ; provide memory map 
MACHO  equ 1<<16 
FLAGS  equ MODULEALIGN | MEMINFO | MACHO ; this is the Multiboot 'flag' field 
MAGIC  equ 0x1BADB002   ; 'magic number' lets bootloader find the header 
CHECKSUM equ -(MAGIC + FLAGS)  ; checksum required 

section .text 
align 4 
MultiBootHeader: 
    dd MAGIC 
    dd FLAGS 
    dd CHECKSUM 
    dd MultiBootHeader 
    dd MultiBootHeader 
    dd stack+STACKSIZE 
    dd stack+STACKSIZE 
    dd start 

; reserve initial kernel stack space 
STACKSIZE equ 0x4000     ; that's 16k. 

start: 
    mov esp, stack+STACKSIZE   ; set up the stack 
    push eax       ; pass Multiboot magic number 
    push ebx       ; pass Multiboot info structure 

    call _kmain      ; call kernel proper 

    cli 
hang: 
    hlt        ; halt machine should kernel return 
    jmp hang 

section .bss 
align 4 
stack: 
    resb STACKSIZE      ; reserve 16k stack on a doubleword boundary 

Après avoir fait, quand vous dites GRUB pour charger votre noyau avec la commande kernel 200+x, vous verrez un message pop « multiboot-bidouille » sur l'écran avec des informations sur l'endroit où tout sera chargé. Taper boot chargera votre noyau macho et vous serez réglé!