should be configured, by passing @option{--with-x --with-x11 --with-term
--with-nogui} to @command{configure}.
-This version of Pintos is designed for use with Bochs 2.2.6. A number
+This version of Pintos is designed for use with Bochs 2.6.11. A number
of patches for this version of Bochs are included in @file{src/misc}:
@table @file
-@item bochs-2.2.6-big-endian.patch
+@item bochs-2.6.11-banner-stderr.patch
-Makes the GDB stubs work on big-endian systems such as Solaris/Sparc, by
-doing proper byteswapping. It should be harmless elsewhere.
+Prints startup boilerplate information to stderr instead of stdout.
-@item bochs-2.2.6-jitter.patch
+@item bochs-2.6.11-jitter-plus-segv.patch
Adds the ``jitter'' feature, in which timer interrupts are delivered at
-random intervals (@pxref{Debugging versus Testing}).
-
-@item bochs-2.2.6-triple-fault.patch
-
-Causes Bochs to break to GDB when a triple fault occurs and
-the GDB stub is active (@pxref{Triple Faults}).
-
-@item bochs-2.2.6-ms-extensions.patch
-
-Needed for Bochs to compile with GCC on some hosts. Probably
-harmless elsewhere.
-
-@item bochs-2.2.6-solaris-tty.patch
-
-Needed for Bochs to compile in terminal support on Solaris
-hosts. Probably harmless elsewhere.
-
-@item bochs-2.2.6-page-fault-segv.patch
-
-Makes the GDB stub report a SIGSEGV to the debugger when a page-fault
+random intervals (@pxref{Debugging versus Testing}). Also makes the
+GDB stub report a SIGSEGV to the debugger when a page-fault
exception occurs, instead of ``signal 0.'' The former can be ignored
with @code{handle SIGSEGV nostop} but the latter cannot.
-@item bochs-2.2.6-paranoia.patch
-
-Fixes compile error with modern versions of GCC.
+@item bochs-2.6.11-link-tinfo.patch
-@item bochs-2.2.6-solaris-link.patch
-Needed on Solaris hosts. Do not apply it elsewhere.
+Patches the build mechanism to include the -ltinfo library; doesn't
+change any functionality.
@end table
-To apply all the patches, @command{cd} into the Bochs directory, then
-type:
-@example
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-big-endian.patch
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-jitter.patch
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-triple-fault.patch
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-ms-extensions.patch
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-solaris-tty.patch
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-page-fault-segv.patch
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-paranoia.patch
-patch -p1 < $PINTOSDIR/src/misc/bochs-2.2.6-solaris-link.patch
-@end example
-@noindent
-You will have to supply the proper @env{$PINTOSDIR}, of course. You can
-use @command{patch}'s @option{--dry-run} option if you want to test
-whether the patches would apply cleanly before trying to apply them.
-
-Sample commands to build and install Bochs for Pintos are supplied in
-@file{src/misc/bochs-2.2.6-build.sh}.
+The best way to build Bochs is by invoking
+@code{src/misc/bochs-2.6.11-build.sh}. This should be invoked in
+a directory containing the Bochs distribution file
+(@code{bochs-2.6.11-tar.gz}).
+The build script takes a single argument, which provides the destination
+for installation (the binaries will be placed in the @code{bin}
+subdirectory of that directory).
+The script will apply the patches and build both versions of Bochs.
+
+The @code{src/misc} directory also contains patches and build scripts for
+older versions of Bochs, if desired. However, these may require
+changes elsewhere in Pintos. For example, @code{src/utils/pintos}
+had to be modified for Bochs 2.6.11; if you use an older version of
+Bochs you will need to back out those changes.
--- /dev/null
+--- bochs-2.6.11.dist/main.cc 2020-01-02 08:19:02.083668000 -0800
++++ bochs-2.6.11/main.cc 2021-01-17 17:17:17.526508739 -0800
+@@ -118,18 +118,18 @@
+ {
+ char buffer[128];
+
+- printf("%s\n", divider);
++ fprintf(stderr, "%s\n", divider);
+ sprintf (buffer, "Bochs x86 Emulator %s\n", VERSION);
+- bx_center_print(stdout, buffer, 72);
++ bx_center_print(stderr, buffer, 72);
+ if (REL_STRING[0]) {
+ sprintf(buffer, "%s\n", REL_STRING);
+- bx_center_print(stdout, buffer, 72);
++ bx_center_print(stderr, buffer, 72);
+ if (bx_get_timestamp(buffer) > 0) {
+- bx_center_print(stdout, buffer, 72);
++ bx_center_print(stderr, buffer, 72);
+ printf("\n");
+ }
+ }
+- printf("%s\n", divider);
++ fprintf(stderr, "%s\n", divider);
+ }
+
+ #if BX_WITH_CARBON
--- /dev/null
+#!/bin/sh -xe
+
+# Note: as of 2.6.9, you need to change line 566 of pintos. Replace:
+# user_shortcut: keys=ctrlaltdel
+# with
+# keyboard: user_shortcut=ctrl-alt-del
+# to accommodate the new bochsrc.txt syntax
+
+V=2.6.11
+
+if test 1 != "$#"; then
+ echo "usage: $0 <install-prefix>" >&2
+ exit 2
+fi
+export PREFIX="$1"
+
+SRCDIR=$(dirname $(readlink -f "$0"))
+if test ! -d "$SRCDIR"; then
+ echo "cannot file src directory" >&2
+ exit 1
+fi
+
+if test ! -f "$SRCDIR/bochs-$V.tar.gz"; then
+ wget -O "$SRCDIR/bochs-$V.tar.gz" \
+ "https://sourceforge.net/projects/bochs/files/bochs/$V/bochs-$V.tar.gz/download"
+fi
+
+builddir=$(mktemp -d /tmp/bochsXXXXXXXXX)
+trap "rm -rf \"$builddir\"" 0
+
+cd "$builddir"
+tar xzf "$SRCDIR/bochs-$V.tar.gz"
+cd "bochs-$V"
+
+for patchfile in "$SRCDIR/bochs-$V"-*.patch; do
+ patch -p1 -i "$patchfile"
+done
+
+CFGOPTS="--with-x --with-x11 --with-term --with-nogui"
+mkdir plain
+(cd plain &&
+ ../configure $CFGOPTS --prefix="$PREFIX" --enable-gdb-stub &&
+ make -j$(nproc) &&
+ make install)
+mkdir with-dbg
+(cd with-dbg &&
+ ../configure --enable-debugger --disable-debugger-gui $CFGOPTS --prefix="$PREFIX" &&
+ make -j$(nproc) &&
+ cp bochs "$PREFIX/bin/bochs-dbg")
--- /dev/null
+diff -ru bochs-2.6.11.dist/bochs.h bochs-2.6.11/bochs.h
+--- bochs-2.6.11.dist/bochs.h 2019-12-19 23:42:07.299552000 -0800
++++ bochs-2.6.11/bochs.h 2021-01-17 17:28:08.093933541 -0800
+@@ -409,6 +409,7 @@
+ void bx_gdbstub_init(void);
+ void bx_gdbstub_break(void);
+ int bx_gdbstub_check(unsigned int eip);
++void bx_gdbstub_exception(unsigned int nr);
+ #define GDBSTUB_STOP_NO_REASON (0xac0)
+
+ #if BX_SUPPORT_SMP
+@@ -664,4 +665,6 @@
+
+ #endif
+
++extern int jitter;
++
+ #endif /* BX_BOCHS_H */
+Only in bochs-2.6.11: bochs.h.orig
+diff -ru bochs-2.6.11.dist/cpu/exception.cc bochs-2.6.11/cpu/exception.cc
+--- bochs-2.6.11.dist/cpu/exception.cc 2019-12-26 08:48:33.074097000 -0800
++++ bochs-2.6.11/cpu/exception.cc 2021-01-17 17:28:08.093933541 -0800
+@@ -991,6 +991,10 @@
+
+ BX_CPU_THIS_PTR last_exception_type = exception_type;
+
++#if BX_GDBSTUB
++ bx_gdbstub_exception(vector);
++#endif
++
+ if (real_mode()) {
+ push_error = 0; // not INT, no error code pushed
+ error_code = 0;
+Only in bochs-2.6.11/cpu: exception.cc.orig
+diff -ru bochs-2.6.11.dist/gdbstub.cc bochs-2.6.11/gdbstub.cc
+--- bochs-2.6.11.dist/gdbstub.cc 2017-03-06 13:30:05.467768000 -0800
++++ bochs-2.6.11/gdbstub.cc 2021-01-17 17:28:35.270952903 -0800
+@@ -50,6 +50,7 @@
+ #define GDBSTUB_EXECUTION_BREAKPOINT (0xac1)
+ #define GDBSTUB_TRACE (0xac2)
+ #define GDBSTUB_USER_BREAK (0xac3)
++#define GDBSTUB_EXCEPTION_0E (0xac4)
+
+ static bx_list_c *gdbstub_list;
+ static int listen_socket_fd;
+@@ -319,6 +320,12 @@
+ return GDBSTUB_STOP_NO_REASON;
+ }
+
++void bx_gdbstub_exception(unsigned int nr)
++{
++ if (nr == 0x0e)
++ last_stop_reason = GDBSTUB_EXCEPTION_0E;
++}
++
+ static int remove_breakpoint(Bit64u addr, int len)
+ {
+ if (len != 1)
+@@ -489,6 +496,10 @@
+ {
+ write_signal(&buf[1], SIGTRAP);
+ }
++ else if (last_stop_reason == GDBSTUB_EXCEPTION_0E)
++ {
++ write_signal(&buf[1], SIGSEGV);
++ }
+ else
+ {
+ write_signal(&buf[1], 0);
+@@ -516,6 +527,10 @@
+ {
+ write_signal(&buf[1], SIGTRAP);
+ }
++ else if (last_stop_reason == GDBSTUB_EXCEPTION_0E)
++ {
++ write_signal(&buf[1], SIGSEGV);
++ }
+ else
+ {
+ write_signal(&buf[1], SIGTRAP);
+Only in bochs-2.6.11: gdbstub.cc.orig
+Only in bochs-2.6.11: gdbstub.cc~
+diff -ru bochs-2.6.11.dist/iodev/pit82c54.cc bochs-2.6.11/iodev/pit82c54.cc
+--- bochs-2.6.11.dist/iodev/pit82c54.cc 2018-05-14 11:17:04.955283000 -0700
++++ bochs-2.6.11/iodev/pit82c54.cc 2021-01-17 17:28:08.097266918 -0800
+@@ -49,6 +49,7 @@
+
+ #include "iodev.h"
+ #include "pit82c54.h"
++#include <stdlib.h>
+ #define LOG_THIS this->
+
+
+@@ -410,7 +411,14 @@
+ case 2:
+ if (thisctr.count_written) {
+ if (thisctr.triggerGATE || thisctr.first_pass) {
+- set_count(thisctr, thisctr.inlatch);
++ //set_count(thisctr, thisctr.inlatch);
++ unsigned n = thisctr.inlatch;
++ if (jitter && n > 5) {
++ n *= (double) rand() / RAND_MAX;
++ if (n < 5)
++ n = 5;
++ }
++ set_count(thisctr, n);
+ thisctr.next_change_time=(thisctr.count_binary-1) & 0xFFFF;
+ thisctr.null_count=0;
+ if (thisctr.inlatch==1) {
+diff -ru bochs-2.6.11.dist/main.cc bochs-2.6.11/main.cc
+--- bochs-2.6.11.dist/main.cc 2020-01-02 08:19:02.083668000 -0800
++++ bochs-2.6.11/main.cc 2021-01-17 17:28:08.097266918 -0800
+@@ -94,6 +94,7 @@
+ BOCHSAPI BX_MEM_C bx_mem;
+
+ char *bochsrc_filename = NULL;
++int jitter = 0;
+
+ size_t bx_get_timestamp(char *buffer)
+ {
+@@ -705,6 +706,13 @@
+ else SIM->get_param_string(BXPN_DEBUGGER_LOG_FILENAME)->set(argv[arg]);
+ }
+ #endif
++ else if (!strcmp ("-j", argv[arg])) {
++ if (++arg >= argc) BX_PANIC(("-j must be followed by a number"));
++ else {
++ jitter = 1;
++ srand (atoi (argv[arg]));
++ }
++ }
+ else if (!strcmp("-f", argv[arg])) {
+ if (++arg >= argc) BX_PANIC(("-f must be followed by a filename"));
+ else bochsrc_filename = argv[arg];
+Only in bochs-2.6.11: main.cc.orig
--- /dev/null
+diff -ru bochs-2.6.11.dist/configure bochs-2.6.11/configure
+--- bochs-2.6.11.dist/configure 2020-01-04 23:37:34.155348000 -0800
++++ bochs-2.6.11/configure 2021-01-17 17:30:01.878741469 -0800
+@@ -25331,7 +25331,7 @@
+ $as_echo_n "(cached) " >&6
+ else
+ ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lncurses $LIBS"
++LIBS="-lncurses -ltinfo $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+@@ -25523,7 +25523,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_mvaddch" >&5
+ $as_echo "$ac_cv_lib_ncurses_mvaddch" >&6; }
+ if test "x$ac_cv_lib_ncurses_mvaddch" = xyes; then :
+- GUI_LINK_OPTS_TERM='-lncurses'
++ GUI_LINK_OPTS_TERM='-lncurses -ltinfo'
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mvaddch in -ltermlib" >&5
+Only in bochs-2.6.11: configure.orig
our ($loader_fn); # Bootstrap loader.
our (%geometry); # IDE disk geometry.
our ($align); # Partition alignment.
+our ($gdb_port) = $ENV{"GDB_PORT"} || "1234"; # Port to listen on for GDB
parse_command_line ();
prepare_scratch_disk ();
$align = "bochs",
print STDERR "warning: setting --align=bochs for Bochs support\n"
if $sim eq 'bochs' && defined ($align) && $align eq 'none';
+
+ $kill_on_failure = 0;
}
# usage($exitcode).
megs: $mem
log: bochsout.txt
panic: action=fatal
-user_shortcut: keys=ctrlaltdel
+# For older bochs:
+#user_shortcut: keys=ctrlaltdel
+# For more recent bochs:
+keyboard: user_shortcut=ctrl-alt-del
EOF
- print BOCHSRC "gdbstub: enabled=1\n" if $debug eq 'gdb';
+ print BOCHSRC "gdbstub: enabled=1, port=$gdb_port\n" if $debug eq 'gdb';
print BOCHSRC "clock: sync=", $realtime ? 'realtime' : 'none',
", time0=0\n";
print BOCHSRC "ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15\n"
my (@cmd) = ('qemu-system-i386');
push (@cmd, '-device', 'isa-debug-exit');
- push (@cmd, '-hda', $disks[0]) if defined $disks[0];
- push (@cmd, '-hdb', $disks[1]) if defined $disks[1];
- push (@cmd, '-hdc', $disks[2]) if defined $disks[2];
- push (@cmd, '-hdd', $disks[3]) if defined $disks[3];
+ my ($i);
+ for ($i = 0; $i < 4; $i++) {
+ if (defined $disks[$i]) {
+ push (@cmd, '-drive');
+ push (@cmd, "file=$disks[$i],format=raw,index=$i,media=disk");
+ }
+ }
+# push (@cmd, '-hda', $disks[0]) if defined $disks[0];
+# push (@cmd, '-hdb', $disks[1]) if defined $disks[1];
+# push (@cmd, '-hdc', $disks[2]) if defined $disks[2];
+# push (@cmd, '-hdd', $disks[3]) if defined $disks[3];
push (@cmd, '-m', $mem);
push (@cmd, '-net', 'none');
push (@cmd, '-nographic') if $vga eq 'none';
push (@cmd, '-serial', 'stdio') if $serial && $vga ne 'none';
push (@cmd, '-S') if $debug eq 'monitor';
- push (@cmd, '-s', '-S') if $debug eq 'gdb';
+ push (@cmd, '-gdb', "tcp::$gdb_port", '-S') if $debug eq 'gdb';
push (@cmd, '-monitor', 'null') if $vga eq 'none' && $debug eq 'none';
run_command (@cmd);
}