From f2f8875638593bd5365cfd6a5ba7c9578e52322f Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 6 Sep 2004 05:19:18 +0000 Subject: [PATCH] Rename printk() to printf(). Create user library by separating kernel library into kernel-specific and kernel-independent bits. Break up lib.c by standard header. Break up lib.h by standard header. Write our own standard headers for , etc., and stop using compiler include path. --- src/Makefile.build | 31 +-- src/Makefile.kernel | 8 +- src/devices/16550a.h | 2 +- src/devices/disk.c | 45 ++-- src/devices/disk.h | 4 +- src/devices/kbd.c | 8 +- src/devices/serial.c | 8 +- src/devices/timer.c | 4 +- src/devices/vga.c | 5 +- src/filesys/Makefile.vars | 2 +- src/filesys/directory.c | 15 +- src/filesys/file.c | 12 +- src/filesys/file.h | 2 +- src/filesys/filehdr.c | 18 +- src/filesys/filehdr.h | 2 +- src/filesys/filesys.c | 25 ++- src/filesys/filesys.h | 2 +- src/filesys/fsutil.c | 14 +- src/lib/ctype.h | 24 ++ src/lib/debug.c | 47 ++-- src/lib/inttypes.h | 48 ++++ src/lib/{ => kernel}/bitmap.c | 5 +- src/lib/{ => kernel}/bitmap.h | 0 src/lib/{ => kernel}/hash.c | 2 +- src/lib/{ => kernel}/hash.h | 0 src/lib/{ => kernel}/list.c | 2 +- src/lib/{ => kernel}/list.h | 0 src/lib/kernel/printf.c | 39 ++++ src/lib/lib.h | 68 ------ src/lib/limits.h | 34 +++ src/lib/round.h | 18 ++ src/lib/stdarg.h | 14 ++ src/lib/stdbool.h | 9 + src/lib/stddef.h | 9 + src/lib/stdint.h | 51 +++++ src/lib/{lib.c => stdio.c} | 410 ++++------------------------------ src/lib/stdio.h | 30 +++ src/lib/stdlib.c | 37 +++ src/lib/stdlib.h | 8 + src/lib/string.c | 373 +++++++++++++++++++++++++++++++ src/lib/string.h | 35 +++ src/lib/syscall-nr.h | 23 ++ src/lib/user/entry.c | 11 + src/lib/user/printf.c | 47 ++++ src/lib/user/syscall-stub.S | 4 + src/lib/user/syscall-stub.h | 6 + src/lib/user/syscall.c | 65 ++++++ src/lib/user/syscall.h | 20 ++ src/lib/user/user.c | 1 + src/lib/user/user.h | 14 ++ src/threads/Makefile.vars | 2 +- src/threads/init.c | 40 ++-- src/threads/interrupt.c | 24 +- src/threads/loader.S | 4 +- src/threads/malloc.c | 17 +- src/threads/malloc.h | 2 +- src/threads/mmu.h | 4 +- src/threads/paging.c | 10 +- src/threads/palloc.c | 16 +- src/threads/switch.S | 2 +- src/threads/synch.c | 15 +- src/threads/synch.h | 2 +- src/threads/thread.c | 18 +- src/threads/thread.h | 4 +- src/userprog/Makefile.vars | 2 +- src/userprog/addrspace.c | 28 +-- src/userprog/exception.c | 12 +- src/userprog/gdt.c | 6 +- src/userprog/syscall.c | 7 +- src/userprog/tss.c | 6 +- 70 files changed, 1224 insertions(+), 658 deletions(-) create mode 100644 src/lib/ctype.h create mode 100644 src/lib/inttypes.h rename src/lib/{ => kernel}/bitmap.c (99%) rename src/lib/{ => kernel}/bitmap.h (100%) rename src/lib/{ => kernel}/hash.c (99%) rename src/lib/{ => kernel}/hash.h (100%) rename src/lib/{ => kernel}/list.c (99%) rename src/lib/{ => kernel}/list.h (100%) create mode 100644 src/lib/kernel/printf.c delete mode 100644 src/lib/lib.h create mode 100644 src/lib/limits.h create mode 100644 src/lib/round.h create mode 100644 src/lib/stdarg.h create mode 100644 src/lib/stdbool.h create mode 100644 src/lib/stddef.h create mode 100644 src/lib/stdint.h rename src/lib/{lib.c => stdio.c} (63%) create mode 100644 src/lib/stdio.h create mode 100644 src/lib/stdlib.c create mode 100644 src/lib/stdlib.h create mode 100644 src/lib/string.c create mode 100644 src/lib/string.h create mode 100644 src/lib/syscall-nr.h create mode 100644 src/lib/user/entry.c create mode 100644 src/lib/user/printf.c create mode 100644 src/lib/user/syscall-stub.S create mode 100644 src/lib/user/syscall-stub.h create mode 100644 src/lib/user/syscall.c create mode 100644 src/lib/user/syscall.h create mode 100644 src/lib/user/user.c create mode 100644 src/lib/user/user.h diff --git a/src/Makefile.build b/src/Makefile.build index 0a25309..8fe960a 100644 --- a/src/Makefile.build +++ b/src/Makefile.build @@ -6,13 +6,13 @@ SHELL = /bin/sh CC = gcc -SRC_ROOT = ../.. -VPATH = $(SRC_ROOT) +VPATH = ../.. +DEFINES += -DKERNEL WARNINGS = -Wall -W -Wstrict-prototypes -Wmissing-prototypes -INCLUDES = -I$(SRC_ROOT) +INCLUDES = -nostdinc -I../.. -I- -I../../lib -I../../lib/kernel CFLAGS = -g -O3 -MMD -msoft-float $(INCLUDES) $(WARNINGS) $(DEFINES) -ASFLAGS = -Wa,--gstabs $(INCLUDES) $(DEFINES) +ASFLAGS = -Wa,--gstabs -MMD $(INCLUDES) $(DEFINES) # Core kernel. threads_SRC = threads/init.c # Main program. @@ -33,13 +33,18 @@ devices_SRC += devices/vga.c # Video device. devices_SRC += devices/serial.c # Serial port device. devices_SRC += devices/disk.c # IDE disk device. -# Library code. +# Library code shared between kernel and user programs. lib_SRC = lib/debug.c # Debug helpers. -lib_SRC += lib/lib.c # Standard C library. lib_SRC += lib/random.c # Pseudo-random numbers. -lib_SRC += lib/list.c # Doubly-linked lists. -lib_SRC += lib/bitmap.c # Bitmaps. -lib_SRC += lib/hash.c # Hash tables. +lib_SRC += lib/stdio.c # I/O library. +lib_SRC += lib/stdlib.c # Utility functions. +lib_SRC += lib/string.c # String functions. + +# Kernel-specific library code. +lib_kernel_SRC += lib/kernel/list.c # Doubly-linked lists. +lib_kernel_SRC += lib/kernel/bitmap.c # Bitmaps. +lib_kernel_SRC += lib/kernel/hash.c # Hash tables. +lib_kernel_SRC += lib/kernel/printf.c # Kernel printf(). # Filesystem code. filesys_SRC = filesys/filesys.c # Filesystem core. @@ -55,7 +60,7 @@ userprog_SRC += userprog/syscall.c # System call handler. userprog_SRC += userprog/gdt.c # GDT initialization. userprog_SRC += userprog/tss.c # TSS management. -SOURCES = $(foreach dir,$(SUBDIRS),$($(dir)_SRC)) +SOURCES = $(foreach dir,$(SUBDIRS),$($(subst /,_,$(dir))_SRC)) OBJECTS = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(SOURCES))) DEPENDS = $(patsubst %.o,%.d,$(OBJECTS)) @@ -72,11 +77,11 @@ kernel.o: threads/kernel.lds.s $(OBJECTS) kernel.bin: kernel.o objcopy -O binary -R .note -R .comment -S $< $@.tmp - $(SRC_ROOT)/pad 4096 < $@.tmp > $@ + ../../pad 4096 < $@.tmp > $@ rm $@.tmp -threads/loader.o: threads/loader.S threads/loader.h kernel.bin - gcc -c $< -o $@ -DKERNEL_LOAD_PAGES=`perl -e 'print +(-s "kernel.bin") / 4096;'` +threads/loader.o: kernel.bin +threads/loader.o: DEFINES += -DKERNEL_LOAD_PAGES=`perl -e 'print +(-s "kernel.bin") / 4096;'` loader.bin: threads/loader.o ld -N -e start -Ttext 0x7c00 --oformat binary -o $@ $< diff --git a/src/Makefile.kernel b/src/Makefile.kernel index 9337203..92522fa 100644 --- a/src/Makefile.kernel +++ b/src/Makefile.kernel @@ -1,15 +1,17 @@ include Makefile.vars BUILD_SUBDIRS = $(addprefix build/, $(SUBDIRS)) +LN = ln +MKDIR = mkdir all: build build/Makefile $(BUILD_SUBDIRS) $(MAKE) -C build $(BUILD_SUBDIRS): - mkdir $@ + $(MKDIR) $@ build: - mkdir $@ + $(MKDIR) $@ build/Makefile: ../Makefile.build - cp $< $@ + $(LN) $< $@ clean: rm -rf build diff --git a/src/devices/16550a.h b/src/devices/16550a.h index 9a1e37d..b3cb37a 100644 --- a/src/devices/16550a.h +++ b/src/devices/16550a.h @@ -1,9 +1,9 @@ #ifndef HEADER_16550A_H #define HEADER_16550A_H 1 +#include #include #include -#include "lib/debug.h" /* Register definitions for the 16550A UART used in PCs. This is a full definition of all the registers and their bits. We diff --git a/src/devices/disk.c b/src/devices/disk.c index 9e4b9f5..d8bed65 100644 --- a/src/devices/disk.c +++ b/src/devices/disk.c @@ -1,8 +1,9 @@ -#include "disk.h" +#include "devices/disk.h" +#include +#include #include -#include "timer.h" -#include "lib/debug.h" -#include "lib/lib.h" +#include +#include "devices/timer.h" #include "threads/io.h" #include "threads/interrupt.h" #include "threads/synch.h" @@ -220,7 +221,7 @@ disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer) /* Disk detection and identification. */ -static void printk_ata_string (char *string, size_t size); +static void print_ata_string (char *string, size_t size); /* Resets an ATA channel and waits for any devices present on it to finish the reset. */ @@ -341,28 +342,28 @@ identify_ata_device (struct disk *d) d->capacity = id[60] | ((uint32_t) id[61] << 16); /* Print identification message. */ - printk ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity); + printf ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity); if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024 * 1024) - printk ("%"PRDSNu" GB", + printf ("%"PRDSNu" GB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024 * 1024)); else if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024) - printk ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024)); + printf ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024)); else if (d->capacity > 1024 / DISK_SECTOR_SIZE) - printk ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE)); + printf ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE)); else - printk ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE); - printk (") disk, model \""); - printk_ata_string ((char *) &id[27], 40); - printk ("\", serial \""); - printk_ata_string ((char *) &id[10], 20); - printk ("\"\n"); + printf ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE); + printf (") disk, model \""); + print_ata_string ((char *) &id[27], 40); + printf ("\", serial \""); + print_ata_string ((char *) &id[10], 20); + printf ("\"\n"); } /* Prints STRING, which consists of SIZE bytes in a funky format: each pair of bytes is in reverse order. Does not print trailing whitespace and/or nulls. */ static void -printk_ata_string (char *string, size_t size) +print_ata_string (char *string, size_t size) { size_t i; @@ -376,7 +377,7 @@ printk_ata_string (char *string, size_t size) /* Print. */ for (i = 0; i < size; i++) - printk ("%c", string[i ^ 1]); + printf ("%c", string[i ^ 1]); } /* Selects device D, waiting for it to become ready, and then @@ -447,7 +448,7 @@ wait_until_idle (const struct disk *d) timer_usleep (10); } - printk ("%s: idle timeout\n", d->name); + printf ("%s: idle timeout\n", d->name); } /* Wait up to 30 seconds for disk D to clear BSY, @@ -463,17 +464,17 @@ wait_while_busy (const struct disk *d) for (i = 0; i < 3000; i++) { if (i == 700) - printk ("%s: busy, waiting...", d->name); + printf ("%s: busy, waiting...", d->name); if (!(inb (reg_alt_status (c)) & STA_BSY)) { if (i >= 700) - printk ("ok\n"); + printf ("ok\n"); return (inb (reg_alt_status (c)) & STA_DRQ) != 0; } timer_msleep (10); } - printk ("failed\n"); + printf ("failed\n"); return false; } @@ -515,7 +516,7 @@ interrupt_handler (struct intr_frame *f) sema_up (&c->completion_wait); /* Wake up waiter. */ } else - printk ("%s: unexpected interrupt\n", c->name); + printf ("%s: unexpected interrupt\n", c->name); return; } diff --git a/src/devices/disk.h b/src/devices/disk.h index d149682..9e785e5 100644 --- a/src/devices/disk.h +++ b/src/devices/disk.h @@ -11,8 +11,8 @@ Good enough for disks up to 2 TB. */ typedef uint32_t disk_sector_t; -/* Format specifier for printk(), e.g.: - printk ("sector=%"PRDSNu"\n", sector); */ +/* Format specifier for printf(), e.g.: + printf ("sector=%"PRDSNu"\n", sector); */ #define PRDSNu PRIu32 void disk_init (void); diff --git a/src/devices/kbd.c b/src/devices/kbd.c index 867c64a..bcfe2c8 100644 --- a/src/devices/kbd.c +++ b/src/devices/kbd.c @@ -1,13 +1,13 @@ -#include "kbd.h" -#include "lib/debug.h" -#include "lib/lib.h" +#include "devices/kbd.h" +#include +#include #include "threads/interrupt.h" #include "threads/io.h" static void irq21_keyboard (struct intr_frame *args UNUSED) { - printk ("Keyboard!\n"); + printf ("Keyboard!\n"); inb (0x60); } diff --git a/src/devices/serial.c b/src/devices/serial.c index eeac40a..41b52f6 100644 --- a/src/devices/serial.c +++ b/src/devices/serial.c @@ -1,7 +1,7 @@ -#include "serial.h" -#include "16550a.h" -#include "timer.h" -#include "lib/debug.h" +#include "devices/serial.h" +#include +#include "devices/16550a.h" +#include "devices/timer.h" #include "threads/io.h" static void set_serial (int bps, int bits, enum parity_type parity, int stop); diff --git a/src/devices/timer.c b/src/devices/timer.c index 85bc3ee..1706201 100644 --- a/src/devices/timer.c +++ b/src/devices/timer.c @@ -1,5 +1,5 @@ -#include "timer.h" -#include "lib/debug.h" +#include "devices/timer.h" +#include #include "threads/interrupt.h" #include "threads/io.h" diff --git a/src/devices/vga.c b/src/devices/vga.c index fcdc689..bc2d6b7 100644 --- a/src/devices/vga.c +++ b/src/devices/vga.c @@ -1,7 +1,8 @@ -#include "vga.h" +#include "devices/vga.h" +#include #include #include -#include "lib/lib.h" +#include #include "threads/io.h" #include "threads/mmu.h" diff --git a/src/filesys/Makefile.vars b/src/filesys/Makefile.vars index db29a74..03e8f08 100644 --- a/src/filesys/Makefile.vars +++ b/src/filesys/Makefile.vars @@ -1,2 +1,2 @@ DEFINES = -DUSERPROG -DFILESYS -SUBDIRS = threads devices lib userprog filesys +SUBDIRS = threads devices lib lib/kernel userprog filesys diff --git a/src/filesys/directory.c b/src/filesys/directory.c index 32911b8..fba32f0 100644 --- a/src/filesys/directory.c +++ b/src/filesys/directory.c @@ -1,7 +1,8 @@ -#include "directory.h" -#include "file.h" -#include "fsutil.h" -#include "lib/lib.h" +#include "filesys/directory.h" +#include +#include +#include "filesys/file.h" +#include "filesys/fsutil.h" #include "threads/malloc.h" /* Initializes D as a directory that holds ENTRY_CNT entries. */ @@ -160,7 +161,7 @@ dir_list (const struct dir *d) for (e = d->entries; e < d->entries + d->entry_cnt; e++) if (e->in_use) - printk ("%s\n", e->name); + printf ("%s\n", e->name); } /* Dumps the contents of D, including its files' names and their @@ -173,8 +174,8 @@ dir_dump (const struct dir *d) for (e = d->entries; e < d->entries + d->entry_cnt; e++) if (e->in_use) { - printk ("Contents of %s:\n", e->name); + printf ("Contents of %s:\n", e->name); fsutil_print (e->name); - printk ("\n"); + printf ("\n"); } } diff --git a/src/filesys/file.c b/src/filesys/file.c index a40c073..e1a70f3 100644 --- a/src/filesys/file.c +++ b/src/filesys/file.c @@ -1,9 +1,9 @@ -#include "file.h" -#include "directory.h" -#include "filehdr.h" -#include "filesys.h" -#include "lib/debug.h" -#include "lib/lib.h" +#include "filesys/file.h" +#include +#include +#include "filesys/directory.h" +#include "filesys/filehdr.h" +#include "filesys/filesys.h" #include "threads/malloc.h" bool diff --git a/src/filesys/file.h b/src/filesys/file.h index afa1990..28495c2 100644 --- a/src/filesys/file.h +++ b/src/filesys/file.h @@ -5,7 +5,7 @@ #include #include #include "devices/disk.h" -#include "off_t.h" +#include "filesys/off_t.h" struct file { diff --git a/src/filesys/filehdr.c b/src/filesys/filehdr.c index eafe211..5817912 100644 --- a/src/filesys/filehdr.c +++ b/src/filesys/filehdr.c @@ -1,8 +1,8 @@ -#include "filehdr.h" -#include "filesys.h" -#include "lib/bitmap.h" -#include "lib/debug.h" -#include "lib/lib.h" +#include "filesys/filehdr.h" +#include +#include +#include +#include "filesys/filesys.h" #include "threads/malloc.h" /* Allocates sectors from bitmap B for the content of a file @@ -122,7 +122,7 @@ filehdr_print (const struct filehdr *h) { size_t i; - printk ("File header: %jd bytes, %zd sectors (", + printf ("File header: %jd bytes, %zd sectors (", (intmax_t) h->length, h->sector_cnt); /* This loop could be unsafe for large h->sector_cnt, can you @@ -130,8 +130,8 @@ filehdr_print (const struct filehdr *h) for (i = 0; i < h->sector_cnt; i++) { if (i != 0) - printk (", "); - printk ("%jd", (intmax_t) h->sectors[i]); + printf (", "); + printf ("%jd", (intmax_t) h->sectors[i]); } - printk (")\n"); + printf (")\n"); } diff --git a/src/filesys/filehdr.h b/src/filesys/filehdr.h index cb28416..7c9f37f 100644 --- a/src/filesys/filehdr.h +++ b/src/filesys/filehdr.h @@ -3,7 +3,7 @@ #include #include -#include "off_t.h" +#include "filesys/off_t.h" #include "devices/disk.h" /* Number of direct sector pointers in a file header. */ diff --git a/src/filesys/filesys.c b/src/filesys/filesys.c index 77284ad..c0e3938 100644 --- a/src/filesys/filesys.c +++ b/src/filesys/filesys.c @@ -26,14 +26,15 @@ MODIFICATIONS. */ -#include "filesys.h" -#include "file.h" -#include "filehdr.h" -#include "directory.h" +#include "filesys/filesys.h" +#include +#include +#include +#include +#include "filesys/file.h" +#include "filesys/filehdr.h" +#include "filesys/directory.h" #include "devices/disk.h" -#include "lib/bitmap.h" -#include "lib/debug.h" -#include "lib/lib.h" /* Filesystem. @@ -276,13 +277,13 @@ filesys_dump (void) struct bitmap free_map; struct dir dir; - printk ("Free map:\n"); + printf ("Free map:\n"); if (!bitmap_init (&free_map, disk_size (filesys_disk))) return false; bitmap_read (&free_map, &free_map_file); bitmap_dump (&free_map); bitmap_destroy (&free_map); - printk ("\n"); + printf ("\n"); if (!dir_init (&dir, NUM_DIR_ENTRIES)) return false; @@ -322,7 +323,7 @@ filesys_self_test (void) MUST_SUCCEED (filesys_remove ("foo")); - printk ("filesys: self test ok\n"); + printf ("filesys: self test ok\n"); } /* Formats the filesystem. */ @@ -333,7 +334,7 @@ do_format (void) struct filehdr *map_hdr, *dir_hdr; struct dir dir; - printk ("Formatting filesystem..."); + printf ("Formatting filesystem..."); /* Create the initial bitmap and reserve sectors for the free map and root directory file headers. */ @@ -375,7 +376,7 @@ do_format (void) dir_destroy (&dir); file_close (&free_map_file); - printk ("done.\n"); + printf ("done.\n"); } /* If SUCCESS is false, panics with an error complaining about diff --git a/src/filesys/filesys.h b/src/filesys/filesys.h index 1f06c34..6e6c136 100644 --- a/src/filesys/filesys.h +++ b/src/filesys/filesys.h @@ -3,7 +3,7 @@ #include #include -#include "off_t.h" +#include "filesys/off_t.h" /* Disk used for filesystem. */ extern struct disk *filesys_disk; diff --git a/src/filesys/fsutil.c b/src/filesys/fsutil.c index 6598785..a51fac6 100644 --- a/src/filesys/fsutil.c +++ b/src/filesys/fsutil.c @@ -1,9 +1,11 @@ -#include "fsutil.h" +#include "filesys/fsutil.h" +#include #include -#include "file.h" -#include "filesys.h" -#include "lib/debug.h" -#include "lib/lib.h" +#include +#include +#include +#include "filesys/file.h" +#include "filesys/filesys.h" #include "threads/mmu.h" #include "threads/palloc.h" @@ -88,7 +90,7 @@ fsutil_run (void) if (fsutil_remove_file != NULL) { if (filesys_remove (fsutil_remove_file)) - printk ("%s: removed\n", fsutil_remove_file); + printf ("%s: removed\n", fsutil_remove_file); else PANIC ("%s: remove failed\n", fsutil_remove_file); } diff --git a/src/lib/ctype.h b/src/lib/ctype.h new file mode 100644 index 0000000..fafa51f --- /dev/null +++ b/src/lib/ctype.h @@ -0,0 +1,24 @@ +#ifndef LIB_CTYPE_H +#define LIB_CTYPE_H 1 + +static inline int islower (int c) { return c >= 'a' && c <= 'z'; } +static inline int isupper (int c) { return c >= 'A' && c <= 'Z'; } +static inline int isalpha (int c) { return islower (c) || isupper (c); } +static inline int isdigit (int c) { return c >= '0' && c <= '9'; } +static inline int isalnum (int c) { return isalpha (c) || isdigit (c); } +static inline int isxdigit (int c) { + return isdigit (c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} +static inline int isspace (int c) { + return (c == ' ' || c == '\f' || c == '\n' + || c == '\r' || c == '\t' || c == '\v'); +} +static inline int isgraph (int c) { return c >= 33 && c < 127; } +static inline int isprint (int c) { return c >= 32 && c < 127; } +static inline int iscntrl (int c) { return c >= 0 && c < 32; } +static inline int isascii (int c) { return c >= 0 && c < 128; } +static inline int ispunct (int c) { + return isprint (c) && !isalnum (c) && !isspace (c); +} + +#endif /* lib/ctype.h */ diff --git a/src/lib/debug.c b/src/lib/debug.c index babf229..2082eed 100644 --- a/src/lib/debug.c +++ b/src/lib/debug.c @@ -1,7 +1,14 @@ -#include "debug.h" +#include #include -#include "lib.h" +#include +#include +#include +#include +#ifdef KERNEL #include "threads/interrupt.h" +#else +#include +#endif #define MAX_CLASSES 16 static bool all_enabled; @@ -39,13 +46,17 @@ debug_message (const char *file, int line, const char *function, { va_list args; +#ifdef KERNEL enum intr_level old_level = intr_disable (); - printk ("%s:%d: %s(): ", file, line, function); +#endif + printf ("%s:%d: %s(): ", file, line, function); va_start (args, message); - vprintk (message, args); - printk ("\n"); + vprintf (message, args); + printf ("\n"); va_end (args); +#ifdef KERNEL intr_set_level (old_level); +#endif } } @@ -57,34 +68,40 @@ debug_panic (const char *file, int line, const char *function, { va_list args; +#ifdef KERNEL intr_disable (); +#endif - printk ("PANIC at %s:%d in %s(): ", file, line, function); + printf ("PANIC at %s:%d in %s(): ", file, line, function); va_start (args, message); - vprintk (message, args); - printk ("\n"); + vprintf (message, args); + printf ("\n"); va_end (args); debug_backtrace (); +#ifdef KERNEL for (;;); +#else + exit (1); +#endif } -/* Prints the call stack, that is, a list of addresses in each of - the functions we are nested within. gdb or addr2line may be - applied to kernel.o to translate these into file names, line - numbers, and function names. */ +/* Prints the call stack, that is, a list of addresses, one in + each of the functions we are nested within. gdb or addr2line + may be applied to kernel.o to translate these into file names, + line numbers, and function names. */ void debug_backtrace (void) { void **frame; - printk ("Call stack:"); + printf ("Call stack:"); for (frame = __builtin_frame_address (0); frame != NULL && frame[0] != NULL; frame = frame[0]) - printk (" %p", frame[1]); - printk (".\n"); + printf (" %p", frame[1]); + printf (".\n"); } diff --git a/src/lib/inttypes.h b/src/lib/inttypes.h new file mode 100644 index 0000000..70bb898 --- /dev/null +++ b/src/lib/inttypes.h @@ -0,0 +1,48 @@ +#ifndef LIB_INTTYPES_H +#define LIB_INTTYPES_H + +#define PRId8 "hhd" +#define PRId16 "hd" +#define PRId32 "d" +#define PRId64 "lld" + +#define PRIi8 "hhi" +#define PRIi16 "hi" +#define PRIi32 "i" +#define PRIi64 "lli" + +#define PRIo8 "hho" +#define PRIo16 "ho" +#define PRIo32 "o" +#define PRIo64 "llo" + +#define PRIu8 "hhu" +#define PRIu16 "hu" +#define PRIu32 "u" +#define PRIu64 "llu" + +#define PRIx8 "hhx" +#define PRIx16 "hx" +#define PRIx32 "x" +#define PRIx64 "llx" + +#define PRIX8 "hhX" +#define PRIX16 "hX" +#define PRIX32 "X" +#define PRIX64 "llX" + +#define PRIdMAX "lld" +#define PRIiMAX "lli" +#define PRIoMAX "llo" +#define PRIuMAX "llu" +#define PRIxMAX "llx" +#define PRIXMAX "llX" + +#define PRIdPTR "d" +#define PRIiPTR "i" +#define PRIoPTR "o" +#define PRIuPTR "u" +#define PRIxPTR "x" +#define PRIXPTR "X" + +#endif /* lib/inttypes.h */ diff --git a/src/lib/bitmap.c b/src/lib/kernel/bitmap.c similarity index 99% rename from src/lib/bitmap.c rename to src/lib/kernel/bitmap.c index 0be0379..7bbc928 100644 --- a/src/lib/bitmap.c +++ b/src/lib/kernel/bitmap.c @@ -1,7 +1,8 @@ #include "bitmap.h" +#include #include -#include "debug.h" -#include "lib.h" +#include +#include #include "threads/malloc.h" #ifdef FILESYS #include "filesys/file.h" diff --git a/src/lib/bitmap.h b/src/lib/kernel/bitmap.h similarity index 100% rename from src/lib/bitmap.h rename to src/lib/kernel/bitmap.h diff --git a/src/lib/hash.c b/src/lib/kernel/hash.c similarity index 99% rename from src/lib/hash.c rename to src/lib/kernel/hash.c index a6b18a9..3c0243b 100644 --- a/src/lib/hash.c +++ b/src/lib/kernel/hash.c @@ -1,5 +1,5 @@ #include "hash.h" -#include "debug.h" +#include "../debug.h" #include "threads/malloc.h" static struct list *find_bucket (struct hash *, hash_elem *); diff --git a/src/lib/hash.h b/src/lib/kernel/hash.h similarity index 100% rename from src/lib/hash.h rename to src/lib/kernel/hash.h diff --git a/src/lib/list.c b/src/lib/kernel/list.c similarity index 99% rename from src/lib/list.c rename to src/lib/kernel/list.c index a5f7c1a..3631b2e 100644 --- a/src/lib/list.c +++ b/src/lib/kernel/list.c @@ -1,5 +1,5 @@ #include "list.h" -#include "debug.h" +#include "../debug.h" /* Our doubly linked lists have two header elements: the "head" just before the first element and the "tail" just after the diff --git a/src/lib/list.h b/src/lib/kernel/list.h similarity index 100% rename from src/lib/list.h rename to src/lib/kernel/list.h diff --git a/src/lib/kernel/printf.c b/src/lib/kernel/printf.c new file mode 100644 index 0000000..886706c --- /dev/null +++ b/src/lib/kernel/printf.c @@ -0,0 +1,39 @@ +#include +#include + +#include "devices/serial.h" +#include "devices/vga.h" +#include "threads/interrupt.h" + +static void vprintf_helper (char, void *); + +int +vprintf (const char *format, va_list args) +{ + enum intr_level old_level; + int char_cnt = 0; + + old_level = intr_disable (); + __vprintf (format, args, vprintf_helper, &char_cnt); + intr_set_level (old_level); + + return char_cnt; +} + +/* Helper function for vprintf(). */ +static void +vprintf_helper (char c, void *char_cnt_) +{ + int *char_cnt = char_cnt_; + (*char_cnt)++; + putchar (c); +} + +/* Writes C to the console. */ +int +putchar (int c) +{ + serial_outb (c); + vga_putc (c); + return c; +} diff --git a/src/lib/lib.h b/src/lib/lib.h deleted file mode 100644 index 8883cf7..0000000 --- a/src/lib/lib.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef HEADER_LIB_H -#define HEADER_LIB_H 1 - -#include -#include -#include -#include "debug.h" - -/* */ -void *memset (void *, int, size_t); -void *memcpy (void *, const void *, size_t); -void *memmove (void *, const void *, size_t); -void *memchr (const void *, int, size_t); -int memcmp (const void *, const void *, size_t); - -char *strchr (const char *, int); -size_t strlcpy (char *, const char *, size_t); -size_t strlen (const char *); -size_t strnlen (const char *, size_t); -int strcmp (const char *, const char *); -char *strtok_r (char *, const char *, char **); - -/* */ -int atoi (const char *); - -/* */ -int vsnprintf (char *, size_t, const char *, va_list) PRINTF_FORMAT (3, 0); -int snprintf (char *, size_t, const char *, ...) PRINTF_FORMAT (3, 4); - -/* */ -static inline int islower (int c) { return c >= 'a' && c <= 'z'; } -static inline int isupper (int c) { return c >= 'A' && c <= 'Z'; } -static inline int isalpha (int c) { return islower (c) || isupper (c); } -static inline int isdigit (int c) { return c >= '0' && c <= '9'; } -static inline int isalnum (int c) { return isalpha (c) || isdigit (c); } -static inline int isxdigit (int c) { - return isdigit (c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); -} -static inline int isspace (int c) { return strchr (" \f\n\r\t\v", c) != NULL; } -static inline int isgraph (int c) { return c >= 33 && c < 127; } -static inline int isprint (int c) { return c >= 32 && c < 127; } -static inline int iscntrl (int c) { return c >= 0 && c < 32; } -static inline int isascii (int c) { return c >= 0 && c < 128; } -static inline int ispunct (int c) { - return isprint (c) && !isalnum (c) && !isspace (c); -} - -/* Nonstandard. */ - -/* Yields X rounded up to the nearest multiple of STEP. - For X >= 0, STEP >= 1 only. */ -#define ROUND_UP(X, STEP) (((X) + (STEP) - 1) / (STEP) * (STEP)) - -/* Yields X divided by STEP, rounded up. - For X >= 0, STEP >= 1 only. */ -#define DIV_ROUND_UP(X, STEP) (((X) + (STEP) - 1) / (STEP)) - -/* Yields X rounded down to the nearest multiple of STEP. - For X >= 0, STEP >= 1 only. */ -#define ROUND_DOWN(X, STEP) ((X) / (STEP) * (STEP)) - -/* There is no DIV_ROUND_DOWN. It would be simply X / STEP. */ - -void vprintk (const char *, va_list) PRINTF_FORMAT (1, 0); -void printk (const char *, ...) PRINTF_FORMAT (1, 2); -void hex_dump (const void *, size_t size, bool ascii); - -#endif /* lib.h */ diff --git a/src/lib/limits.h b/src/lib/limits.h new file mode 100644 index 0000000..930a97b --- /dev/null +++ b/src/lib/limits.h @@ -0,0 +1,34 @@ +#ifndef LIB_LIMITS_H +#define LIB_LIMITS_H + +#define CHAR_BIT 8 + +#define SCHAR_MAX 127 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define UCHAR_MAX 255 + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MAX 32767 +#define SHRT_MIN (-SHRT_MAX - 1) +#define USHRT_MAX 65535 + +#define INT_MAX 2147483647 +#define INT_MIN (-INT_MAX - 1) +#define UINT_MAX 4294967295U + +#define LONG_MAX 2147483647L +#define LONG_MIN (-LONG_MAX - 1) +#define ULONG_MAX 4294967295UL + +#define LLONG_MAX 9223372036854775807LL +#define LLONG_MIN (-LLONG_MAX - 1) +#define ULLONG_MAX 18446744073709551615ULL + +#endif /* lib/limits.h */ diff --git a/src/lib/round.h b/src/lib/round.h new file mode 100644 index 0000000..df0fb4a --- /dev/null +++ b/src/lib/round.h @@ -0,0 +1,18 @@ +#ifndef LIB_ROUND_H +#define LIB_ROUND_H + +/* Yields X rounded up to the nearest multiple of STEP. + For X >= 0, STEP >= 1 only. */ +#define ROUND_UP(X, STEP) (((X) + (STEP) - 1) / (STEP) * (STEP)) + +/* Yields X divided by STEP, rounded up. + For X >= 0, STEP >= 1 only. */ +#define DIV_ROUND_UP(X, STEP) (((X) + (STEP) - 1) / (STEP)) + +/* Yields X rounded down to the nearest multiple of STEP. + For X >= 0, STEP >= 1 only. */ +#define ROUND_DOWN(X, STEP) ((X) / (STEP) * (STEP)) + +/* There is no DIV_ROUND_DOWN. It would be simply X / STEP. */ + +#endif /* lib/round.h */ diff --git a/src/lib/stdarg.h b/src/lib/stdarg.h new file mode 100644 index 0000000..690bb28 --- /dev/null +++ b/src/lib/stdarg.h @@ -0,0 +1,14 @@ +#ifndef LIB_STDARG_H +#define LIB_STDARG_H + +/* GCC has functionality as built-ins, + so all we need is to use it. */ + +typedef __builtin_va_list va_list; + +#define va_start(LIST, ARG) __builtin_va_start (LIST, ARG) +#define va_end(LIST) __builtin_va_end (LIST) +#define va_arg(LIST, TYPE) __builtin_va_arg (LIST, TYPE) +#define va_copy(DST, SRC) __builtin_va_copy (DST, SRC) + +#endif /* lib/stdarg.h */ diff --git a/src/lib/stdbool.h b/src/lib/stdbool.h new file mode 100644 index 0000000..45fc515 --- /dev/null +++ b/src/lib/stdbool.h @@ -0,0 +1,9 @@ +#ifndef LIB_STDBOOL_H +#define LIB_STDBOOL_H + +#define bool _Bool +#define true 1 +#define false 0 +#define __bool_true_false_are_defined 1 + +#endif /* lib/stdbool.h */ diff --git a/src/lib/stddef.h b/src/lib/stddef.h new file mode 100644 index 0000000..836b8f2 --- /dev/null +++ b/src/lib/stddef.h @@ -0,0 +1,9 @@ +#ifndef LIB_STDDEF_H +#define LIB_STDDEF_H + +#define NULL ((void *) 0) +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) +typedef int ptrdiff_t; +typedef unsigned int size_t; + +#endif /* lib/stddef.h */ diff --git a/src/lib/stdint.h b/src/lib/stdint.h new file mode 100644 index 0000000..2f0218f --- /dev/null +++ b/src/lib/stdint.h @@ -0,0 +1,51 @@ +#ifndef LIB_STDINT_H +#define LIB_STDINT_H + +typedef signed char int8_t; +#define INT8_MAX 127 +#define INT8_MIN (-INT8_MAX - 1) + +typedef signed short int int16_t; +#define INT16_MAX 32767 +#define INT16_MIN (-INT16_MAX - 1) + +typedef signed int int32_t; +#define INT32_MAX 2147483647 +#define INT32_MIN (-INT32_MAX - 1) + +typedef signed long long int int64_t; +#define INT64_MAX 9223372036854775807LL +#define INT64_MIN (-INT64_MAX - 1) + +typedef unsigned char uint8_t; +#define UINT8_MAX 255 + +typedef unsigned short int uint16_t; +#define UINT16_MAX 65535 + +typedef unsigned int uint32_t; +#define UINT32_MAX 4294967295 + +typedef unsigned long long int uint64_t; +#define UINT64_MAX 18446744073709551615ULL + +typedef int32_t intptr_t; +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX + +typedef uint32_t uintptr_t; +#define UINTPTR_MAX UINT32_MAX + +typedef int64_t intmax_t; +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX + +typedef uint64_t uintmax_t; +#define UINTMAX_MAX UINT64_MAX + +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX + +#define SIZE_MAX UINT32_MAX + +#endif /* lib/stdint.h */ diff --git a/src/lib/lib.c b/src/lib/stdio.c similarity index 63% rename from src/lib/lib.c rename to src/lib/stdio.c index 91fb318..6a03f53 100644 --- a/src/lib/lib.c +++ b/src/lib/stdio.c @@ -1,322 +1,7 @@ -#include "lib.h" +#include +#include #include -#include -#include -#include -#include "debug.h" -#include "devices/serial.h" -#include "devices/vga.h" -#include "threads/interrupt.h" - -static void -vprintf_core (const char *format, va_list args, - void (*output) (char, void *), void *aux); - -/* */ - -/* Sets the SIZE bytes in DST to VALUE. */ -void * -memset (void *dst_, int value, size_t size) -{ - unsigned char *dst = dst_; - - ASSERT (dst != NULL || size == 0); - - while (size-- > 0) - *dst++ = value; - - return dst_; -} - -/* Copies SIZE bytes from SRC to DST, which must not overlap. - Returns DST. */ -void * -memcpy (void *dst_, const void *src_, size_t size) -{ - unsigned char *dst = dst_; - const unsigned char *src = src_; - - ASSERT (dst != NULL || size == 0); - ASSERT (src != NULL || size == 0); - - while (size-- > 0) - *dst++ = *src++; - - return dst_; -} - -/* Copies SIZE bytes from SRC to DST, which are allowed to - overlap. Returns DST. */ -void * -memmove (void *dst_, const void *src_, size_t size) -{ - unsigned char *dst = dst_; - const unsigned char *src = src_; - - ASSERT (dst != NULL || size == 0); - ASSERT (src != NULL || size == 0); - - if (dst < src) - { - while (size-- > 0) - *dst++ = *src++; - } - else - { - dst += size; - src += size; - while (size-- > 0) - *--dst = *--src; - } - - return dst; -} - -/* Returns a pointer to the first occurrence of CH in the first - SIZE bytes starting at BLOCK. Returns a null pointer if CH - does not occur in BLOCK. */ -void * -memchr (const void *block_, int ch_, size_t size) -{ - const unsigned char *block = block_; - unsigned char ch = ch_; - - ASSERT (block != NULL || size == 0); - - for (; size-- > 0; block++) - if (*block == ch) - return (void *) block; - - return NULL; -} - -/* Find the first differing byte in the two blocks of SIZE bytes - at A and B. Returns a positive value if the byte in A is - greater, a negative value if the byte in B is greater, or zero - if blocks A and B are equal. */ -int -memcmp (const void *a_, const void *b_, size_t size) -{ - const unsigned char *a = a_; - const unsigned char *b = b_; - - ASSERT (a != NULL || size == 0); - ASSERT (b != NULL || size == 0); - - for (; size-- > 0; a++, b++) - if (*a != *b) - return *a > *b ? +1 : -1; - return 0; -} - -/* Finds and returns the first occurrence of C in STRING, or a - null pointer if C does not appear in STRING. If C == '\0' - then returns a pointer to the null terminator at the end of - STRING. */ -char * -strchr (const char *string, int c_) -{ - char c = c_; - - ASSERT (string != NULL); - - for (;;) - if (*string == c) - return (char *) string; - else if (*string == '\0') - return NULL; - else - string++; -} - -/* Copies string SRC to DST. If SRC is longer than SIZE - 1 - characters, only SIZE - 1 characters are copied. A null - terminator is always written to DST, unless SIZE is 0. - Returns the length of SRC. - - strlcpy() is not in the standard C library, but it is an - increasingly popular extension. See - http://www.courtesan.com/todd/papers/strlcpy.html for - information on strlcpy(). */ -size_t -strlcpy (char *dst, const char *src, size_t size) -{ - size_t src_len; - - ASSERT (dst != NULL); - ASSERT (src != NULL); - - src_len = strlen (src); - if (size > 0) - { - size_t dst_len = size - 1; - if (src_len < dst_len) - src_len = dst_len; - memcpy (dst, src, dst_len); - dst[dst_len] = '\0'; - } - return src_len; -} - -/* Returns the length of STRING. */ -size_t -strlen (const char *string) -{ - const char *p; - - ASSERT (string != NULL); - - for (p = string; *p != '\0'; p++) - continue; - return p - string; -} - -/* If STRING is less than MAXLEN characters in length, returns - its actual length. Otherwise, returns MAXLEN. */ -size_t -strnlen (const char *string, size_t maxlen) -{ - size_t length; - - for (length = 0; string[length] != '\0' && length < maxlen; length++) - continue; - return length; -} - -/* Finds the first differing characters in strings A and B. - Returns a positive value if the character in A (as an unsigned - char) is greater, a negative value if the character in B (as - an unsigned char) is greater, or zero if strings A and B are - equal. */ -int -strcmp (const char *a_, const char *b_) -{ - const unsigned char *a = (const unsigned char *) a_; - const unsigned char *b = (const unsigned char *) b_; - - ASSERT (a != NULL); - ASSERT (b != NULL); - - while (*a != '\0' && *a == *b) - { - a++; - b++; - } - - return *a < *b ? -1 : *a > *b; -} - -/* Breaks a string into tokens separated by DELIMITERS. The - first time this function is called, S should be the string to - tokenize, and in subsequent calls it must be a null pointer. - SAVE_PTR is the address of a `char *' variable used to keep - track of the tokenizer's position. The return value each time - is the next token in the string, or a null pointer if no - tokens remain. - - This function treats multiple adjacent delimiters as a single - delimiter. The returned tokens will never be length 0. - DELIMITERS may change from one call to the next within a - single string. - - strtok_r() modifies the string S, changing delimiters to null - bytes. Thus, S must be a modifiable string. - - Example usage: - - char s[] = " String to tokenize. "; - char *token, *save_ptr; - - for (token = strtok_r (s, " ", &save_ptr); token != NULL; - token = strtok_r (NULL, " ", &save_ptr)) - printf ("'%s'\n", token); - - outputs: - - 'String' - 'to' - 'tokenize.' -*/ -char * -strtok_r (char *s, const char *delimiters, char **save_ptr) -{ - char *token; - - ASSERT (delimiters != NULL); - ASSERT (save_ptr != NULL); - - /* If S is nonnull, start from it. - If S is null, start from saved position. */ - if (s == NULL) - s = *save_ptr; - ASSERT (s != NULL); - - /* Skip any DELIMITERS at our current position. */ - while (strchr (delimiters, *s) != NULL) - { - /* strchr() will always return nonnull if we're searching - for a null byte, because every string contains a null - byte (at the end). */ - if (*s == '\0') - { - *save_ptr = s; - return NULL; - } - - s++; - } - - /* Skip any non-DELIMITERS up to the end of the string. */ - token = s; - while (strchr (delimiters, *s) == NULL) - s++; - if (*s != '\0') - { - *s = '\0'; - *save_ptr = s + 1; - } - else - *save_ptr = s; - return token; -} - -/* */ - -/* Converts a string representation of a signed decimal integer - in S into an `int', which is returned. */ -int -atoi (const char *s) -{ - bool negative; - int value; - - /* Skip white space. */ - while (isspace (*s)) - s++; - - /* Parse sign. */ - negative = false; - if (*s == '+') - s++; - else if (*s == '-') - { - negative = true; - s++; - } - - /* Parse digits. We always initially parse the value as - negative, and then make it positive later, because the - negative range of an int is bigger than the positive range - on a 2's complement system. */ - for (value = 0; isdigit (*s); s++) - value = value * 10 - (*s - '0'); - if (!negative) - value = -value; - - return value; -} - -/* */ +#include /* Auxiliary data for vsnprintf_helper(). */ struct vsnprintf_aux @@ -345,7 +30,7 @@ vsnprintf (char *buffer, size_t buf_size, const char *format, va_list args) aux.max_length = buf_size > 0 ? buf_size - 1 : 0; /* Do most of the work. */ - vprintf_core (format, args, vsnprintf_helper, &aux); + __vprintf (format, args, vsnprintf_helper, &aux); /* Add null terminator. */ if (buf_size > 0) @@ -383,41 +68,23 @@ snprintf (char *buffer, size_t buf_size, const char *format, ...) return retval; } - -/* Nonstandard functions. */ - -static void vprintk_helper (char, void *); - -/* Like vprintf(), except that output is written to the system - console, which is defined as the video display and the first - serial port (at the same time). */ -void -vprintk (const char *format, va_list args) -{ - enum intr_level old_level = intr_disable (); - vprintf_core (format, args, vprintk_helper, NULL); - intr_set_level (old_level); -} - -/* Helper function for vprintk(). */ -static void -vprintk_helper (char ch, void *aux UNUSED) -{ - vga_putc (ch); - serial_outb (ch); -} -/* Like printf(), except that output is written to the system - console, which is defined as the video display and the first - serial port (at the same time). */ -void -printk (const char *format, ...) +/* Writes formatted output to the console. + In the kernel, the console is both the video display and first + serial port. + In userspace, the console is file descriptor 1. +*/ +int +printf (const char *format, ...) { va_list args; + int retval; va_start (args, format); - vprintk (format, args); + retval = vprintf (format, args); va_end (args); + + return retval; } /* printf() formatting internals. */ @@ -484,12 +151,10 @@ static void output_dup (char ch, size_t cnt, static void format_string (const char *string, size_t length, struct printf_conversion *, void (*output) (char, void *), void *aux); -static void printf_core (const char *format, - void (*output) (char, void *), void *aux, ...); -static void -vprintf_core (const char *format, va_list args, - void (*output) (char, void *), void *aux) +void +__vprintf (const char *format, va_list args, + void (*output) (char, void *), void *aux) { for (; *format != '\0'; format++) { @@ -647,11 +312,11 @@ vprintf_core (const char *format, va_list args, case 'n': /* We don't support floating-point arithmetic, and %n can be part of a security hole. */ - printf_core ("<>", output, aux, *format); + __printf ("<>", output, aux, *format); break; default: - printf_core ("<>", output, aux, *format); + __printf ("<>", output, aux, *format); break; } } @@ -878,18 +543,29 @@ format_string (const char *string, size_t length, output_dup (' ', c->width - 1, output, aux); } -/* Wrapper for vprintf_core() that converts varargs into a +/* Wrapper for __vprintf() that converts varargs into a va_list. */ -static void -printf_core (const char *format, - void (*output) (char, void *), void *aux, ...) +void +__printf (const char *format, + void (*output) (char, void *), void *aux, ...) { va_list args; va_start (args, aux); - vprintf_core (format, args, output, aux); + __vprintf (format, args, output, aux); va_end (args); } + +/* Writes string S to the console, followed by a new-line + character. */ +int +puts (const char *s) +{ + while (*s != '\0') + putchar (*s++); + putchar ('\n'); + return 0; +} /* Dumps the SIZE bytes in BUFFER to the console as hex bytes arranged 16 per line. If ASCII is true then the corresponding @@ -912,18 +588,18 @@ hex_dump (const void *buffer, size_t size, bool ascii) /* Print line. */ for (i = 0; i < n; i++) - printk ("%c%02x", i == n_per_line / 2 ? '-' : ' ', (unsigned) p[i]); + printf ("%c%02x", i == n_per_line / 2 ? '-' : ' ', (unsigned) p[i]); if (ascii) { for (; i < n_per_line; i++) - printk (" "); - printk (" |"); + printf (" "); + printf (" |"); for (i = 0; i < n; i++) - printk ("%c", isprint (p[i]) ? p[i] : '.'); + printf ("%c", isprint (p[i]) ? p[i] : '.'); for (; i < n_per_line; i++) - printk (" "); - printk ("|"); + printf (" "); + printf ("|"); } - printk ("\n"); + printf ("\n"); } } diff --git a/src/lib/stdio.h b/src/lib/stdio.h new file mode 100644 index 0000000..7141387 --- /dev/null +++ b/src/lib/stdio.h @@ -0,0 +1,30 @@ +#ifndef LIB_STDIO_H +#define LIB_STDIO_H + +#include +#include +#include +#include + +/* Standard functions. */ +int vsnprintf (char *, size_t, const char *, va_list) PRINTF_FORMAT (3, 0); +int snprintf (char *, size_t, const char *, ...) PRINTF_FORMAT (3, 4); +int vprintf (const char *, va_list) PRINTF_FORMAT (1, 0); +int printf (const char *, ...) PRINTF_FORMAT (1, 2); +int putchar (int); +int puts (const char *); + +/* Nonstandard functions. */ +void hex_dump (const void *, size_t size, bool ascii); + +/* Internal functions. */ +void __vprintf (const char *format, va_list args, + void (*output) (char, void *), void *aux); +void __printf (const char *format, + void (*output) (char, void *), void *aux, ...); + +/* Try to be helpful. */ +#define sprintf dont_use_sprintf_use_snprintf +#define vsprintf dont_use_vsprintf_use_vsnprintf + +#endif /* lib/stdio.h */ diff --git a/src/lib/stdlib.c b/src/lib/stdlib.c new file mode 100644 index 0000000..56a94c6 --- /dev/null +++ b/src/lib/stdlib.c @@ -0,0 +1,37 @@ +#include +#include +#include + +/* Converts a string representation of a signed decimal integer + in S into an `int', which is returned. */ +int +atoi (const char *s) +{ + bool negative; + int value; + + /* Skip white space. */ + while (isspace (*s)) + s++; + + /* Parse sign. */ + negative = false; + if (*s == '+') + s++; + else if (*s == '-') + { + negative = true; + s++; + } + + /* Parse digits. We always initially parse the value as + negative, and then make it positive later, because the + negative range of an int is bigger than the positive range + on a 2's complement system. */ + for (value = 0; isdigit (*s); s++) + value = value * 10 - (*s - '0'); + if (!negative) + value = -value; + + return value; +} diff --git a/src/lib/stdlib.h b/src/lib/stdlib.h new file mode 100644 index 0000000..0a8abcb --- /dev/null +++ b/src/lib/stdlib.h @@ -0,0 +1,8 @@ +#ifndef LIB_STDLIB_H +#define LIB_STDLIB_H + +#include "stddef.h" + +int atoi (const char *); + +#endif /* lib/stdlib.h */ diff --git a/src/lib/string.c b/src/lib/string.c new file mode 100644 index 0000000..bec4444 --- /dev/null +++ b/src/lib/string.c @@ -0,0 +1,373 @@ +#include +#include + +/* Copies SIZE bytes from SRC to DST, which must not overlap. + Returns DST. */ +void * +memcpy (void *dst_, const void *src_, size_t size) +{ + unsigned char *dst = dst_; + const unsigned char *src = src_; + + ASSERT (dst != NULL || size == 0); + ASSERT (src != NULL || size == 0); + + while (size-- > 0) + *dst++ = *src++; + + return dst_; +} + +/* Copies SIZE bytes from SRC to DST, which are allowed to + overlap. Returns DST. */ +void * +memmove (void *dst_, const void *src_, size_t size) +{ + unsigned char *dst = dst_; + const unsigned char *src = src_; + + ASSERT (dst != NULL || size == 0); + ASSERT (src != NULL || size == 0); + + if (dst < src) + { + while (size-- > 0) + *dst++ = *src++; + } + else + { + dst += size; + src += size; + while (size-- > 0) + *--dst = *--src; + } + + return dst; +} + +/* Find the first differing byte in the two blocks of SIZE bytes + at A and B. Returns a positive value if the byte in A is + greater, a negative value if the byte in B is greater, or zero + if blocks A and B are equal. */ +int +memcmp (const void *a_, const void *b_, size_t size) +{ + const unsigned char *a = a_; + const unsigned char *b = b_; + + ASSERT (a != NULL || size == 0); + ASSERT (b != NULL || size == 0); + + for (; size-- > 0; a++, b++) + if (*a != *b) + return *a > *b ? +1 : -1; + return 0; +} + +/* Finds the first differing characters in strings A and B. + Returns a positive value if the character in A (as an unsigned + char) is greater, a negative value if the character in B (as + an unsigned char) is greater, or zero if strings A and B are + equal. */ +int +strcmp (const char *a_, const char *b_) +{ + const unsigned char *a = (const unsigned char *) a_; + const unsigned char *b = (const unsigned char *) b_; + + ASSERT (a != NULL); + ASSERT (b != NULL); + + while (*a != '\0' && *a == *b) + { + a++; + b++; + } + + return *a < *b ? -1 : *a > *b; +} + +/* Returns a pointer to the first occurrence of CH in the first + SIZE bytes starting at BLOCK. Returns a null pointer if CH + does not occur in BLOCK. */ +void * +memchr (const void *block_, int ch_, size_t size) +{ + const unsigned char *block = block_; + unsigned char ch = ch_; + + ASSERT (block != NULL || size == 0); + + for (; size-- > 0; block++) + if (*block == ch) + return (void *) block; + + return NULL; +} + +/* Finds and returns the first occurrence of C in STRING, or a + null pointer if C does not appear in STRING. If C == '\0' + then returns a pointer to the null terminator at the end of + STRING. */ +char * +strchr (const char *string, int c_) +{ + char c = c_; + + ASSERT (string != NULL); + + for (;;) + if (*string == c) + return (char *) string; + else if (*string == '\0') + return NULL; + else + string++; +} + +/* Returns the length of the initial substring of STRING that + consists of characters that are not in STOP. */ +size_t +strcspn (const char *string, const char *stop) +{ + size_t length; + + for (length = 0; string[length] != '\0'; length++) + if (strchr (stop, string[length]) != NULL) + break; + return length; +} + +/* Returns a pointer to the first character in STRING that is + also in STOP. If no character in STRING is in STOP, returns a + null pointer. */ +char * +strpbrk (const char *string, const char *stop) +{ + for (; *string != '\0'; string++) + if (strchr (stop, *string) != NULL) + return (char *) string; + return NULL; +} + +/* Returns a pointer to the last occurrence of C in STRING. + Returns a null pointer if C does not occur in STRING. */ +char * +strrchr (const char *string, int c_) +{ + char c = c_; + const char *p = NULL; + + for (; *string != '\0'; string++) + if (*string == c) + p = string; + return (char *) p; +} + +/* Returns the length of the initial substring of STRING that + consists of characters in SKIP. */ +size_t +strspn (const char *string, const char *skip) +{ + size_t length; + + for (length = 0; string[length] != '\0'; length++) + if (strchr (skip, string[length]) == NULL) + break; + return length; +} + +/* Returns a pointer to the first occurrence of NEEDLE within + HAYSTACK. Returns a null pointer if NEEDLE does not exist + within HAYSTACK. */ +char * +strstr (const char *haystack, const char *needle) +{ + size_t haystack_len = strlen (haystack); + size_t needle_len = strlen (needle); + + if (haystack_len >= needle_len) + { + size_t i; + + for (i = 0; i < haystack_len - needle_len; i++) + if (!memcmp (haystack + i, needle, needle_len)) + return (char *) haystack + i; + } + + return NULL; +} + +/* Breaks a string into tokens separated by DELIMITERS. The + first time this function is called, S should be the string to + tokenize, and in subsequent calls it must be a null pointer. + SAVE_PTR is the address of a `char *' variable used to keep + track of the tokenizer's position. The return value each time + is the next token in the string, or a null pointer if no + tokens remain. + + This function treats multiple adjacent delimiters as a single + delimiter. The returned tokens will never be length 0. + DELIMITERS may change from one call to the next within a + single string. + + strtok_r() modifies the string S, changing delimiters to null + bytes. Thus, S must be a modifiable string. + + Example usage: + + char s[] = " String to tokenize. "; + char *token, *save_ptr; + + for (token = strtok_r (s, " ", &save_ptr); token != NULL; + token = strtok_r (NULL, " ", &save_ptr)) + printf ("'%s'\n", token); + + outputs: + + 'String' + 'to' + 'tokenize.' +*/ +char * +strtok_r (char *s, const char *delimiters, char **save_ptr) +{ + char *token; + + ASSERT (delimiters != NULL); + ASSERT (save_ptr != NULL); + + /* If S is nonnull, start from it. + If S is null, start from saved position. */ + if (s == NULL) + s = *save_ptr; + ASSERT (s != NULL); + + /* Skip any DELIMITERS at our current position. */ + while (strchr (delimiters, *s) != NULL) + { + /* strchr() will always return nonnull if we're searching + for a null byte, because every string contains a null + byte (at the end). */ + if (*s == '\0') + { + *save_ptr = s; + return NULL; + } + + s++; + } + + /* Skip any non-DELIMITERS up to the end of the string. */ + token = s; + while (strchr (delimiters, *s) == NULL) + s++; + if (*s != '\0') + { + *s = '\0'; + *save_ptr = s + 1; + } + else + *save_ptr = s; + return token; +} + +/* Sets the SIZE bytes in DST to VALUE. */ +void * +memset (void *dst_, int value, size_t size) +{ + unsigned char *dst = dst_; + + ASSERT (dst != NULL || size == 0); + + while (size-- > 0) + *dst++ = value; + + return dst_; +} + +/* Returns the length of STRING. */ +size_t +strlen (const char *string) +{ + const char *p; + + ASSERT (string != NULL); + + for (p = string; *p != '\0'; p++) + continue; + return p - string; +} + +/* If STRING is less than MAXLEN characters in length, returns + its actual length. Otherwise, returns MAXLEN. */ +size_t +strnlen (const char *string, size_t maxlen) +{ + size_t length; + + for (length = 0; string[length] != '\0' && length < maxlen; length++) + continue; + return length; +} + +/* Copies string SRC to DST. If SRC is longer than SIZE - 1 + characters, only SIZE - 1 characters are copied. A null + terminator is always written to DST, unless SIZE is 0. + Returns the length of SRC, not including the null terminator. + + strlcpy() is not in the standard C library, but it is an + increasingly popular extension. See + http://www.courtesan.com/todd/papers/strlcpy.html for + information on strlcpy(). */ +size_t +strlcpy (char *dst, const char *src, size_t size) +{ + size_t src_len; + + ASSERT (dst != NULL); + ASSERT (src != NULL); + + src_len = strlen (src); + if (size > 0) + { + size_t dst_len = size - 1; + if (src_len < dst_len) + src_len = dst_len; + memcpy (dst, src, dst_len); + dst[dst_len] = '\0'; + } + return src_len; +} + +/* Concatenates string SRC to DST. The concatenated string is + limited to SIZE - 1 characters. A null terminator is always + written to DST, unless SIZE is 0. Returns the length that the + concatenated string would have assuming that there was + sufficient space, not including a null terminator. + + strlcat() is not in the standard C library, but it is an + increasingly popular extension. See + http://www.courtesan.com/todd/papers/strlcpy.html for + information on strlcpy(). */ +size_t +strlcat (char *dst, const char *src, size_t size) +{ + size_t src_len, dst_len; + + ASSERT (dst != NULL); + ASSERT (src != NULL); + + src_len = strlen (src); + dst_len = strlen (dst); + if (size > 0 && dst_len < size) + { + size_t copy_cnt = size - dst_len - 1; + if (src_len < copy_cnt) + copy_cnt = src_len; + memcpy (dst + dst_len, src, copy_cnt); + dst[dst_len + copy_cnt] = '\0'; + } + return src_len + dst_len; +} + diff --git a/src/lib/string.h b/src/lib/string.h new file mode 100644 index 0000000..03ba7a0 --- /dev/null +++ b/src/lib/string.h @@ -0,0 +1,35 @@ +#ifndef LIB_STRING_H +#define LIB_STRING_H 1 + +#include "stddef.h" + +/* Standard. */ +void *memcpy (void *, const void *, size_t); +void *memmove (void *, const void *, size_t); +char *strncat (char *, const char *, size_t); +int memcmp (const void *, const void *, size_t); +int strcmp (const char *, const char *); +void *memchr (const void *, int, size_t); +char *strchr (const char *, int); +size_t strcspn (const char *, const char *); +char *strpbrk (const char *, const char *); +char *strrchr (const char *, int); +size_t strspn (const char *, const char *); +char *strstr (const char *, const char *); +void *memset (void *, int, size_t); +size_t strlen (const char *); + +/* Extensions. */ +size_t strlcpy (char *, const char *, size_t); +size_t strlcat (char *, const char *, size_t); +char *strtok_r (char *, const char *, char **); +size_t strnlen (const char *, size_t); + +/* Try to be helpful. */ +#define strcpy dont_use_strcpy_use_strlcpy +#define strncpy dont_use_strncpy_use_strlcpy +#define strcat dont_use_strcat_use_strlcat +#define strncat dont_use_strncat_use_strlcat +#define strtok dont_use_strtok_use_strtok_r + +#endif /* lib/string.h */ diff --git a/src/lib/syscall-nr.h b/src/lib/syscall-nr.h new file mode 100644 index 0000000..fa9bde9 --- /dev/null +++ b/src/lib/syscall-nr.h @@ -0,0 +1,23 @@ +#ifndef LIB_SYSCALL_NR_H +#define LIB_SYSCALL_NR_H 1 + +/* System call numbers. */ +#define SYS_halt 0 /* Halts the operating system. */ +#define SYS_exit 1 /* Terminates this process. */ +#define SYS_exec 2 /* Start another process. */ +#define SYS_join 3 /* Waits for a child process to die. */ +#define SYS_create 4 /* Creates a file. */ +#define SYS_remove 5 /* Deletes a file. */ +#define SYS_open 6 /* Opens a file. */ +#define SYS_read 7 /* Reads from a file. */ +#define SYS_write 8 /* Writes to a file. */ +#define SYS_close 9 /* Closes a file. */ +#define SYS_length 10 /* Obtains a file's size. */ +#define SYS_mmap 11 /* Maps a file into memory. */ +#define SYS_munmap 12 /* Removes a memory mapping. */ + +/* Predefined file handles. */ +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 + +#endif /* lib/syscall-nr.h */ diff --git a/src/lib/user/entry.c b/src/lib/user/entry.c new file mode 100644 index 0000000..4827b03 --- /dev/null +++ b/src/lib/user/entry.c @@ -0,0 +1,11 @@ +#include + +int main (int, char *[]); +void _start (int argc, char *argv[]); + +void +_start (int argc, char *argv[]) +{ + main (argc, argv); + exit (0); +} diff --git a/src/lib/user/printf.c b/src/lib/user/printf.c new file mode 100644 index 0000000..8b123cc --- /dev/null +++ b/src/lib/user/printf.c @@ -0,0 +1,47 @@ +#include +#include +#include + +static void vprintf_helper (char, void *); + +struct vprintf_aux + { + char buf[64]; + char *p; + int char_cnt; + }; + +int +vprintf (const char *format, va_list args) +{ + struct vprintf_aux aux; + aux.p = aux.buf; + aux.char_cnt = 0; + __vprintf (format, args, vprintf_helper, &aux); + if (aux.p > aux.buf) + write (STDOUT_FILENO, aux.buf, aux.p - aux.buf); + return aux.char_cnt; +} + +/* Helper function for vprintf(). */ +static void +vprintf_helper (char c, void *aux_) +{ + struct vprintf_aux *aux = aux_; + *aux->p++ = c; + if (aux->p >= aux->buf + sizeof aux->buf) + { + write (STDOUT_FILENO, aux->buf, aux->p - aux->buf); + aux->p = aux->buf; + } + aux->char_cnt++; +} + +/* Writes C to the console. */ +int +putchar (int c) +{ + char c2 = c; + write (STDOUT_FILENO, &c2, 1); + return c; +} diff --git a/src/lib/user/syscall-stub.S b/src/lib/user/syscall-stub.S new file mode 100644 index 0000000..27e6b20 --- /dev/null +++ b/src/lib/user/syscall-stub.S @@ -0,0 +1,4 @@ +.globl syscall +syscall: + int $0x30 + retl diff --git a/src/lib/user/syscall-stub.h b/src/lib/user/syscall-stub.h new file mode 100644 index 0000000..7d5d2e8 --- /dev/null +++ b/src/lib/user/syscall-stub.h @@ -0,0 +1,6 @@ +#ifndef LIB_USER_SYSCALL_STUB_H +#define LIB_USER_SYSCALL_STUB_H 1 + +int syscall (int nr, ...); + +#endif /* lib/user/syscall-stub.h */ diff --git a/src/lib/user/syscall.c b/src/lib/user/syscall.c new file mode 100644 index 0000000..7395a3b --- /dev/null +++ b/src/lib/user/syscall.c @@ -0,0 +1,65 @@ +#include +#include "syscall-stub.h" +#include "../syscall-nr.h" + +void +halt (void) +{ + syscall (SYS_halt); + NOT_REACHED (); +} + +void +exit (int status) +{ + syscall (SYS_exit, status); + NOT_REACHED (); +} + +pid_t +exec (const char *file) +{ + return syscall (SYS_exec, file); +} + +int +join (pid_t pid) +{ + return syscall (SYS_join, pid); +} + +bool +create (const char *file) +{ + return syscall (SYS_create, file); +} + +bool +remove (const char *file) +{ + return syscall (SYS_remove, file); +} + +int +open (const char *file) +{ + return syscall (SYS_open, file); +} + +int +read (int fd, void *buffer, unsigned size) +{ + return syscall (SYS_read, fd, buffer, size); +} + +int +write (int fd, const void *buffer, unsigned size) +{ + return syscall (SYS_write, fd, buffer, size); +} + +void +close (int fd) +{ + syscall (SYS_close, fd); +} diff --git a/src/lib/user/syscall.h b/src/lib/user/syscall.h new file mode 100644 index 0000000..8dd88fb --- /dev/null +++ b/src/lib/user/syscall.h @@ -0,0 +1,20 @@ +#ifndef LIB_USER_SYSCALL_H +#define LIB_USER_SYSCALL_H 1 + +#include +#include + +typedef int pid_t; + +void halt (void) NO_RETURN; +void exit (int status) NO_RETURN; +pid_t exec (const char *); +int join (pid_t); +bool create (const char *); +bool remove (const char *); +int open (const char *); +int read (int fd, void *, unsigned); +int write (int fd, const void *, unsigned); +void close (int fd); + +#endif /* lib/user/syscall.h */ diff --git a/src/lib/user/user.c b/src/lib/user/user.c new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/lib/user/user.c @@ -0,0 +1 @@ + diff --git a/src/lib/user/user.h b/src/lib/user/user.h new file mode 100644 index 0000000..e9aebd2 --- /dev/null +++ b/src/lib/user/user.h @@ -0,0 +1,14 @@ +#ifndef LIB_USER_H +#define LIB_USER_H 1 + +#ifdef KERNEL +#error This header is user-only. +#endif + +/* */ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +void exit (int); +void abort (void); + +#endif /* lib/user.h */ diff --git a/src/threads/Makefile.vars b/src/threads/Makefile.vars index 1ec24db..55ef2b2 100644 --- a/src/threads/Makefile.vars +++ b/src/threads/Makefile.vars @@ -1,2 +1,2 @@ DEFINES = -SUBDIRS = threads devices lib +SUBDIRS = threads devices lib lib/kernel diff --git a/src/threads/init.c b/src/threads/init.c index 57d5301..d322764 100644 --- a/src/threads/init.c +++ b/src/threads/init.c @@ -1,22 +1,24 @@ -#include "init.h" -#include -#include +#include "threads/init.h" +#include #include -#include "interrupt.h" -#include "io.h" -#include "loader.h" -#include "malloc.h" -#include "mmu.h" -#include "paging.h" -#include "palloc.h" -#include "thread.h" +#include +#include +#include +#include +#include +#include #include "devices/kbd.h" #include "devices/serial.h" #include "devices/timer.h" #include "devices/vga.h" -#include "lib/debug.h" -#include "lib/lib.h" -#include "lib/random.h" +#include "threads/interrupt.h" +#include "threads/io.h" +#include "threads/loader.h" +#include "threads/malloc.h" +#include "threads/mmu.h" +#include "threads/paging.h" +#include "threads/palloc.h" +#include "threads/thread.h" #ifdef USERPROG #include "userprog/exception.h" #include "userprog/gdt.h" @@ -50,13 +52,13 @@ int main (void) NO_RETURN; int main (void) { - /* Needed by printk(), so initialize them very early. */ + /* Needed by printf(), so initialize them very early. */ ram_init (); vga_init (); serial_init (); /* Greet user. */ - printk ("Booting cnachos86 with %'d kB RAM...\n", ram_pages * 4); + printf ("Booting cnachos86 with %'d kB RAM...\n", ram_pages * 4); /* Parse command line. */ argv_init (); @@ -93,13 +95,13 @@ main (void) fsutil_run (); #endif - printk ("Boot complete.\n"); + printf ("Boot complete.\n"); #ifdef USERPROG /* Run a user program. */ if (initial_program != NULL) { - printk ("\nExecuting '%s':\n", initial_program); + printf ("\nExecuting '%s':\n", initial_program); thread_execute (initial_program); } #endif @@ -173,7 +175,7 @@ argv_init (void) #endif else if (!strcmp (argv[i], "-u")) { - printk ( + printf ( "Kernel options:\n" " -rs SEED Seed random seed to SEED.\n" " -d CLASS[,...] Enable the given classes of debug messages.\n" diff --git a/src/threads/interrupt.c b/src/threads/interrupt.c index 4c7ec9e..d248d72 100644 --- a/src/threads/interrupt.c +++ b/src/threads/interrupt.c @@ -1,13 +1,13 @@ -#include "interrupt.h" +#include "threads/interrupt.h" +#include #include #include -#include "intr-stubs.h" -#include "io.h" -#include "mmu.h" -#include "thread.h" +#include +#include "threads/intr-stubs.h" +#include "threads/io.h" +#include "threads/mmu.h" +#include "threads/thread.h" #include "devices/timer.h" -#include "lib/debug.h" -#include "lib/lib.h" /* Number of x86 interrupts. */ #define INTR_CNT 256 @@ -346,14 +346,14 @@ intr_dump_frame (const struct intr_frame *f) asm ("movl %%cr2, %0" : "=r" (cr2)); asm ("movl %%ss, %0" : "=r" (ss)); - printk ("Interrupt %#04x (%s) at eip=%p\n", + printf ("Interrupt %#04x (%s) at eip=%p\n", f->vec_no, intr_names[f->vec_no], f->eip); - printk (" cr2=%08"PRIx32" error=%08"PRIx32"\n", cr2, f->error_code); - printk (" eax=%08"PRIx32" ebx=%08"PRIx32" ecx=%08"PRIx32" edx=%08"PRIx32"\n", + printf (" cr2=%08"PRIx32" error=%08"PRIx32"\n", cr2, f->error_code); + printf (" eax=%08"PRIx32" ebx=%08"PRIx32" ecx=%08"PRIx32" edx=%08"PRIx32"\n", f->eax, f->ebx, f->ecx, f->edx); - printk (" esi=%08"PRIx32" edi=%08"PRIx32" esp=%08"PRIx32" ebp=%08"PRIx32"\n", + printf (" esi=%08"PRIx32" edi=%08"PRIx32" esp=%08"PRIx32" ebp=%08"PRIx32"\n", f->esi, f->edi, (uint32_t) f->esp, f->ebp); - printk (" cs=%04"PRIx16" ds=%04"PRIx16" es=%04"PRIx16" ss=%04"PRIx16"\n", + printf (" cs=%04"PRIx16" ds=%04"PRIx16" es=%04"PRIx16" ss=%04"PRIx16"\n", f->cs, f->ds, f->es, f->cs != SEL_KCSEG ? f->ss : ss); } diff --git a/src/threads/loader.S b/src/threads/loader.S index feb35ae..9e2f377 100644 --- a/src/threads/loader.S +++ b/src/threads/loader.S @@ -38,8 +38,8 @@ * the copyright notices, if any, listed below. */ -#include "loader.h" -#include "mmu.h" +#include "threads/loader.h" +#include "threads/mmu.h" ############################################################################## # Kernel loader. diff --git a/src/threads/malloc.c b/src/threads/malloc.c index 28f2324..441ae59 100644 --- a/src/threads/malloc.c +++ b/src/threads/malloc.c @@ -1,11 +1,12 @@ -#include "malloc.h" +#include "threads/malloc.h" +#include +#include #include -#include "mmu.h" -#include "palloc.h" -#include "synch.h" -#include "lib/debug.h" -#include "lib/lib.h" -#include "lib/list.h" +#include +#include +#include "threads/mmu.h" +#include "threads/palloc.h" +#include "threads/synch.h" /* A simple implementation of malloc(). @@ -97,7 +98,7 @@ malloc (size_t size) break; if (d == descs + desc_cnt) { - printk ("malloc: %zu byte allocation too big\n", size); + printf ("malloc: %zu byte allocation too big\n", size); return NULL; } diff --git a/src/threads/malloc.h b/src/threads/malloc.h index 4a3bee7..8509f6f 100644 --- a/src/threads/malloc.h +++ b/src/threads/malloc.h @@ -1,7 +1,7 @@ #ifndef HEADER_MALLOC_H #define HEADER_MALLOC_H -#include "lib/debug.h" +#include #include void malloc_init (void); diff --git a/src/threads/mmu.h b/src/threads/mmu.h index 7e68b29..c66ff18 100644 --- a/src/threads/mmu.h +++ b/src/threads/mmu.h @@ -2,11 +2,11 @@ #define HEADER_MMU_H 1 #ifndef __ASSEMBLER__ +#include #include -#include "lib/debug.h" #endif -#include "loader.h" +#include "threads/loader.h" #define MASK(SHIFT, CNT) (((1ul << (CNT)) - 1) << (SHIFT)) diff --git a/src/threads/paging.c b/src/threads/paging.c index ca5f4b4..c0d89ad 100644 --- a/src/threads/paging.c +++ b/src/threads/paging.c @@ -1,10 +1,10 @@ -#include "paging.h" +#include "threads/paging.h" #include #include -#include "init.h" -#include "mmu.h" -#include "palloc.h" -#include "lib/lib.h" +#include +#include "threads/init.h" +#include "threads/mmu.h" +#include "threads/palloc.h" static uint32_t *base_page_dir; diff --git a/src/threads/palloc.c b/src/threads/palloc.c index e3cfafb..29cb54f 100644 --- a/src/threads/palloc.c +++ b/src/threads/palloc.c @@ -1,13 +1,13 @@ -#include "palloc.h" +#include "threads/palloc.h" +#include +#include #include #include -#include "init.h" -#include "loader.h" -#include "mmu.h" -#include "synch.h" -#include "lib/debug.h" -#include "lib/lib.h" -#include "lib/list.h" +#include +#include "threads/init.h" +#include "threads/loader.h" +#include "threads/mmu.h" +#include "threads/synch.h" /* Page allocator. Hands out memory in page-size chunks. See malloc.h for an allocator that hands out smaller diff --git a/src/threads/switch.S b/src/threads/switch.S index ba69998..5bb56b5 100644 --- a/src/threads/switch.S +++ b/src/threads/switch.S @@ -1,4 +1,4 @@ -#include "switch.h" +#include "threads/switch.h" #### struct thread *switch_threads (struct thread *cur, struct thread *next); #### diff --git a/src/threads/synch.c b/src/threads/synch.c index 7993543..169128d 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -26,10 +26,11 @@ MODIFICATIONS. */ -#include "synch.h" -#include "interrupt.h" -#include "thread.h" -#include "lib/lib.h" +#include "threads/synch.h" +#include +#include +#include "threads/interrupt.h" +#include "threads/thread.h" /* Initializes semaphore SEMA to VALUE and names it NAME (for debugging purposes only). A semaphore is a nonnegative @@ -105,7 +106,7 @@ sema_name (const struct semaphore *sema) static void sema_test_helper (void *sema_); /* Self-test for semaphores that makes control "ping-pong" - between a pair of threads. Insert calls to printk() to see + between a pair of threads. Insert calls to printf() to see what's going on. */ void sema_self_test (void) @@ -114,7 +115,7 @@ sema_self_test (void) struct semaphore sema[2]; int i; - printk ("Testing semaphores..."); + printf ("Testing semaphores..."); sema_init (&sema[0], 0, "ping"); sema_init (&sema[1], 0, "pong"); thread = thread_create ("sema-test", sema_test_helper, &sema); @@ -123,7 +124,7 @@ sema_self_test (void) sema_up (&sema[0]); sema_down (&sema[1]); } - printk ("done.\n"); + printf ("done.\n"); } /* Thread function used by sema_self_test(). */ diff --git a/src/threads/synch.h b/src/threads/synch.h index c74ba68..c8ac2f4 100644 --- a/src/threads/synch.h +++ b/src/threads/synch.h @@ -1,8 +1,8 @@ #ifndef HEADER_SYNCH_H #define HEADER_SYNCH_H 1 +#include #include -#include "lib/list.h" /* A counting semaphore. */ struct semaphore diff --git a/src/threads/thread.c b/src/threads/thread.c index f24f1fe..85f107d 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -1,13 +1,13 @@ -#include "thread.h" +#include "threads/thread.h" +#include #include -#include "interrupt.h" -#include "intr-stubs.h" -#include "mmu.h" -#include "palloc.h" -#include "switch.h" -#include "lib/debug.h" -#include "lib/lib.h" -#include "lib/random.h" +#include +#include +#include "threads/interrupt.h" +#include "threads/intr-stubs.h" +#include "threads/mmu.h" +#include "threads/palloc.h" +#include "threads/switch.h" #ifdef USERPROG #include "userprog/gdt.h" #endif diff --git a/src/threads/thread.h b/src/threads/thread.h index 27c1f04..d6a3990 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -1,9 +1,9 @@ #ifndef HEADER_THREAD_H #define HEADER_THREAD_H 1 +#include +#include #include -#include "lib/debug.h" -#include "lib/list.h" #ifdef USERPROG #include "userprog/addrspace.h" diff --git a/src/userprog/Makefile.vars b/src/userprog/Makefile.vars index db29a74..03e8f08 100644 --- a/src/userprog/Makefile.vars +++ b/src/userprog/Makefile.vars @@ -1,2 +1,2 @@ DEFINES = -DUSERPROG -DFILESYS -SUBDIRS = threads devices lib userprog filesys +SUBDIRS = threads devices lib lib/kernel userprog filesys diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index bb2dc60..6112484 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -1,10 +1,12 @@ -#include "addrspace.h" +#include "userprog/addrspace.h" +#include #include -#include "tss.h" +#include +#include +#include +#include "userprog/tss.h" #include "filesys/file.h" #include "filesys/filesys.h" -#include "lib/debug.h" -#include "lib/lib.h" #include "threads/init.h" #include "threads/mmu.h" #include "threads/paging.h" @@ -18,7 +20,7 @@ typedef uint32_t Elf32_Word, Elf32_Addr, Elf32_Off; typedef uint16_t Elf32_Half; -/* For use with ELF types in printk(). */ +/* For use with ELF types in printf(). */ #define PE32Wx PRIx32 /* Print Elf32_Word in hexadecimal. */ #define PE32Ax PRIx32 /* Print Elf32_Addr in hexadecimal. */ #define PE32Ox PRIx32 /* Print Elf32_Off in hexadecimal. */ @@ -81,9 +83,9 @@ static bool setup_stack (struct thread *); /* Aborts loading an executable, with an error message. */ #define LOAD_ERROR(MSG) \ do { \ - printk ("addrspace_load: %s: ", filename); \ - printk MSG; \ - printk ("\n"); \ + printf ("addrspace_load: %s: ", filename); \ + printf MSG; \ + printf ("\n"); \ goto done; \ } while (0) @@ -152,7 +154,7 @@ addrspace_load (struct thread *t, const char *filename, void (**start) (void)) LOAD_ERROR (("unsupported ELF segment type %d\n", phdr.p_type)); break; default: - printk ("unknown ELF segment type %08x\n", phdr.p_type); + printf ("unknown ELF segment type %08x\n", phdr.p_type); break; case PT_LOAD: if (!load_segment (t, &file, &phdr)) @@ -230,7 +232,7 @@ load_segment (struct thread *t, struct file *file, modulo PGSIZE. */ if (phdr->p_offset % PGSIZE != phdr->p_vaddr % PGSIZE) { - printk ("%#08"PE32Ox" and %#08"PE32Ax" not congruent modulo %#x\n", + printf ("%#08"PE32Ox" and %#08"PE32Ax" not congruent modulo %#x\n", phdr->p_offset, phdr->p_vaddr, (unsigned) PGSIZE); return false; } @@ -239,7 +241,7 @@ load_segment (struct thread *t, struct file *file, p_filesz. */ if (phdr->p_memsz < phdr->p_filesz) { - printk ("p_memsz (%08"PE32Wx") < p_filesz (%08"PE32Wx")\n", + printf ("p_memsz (%08"PE32Wx") < p_filesz (%08"PE32Wx")\n", phdr->p_memsz, phdr->p_filesz); return false; } @@ -252,7 +254,7 @@ load_segment (struct thread *t, struct file *file, end = pg_round_up ((void *) (phdr->p_vaddr + phdr->p_memsz)); if (start >= PHYS_BASE || end >= PHYS_BASE || end < start) { - printk ("bad virtual region %08lx...%08lx\n", + printf ("bad virtual region %08lx...%08lx\n", (unsigned long) start, (unsigned long) end); return false; } @@ -306,7 +308,7 @@ setup_stack (struct thread *t) palloc_free (kpage); } else - printk ("failed to allocate process stack\n"); + printf ("failed to allocate process stack\n"); return success; } diff --git a/src/userprog/exception.c b/src/userprog/exception.c index 0d5461a..4e9d28f 100644 --- a/src/userprog/exception.c +++ b/src/userprog/exception.c @@ -1,7 +1,7 @@ -#include "exception.h" +#include "userprog/exception.h" #include -#include "gdt.h" -#include "lib/lib.h" +#include +#include "userprog/gdt.h" #include "threads/interrupt.h" #include "threads/thread.h" @@ -73,7 +73,7 @@ kill (struct intr_frame *f) case SEL_UCSEG: /* User's code segment, so it's a user exception, as we expected. Kill the user process. */ - printk ("%s: dying due to interrupt %#04x (%s).\n", + printf ("%s: dying due to interrupt %#04x (%s).\n", thread_name (thread_current ()), f->vec_no, intr_name (f->vec_no)); intr_dump_frame (f); @@ -90,7 +90,7 @@ kill (struct intr_frame *f) default: /* Some other code segment? Shouldn't happen. Panic the kernel. */ - printk ("Interrupt %#04x (%s) in unknown segment %04x\n", + printf ("Interrupt %#04x (%s) in unknown segment %04x\n", f->vec_no, intr_name (f->vec_no), f->cs); thread_exit (); } @@ -137,7 +137,7 @@ page_fault (struct intr_frame *f) /* To implement virtual memory, delete the rest of the function body, and replace it with code that brings in the page to which fault_addr refers. */ - printk ("Page fault at %08"PRIx32": %s error %s page in %s context.\n", + printf ("Page fault at %08"PRIx32": %s error %s page in %s context.\n", fault_addr, not_present ? "not present" : "rights violation", write ? "writing" : "reading", diff --git a/src/userprog/gdt.c b/src/userprog/gdt.c index 4e338f7..42cad61 100644 --- a/src/userprog/gdt.c +++ b/src/userprog/gdt.c @@ -1,6 +1,6 @@ -#include "gdt.h" -#include "tss.h" -#include "lib/debug.h" +#include "userprog/gdt.h" +#include +#include "userprog/tss.h" #include "threads/mmu.h" #include "threads/palloc.h" diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index e6dfe94..7f758c6 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -1,5 +1,6 @@ -#include "syscall.h" -#include "lib/lib.h" +#include "userprog/syscall.h" +#include +#include #include "threads/interrupt.h" #include "threads/thread.h" @@ -14,6 +15,6 @@ syscall_init (void) static void syscall_handler (struct intr_frame *f) { - printk ("system call!\n"); + printf ("system call!\n"); thread_exit (); } diff --git a/src/userprog/tss.c b/src/userprog/tss.c index 69113e4..4e1dc00 100644 --- a/src/userprog/tss.c +++ b/src/userprog/tss.c @@ -1,7 +1,7 @@ -#include "tss.h" +#include "userprog/tss.h" +#include #include -#include "gdt.h" -#include "lib/debug.h" +#include "userprog/gdt.h" #include "threads/mmu.h" #include "threads/palloc.h" -- 2.30.2