aboutsummaryrefslogtreecommitdiff
path: root/run
blob: 73aef004388e7cbdfac6f3c1e32d3092819111e5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env sh

set -e

cd "$(dirname "$0")"

MAKE=make
NPROC=nproc
SUDO=sudo
TAGS=ctags
if [ "$(uname -s)" = "OpenBSD" ]; then
    NPROC="sysctl -n hw.ncpuonline"
    SUDO="doas"
    TAGS="ectags"
    export MAKE=gmake
    export CC="egcc"
    export CXX="eg++"
    export LDFLAGS=-Wl,-z,notext
fi

mode="${1}"
no_ask="${2}"

make_cross() {
    if [ ! -d "./cross/" ]; then
        if [ "$no_ask" != "-y" ]; then
            echo -n "Do you want to compile a cross compiler (this can take around 20 minutes)? [yn] "
            read -r answer
            if ! [ "$answer" != "${answer#[Yy]}" ]; then
                echo "The compilation of melvix requires a cross compiler!"
                exit 1
            fi
        fi

        # Create directory
        mkdir -p cross
        cd cross
        DIR=$(pwd)

        # Get sources
        mkdir "${DIR}/src" && cd "${DIR}/src"
        echo "Downloading..."
        curl "https://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.gz" >binutils.tar.gz
        tar xzf binutils.tar.gz
        curl "https://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.gz" >gcc.tar.gz
        tar xzf gcc.tar.gz

        # Prepare compiling
        mkdir -p "${DIR}/opt/bin"
        export PREFIX="${DIR}/opt"
        export TARGET=i686-elf
        export PATH="$PREFIX/bin:$PATH"

        if [ "$(uname -s)" = "OpenBSD" ]; then
            export with_gmp=/usr/local
            sed -i 's/-no-pie/-nopie/g' "${DIR}/src/gcc-9.2.0/gcc/configure"
        fi

        # Compile binutils
        mkdir "${DIR}/src/build-binutils" && cd "${DIR}/src/build-binutils"
        ../binutils-2.33.1/configure --target="$TARGET" --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror
        $MAKE -j $($NPROC)
        $MAKE install

        # Compile GCC
        mkdir "${DIR}/src/build-gcc" && cd "${DIR}/src/build-gcc"
        ../gcc-9.2.0/configure --target="$TARGET" --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers
        $MAKE -j $($NPROC) all-gcc all-target-libgcc
        $MAKE install-gcc install-target-libgcc

        # Fix things
        if [ "$(uname -s)" = "OpenBSD" ]; then
            cd "${DIR}/opt/libexec/gcc/i686-elf/9.2.0/" && ln -sf liblto_plugin.so.0.0 liblto_plugin.so
        fi

        cd "${DIR}/.."
    fi
}

make_build() {
    mkdir -p build/

    # Build
    printf "\nBuilding...\n"
    $MAKE -j $($NPROC)

    # Create disk image
    dd if=/dev/zero of=build/disk.img bs=1k count=32k status=none
    if [ "$(uname -s)" = "OpenBSD" ]; then
        VND=$($SUDO vnconfig build/disk.img)
        (
            echo "e 0"
            echo 83
            echo n
            echo 0
            echo "*"
            echo "quit"
        ) | $SUDO fdisk -e $VND >/dev/null
        $SUDO mkfs.ext2 -F /dev/${VND}i >/dev/null
        $SUDO dd if=build/boot.bin of=/dev/${VND}i conv=notrunc status=none
    else
        $SUDO mke2fs -b 1024 -q build/disk.img
        dd if=build/boot.bin of=build/disk.img conv=notrunc status=none
    fi

    # Mount disk and copy files
    mkdir -p mnt/
    if [ "$(uname -s)" = "OpenBSD" ]; then
        $SUDO mount -t ext2fs /dev/${VND}i mnt/
    else
        $SUDO mount build/disk.img mnt/
    fi
    $SUDO cp -r build/load.bin mnt/load
    $SUDO cp -r build/example mnt/kernel
    $SUDO umount mnt/
    rm -rf mnt/

    if [ "$(uname -s)" = "OpenBSD" ]; then
        $SUDO vnconfig -u $VND
    fi
}

make_example() {
    qemu-system-i386 -d guest_errors -cpu max -serial stdio -m 256M -vga std -drive file=build/disk.img,format=raw,index=1,media=disk
}

if [ "${mode}" = "cross" ]; then
    make_cross
elif [ "${mode}" = "build" ]; then
    make_cross
    $MAKE clean
    make_build
elif [ "${mode}" = "example" ]; then
    make_cross
    $MAKE clean
    make_build
    make_example
fi