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
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).
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.
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 .textload_end_addr
: où GRUB devrait arrêter le chargement. Habituellement, quelque chose commestack+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 eststart
mais, selon ce guide, elle estloader
.
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é!
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