summaryrefslogtreecommitdiff
path: root/kernel/run
blob: 3420ac1c3e08f2765b5a1ffc3224deae82a73dc2 (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
#!/bin/sh

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

trap onerr ERR

name="uff"
build_mode=debug
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) [Path]"
    echo "  build and lauch the iso in qemu"
    echo
    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 "  -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
    build_iso
}

run() {
    case "$target" in
        "x86_64")
            qemu="qemu-system-x86_64 -cdrom $iso_path/$name.iso -cpu kvm64,+apic"
            if $test_mode; then
                qemu="$qemu -device isa-debug-exit,iobase=0xf4,iosize=0x04 -serial stdio -no-reboot "
            fi
            if $serial_mode; then
                qemu="$qemu -display none"
            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;;
        -help)
            print_help;;
        *)
            # echo "warn: ignoring unknown option '$arg'"
            kernel_libary=$arg;;
    esac
done

build
run

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