summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Make.config2
-rw-r--r--src/threads/init.c9
-rwxr-xr-xsrc/utils/pintos25
3 files changed, 31 insertions, 5 deletions
diff --git a/src/Make.config b/src/Make.config
index 8992e60..1301180 100644
--- a/src/Make.config
+++ b/src/Make.config
@@ -45,7 +45,7 @@ endif
# Compiler and assembler invocation.
DEFINES =
WARNINGS = -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wsystem-headers
-CFLAGS = -g -msoft-float -O $(CFLAG_STACK_PROTECTOR)
+CFLAGS = -std=gnu99 -ggdb -msoft-float -fno-omit-frame-pointer -ffreestanding -fno-inline -fno-pic -O $(CFLAG_STACK_PROTECTOR)
CPPFLAGS = -nostdinc -I$(SRCDIR) -I$(SRCDIR)/lib
ASFLAGS = -Wa,--gstabs
LDFLAGS =
diff --git a/src/threads/init.c b/src/threads/init.c
index 0e97c39..3ad3f07 100644
--- a/src/threads/init.c
+++ b/src/threads/init.c
@@ -374,6 +374,15 @@ power_off (void)
printf ("Powering off...\n");
serial_flush ();
outw(0xB004, 0x2000);
+ outb(0xF4, 0x30);
+
+ /* For newer versions of qemu, you must run with -device
+ * isa-debug-exit, which exits on any write to an IO port (by
+ * default 0x501). Qemu's exit code is double the value plus one,
+ * so there is no way to exit cleanly. We use 0x31 which should
+ * result in a qemu exit code of 0x63. */
+ outb (0x501, 0x31);
+
for (p = s; *p != '\0'; p++)
outb (0x8900, *p);
asm volatile ("cli; hlt" : : : "memory");
diff --git a/src/utils/pintos b/src/utils/pintos
index dacf900..a3af3f8 100755
--- a/src/utils/pintos
+++ b/src/utils/pintos
@@ -475,7 +475,7 @@ sub run_qemu {
my (@cmd) = ('qemu');
for my $iface (0...3) {
my ($option) = ('-hda', '-hdb', '-hdc', '-hdd')[$iface];
- push (@cmd, $option, $disks_by_iface[$iface]{FILE_NAME})
+ push (@cmd, '-drive', "file=" . $disks_by_iface[$iface]{FILE_NAME} . ",index=$iface,format=raw")
if defined $disks_by_iface[$iface]{FILE_NAME};
}
push (@cmd, '-m', $mem);
@@ -485,7 +485,23 @@ sub run_qemu {
push (@cmd, '-S') if $debug eq 'monitor';
push (@cmd, '-s', '-S') if $debug eq 'gdb';
push (@cmd, '-monitor', 'null') if $vga eq 'none' && $debug eq 'none';
- run_command (@cmd);
+
+ # Insert a device that lets us shutdown Pintos. See https://wiki.osdev.org/Shutdown for details
+ push (@cmd, '-device', 'isa-debug-exit,iobase=0xf4,iosize=0x04');
+
+ # When using isa-debug-exit, we can not exit QEMU cleanly. We exit with 0x30, which will make QEMU exit
+ # with the code 0x30*2 + 1 = 97, and therefore we treat 97 as success as well.
+ my ($exit) = xsystem (@cmd);
+ if (WIFEXITED($exit)) {
+ $exit = WEXITSTATUS($exit);
+ if ($exit == 97) {
+ # We use this code to exit cleanly from within Pintos (see https://wiki.osdev.org/Shutdown)
+ # since we can not exit with code 0 using the debug shutdown device in QEMU.
+ $exit = 0;
+ }
+ }
+ die "command failed\n" if $exit;
+
}
# player_unsup($flag)
@@ -763,9 +779,10 @@ sub xsystem {
}
# Read and print out pipe data.
- my ($len) = length ($buf);
+ my ($len) = length ($buf);
+ my ($readcount) = sysread ($in, $buf, 4096, $len);
waitpid ($pid, 0), last
- if sysread ($in, $buf, 4096, $len) <= 0;
+ if $readcount <= 0;
print substr ($buf, $len);
# Remove full lines from $buf and scan them for keywords.