summaryrefslogtreecommitdiff
path: root/kernel/run
blob: 8c52bd91788a601ec0163446698c8700289fcbda (plain)
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
139
140
141
142
#!/bin/sh

onerr() {
    echo -e "\x1b[1;31merror: '$action' failed\x1b[m"
    exit 1
}

trap onerr ERR

name="uff"
build_mode=release
action=help
target=x86_64
test_mode=false
serial_mode=false
function define_vars() {
    target_name="$target-$name"
    target_path="target/"
    rust_target_path="$target_path/$target_name/$build_mode/"
    kernel_libary="$rust_target_path/libkernel.a"
    iso_path="$target_path/iso/"
    obj_path="$iso_path/obj/"
    src_path="src/"
    asm_path="$src_path/asm/"
    link_script="$src_path/linker.ld"
    grub_cfg="$src_path/grub.cfg"
}
define_vars

print_help() {
    echo "usage: $0 (options) [action]"
    echo "options:"
    echo "  -name=<str>          set application name (standard: $name)"
    echo "  -mode=<str>          set build mode (standard: $build_mode)"
    echo "  -target=<str>        set target (standard: $target)"
    echo "  -test                enable test mode (standard: disabled)"
    echo "  -serial              enable serial mode (standard: disabled)"
    echo
    echo "actions:"
    echo "  build                build the iso"
    echo "  run                  build and lauch the iso in qemu"
    echo "  test                 build iso in test mode and run it in qemu"
    echo "  help                 show this help message"
    exit
}

get_rust_bin() {
    #if $test_mode; then
    #    echo "$rust_target_path/$(ls -t1 $rust_target_path | grep -P '^kernel-[a-fA-F0-9]+$' | head -n1)"
    #else
    #    echo "$rust_target_path/libkernel.a"
    #fi
    echo "$kernel_libary"
}

prepare_iso() {
    mkdir "$target_path" &> /dev/null
    mkdir "$iso_path" &> /dev/null
    mkdir "$obj_path" &> /dev/null
    mkdir "$iso_path/isofiles" &> /dev/null
    mkdir "$iso_path/isofiles/boot" &> /dev/null
    mkdir "$iso_path/isofiles/boot/grub" &> /dev/null
    for f in "$asm_path"/*.asm; do
        nasm -felf64 "$f" -o "$obj_path/$(basename -s .asm $f).o"
    done
    cp "$grub_cfg" "$iso_path/isofiles/boot/grub/grub.cfg"
}

build_iso() {
    ld -n -s -o "$iso_path/isofiles/boot/kernel.bin" -gc-sections -T "$link_script" "$obj_path"/*.o "$(get_rust_bin)"
    grub-mkrescue -d /usr/lib/grub/i386-pc -o "$iso_path/$name.iso" "$iso_path/isofiles" &> /dev/null
    echo "$kernel_libary"
}

build() {
    if test ! -d "$iso_path/isofiles"; then
        prepare_iso
    fi
    #if $test_mode; then
    #    RUSTFLAGS="-Clink-arg=-r -Clink-dead-code" cargo xtest --no-run
    #else
    #    cargo xbuild
    #fi
    if ! $test_mode; then
        cargo xbuild "--$build_mode"
    fi
    build_iso
}

run() {
    case "$target" in
        "x86_64")
            qemu="qemu-system-x86_64 -cdrom $iso_path/$name.iso"
            if $test_mode; then
                qemu="$qemu -device isa-debug-exit,iobase=0xf4,iosize=0x04 -serial stdio -no-reboot "
                if $serial_mode; then
                    qemu="$qemu -display none"
                fi
            fi
            $qemu
            case "$?" in 
                33) exit 0;;
                35) exit 1;;
                *) 
                    echo "qemu exited unexpectedly $?";
                    exit 1;;
            esac;;
        *)
            echo "error: no laucher defined for target '$target'";;
    esac
}

for arg in "$@"; do
    case "$arg" in
        -mode=*)
            build_mode="$(echo $arg | sed "s/^-mode=//")"; define_vars;;
        -name=*)
            name="$(echo $arg | sed "s/^-name=//")"; define_vars;;
        -target=*)
            target="$(echo $arg | sed "s/^-target=//")"; define_vars;;
        -test)
            test_mode=true; define_vars;;
        -serial)
            serial_mode=true; define_vars;;
        "run") action=run;;
        "build") action=build;;
        "test") action=test;;
        "help") action=help;;
        *)
            # echo "warn: ignoring unknown option '$arg'"
            kernel_libary=$arg;;
    esac
done

case "$action" in
    "help") print_help;;
    "build") build;;
    "test") test_mode=true; build; run;;
    "run") build; run;;
esac

echo -e "\x1b[1;32mdone\x1b[m"