Compilieren unter Mac OS X Snow Leopard



  • Hallo,

    Ich habe mich mit der Erstellung von PrettyOS unter Mac OS X (Snow Leopard, 10.6.2) befasst. Ich stehe auch kurz vor dem Durchbruch, allerdings hapert es hier:

    Mac:source user$ make
    nasm -f bin stage1_bootloader/boot.asm -Istage1_bootloader/ -o stage1_bootloader/boot.bin
    nasm -f bin stage2_bootloader/boot2.asm -Istage2_bootloader/ -o stage2_bootloader/BOOT2.BIN
    rm -f .o
    nasm -O32 -f macho user/user_program_c/start.asm -Iuser/user_program_c/ -o start.o
    gcc user/user_program_c/
    .c -c -Iuser/user_program_c -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin -mdynamic-no-pic -dynamiclib -undefined dynamic_lookup -single_module -arch i386
    nasm -O32 -f macho user/user_program_c/start.asm -o start.o
    gcc *.o --script=user/user_program_c/user.ld -Map user/user_program_c/kernel.map -nostdinc -o user/user_program_c/program.elf -arch i386 -m32
    ld: warning: in user/user_program_c/kernel.map, file is not of required architecture
    rm -f *.o
    tools/make_initrd user/init_rd_img/test1.txt file1 user/init_rd_img/test2.txt file2 user/init_rd_img/test3.txt file3 user/user_program_c/program.elf shell
    make: tools/make_initrd: Permission denied
    make: *** [initrd] Error 1

    Ich möchte wissen, woher die "kernel.map" im Verzeichnis "user/user_program_c" kommt!

    Dem aufmerksamen Leser ist nun aufgefallen, dass teilweise das "macho"-Format vom NASM verwendet wird, "nasm -hf" gibt (u.a.) folgendes aus:
    "macho NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files"

    Ausserdem wird der gcc als Linker "missbraucht", da der ld die Option -T nicht kennt.

    Mir ist klar, dass ich dem gcc einige sinnlose Parameter hinzugefügt habe, aber solange es klappt, ist es ok.



  • Für mich sieht es so aus, als würde diese erst durch den Linkvorgang erstellt und dient wohl nur der Information des Programmierers (wobei ich das nie selbst genutzt habe).

    Der Linkvorgang bricht nicht deswegen ab, falls du das denken solltest, sondern weil sich dein OS weigert, die Datei "tools/make_initrd" auszuführen. Ein "chmod a+x tools/make_initrd" sollte dem Abhilfe schaffen, indem es die Datei als ausführbar kennzeichnet.



  • Mit XanClics Hilfe bin ich jetzt bis hier hin gekommen:

    Mac:source user$ make
    nasm -f bin stage1_bootloader/boot.asm -Istage1_bootloader/ -o stage1_bootloader/boot.bin
    nasm -f bin stage2_bootloader/boot2.asm -Istage2_bootloader/ -o stage2_bootloader/BOOT2.BIN
    rm -f .o
    nasm -O32 -f macho user/user_program_c/start.asm -Iuser/user_program_c/ -o start.o
    gcc user/user_program_c/
    .c -c -Iuser/user_program_c -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin -mdynamic-no-pic -dynamiclib -undefined dynamic_lookup -single_module -arch i386
    nasm -O32 -f macho user/user_program_c/start.asm -o start.o
    gcc *.o --script=user/user_program_c/user.ld -Map user/user_program_c/kernel.map -nostdinc -o user/user_program_c/program.elf -arch i386 -m32
    ld: warning: in user/user_program_c/kernel.map, file is not of required architecture
    rm -f *.o
    tools/make_initrd user/init_rd_img/test1.txt file1 user/init_rd_img/test2.txt file2 user/init_rd_img/test3.txt file3 user/user_program_c/program.elf shell
    writing file user/init_rd_img/test1.txt->file1 at 0x1304
    writing file user/init_rd_img/test2.txt->file2 at 0x1327
    writing file user/init_rd_img/test3.txt->file3 at 0x134a
    writing file user/user_program_c/program.elf->shell at 0x1910
    mv initrd.dat kernel/initrd.dat
    rm -f .o
    gcc kernel/
    .c -c -Ikernel/include -std=c99 -march=i386 -mtune=i386 -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Iinclude -mdynamic-no-pic -dynamiclib -undefined dynamic_lookup -single_module -arch i386
    nasm -O32 -f macho kernel/data.asm -Ikernel/ -o data.o
    nasm -O32 -f macho kernel/flush.asm -Ikernel/ -o flush.o
    nasm -O32 -f macho kernel/interrupts.asm -Ikernel/ -o interrupts.o
    nasm -O32 -f macho kernel/kernel.asm -Ikernel/ -o kernel.o
    nasm -O32 -f macho kernel/process.asm -Ikernel/ -o process.o
    gcc *.o --script=kernel/kernel.ld -nostdinc -o kernel/KERNEL.BIN -arch i386 -m32
    Undefined symbols:
    "__kernel_beg", referenced from:
    __kernel_begnon_lazy_ptrinpaging.o"__kernel_end",referencedfrom:__kernel_endnon\_lazy\_ptr in paging.o "\_\_kernel\_end", referenced from: \_\_kernel\_endnon_lazy_ptr in paging.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    make: *** [ckernel] Error 1

    Falls hier jemand weiß, warum die Symbole nicht gefunden wurden, bitte antworten,
    ansonsten müssen wir auf Herr Dr. Henkes warten, der derzeit im Urlaub ist..-.-



  • Hallo,

    man könnte das Problem bei Dir zuerst mit GNU nm untersuchen. Lass Dir die Symbole in paging.o ausgeben:

    nm paging.o
    

    In der Ausgabe siehst Du irgendwo sowas wie "U __kernel_beg" (U = undefiniert).
    Dann die Symbole in der Objektdatei, wo diese vermutet werden:

    nm x.o
    

    Wie sieht __kernel_beg dann aus? Mit einem Unterstrich, mit zwei usw...



  • Mac:source user$ nm paging.o
    U __kernel_beg
    U __kernel_end
    U _alignDown
    U _alignUp
    00000904 b _data
    00000908 b _dword_count
    0000090c b _first_free_dword
    U _free
    00000910 b _kernel_pd
    U _malloc
    U _memcpy
    U _memset
    0000021b T _paging_alloc
    000001c5 T _paging_create_user_pd
    0000004b T _paging_destroy_user_pd
    000000cb T _paging_free
    0000016c t _paging_get_phys_addr
    000004b7 T _paging_install
    00000031 T _paging_switch
    U _panic_assert
    00000000 t _phys_free
    00000436 t _phys_set_bits
    U _printformat



  • abc.w schrieb:

    Dann die Symbole in der Objektdatei, wo diese vermutet werden:

    __kernel_beg und __kernel_end werden in keiner Objektdatei, sondern im Linkerscript definiert. 😉



  • XanClic schrieb:

    __kernel_beg und __kernel_end werden in keiner Objektdatei, sondern im Linkerscript definiert. 😉

    Ach so, ok, habe da, ehrlich gesagt, keine Durchblick... Dann wird die Linker Script Datei nicht abgearbeitet oder wie, oder warum auch immer 😕



  • Ok, wozu brauchen wir dieses Linkerscript umbedingt?
    -Map kernel.map wurde auch weggelassen^^
    Warscheinlich will der gcc das Linkerscript gar nicht..

    Cuervo



  • Man braucht das, damit der Linker das Zeug nicht einfach dahin packt, wo es ihm grad passt bzw. wo es dem Betriebssystem passt. Mein Kernel (paloxena2) beispielsweise befindet sich virtuell ab 0xC0100000, ohne Linkerscript würde die Linuxstandardadresse verwendet werden und die ist 0x08048000. Außerdem wollt ihr genau solche Symbole wie __kernel_beg oder __kernel_end haben (ich persönlich brauche die nicht, kenne aber genug Leute, die ebenso wie ihr verfahren) und die werden eben im Linkerscript definiert. Deshalb wäre es eine ganz schlechte Idee, das einfach wegzulassen (wobei man das mit __kernel_beg und __kernel_end auch notdürftig fixen könnte, indem man dafür einfach bestimmte Werte annimmt (den Beginn des Kernels solltet ihr ja kennen und für __kernel_end nehmt ihr dann z. B. __kernel_beg + 1048576 (also ein Megabyte für den Kernel), aber dass das Problem auftaucht, weist darauf hin, dass das Script nicht richtig abgearbeitet wird – und dann habt ihr immer noch Problem Nummer 1 (der Kernel muss an eine bestimmte Adresse geladen werden)).



  • Oh.. was machen wir denn da?



  • Cuervo schrieb:

    Oh.. was machen wir denn da?

    Man könnte beim gcc noch den Parameter --verbose (glaube ich) angeben, vielleicht sieht man da mehr...



  • *ähm.. naja..

    `gcc *.o --script=kernel/kernel.ld -nostdinc -o kernel/KERNEL.BIN -arch i386 -m32 --verbose

    Using built-in specs.

    Target: i686-apple-darwin10

    Configured with: /var/tmp/gcc/gcc-5646.1~2/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/[cg][.-]*/s//s//-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10

    Thread model: posix

    gcc version 4.2.1 (Apple Inc. build 5646) (dot 1)

    /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.2 -weak_reference_mismatches non-weak -o kernel/KERNEL.BIN -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. ckernel.o cmos.o data.o descriptor_tables.o elf.o flpydsk.o flush.o fs.o gdt.o initrd.o interrupts.o irq.o kernel.o keyboard.o kheap.o list.o math.o paging.o pci.o process.o shared_pages.o syscall.o task.o time.o timer.o util.o video.o -lSystem -lgcc -lSystem

    Undefined symbols:

    "__kernel_beg", referenced from:

      __kernel_beg$non_lazy_ptr in paging.o
    

    "__kernel_end", referenced from:

      __kernel_end$non_lazy_ptr in paging.o
    

    ld: symbol(s) not found

    collect2: ld returned 1 exit status

    make: *** [ckernel] Error 1`



  • Soweit ich gelesen habe bringt Mac OS kein binutils mit. Das ld ist daher nicht das GNU ld, sondern eine Eigenkreation von Apple. Diese unterstützt zum einen nur das macho Format und hat keine Unterstützung für Linkerscripte. Der mitgelieferte gcc ist natürlich auch darauf getrimmt diesen Linker zu nutzen.

    Die beste Lösung wäre sich ein (ordentliches) gcc und ld zu besorgen/bauen und diese dann einsetzen. Stichwort cross-compiler.



  • Ok, ich hab mal alle ports gesucht, welchen soll ich nehmen?

    apple-gcc33 @1823 (lang)
    Apple's version of gcc 3.3

    apple-gcc40 @5465 (lang)
    Apple's version of gcc 4.0

    apple-gcc42 @5531 (lang)
    Apple's version of gcc 4.2

    apple-gcc42-devel @5564 (lang)
    Updated version of Apple's version of gcc 4.2

    arm-aout-gcc @3.3.6 (cross, devel)
    gcc cross-compilers for arm-aout, with newlib runtime library.

    arm-elf-gcc @4.3.2 (cross, devel)
    gcc cross-compilers for arm-elf, with newlib runtime library.

    arm-elf-gcc3 @3.4.6 (cross, devel)
    gcc 3.x cross-compilers for arm-elf, with newlib runtime library.

    arm-none-linux-gnueabi-gcc @2005q3-2 (cross, devel)
    gcc 3.x cross-compilers for arm-none-linux-gnueabi.

    arm-rtems-gcc @4.2.3 (cross, devel)
    gcc cross-compilers for arm-rtems, with newlib runtime library.

    avr-gcc @4.0.2 (cross, devel)
    gcc cross-compilers for avr

    gcc33 @3.3.6 (lang)
    The GNU compiler collection

    gcc34 @3.4.6 (lang)
    The GNU compiler collection

    gcc40 @4.0.4 (lang)
    The GNU compiler collection

    gcc41 @4.1.2 (lang)
    The GNU compiler collection

    gcc42 @4.2.4 (lang)
    The GNU compiler collection

    gcc43 @4.3.4 (lang)
    The GNU compiler collection

    gcc44 @4.4.2 (lang)
    The GNU compiler collection

    gcc45 @4.5-20091217 (lang)
    The GNU compiler collection, prerelease BETA

    gcc_select @0.1 (sysutils)
    Switch the default compiler

    gccmakedep @1.0.2 (x11, devel)
    Create dependencies in makefiles using 'gcc -M'

    gccxml @0.6.0 (lang)
    generates XML description of C++ code

    gccxml-devel @20090713 (lang)
    generates XML description of C++ code

    gnat-gcc @4.4.2 (lang)
    The GNU compiler collection with GNAT

    i386-elf-gcc @4.3.2 (cross, devel)
    gcc cross-compilers for i386-elf, with newlib runtime library.

    i386-mingw32-gcc @3.4.5-20060117-2 (cross, devel)
    Mingw32 cross-compiler for i386-Win32

    i386-rtems-gcc @4.2.3 (cross, devel)
    gcc cross-compilers for i386-rtems, with newlib runtime library.

    i960-rtems-gcc @3.2.3 (cross, devel)
    gcc cross-compilers for i960-rtems, with newlib runtime library.

    lcov @1.7 (devel)
    LCOV is a graphical front-end for GCC's coverage testing tool gcov.

    llvm-gcc42 @2.6 (lang)
    llvm is a next generation compiler infrastructure

    m68k-elf-gcc @3.4.6 (cross, devel)
    gcc cross-compilers for m68k-elf, with newlib runtime library.

    m68k-rtems-gcc @4.2.3 (cross, devel)
    gcc cross-compilers for m68k-rtems, with newlib runtime library.

    mips-elf-gcc @3.4.6 (cross, devel)
    gcc cross-compilers for mips-elf, with newlib runtime library.

    mips-rtems-gcc @4.2.3 (cross, devel)
    gcc cross-compilers for mips-rtems, with newlib runtime library.

    mipsel-linux-gcc34 @3.4.6 (cross)
    gcc cross compiler for mips-linux with uClib

    powerpc-rtems-gcc @4.2.3 (cross, devel)
    gcc cross-compilers for powerpc-rtems, with newlib runtime library.

    py26-pygccxml @1.0.0 (python, devel)
    pygccxml is a python interface to gcc-xml

    sh-rtems-gcc @4.2.3 (cross, devel)
    gcc cross-compilers for sh-rtems, with newlib runtime library.

    sparc-rtems-gcc @4.2.3 (cross, devel)
    gcc cross-compilers for sparc-rtems, with newlib runtime library.



  • Entweder gcc44 oder i386-elf-gcc – allerdings fehlen dann noch die binutils, also ld. 😉



  • XanClic schrieb:

    Entweder gcc44 oder i386-elf-gcc – allerdings fehlen dann noch die binutils, also ld. 😉

    Unter Windows verwende ich (logischerweise) auch einen Crosscompiler, der afair auch "i386-elf-gcc" heißt. Da ist ld aber mit dabei, vielleicht hier ja auch?



  • Ausschließen will ich es nicht, aber dann hätte das Paket einen irreführenden Namen – weil ld nunmal zu den binutils und nicht zu gcc gehört.


  • Mod

    gcc ohne ld macht doch keinen Sinn?



  • ld gehört aber nicht zur GCC (also zur GNU Compiler Collection), sondern zu besagten GNU binutils. Es ist halt einfach so. 😉

    (Wenn man also die Quellcodepakete einzeln runterlädt und kompiliert, hat man nach Kompilieren von GCC halt nur den Compiler und muss dann noch die binutils kompilieren, um den etwas sinnvolles tun zu lassen)



  • ENDLICH! ICH HABE ES GESCHAFFT!

    Ich kann jetzt mit meinem Mac PrettyOS compilieren! Vielen Dank an alle, die mir geholfen haben.

    (Sollte jemand eine Anleitung benötigen, so ist dies bitte hier zu melden!)


Anmelden zum Antworten