13 if gmake
--version >/dev
/null
2>&1; then make=gmake
; else make=make; fi
21 qemu
=`$make -s --no-print-directory print-qemu`
22 gdbport
=`$make -s --no-print-directory print-gdbport`
23 qemugdb
=`$make -s --no-print-directory print-qemugdb`
24 cxxfilt
=`$make -s --no-print-directory print-c++filt`
29 # suns can't echo -n, and Mac OS X can't echo "x\c"
30 # assume argument has no doublequotes
31 awk 'BEGIN { printf("'"$*"'"); }' </dev
/null
35 # solaris "sleep" doesn't take fractions
36 perl
-e "select(undef, undef, undef, $1);"
39 # Run QEMU with serial output redirected to jos.out. If $brkfn is
40 # non-empty, wait until $brkfn is reached or $timeout expires, then
44 if [ -n "$brkfn" -a -z "$keystrokes" ]; then
45 qemuextra
="-monitor null -S $qemugdb"
47 qemuextra
="-monitor telnet::$gdbport,server,nowait"
50 t0
=`date +%s.%N 2>/dev/null`
54 exec $qemu -nographic $qemuopts -serial file:jos.out
-no-reboot $qemuextra
58 # Wait for QEMU to start
61 if [ -n "$brkfn" -a -z "$keystrokes" ]; then
62 # Find the address of the kernel $brkfn function,
63 # which is typically what the kernel monitor uses to
64 # read commands interactively.
65 brkaddr
=`grep " $brkfn\$" obj/kernel.sym | sed -e's/ .*$//g'`
66 if [ -z "$brkaddr" ]; then
67 # Perhaps the symbol was mangled.
68 brkaddr
=`$cxxfilt < obj/kernel.sym | grep " $brkfn(" | sed -e's/ .*$//g'`
72 echo "target remote localhost:$gdbport"
76 gdb
-batch -nx -x jos.
in > /dev
/null
2>&1
78 # Wait until "Welcome to the JOS kernel monitor" is printed.
79 while ! grep -l -q "^Welcome to the JOS kernel monitor" jos.out
>/dev
/null
2>&1; do
84 while [ -n "$keystrokes" ]; do
85 firstchar
=`echo "$keystrokes" | sed -e 's/^\(.\).*/\1/'`
86 keystrokes
=`echo "$keystrokes" | sed -e 's/^.//'`
87 if [ "$firstchar" = ';' ]; then
89 elif [ "$firstchar" = ' ' ]; then
92 echo "sendkey $firstchar"
99 ) |
telnet localhost
$gdbport >/dev
/null
2>$err
102 # Make sure QEMU is dead. On OS X, exiting gdb
103 # doesn't always exit QEMU.
104 kill $PID > /dev
/null
2>&1
118 echo "Part $1 score: $part/$partpos"
120 total
=`expr $total + $part`
121 totalpos
=`expr $totalpos + $partpos`
127 total
=`expr $total + $part`
128 totalpos
=`expr $totalpos + $partpos`
129 echo "Score: $total/$totalpos"
130 if [ $total -lt $totalpos ]; then
138 if [ $# -gt 0 ]; then
142 t1
=`date +%s.%N 2>/dev/null`
143 time=`echo "scale=1; ($t1-$t0)/1" | sed 's/.N/.0/g' | bc 2>/dev/null`
145 echo $msg "$@" "(${time}s)"
150 part
=`expr $part + $pts`
151 partpos
=`expr $partpos + $pts`
155 passfailmsg WRONG
"$@"
156 partpos
=`expr $partpos + $pts`
164 # Usage: runtest <tagname> <defs> <check fn> <check args...>
167 perl
-e "print '$tag: '"
168 rm -f obj
/kern
/init.o obj
/kernel obj
/kern
/kernel obj
/kernel.img
169 [ "$preservefs" = y
] ||
rm -f obj
/fs.img
177 rm -f obj
/kern
/init.o
181 # We just built a weird init.o that runs a specific test. As
182 # a result, 'make qemu' will run the last graded test and
183 # 'make clean; make qemu' will run the user-specified
184 # environment. Remove our weird init.o to fix this.
185 rm -f obj
/kern
/init.o
188 # Give qemu some more time to run (for asynchronous mode).
189 # This way, we get the small 1 second wait for most tests
190 # and a longer wait (5 seconds) in case qemu needs that
199 fail
> /dev
/null
# Still increment number of possible points
211 perl
-e "print '$1: '"
229 if egrep "^$i\$" jos.out
>/dev
/null
231 echo "got unexpected line '$i'"
240 egrep "^$i\$" jos.out
>/dev
/null
253 if [ "$okay" = "yes" ]
258 if [ -n "$tag" ]; then
259 modtag
=`echo "$tag" | tr -d '\012' | tr -cs A-Za-z0-9_.- _`
260 cp jos.out jos.out.
$modtag
261 echo " => Saving QEMU output in jos.out.$modtag"
266 # Usage: runtest1 [-tag <tagname>] [-dir <dirname>] <progname> [-Ddef...] [-check checkfn] checkargs...
291 while expr "x$1" : 'x-D.*' >/dev
/null
; do
292 runtest1_defs
="DEFS+='$1' $runtest1_defs"
295 if [ "x$1" = "x-check" ]; then
300 runtest
"$tag" "DEFS='-DTEST=_binary_obj_${dir}_${prog}_start' DEFS+='-DTESTSIZE=_binary_obj_${dir}_${prog}_size' $runtest1_defs" "$check" "$@"