├── user ├── newlib │ ├── include │ │ ├── fcntl.h │ │ ├── sys │ │ │ ├── file.h │ │ │ ├── custom_file.h │ │ │ ├── fcntl.h │ │ │ ├── string.h │ │ │ ├── dir.h │ │ │ ├── resource.h │ │ │ ├── dirent.h │ │ │ ├── utime.h │ │ │ ├── param.h │ │ │ ├── times.h │ │ │ ├── lock.h │ │ │ ├── stdio.h │ │ │ ├── timeb.h │ │ │ ├── _intsup.h │ │ │ ├── _stdint.h │ │ │ ├── wait.h │ │ │ ├── sched.h │ │ │ ├── _timespec.h │ │ │ └── _types.h │ │ ├── machine │ │ │ ├── termios.h │ │ │ ├── ansi.h │ │ │ ├── param.h │ │ │ ├── _types.h │ │ │ ├── malloc.h │ │ │ ├── stdlib.h │ │ │ ├── time.h │ │ │ ├── endian.h │ │ │ ├── types.h │ │ │ └── setjmp-dj.h │ │ ├── newlib.h │ │ ├── unistd.h │ │ ├── utmp.h │ │ ├── termios.h │ │ ├── errno.h │ │ ├── paths.h │ │ ├── utime.h │ │ ├── regdef.h │ │ ├── fastmath.h │ │ ├── dirent.h │ │ ├── envlock.h │ │ ├── setjmp.h │ │ ├── alloca.h │ │ ├── envz.h │ │ ├── signal.h │ │ ├── libgen.h │ │ ├── strings.h │ │ ├── wctype.h │ │ ├── _syslist.h │ │ ├── assert.h │ │ ├── argz.h │ │ ├── tar.h │ │ ├── locale.h │ │ ├── search.h │ │ ├── wordexp.h │ │ ├── stdio_ext.h │ │ └── unctrl.h │ └── arch │ │ └── x86 │ │ └── libc.a ├── include │ └── moridin │ │ └── syscall.h ├── sys │ ├── arch │ │ └── x86 │ │ │ ├── crt0.S │ │ │ └── syscall.S │ ├── syscall_internal.h │ └── syscall.c ├── progs │ ├── init.c │ └── fork_test.c ├── user.ld └── Makefile ├── kernel ├── inc │ ├── lib │ │ ├── staticq.h │ │ ├── stdlib.h │ │ ├── stdarg.h │ │ ├── fmt │ │ │ ├── _printf.h │ │ │ ├── doscan.h │ │ │ └── doprnt.h │ │ ├── types.h │ │ ├── math.h │ │ ├── stdint.h │ │ ├── ctype.h │ │ ├── assert.h │ │ └── fmt.h │ ├── dev │ │ ├── block.h │ │ ├── ide │ │ │ └── lba.h │ │ ├── bochs.h │ │ ├── ide.h │ │ ├── serial.h │ │ └── serial │ │ │ └── 8250.h │ ├── kernel │ │ ├── compiler.h │ │ ├── loader.h │ │ ├── stack.h │ │ ├── init.h │ │ ├── proc_types.h │ │ ├── timer.h │ │ ├── elf.h │ │ ├── irq.h │ │ ├── syscall.h │ │ ├── symbols.h │ │ ├── mutex.h │ │ ├── sched.h │ │ ├── log.h │ │ ├── config.h │ │ ├── spinlock.h │ │ ├── test.h │ │ └── wait.h │ ├── mm │ │ ├── kmap.h │ │ ├── kmalloc.h │ │ ├── pages.h │ │ └── lmm_types.h │ └── fs │ │ └── initrd.h ├── lib │ ├── stdlib │ │ ├── atol.c │ │ ├── abs.c │ │ ├── rand.c │ │ ├── strtol.c │ │ ├── strtoul.c │ │ └── ctype.c │ ├── string │ │ ├── rindex.c │ │ ├── strncmp.c │ │ ├── strdup.c │ │ ├── strcat.c │ │ ├── strchr.c │ │ ├── strrchr.c │ │ ├── strstr.c │ │ ├── memset.c │ │ ├── strlen.c │ │ ├── strcpy.c │ │ ├── strncpy.c │ │ ├── strcmp.c │ │ └── memcmp.c │ └── fmt │ │ ├── _printf.c │ │ └── sscanf.c ├── arch │ └── x86 │ │ ├── proc.c │ │ ├── inc │ │ ├── syscall.h │ │ ├── page.h │ │ ├── sched.h │ │ ├── x86 │ │ │ └── macros.S │ │ ├── io.h │ │ ├── seg.h │ │ ├── cpu.h │ │ ├── idtr.h │ │ ├── atomic.h │ │ ├── fork.h │ │ ├── vm.h │ │ └── irq.h │ │ ├── atomic.S │ │ ├── syscall.c │ │ ├── irq_wrappers.S │ │ ├── bzero.S │ │ ├── cpu.c │ │ ├── backtrace.c │ │ ├── linker.ld │ │ ├── startup.c │ │ ├── syscall_entry.S │ │ ├── 8253.c │ │ └── pic.c ├── dev │ ├── bochs │ │ └── bochs.c │ ├── ide │ │ └── ide.c │ └── serial │ │ └── serial.c ├── tools │ └── symbols_section_offset.sh ├── kernel │ ├── timer.c │ ├── symbols.c │ ├── wait.c │ ├── syscall.c │ ├── mutex.c │ ├── loader.c │ ├── log.c │ ├── kernel.c │ ├── irq.c │ ├── spinlock.c │ └── fork.c ├── mm │ ├── malloc │ │ ├── malloc_lmm.c │ │ ├── free.c │ │ ├── sfree.c │ │ ├── smalloc.c │ │ ├── malloc.c │ │ ├── calloc.c │ │ ├── realloc.c │ │ ├── memalign.c │ │ ├── malloc_internal.h │ │ └── smemalign.c │ ├── lmm │ │ ├── lmm_init.c │ │ ├── lmm_free_page.c │ │ ├── lmm_alloc_page.c │ │ ├── lmm_alloc_aligned.c │ │ ├── lmm_avail.c │ │ ├── lmm_remove_free.c │ │ └── README │ └── memory.c └── Makefile ├── qemu.sh ├── boot ├── grub.cfg └── initrd │ └── hello.txt ├── tools ├── Makefile └── create_disk.sh ├── .gitignore ├── config.mk ├── Makefile └── doc └── vmcopy.txt /user/newlib/include/fcntl.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /user/newlib/include/sys/file.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /user/newlib/include/machine/termios.h: -------------------------------------------------------------------------------- 1 | #define __MAX_BAUD B4000000 2 | -------------------------------------------------------------------------------- /user/newlib/include/machine/ansi.h: -------------------------------------------------------------------------------- 1 | /* dummy header file to support BSD compiler */ 2 | -------------------------------------------------------------------------------- /user/newlib/include/machine/param.h: -------------------------------------------------------------------------------- 1 | /* Place holder for machine-specific param.h. */ 2 | -------------------------------------------------------------------------------- /user/newlib/include/sys/custom_file.h: -------------------------------------------------------------------------------- 1 | #error System-specific custom_file.h is missing. 2 | 3 | -------------------------------------------------------------------------------- /kernel/inc/lib/staticq.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file staticq.h 3 | * 4 | */ 5 | #include 6 | -------------------------------------------------------------------------------- /user/newlib/arch/x86/libc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmatlack/moridin/HEAD/user/newlib/arch/x86/libc.a -------------------------------------------------------------------------------- /qemu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | qemu-system-i386 -m 1024 -serial stdio -display none -cdrom OS.iso -enable-kvm 4 | -------------------------------------------------------------------------------- /user/newlib/include/newlib.h: -------------------------------------------------------------------------------- 1 | /* dummy file for external tools to use. Real file is created by 2 | newlib configuration. */ 3 | -------------------------------------------------------------------------------- /user/newlib/include/sys/fcntl.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_FCNTL_H_ 2 | #define _SYS_FCNTL_H_ 3 | #include 4 | #endif 5 | -------------------------------------------------------------------------------- /boot/grub.cfg: -------------------------------------------------------------------------------- 1 | default=0 2 | timeout=3 3 | 4 | menuentry "moridin" { 5 | multiboot /boot/KERNEL.o 6 | module /boot/initrd.img 7 | } 8 | -------------------------------------------------------------------------------- /user/newlib/include/unistd.h: -------------------------------------------------------------------------------- 1 | #ifndef _UNISTD_H_ 2 | #define _UNISTD_H_ 3 | 4 | # include 5 | 6 | #endif /* _UNISTD_H_ */ 7 | -------------------------------------------------------------------------------- /user/newlib/include/utmp.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | #include 5 | #ifdef __cplusplus 6 | } 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /user/newlib/include/termios.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | #include 5 | #ifdef __cplusplus 6 | } 7 | #endif 8 | -------------------------------------------------------------------------------- /user/newlib/include/sys/string.h: -------------------------------------------------------------------------------- 1 | /* This is a dummy used as a placeholder for 2 | systems that need to have a special header file. */ 3 | -------------------------------------------------------------------------------- /kernel/lib/stdlib/atol.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | long 5 | atol(const char *str) 6 | { 7 | return strtol(str, NULL, 10); 8 | } 9 | -------------------------------------------------------------------------------- /user/newlib/include/machine/_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id$ 3 | */ 4 | 5 | #ifndef _MACHINE__TYPES_H 6 | #define _MACHINE__TYPES_H 7 | #include 8 | #endif 9 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all initrd 2 | 3 | all: initrd 4 | 5 | initrd: create_initrd.c 6 | gcc -std=c99 create_initrd.c -o create_initrd 7 | 8 | clean: 9 | rm -f create_initrd 10 | -------------------------------------------------------------------------------- /kernel/arch/x86/proc.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/x86/proc.c 3 | */ 4 | #include 5 | 6 | void set_thread_regs(struct registers *regs) 7 | { 8 | CURRENT_THREAD->regs = regs; 9 | } 10 | -------------------------------------------------------------------------------- /user/newlib/include/machine/malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHMALLOC_H_ 2 | #define _MACHMALLOC_H_ 3 | 4 | /* place holder so platforms may add malloc.h extensions */ 5 | 6 | #endif /* _MACHMALLOC_H_ */ 7 | 8 | 9 | -------------------------------------------------------------------------------- /user/newlib/include/machine/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHSTDLIB_H_ 2 | #define _MACHSTDLIB_H_ 3 | 4 | /* place holder so platforms may add stdlib.h extensions */ 5 | 6 | #endif /* _MACHSTDLIB_H_ */ 7 | 8 | 9 | -------------------------------------------------------------------------------- /kernel/inc/dev/block.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dev/block.h 3 | * 4 | * @brief Block Devices. 5 | * 6 | */ 7 | #ifndef __DEV_BLOCK_H__ 8 | #define __DEV_BLOCK_H__ 9 | 10 | #endif /* !__DEV_BLOCK_H__ */ 11 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/syscall.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/x86/syscall.h 3 | */ 4 | #ifndef __ARCH_X86_SYSCALL_H__ 5 | #define __ARCH_X86_SYSCALL_H__ 6 | 7 | void return_from_syscall(int ret); 8 | 9 | #endif /* !__ARCH_X86_SYSCALL_H__ */ 10 | -------------------------------------------------------------------------------- /user/newlib/include/sys/dir.h: -------------------------------------------------------------------------------- 1 | /* BSD predecessor of POSIX.1 and struct dirent */ 2 | 3 | #ifndef _SYS_DIR_H_ 4 | #define _SYS_DIR_H_ 5 | 6 | #include 7 | 8 | #define direct dirent 9 | 10 | #endif /*_SYS_DIR_H_*/ 11 | -------------------------------------------------------------------------------- /user/newlib/include/errno.h: -------------------------------------------------------------------------------- 1 | #ifndef __ERRNO_H__ 2 | #define __ERRNO_H__ 3 | 4 | #ifndef __error_t_defined 5 | typedef int error_t; 6 | #define __error_t_defined 1 7 | #endif 8 | 9 | #include 10 | 11 | #endif /* !__ERRNO_H__ */ 12 | -------------------------------------------------------------------------------- /kernel/inc/kernel/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_COMPILER_H__ 2 | #define __KERNEL_COMPILER_H__ 3 | 4 | #define __section(_s) __attribute__(( section( _s ) )) 5 | #define __aligned(_a) __attribute__(( aligned( _a ) )) 6 | 7 | #endif /* __KERNEL_COMPILER_H__ */ 8 | -------------------------------------------------------------------------------- /kernel/inc/kernel/loader.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/loader.h 3 | */ 4 | #ifndef __KERNEL_LOADER_H__ 5 | #define __KERNEL_LOADER_H__ 6 | 7 | #include 8 | 9 | int load_binary(struct vfs_file *exec); 10 | 11 | #endif /* !__KERNEL_LOADER_H__ */ 12 | -------------------------------------------------------------------------------- /user/newlib/include/paths.h: -------------------------------------------------------------------------------- 1 | #ifndef _PATHS_H_ 2 | #define _PATHS_H_ 3 | 4 | #define _PATH_DEV "/dev/" 5 | #define _PATH_DEVNULL "/dev/null" 6 | #define _PATH_DEVZERO "/dev/zero" 7 | #define _PATH_BSHELL "/bin/sh" 8 | 9 | #endif /* _PATHS_H_ */ 10 | -------------------------------------------------------------------------------- /user/newlib/include/utime.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include <_ansi.h> 6 | 7 | /* The utime function is defined in libc/sys//sys if it exists. */ 8 | #include 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /kernel/inc/kernel/stack.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/stack.h 3 | */ 4 | #ifndef __KERNEL_STACK_H__ 5 | #define __KERNEL_STACK_H__ 6 | 7 | #include 8 | 9 | int create_process_stack(int argc, char **argv); 10 | 11 | #endif /* !__KERNEL_STACK_H__ */ 12 | -------------------------------------------------------------------------------- /user/newlib/include/regdef.h: -------------------------------------------------------------------------------- 1 | /* regdef.h -- define register names. */ 2 | 3 | /* This is a standard include file for MIPS targets. Other target 4 | probably don't define it, and attempts to include this file will 5 | fail. */ 6 | 7 | #include 8 | -------------------------------------------------------------------------------- /user/newlib/include/fastmath.h: -------------------------------------------------------------------------------- 1 | #ifndef _FASTMATH_H_ 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | #define _FASTMATH_H_ 6 | 7 | #include 8 | #include 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | #endif /* _FASTMATH_H_ */ 14 | -------------------------------------------------------------------------------- /kernel/dev/bochs/bochs.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file bochs.c 3 | * 4 | * @brief Debug utility for the bochs machine emulator. 5 | * 6 | */ 7 | #include 8 | #include 9 | 10 | void bochs_putchar(char c) 11 | { 12 | outb(BOCHS_PUTCHAR_PORT, (u8) c); 13 | } 14 | -------------------------------------------------------------------------------- /kernel/inc/mm/kmap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mm/kmap.h 3 | */ 4 | #ifndef __MM_KMAP_H__ 5 | #define __MM_KMAP_H__ 6 | 7 | #include 8 | 9 | void kmap_init(void); 10 | 11 | void *kmap(struct page *); 12 | void kunmap(void *); 13 | 14 | #endif /* !__MM_KMAP_H__ */ 15 | -------------------------------------------------------------------------------- /tools/create_disk.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Make sure to change bochsrc if you change these values 4 | cylinders=306 5 | heads=4 6 | spt=17 7 | 8 | sectors="$(expr $cylinders \* $heads \* $spt)" 9 | 10 | dd if=/dev/zero of=DISK.$cylinders.$heads.$spt bs=512 count=$sectors 11 | -------------------------------------------------------------------------------- /user/include/moridin/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef __MORIDIN_SYSCALL_H__ 2 | #define __MORIDIN_SYSCALL_H__ 3 | 4 | /* 5 | * Syscalls provided by the moridin kernel that aren't part of the 6 | * standard C library. 7 | */ 8 | 9 | int yield(void); 10 | 11 | #endif /* !__MORIDIN_SYSCALL_H__ */ 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | *.o 3 | *.bin 4 | *.iso 5 | *.img 6 | *.sym 7 | /DISK* 8 | 9 | bochs.out 10 | 11 | TODO 12 | 13 | kernel/KERNEL.S 14 | kernel/tags 15 | kernel/inc/arch 16 | 17 | iso/ 18 | user/bin/ 19 | 20 | tools/create_initrd 21 | kernel/tools/inject_symbol_table 22 | 23 | tags 24 | -------------------------------------------------------------------------------- /kernel/tools/symbols_section_offset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | [ $1 ] || exit 42 6 | 7 | file=$1 8 | 9 | offset=$(readelf -S $file \ 10 | | grep \.symbols \ 11 | | sed -e 's/\[\s\+[0-9]\+\]/ /g' \ 12 | | sed -e 's/\s\+/ /g' \ 13 | | cut -d" " -f5) 14 | 15 | echo 0x${offset} 16 | -------------------------------------------------------------------------------- /kernel/inc/kernel/init.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/exec.h 3 | */ 4 | #ifndef __KERNEL_EXEC_H__ 5 | #define __KERNEL_EXEC_H__ 6 | 7 | extern struct thread init_thread; 8 | extern struct process init_proc; 9 | 10 | void run_init(char *execpath, int argc, char **argv); 11 | 12 | #endif /* !__KERNEL_EXEC_H__ */ 13 | -------------------------------------------------------------------------------- /kernel/inc/kernel/proc_types.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_PROC_TYPES_H__ 2 | #define __KERNEL_PROC_TYPES_H__ 3 | 4 | #include 5 | 6 | struct thread; 7 | struct process; 8 | 9 | list_typedef(struct thread) thread_list_t; 10 | list_typedef(struct process) process_list_t; 11 | 12 | #endif /* !__KERNEL_PROC_TYPES_H__ */ 13 | -------------------------------------------------------------------------------- /user/newlib/include/dirent.h: -------------------------------------------------------------------------------- 1 | #ifndef _DIRENT_H_ 2 | #define _DIRENT_H_ 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | #include 7 | 8 | #if !defined(MAXNAMLEN) && !defined(_POSIX_SOURCE) 9 | #define MAXNAMLEN 1024 10 | #endif 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | #endif /*_DIRENT_H_*/ 16 | -------------------------------------------------------------------------------- /boot/initrd/hello.txt: -------------------------------------------------------------------------------- 1 | 2 | # ""# ""# 3 | # mm mmm # # mmm 4 | #" # #" # # # #" "# 5 | # # #"""" # # # # 6 | # # "#mm" "mm "mm "#m#" 7 | 8 | 9 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/page.h: -------------------------------------------------------------------------------- 1 | /* 2 | * page.h 3 | * Created for use in 15-410 at CMU 4 | * Joey Echeverria (jge) 5 | */ 6 | 7 | #ifndef _X86_PAGE_H_ 8 | #define _X86_PAGE_H_ 9 | 10 | /* Pages are 4K */ 11 | #define X86_PAGE_SHIFT 12 12 | #define X86_PAGE_SIZE (1 << X86_PAGE_SHIFT) 13 | 14 | 15 | 16 | #endif /* !_X86_PAGE_H_ */ 17 | -------------------------------------------------------------------------------- /user/sys/arch/x86/crt0.S: -------------------------------------------------------------------------------- 1 | .section .text 2 | 3 | .extern exit 4 | 5 | # 6 | # void _start(int argc, char **argv); 7 | # 8 | .global _start 9 | _start: 10 | push $0x0 11 | movl %esp, %ebp 12 | 13 | pushl 0xC(%ebp) 14 | pushl 0x8(%ebp) 15 | 16 | xor %eax, %eax 17 | call main 18 | 19 | pushl %eax 20 | call exit 21 | 22 | exit_returned: 23 | jmp exit_returned 24 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/sched.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/x86/sched.h 3 | */ 4 | #ifndef __ARCH_X86_SCHED_H__ 5 | #define __ARCH_X86_SCHED_H__ 6 | 7 | void __context_switch(void **save_addr, void *restore_addr); 8 | 9 | static inline void context_switch(struct thread *to) 10 | { 11 | __context_switch(&CURRENT_THREAD->context, to->context); 12 | } 13 | 14 | #endif /* !__ARCH_X86_SCHED_H__ */ 15 | -------------------------------------------------------------------------------- /kernel/inc/dev/ide/lba.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dev/ide/lba.h 3 | * 4 | * @brief Logical Block Addressing 5 | * 6 | * LBA is an alternative to CHA (Cylinder, Head, Sector) address of hard 7 | * drives. Sectors are addressed linearly, starting at 0. 8 | * 9 | */ 10 | #ifndef __DEV_IDE_LBA_H__ 11 | #define __DEV_IDE_LBA_H__ 12 | 13 | typedef unsigned int lba28_t; 14 | 15 | #endif /* !__DEV_IDE_LBA_H__ */ 16 | -------------------------------------------------------------------------------- /kernel/inc/dev/bochs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file bochs.h 3 | * 4 | * @brief Debug utility for the bochs machine emulator. 5 | * 6 | */ 7 | #ifndef __BOCHS_H__ 8 | #define __BOCHS_H__ 9 | 10 | #define BOCHS 11 | 12 | #define BOCHS_PUTCHAR_PORT 0xE9 // compile bochs with the e9 hack! 13 | 14 | #define BOCHS_MAGIC_BREAK __asm__("xchg %bx, %bx") 15 | 16 | void bochs_putchar(char c); 17 | 18 | #endif /* __BOCHS_H__ */ 19 | -------------------------------------------------------------------------------- /user/progs/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int child_pid; 7 | int i; 8 | 9 | printf("%d: Hello from userspace! :)\n", getpid()); 10 | 11 | for (i = 0; i < argc; i++) 12 | printf("arg %d: %s\n", i, argv[i]); 13 | 14 | child_pid = fork(); 15 | 16 | if (child_pid < 0) 17 | printf("fork() failed: %d\n", child_pid); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /kernel/inc/kernel/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/timer.h 3 | */ 4 | #ifndef __KERNEL_TIMER_H__ 5 | #define __KERNEL_TIMER_H__ 6 | 7 | struct timer { 8 | /* Schedule interrupt at the provided frequency and start the timer. */ 9 | void (*start)(struct timer *timer, int hz); 10 | const char *name; 11 | }; 12 | 13 | void set_timer(struct timer *t); 14 | void start_timer(int hz); 15 | void timer_tick(void); 16 | 17 | #endif /* !__KERNEL_TIMER_H__ */ 18 | -------------------------------------------------------------------------------- /user/newlib/include/envlock.h: -------------------------------------------------------------------------------- 1 | /* envlock.h -- header file for env routines. */ 2 | 3 | #ifndef _INCLUDE_ENVLOCK_H_ 4 | #define _INCLUDE_ENVLOCK_H_ 5 | 6 | #include <_ansi.h> 7 | #include 8 | 9 | #define ENV_LOCK __env_lock(reent_ptr) 10 | #define ENV_UNLOCK __env_unlock(reent_ptr) 11 | 12 | void _EXFUN(__env_lock,(struct _reent *reent)); 13 | void _EXFUN(__env_unlock,(struct _reent *reent)); 14 | 15 | #endif /* _INCLUDE_ENVLOCK_H_ */ 16 | -------------------------------------------------------------------------------- /kernel/inc/dev/ide.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dev/ide.h 3 | */ 4 | #ifndef __DEV_IDE_H__ 5 | #define __DEV_IDE_H__ 6 | 7 | #include 8 | #include 9 | 10 | struct ide_device { 11 | struct ata_bus ata; 12 | struct pci_bus_master bm; 13 | }; 14 | 15 | int ide_init(struct ide_device *ide, unsigned bm, int irq, 16 | unsigned ata_cmd, unsigned ata_ctl); 17 | 18 | void ide_destroy(struct ide_device *ide); 19 | 20 | #endif /* !__DEV_IDE_H__ */ 21 | -------------------------------------------------------------------------------- /user/newlib/include/machine/time.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHTIME_H_ 2 | #define _MACHTIME_H_ 3 | 4 | #if defined(__rtems__) || defined(__VISIUM__) 5 | #define _CLOCKS_PER_SEC_ 1000000 6 | #elif defined(__aarch64__) || defined(__arm__) || defined(__thumb__) 7 | #define _CLOCKS_PER_SEC_ 100 8 | #endif 9 | 10 | #ifdef __SPU__ 11 | #include 12 | int nanosleep (const struct timespec *, struct timespec *); 13 | #endif 14 | 15 | #endif /* _MACHTIME_H_ */ 16 | -------------------------------------------------------------------------------- /user/newlib/include/sys/resource.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_RESOURCE_H_ 2 | #define _SYS_RESOURCE_H_ 3 | 4 | #include 5 | 6 | #define RUSAGE_SELF 0 /* calling process */ 7 | #define RUSAGE_CHILDREN -1 /* terminated child processes */ 8 | 9 | struct rusage { 10 | struct timeval ru_utime; /* user time used */ 11 | struct timeval ru_stime; /* system time used */ 12 | }; 13 | 14 | int _EXFUN(getrusage, (int, struct rusage*)); 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /user/newlib/include/sys/dirent.h: -------------------------------------------------------------------------------- 1 | /* includes , which is this file. On a 2 | system which supports , this file is overridden by 3 | dirent.h in the libc/sys/.../sys directory. On a system which does 4 | not support , we will get this file which uses #error to force 5 | an error. */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | #error " not supported" 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /user/newlib/include/sys/utime.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_UTIME_H 2 | #define _SYS_UTIME_H 3 | 4 | /* This is a dummy file, not customized for any 5 | particular system. If there is a utime.h in libc/sys/SYSDIR/sys, 6 | it will override this one. */ 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | struct utimbuf 13 | { 14 | time_t actime; 15 | time_t modtime; 16 | }; 17 | 18 | #ifdef __cplusplus 19 | }; 20 | #endif 21 | 22 | #endif /* _SYS_UTIME_H */ 23 | -------------------------------------------------------------------------------- /user/user.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | /* 6 | * All user programs should be loaded starting at 1GB because the kernel 7 | * occupies virtual addresses [0, 1GB). 8 | */ 9 | . = 0x40000000; 10 | 11 | .text : ALIGN(4K) 12 | { 13 | *(.text) 14 | } 15 | .rodata : ALIGN(4K) 16 | { 17 | *(.rodata) 18 | } 19 | .data : ALIGN(4K) 20 | { 21 | *(.data) 22 | } 23 | .bss : ALIGN(4K) 24 | { 25 | *(.bss) 26 | } 27 | _end = .; 28 | } 29 | -------------------------------------------------------------------------------- /user/newlib/include/machine/endian.h: -------------------------------------------------------------------------------- 1 | #ifndef __MACHINE_ENDIAN_H__ 2 | 3 | #include 4 | 5 | #ifndef BIG_ENDIAN 6 | #define BIG_ENDIAN 4321 7 | #endif 8 | #ifndef LITTLE_ENDIAN 9 | #define LITTLE_ENDIAN 1234 10 | #endif 11 | 12 | #ifndef BYTE_ORDER 13 | #if defined(__IEEE_LITTLE_ENDIAN) || defined(__IEEE_BYTES_LITTLE_ENDIAN) 14 | #define BYTE_ORDER LITTLE_ENDIAN 15 | #else 16 | #define BYTE_ORDER BIG_ENDIAN 17 | #endif 18 | #endif 19 | 20 | #endif /* __MACHINE_ENDIAN_H__ */ 21 | -------------------------------------------------------------------------------- /user/newlib/include/setjmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | setjmp.h 3 | stubs for future use. 4 | */ 5 | 6 | #ifndef _SETJMP_H_ 7 | #define _SETJMP_H_ 8 | 9 | #include "_ansi.h" 10 | #include 11 | 12 | _BEGIN_STD_C 13 | 14 | #ifdef __GNUC__ 15 | void _EXFUN(longjmp,(jmp_buf __jmpb, int __retval)) 16 | __attribute__ ((__noreturn__)); 17 | #else 18 | void _EXFUN(longjmp,(jmp_buf __jmpb, int __retval)); 19 | #endif 20 | int _EXFUN(setjmp,(jmp_buf __jmpb)); 21 | 22 | _END_STD_C 23 | 24 | #endif /* _SETJMP_H_ */ 25 | 26 | -------------------------------------------------------------------------------- /kernel/arch/x86/atomic.S: -------------------------------------------------------------------------------- 1 | ### 2 | # @file arch/x86/atomic.S 3 | # 4 | # @brief Atomic operations in the x86 architecture. 5 | ### 6 | 7 | .global __xadd 8 | __xadd: 9 | movl 4(%esp), %edx 10 | movl 8(%esp), %eax 11 | xaddl %eax, (%edx) 12 | ret 13 | 14 | .global __xchg 15 | __xchg: 16 | movl 4(%esp), %edx 17 | movl 8(%esp), %eax 18 | xchgl %eax, (%edx) 19 | ret 20 | 21 | .global __cmpxchg 22 | __cmpxchg: 23 | movl 4(%esp), %edx 24 | movl 8(%esp), %eax 25 | movl 12(%esp), %ecx 26 | cmpxchgl %ecx, (%edx) 27 | ret 28 | -------------------------------------------------------------------------------- /kernel/inc/mm/kmalloc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mm/kmalloc.h 3 | */ 4 | #ifndef __MM_KMALLOC_H__ 5 | #define __MM_KMALLOC_H__ 6 | 7 | #include 8 | #include 9 | 10 | void kmalloc_early_init(void); 11 | void kmalloc_late_init(void); 12 | 13 | void kmalloc_dump(void); 14 | 15 | size_t kmalloc_bytes_free(void); 16 | size_t kmalloc_bytes_used(void); 17 | 18 | void *kmalloc(size_t size); 19 | void *kmemalign(size_t alignment, size_t size); 20 | void kfree(void *buf, size_t size); 21 | 22 | #endif /* !__MM_KMALLOC_H__ */ 23 | -------------------------------------------------------------------------------- /user/newlib/include/alloca.h: -------------------------------------------------------------------------------- 1 | /* libc/include/alloca.h - Allocate memory on stack */ 2 | 3 | /* Written 2000 by Werner Almesberger */ 4 | /* Rearranged for general inclusion by stdlib.h. 5 | 2001, Corinna Vinschen */ 6 | 7 | #ifndef _NEWLIB_ALLOCA_H 8 | #define _NEWLIB_ALLOCA_H 9 | 10 | #include "_ansi.h" 11 | #include 12 | 13 | #undef alloca 14 | 15 | #ifdef __GNUC__ 16 | #define alloca(size) __builtin_alloca(size) 17 | #else 18 | void * _EXFUN(alloca,(size_t)); 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /kernel/inc/lib/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDLIB_H_ 2 | #define _STDLIB_H_ 3 | 4 | #include /* For size_t, NULL */ 5 | 6 | long atol(const char *__str); 7 | #define atoi(str) ((int)atol(str)) 8 | 9 | long strtol(const char *__p, char **__out_p, int __base); 10 | unsigned long strtoul(const char *__p, char **__out_p, int __base); 11 | 12 | #define RAND_MAX 0x80000000 13 | int rand(void); 14 | void srand(unsigned new_seed); 15 | 16 | int abs(int val); 17 | 18 | void qsort(void *a, size_t n, size_t es, int (*cmp)()); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /kernel/inc/lib/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDARG_H_ 2 | #define _STDARG_H_ 3 | 4 | /* This is awful, but really these are compiler intrinsics, so we use the 5 | * GNU compiler intrinsics. 6 | */ 7 | 8 | #ifdef __GNUC__ 9 | typedef __builtin_va_list va_list; 10 | #define va_start(v,l) __builtin_va_start(v,l) 11 | #define va_end(v) __builtin_va_end(v) 12 | #define va_arg(v,l) __builtin_va_arg(v,l) 13 | #define va_copy(d,s) __builtin_va_copy(d,s) 14 | #else 15 | #error "Don't know how to use varargs not on GNUC, sorry." 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /kernel/kernel/timer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/timer.c 3 | * 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* The timer used to by the kernel. */ 12 | struct timer *timer = NULL; 13 | 14 | void timer_tick(void) 15 | { 16 | sched_tick(); 17 | } 18 | 19 | void set_timer(struct timer *t) 20 | { 21 | INFO("Setting kernel timer to %s.", t->name); 22 | timer = t; 23 | } 24 | 25 | void start_timer(int hz) 26 | { 27 | ASSERT(timer); 28 | 29 | timer->start(timer, hz); 30 | } 31 | -------------------------------------------------------------------------------- /kernel/kernel/symbols.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct symbol symbol_table[SYMBOL_TABLE_LENGTH] __section(".symbols"); 7 | 8 | struct symbol *resolve_symbol(unsigned long address) 9 | { 10 | struct symbol *s = symbol_table; 11 | struct symbol *prev = NULL; 12 | struct symbol *sym = NULL; 13 | 14 | while (s->name[0]) { 15 | /* symbol table is sorted by address, low to high. */ 16 | if (address < s->address) { 17 | sym = prev; 18 | break; 19 | } 20 | 21 | prev = s++; 22 | } 23 | 24 | return sym; 25 | } 26 | -------------------------------------------------------------------------------- /kernel/inc/kernel/elf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/elf.h 3 | */ 4 | #ifndef __KERNEL_ELF_H__ 5 | #define __KERNEL_ELF_H__ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define ELF32_MAGIC_SIZE 4 14 | static char elf32_magic[ELF32_MAGIC_SIZE] = 15 | { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 }; 16 | 17 | static inline bool is_elf32(char *header, size_t bytes) 18 | { 19 | return (bytes >= ELF32_MAGIC_SIZE) 20 | && 21 | (0 == memcmp(header, elf32_magic, ELF32_MAGIC_SIZE)); 22 | } 23 | 24 | int elf32_load(struct vfs_file *file); 25 | 26 | #endif /* !__KERNEL_ELF_H__ */ 27 | -------------------------------------------------------------------------------- /kernel/inc/lib/fmt/_printf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file _printf.h 3 | * 4 | * @brief A putchar-agnostic printf library. 5 | * 6 | */ 7 | #ifndef ___PRINTF_H__ 8 | #define ___PRINTF_H__ 9 | 10 | #include 11 | 12 | #define _PRINTF_BUFMAX 128 13 | 14 | struct printf_state { 15 | /** @brief internal state used by the print functions */ 16 | char buf[_PRINTF_BUFMAX]; 17 | /** @brief internal state used by the print functions */ 18 | unsigned int index; 19 | 20 | /* @brief the putchar method this version of printf will use */ 21 | int (*putchar)(int c); 22 | }; 23 | 24 | int _vprintf(struct printf_state *p, const char *fmt, va_list args); 25 | 26 | #endif /* ___PRINTF_H__ */ 27 | 28 | -------------------------------------------------------------------------------- /kernel/inc/lib/types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lib/types.h 3 | */ 4 | 5 | #ifndef LIB_TYPES_H 6 | #define LIB_TYPES_H 7 | 8 | // POSIX sys/types.h 9 | // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html 10 | 11 | typedef unsigned int size_t; 12 | typedef int ssize_t; 13 | typedef int pid_t; 14 | 15 | 16 | typedef unsigned long vm_offset_t; // needed by lmm 17 | typedef unsigned long vm_size_t; // needed by lmm 18 | 19 | typedef char bool; 20 | #define true 1 21 | #define TRUE 1 22 | #define false 0 23 | #define FALSE 0 24 | 25 | #define boolean_t bool 26 | 27 | typedef int (*printf_f)(const char *fmt, ...); 28 | 29 | #endif /* !LIB_TYPES_H */ 30 | -------------------------------------------------------------------------------- /user/newlib/include/sys/param.h: -------------------------------------------------------------------------------- 1 | /* This is a dummy file, not customized for any 2 | particular system. If there is a param.h in libc/sys/SYSDIR/sys, 3 | it will override this one. */ 4 | 5 | #ifndef _SYS_PARAM_H 6 | # define _SYS_PARAM_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifndef HZ 14 | # define HZ (60) 15 | #endif 16 | #ifndef NOFILE 17 | # define NOFILE (60) 18 | #endif 19 | #ifndef PATHSIZE 20 | # define PATHSIZE (1024) 21 | #endif 22 | 23 | #define MAXPATHLEN PATH_MAX 24 | 25 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) 26 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /kernel/inc/kernel/irq.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/irq.h 3 | * 4 | */ 5 | #ifndef __KERNEL_IRQ_H__ 6 | #define __KERNEL_IRQ_H__ 7 | 8 | #include 9 | #include 10 | 11 | struct irq_context { 12 | int irq; 13 | }; 14 | 15 | typedef void (*irq_handler_f)(struct irq_context *context); 16 | 17 | struct irq_handler { 18 | irq_handler_f f; 19 | list_link(struct irq_handler) link; 20 | }; 21 | 22 | void irq_init(void); 23 | int register_irq(int irq, struct irq_handler *new_handler); 24 | void kernel_irq_handler(int irq); 25 | 26 | /* called at the very end of all interrupt handlers. */ 27 | void irq_exit(void); 28 | 29 | void irq_status_bar(int bar_row); 30 | 31 | #endif /* !__KERNEL_IRQ_H__ */ 32 | -------------------------------------------------------------------------------- /kernel/inc/kernel/syscall.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/syscall.h 3 | */ 4 | #ifndef __KERNEL_SYSCALL_H__ 5 | #define __KERNEL_SYSCALL_H__ 6 | 7 | #define SYS_WRITE 0 8 | #define SYS_GETPID 1 9 | #define SYS_FORK 2 10 | #define SYS_YIELD 3 11 | #define SYS_EXIT 4 12 | #define SYS_WAIT 5 13 | #define SYS_MAX 6 14 | 15 | #ifndef ASSEMBLER 16 | 17 | #include 18 | 19 | extern void *syscall_table[]; 20 | 21 | int sys_write(int fd, char *ptr, int len); 22 | int sys_getpid(void); 23 | pid_t sys_fork(void); 24 | int sys_yield(void); 25 | void sys_exit(int status); 26 | int sys_wait(int *status); 27 | 28 | void bad_syscall(int syscall); 29 | 30 | #endif 31 | 32 | #endif /* !__KERNEL_SYSCALL_H__ */ 33 | -------------------------------------------------------------------------------- /kernel/inc/lib/math.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @math.h 3 | */ 4 | #ifndef __LIB_MATH_H__ 5 | #define __LIB_MATH_H__ 6 | 7 | #include 8 | 9 | static inline bool check_overlap(unsigned int a_start, unsigned int a_len, 10 | unsigned int b_start, unsigned int b_len) 11 | { 12 | return (a_start >= b_start && a_start < b_start + b_len) || 13 | (b_start >= a_start && b_start < a_start + a_len); 14 | } 15 | 16 | static inline unsigned __umin(unsigned a, unsigned b) 17 | { 18 | return a < b ? a : b; 19 | } 20 | #define umin(a, b) __umin((unsigned) (a), (unsigned) (b)) 21 | 22 | static inline unsigned __smin(int a, int b) 23 | { 24 | return a < b ? a : b; 25 | } 26 | #define smin(a, b) __smin((int) (a), (int) (b)) 27 | 28 | #endif /* !__LIB_MATH_H__ */ 29 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/x86/macros.S: -------------------------------------------------------------------------------- 1 | # 2 | # @file arch/x86/macros.S 3 | # 4 | 5 | .macro POP_REGISTERS 6 | popl %ebx 7 | movl %cr3, %eax 8 | cmp %ebx, %eax 9 | je 1f; 10 | movl %ebx, %cr3 11 | 1: 12 | popl %ebx 13 | movl %ebx, %cr2 14 | 15 | popl %edi 16 | popl %esi 17 | popl %ebp 18 | popl %ebx 19 | popl %edx 20 | popl %ecx 21 | popl %eax 22 | 23 | popl %gs 24 | popl %fs 25 | popl %es 26 | popl %ds 27 | .endm # POP_REGISTERS 28 | 29 | .macro PUSH_REGISTERS 30 | pushl %ds 31 | pushl %es 32 | pushl %fs 33 | pushl %gs 34 | 35 | pushl %eax 36 | pushl %ecx 37 | pushl %edx 38 | pushl %ebx 39 | pushl %ebp 40 | pushl %esi 41 | pushl %edi 42 | 43 | movl %cr2, %ebx 44 | pushl %ebx 45 | movl %cr3, %ebx 46 | pushl %ebx 47 | .endm # PUSH_REGISTERS 48 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/io.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file x86/io.h 3 | * 4 | * @brief Utility functions for communicating with x86 io ports. 5 | */ 6 | #include 7 | 8 | /** 9 | * @brief write 1 byte the given port 10 | */ 11 | void outb(u16 port, u8 val); 12 | /** 13 | * @brief write 2 byte the given port 14 | */ 15 | void outw(u16 port, u16 val); 16 | /** 17 | * @brief write 4 byte the given port 18 | */ 19 | void outl(u16 port, u32 val); 20 | 21 | /** 22 | * @brief read 1 byte from the given port 23 | */ 24 | u8 inb(u16 port); 25 | /** 26 | * @brief read 2 byte from the given port 27 | */ 28 | u16 inw(u16 port); 29 | /** 30 | * @brief read 4 byte from the given port 31 | */ 32 | u32 inl(u16 port); 33 | 34 | // Delay 1/8 microsecond 35 | void iodelay(void); 36 | -------------------------------------------------------------------------------- /user/newlib/include/sys/times.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_TIMES_H 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | #define _SYS_TIMES_H 6 | 7 | #include <_ansi.h> 8 | #include 9 | 10 | #ifndef __clock_t_defined 11 | typedef _CLOCK_T_ clock_t; 12 | #define __clock_t_defined 13 | #endif 14 | 15 | /* Get Process Times, P1003.1b-1993, p. 92 */ 16 | struct tms { 17 | clock_t tms_utime; /* user time */ 18 | clock_t tms_stime; /* system time */ 19 | clock_t tms_cutime; /* user time, children */ 20 | clock_t tms_cstime; /* system time, children */ 21 | }; 22 | 23 | clock_t _EXFUN(times,(struct tms *)); 24 | #ifdef _COMPILING_NEWLIB 25 | clock_t _EXFUN(_times,(struct tms *)); 26 | #endif 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | #endif /* !_SYS_TIMES_H */ 32 | -------------------------------------------------------------------------------- /kernel/arch/x86/syscall.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/x86/syscall.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void return_from_syscall(int ret) 10 | { 11 | struct thread *current = CURRENT_THREAD; 12 | 13 | TRACE("ret=0x%x", ret); 14 | 15 | current->regs->eax = ret; 16 | restore_registers(current->regs); 17 | } 18 | 19 | void arch_sched_switch_end(void) 20 | { 21 | set_esp0(KSTACK_TOP); 22 | } 23 | 24 | void jump_to_userspace(void) 25 | { 26 | struct registers *regs = CURRENT_THREAD->regs; 27 | 28 | set_esp0(KSTACK_TOP); 29 | 30 | regs->cr3 = __phys(CURRENT_PAGE_DIR); 31 | regs->cr2 = 0; 32 | regs->eflags = get_eflags() | 0x200; /* enable interrupts */ 33 | 34 | return_from_syscall(0); 35 | } 36 | -------------------------------------------------------------------------------- /kernel/kernel/wait.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/wait.c. 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void begin_wait(struct wait *wait) 10 | { 11 | struct thread *current = CURRENT_THREAD; 12 | unsigned long flags; 13 | 14 | spin_lock_irq(&wait->lock, &flags); 15 | 16 | list_enqueue(&wait->threads, current, state_link); 17 | current->state = BLOCKED; 18 | 19 | spin_unlock_irq(&wait->lock, flags); 20 | } 21 | 22 | void kick(struct wait *wait) 23 | { 24 | unsigned long flags; 25 | 26 | spin_lock_irq(&wait->lock, &flags); 27 | 28 | while (!list_empty(&wait->threads)) 29 | make_runnable(list_dequeue(&wait->threads, state_link)); 30 | 31 | spin_unlock_irq(&wait->lock, flags); 32 | } 33 | -------------------------------------------------------------------------------- /user/sys/syscall_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSCALL_INTERNAL_H 2 | #define SYSCALL_INTERNAL_H 3 | 4 | #define SYS_WRITE 0 5 | #define SYS_GETPID 1 6 | #define SYS_FORK 2 7 | #define SYS_YIELD 3 8 | #define SYS_EXIT 4 9 | #define SYS_WAIT 5 10 | 11 | int __syscall(int system_call, void *arg1, void *arg2, void *arg3, void *arg4); 12 | 13 | #define SYSCALL0(s) \ 14 | __syscall(s, 0, 0, 0, 0) 15 | #define SYSCALL1(s, a1) \ 16 | __syscall(s, (void *) a1, 0, 0, 0) 17 | #define SYSCALL2(s, a1, a2) \ 18 | __syscall(s, (void *) a1, (void *) a2, 0, 0) 19 | #define SYSCALL3(s, a1, a2, a3) \ 20 | __syscall(s, (void *) a1, (void *) a2, (void *) a3, 0) 21 | #define SYSCALL4(s, a1, a2, a3, a4) \ 22 | __syscall(s, (void *) a1, (void *) a2, (void *) a3, (void *) a4) 23 | 24 | #endif /* !SYSCALL_INTERNAL_H */ 25 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/seg.h: -------------------------------------------------------------------------------- 1 | /** @file x86/seg.h 2 | * @brief Predefined segment selectors 3 | * 4 | * @note Must match other course-specific code (e.g., head.S). 5 | * 6 | * @author matthewj S2008 7 | */ 8 | 9 | #ifndef X86_SEG_H 10 | #define X86_SEG_H 11 | 12 | #define SEGSEL_KERNEL_TSS_IDX 1 13 | #define SEGSEL_KERNEL_CS_IDX 2 14 | #define SEGSEL_KERNEL_DS_IDX 3 15 | #define SEGSEL_USER_CS_IDX 4 16 | #define SEGSEL_USER_DS_IDX 5 17 | 18 | #define SEGSEL_TSS 0x08 /**< Task Segment Selector */ 19 | #define SEGSEL_KERNEL_CS 0x10 /**< Kernel Code Segment */ 20 | #define SEGSEL_KERNEL_DS 0x18 /**< Kernel Data Segment */ 21 | #define SEGSEL_USER_CS 0x23 /**< User Code Segment */ 22 | #define SEGSEL_USER_DS 0x2b /**< User Data Segment */ 23 | 24 | #endif /* !X86_SEG_H */ 25 | -------------------------------------------------------------------------------- /user/newlib/include/envz.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. 2 | * 3 | * Permission to use, copy, modify, and distribute this software 4 | * is freely granted, provided that this notice is preserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* The newlib implementation of these functions assumes that sizeof(char) == 1. */ 11 | char * envz_entry (const char *envz, size_t envz_len, const char *name); 12 | char * envz_get (const char *envz, size_t envz_len, const char *name); 13 | error_t envz_add (char **envz, size_t *envz_len, const char *name, const char *value); 14 | error_t envz_merge (char **envz, size_t *envz_len, const char *envz2, size_t envz2_len, int override); 15 | void envz_remove(char **envz, size_t *envz_len, const char *name); 16 | void envz_strip (char **envz, size_t *envz_len); 17 | -------------------------------------------------------------------------------- /kernel/inc/kernel/symbols.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_SYMBOLS_H__ 2 | #define __KERNEL_SYMBOLS_H__ 3 | 4 | #include 5 | 6 | /* 7 | * 8 | * if you change anything in this file (struct symbol, symbol table length, 9 | * etc.), make sure tools/inject_symbol_table matches!!!!! 10 | * 11 | */ 12 | 13 | #define SYMBOL_TABLE_LENGTH 1024 14 | 15 | struct symbol { 16 | u64 address; 17 | #define BSS_SECTION 0x0 18 | #define TEXT_SECTION 0x1 19 | #define RO_SECTION 0x2 20 | #define DATA_SECTION 0x3 21 | #define UNKNOWN_SECTION 0x4 22 | 23 | u8 section; 24 | 25 | #define SYMBOL_NAME_LENGTH 255 26 | char name[SYMBOL_NAME_LENGTH + 1]; /* +1 for null terminator */ 27 | } __attribute__(( packed )); 28 | 29 | extern struct symbol symbol_table[SYMBOL_TABLE_LENGTH]; 30 | 31 | struct symbol *resolve_symbol(unsigned long address); 32 | 33 | #endif /* !__KERNEL_SYMBOLS_H__ */ 34 | -------------------------------------------------------------------------------- /kernel/inc/fs/initrd.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file fs/initrd.h 3 | * 4 | * @brief Initial Ramdisk 5 | * 6 | * The initrd is a very simple, flat, read-only, filesystem. It does not 7 | * support creating or deleting files. 8 | * 9 | */ 10 | #ifndef __FS_INITRD_H__ 11 | #define __FS_INITRD_H__ 12 | 13 | #include 14 | #include 15 | 16 | struct initrd_hdr { 17 | #define INITRD_MAGIC 0x98119 18 | uint32_t magic; 19 | uint32_t nfiles; 20 | }; 21 | 22 | struct initrd_file { 23 | #define INITRD_NAMESIZE 128 24 | char name[INITRD_NAMESIZE]; 25 | /* 26 | * The location of the files data as an offset from the beginning of 27 | * the ramdisk. 28 | */ 29 | uint32_t data; 30 | /* 31 | * The length of the data in bytes 32 | */ 33 | uint32_t length; 34 | }; 35 | 36 | extern size_t initrd_location; 37 | 38 | void initrd_init(void); 39 | 40 | #endif /* !__FS_INITRD_H__ */ 41 | -------------------------------------------------------------------------------- /user/newlib/include/machine/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACHTYPES_H_ 2 | #define _MACHTYPES_H_ 3 | 4 | /* 5 | * The following section is RTEMS specific and is needed to more 6 | * closely match the types defined in the BSD machine/types.h. 7 | * This is needed to let the RTEMS/BSD TCP/IP stack compile. 8 | */ 9 | #if defined(__rtems__) 10 | #include 11 | #endif 12 | 13 | #define _CLOCK_T_ unsigned long /* clock() */ 14 | #define _TIME_T_ long /* time() */ 15 | #define _CLOCKID_T_ unsigned long 16 | #define _TIMER_T_ unsigned long 17 | 18 | #ifndef _HAVE_SYSTYPES 19 | typedef long int __off_t; 20 | typedef int __pid_t; 21 | #ifdef __GNUC__ 22 | __extension__ typedef long long int __loff_t; 23 | #else 24 | typedef long int __loff_t; 25 | #endif 26 | #endif 27 | 28 | typedef long __suseconds_t; /* microseconds (signed) */ 29 | 30 | #endif /* _MACHTYPES_H_ */ 31 | 32 | 33 | -------------------------------------------------------------------------------- /kernel/inc/kernel/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_MUTEX_H__ 2 | #define __KERNEL_MUTEX_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | struct mutex { 11 | struct spinlock lock; 12 | struct wait wait; 13 | struct thread *owner; 14 | }; 15 | 16 | #define INITIALIZED_MUTEX { \ 17 | .lock = INITIALIZED_SPINLOCK, \ 18 | .wait = INITIALIZED_WAIT, \ 19 | .owner = NULL, \ 20 | } 21 | 22 | static inline void mutex_init(struct mutex *m) 23 | { 24 | spin_lock_init(&m->lock); 25 | wait_init(&m->wait); 26 | m->owner = NULL; 27 | } 28 | 29 | /* blocks the calling thread until the mutex is aquired */ 30 | void mutex_aquire(struct mutex *m); 31 | 32 | /* releases the mutex and awakens any threads blocked on the mutex */ 33 | void mutex_release(struct mutex *m); 34 | 35 | #endif /* !__KERNEL_MUTEX_H__ */ 36 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/cpu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file x86/cpu.h 3 | * 4 | */ 5 | #ifndef __X86_CPU_H__ 6 | #define __X86_CPU_H__ 7 | 8 | #include 9 | 10 | void enable_paging(void); 11 | void disable_paging(void); 12 | void enable_protected_mode(void); 13 | void enable_real_mode(void); 14 | void disable_fpu(void); 15 | void enable_global_pages(void); 16 | void enable_write_protect(void); 17 | 18 | /** 19 | * @brief esp0 is a 4-byte file in the Task State Segment (TSS). It 20 | * identifies a region of memory to use as a stack in the event of a 21 | * priveldge level change (3 -> 0), which are usually caused by system 22 | * calls and interrupts. 23 | */ 24 | void set_esp0(u32); 25 | 26 | // FIXME: move this somewhere else? 27 | void jump_to_userspace(void); 28 | // FIXME: move this somewhere else? 29 | void jump_stacks(u32 stack, void (*func)(void *), void *arg); 30 | 31 | #endif /* !__X86_CPU_H__ */ 32 | -------------------------------------------------------------------------------- /user/newlib/include/sys/lock.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYS_LOCK_H__ 2 | #define __SYS_LOCK_H__ 3 | 4 | /* dummy lock routines for single-threaded aps */ 5 | 6 | typedef int _LOCK_T; 7 | typedef int _LOCK_RECURSIVE_T; 8 | 9 | #include <_ansi.h> 10 | 11 | #define __LOCK_INIT(class,lock) static int lock = 0; 12 | #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0; 13 | #define __lock_init(lock) (_CAST_VOID 0) 14 | #define __lock_init_recursive(lock) (_CAST_VOID 0) 15 | #define __lock_close(lock) (_CAST_VOID 0) 16 | #define __lock_close_recursive(lock) (_CAST_VOID 0) 17 | #define __lock_acquire(lock) (_CAST_VOID 0) 18 | #define __lock_acquire_recursive(lock) (_CAST_VOID 0) 19 | #define __lock_try_acquire(lock) (_CAST_VOID 0) 20 | #define __lock_try_acquire_recursive(lock) (_CAST_VOID 0) 21 | #define __lock_release(lock) (_CAST_VOID 0) 22 | #define __lock_release_recursive(lock) (_CAST_VOID 0) 23 | 24 | #endif /* __SYS_LOCK_H__ */ 25 | -------------------------------------------------------------------------------- /kernel/inc/dev/serial.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dev/serial.h 3 | * 4 | * References: 5 | * http://wiki.osdev.org/Serial_Ports 6 | * http://www.sci.muni.cz/docs/pc/serport.txt 7 | * Read this document for a full description of programming the serial 8 | * port and its controller. 9 | */ 10 | #ifndef __DEV_SERIAL_H__ 11 | #define __DEV_SERIAL_H__ 12 | 13 | #include 14 | #include 15 | 16 | struct serial_port { 17 | int (*init)(struct serial_port *); 18 | void (*putchar)(struct serial_port *, char c); 19 | const char *purpose; 20 | const char *name; 21 | bool reserved; 22 | list_link(struct serial_port) list; 23 | }; 24 | 25 | list_typedef(struct serial_port) serial_port_list_t; 26 | 27 | void register_serial_port(struct serial_port *s); 28 | struct serial_port *reserve_serial_port(const char *purpose); 29 | void serial_putchar(struct serial_port *s, char c); 30 | 31 | #endif /* !__DEV_SERIAL_H__ */ 32 | -------------------------------------------------------------------------------- /user/newlib/include/sys/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _NEWLIB_STDIO_H 2 | #define _NEWLIB_STDIO_H 3 | 4 | #include 5 | #include 6 | 7 | /* Internal locking macros, used to protect stdio functions. In the 8 | general case, expand to nothing. Use __SSTR flag in FILE _flags to 9 | detect if FILE is private to sprintf/sscanf class of functions; if 10 | set then do nothing as lock is not initialised. */ 11 | #if !defined(_flockfile) 12 | #ifndef __SINGLE_THREAD__ 13 | # define _flockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_acquire_recursive((fp)->_lock)) 14 | #else 15 | # define _flockfile(fp) (_CAST_VOID 0) 16 | #endif 17 | #endif 18 | 19 | #if !defined(_funlockfile) 20 | #ifndef __SINGLE_THREAD__ 21 | # define _funlockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_release_recursive((fp)->_lock)) 22 | #else 23 | # define _funlockfile(fp) (_CAST_VOID 0) 24 | #endif 25 | #endif 26 | 27 | #endif /* _NEWLIB_STDIO_H */ 28 | -------------------------------------------------------------------------------- /user/newlib/include/sys/timeb.h: -------------------------------------------------------------------------------- 1 | /* timeb.h -- An implementation of the standard Unix file. 2 | Written by Ian Lance Taylor 3 | Public domain; no rights reserved. 4 | 5 | declares the structure used by the ftime function, as 6 | well as the ftime function itself. Newlib does not provide an 7 | implementation of ftime. */ 8 | 9 | #ifndef _SYS_TIMEB_H 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #define _SYS_TIMEB_H 16 | 17 | #include <_ansi.h> 18 | #include 19 | 20 | #ifndef __time_t_defined 21 | typedef _TIME_T_ time_t; 22 | #define __time_t_defined 23 | #endif 24 | 25 | struct timeb 26 | { 27 | time_t time; 28 | unsigned short millitm; 29 | short timezone; 30 | short dstflag; 31 | }; 32 | 33 | extern int ftime _PARAMS ((struct timeb *)); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* ! defined (_SYS_TIMEB_H) */ 40 | -------------------------------------------------------------------------------- /user/newlib/include/signal.h: -------------------------------------------------------------------------------- 1 | #ifndef _SIGNAL_H_ 2 | #define _SIGNAL_H_ 3 | 4 | #include "_ansi.h" 5 | #include 6 | 7 | _BEGIN_STD_C 8 | 9 | typedef int sig_atomic_t; /* Atomic entity type (ANSI) */ 10 | #ifndef _POSIX_SOURCE 11 | typedef _sig_func_ptr sig_t; /* BSD naming */ 12 | typedef _sig_func_ptr sighandler_t; /* glibc naming */ 13 | #endif /* !_POSIX_SOURCE */ 14 | 15 | #define SIG_DFL ((_sig_func_ptr)0) /* Default action */ 16 | #define SIG_IGN ((_sig_func_ptr)1) /* Ignore action */ 17 | #define SIG_ERR ((_sig_func_ptr)-1) /* Error return */ 18 | 19 | struct _reent; 20 | 21 | _sig_func_ptr _EXFUN(_signal_r, (struct _reent *, int, _sig_func_ptr)); 22 | int _EXFUN(_raise_r, (struct _reent *, int)); 23 | 24 | #ifndef _REENT_ONLY 25 | _sig_func_ptr _EXFUN(signal, (int, _sig_func_ptr)); 26 | int _EXFUN(raise, (int)); 27 | void _EXFUN(psignal, (int, const char *)); 28 | #endif 29 | 30 | _END_STD_C 31 | 32 | #endif /* _SIGNAL_H_ */ 33 | -------------------------------------------------------------------------------- /kernel/inc/kernel/sched.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/sched.h 3 | */ 4 | #ifndef __KERNEL_SCHED_H__ 5 | #define __KERNEL_SCHED_H__ 6 | 7 | #include 8 | 9 | void sched_init(void); 10 | void make_runnable(struct thread *); 11 | void sched_switch(void); 12 | void sched_tick(void); 13 | void reschedule(void); 14 | void maybe_reschedule(void); 15 | void child_return_from_fork(void); 16 | 17 | extern void arch_sched_switch_end(void); 18 | 19 | static inline void disable_save_preemption(void) 20 | { 21 | struct thread *current = CURRENT_THREAD; 22 | 23 | current->preempt++; 24 | } 25 | 26 | static inline bool can_preempt(void) 27 | { 28 | struct thread *current = CURRENT_THREAD; 29 | 30 | return (current->preempt == 0); 31 | } 32 | 33 | static inline void restore_preemption(void) 34 | { 35 | struct thread *current = CURRENT_THREAD; 36 | 37 | if (--current->preempt) 38 | maybe_reschedule(); 39 | } 40 | 41 | #endif /* !__KERNEL_SCHED_H__ */ 42 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/idtr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file idtr.h 3 | * 4 | * @breif Function for manipulating the Interrupt Descriptor Table 5 | * Register (IDTR). 6 | * 7 | * .------------+-----------------------. 8 | * IDTR: |0 LIMIT 15|16 BASE 47| 9 | * '------------+-----------------------' 10 | * 11 | * Limit: Defines the length of the IDT in bytes. The minimum value 12 | * is 0x100 and the maximum is 0x1000 (which corresponds to 13 | * 0x200 interrupts). 14 | * Base: The 32-bit physical address where the IDT starts (INT 0). 15 | * 16 | */ 17 | #ifndef __IDTR_H__ 18 | #define __IDTR_H__ 19 | 20 | /** 21 | * @brief Return the 32-bit base address of the Interrupt Descriptor Table. 22 | */ 23 | u32 idt_get_base(void); //TODO test me 24 | 25 | /** 26 | * @brief Return the 16-bit limit (size) of the Interrupt Descriptor Table. 27 | */ 28 | u16 idt_get_limit(void); //TODO test me 29 | 30 | #endif /* __IDTR_H_ */ 31 | -------------------------------------------------------------------------------- /user/newlib/include/libgen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libgen.h - defined by XPG4 3 | */ 4 | 5 | #ifndef _LIBGEN_H_ 6 | #define _LIBGEN_H_ 7 | 8 | #include "_ansi.h" 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /* There are two common basename variants. If you do NOT #include 16 | and you do 17 | 18 | #define _GNU_SOURCE 19 | #include 20 | 21 | you get the GNU version. Otherwise you get the POSIX versionfor which you 22 | should #include i for the function prototype. POSIX requires that 23 | #undef basename will still let you invoke the underlying function. However, 24 | this also implies that the POSIX version is used in this case. That's made 25 | sure here. */ 26 | #undef basename 27 | #define basename basename 28 | char *_EXFUN(basename, (char *)); 29 | char *_EXFUN(dirname, (char *)); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif /* _LIBGEN_H_ */ 36 | 37 | -------------------------------------------------------------------------------- /kernel/arch/x86/irq_wrappers.S: -------------------------------------------------------------------------------- 1 | ### 2 | # @brief Assembly handlers for IRQs generated by the PIC. 3 | ### 4 | 5 | .macro irq_handler_macro irq 6 | 7 | .global irq_\irq 8 | irq_\irq: 9 | pusha 10 | pushl %gs # push all data segment registers 11 | pushl %fs 12 | pushl %es 13 | pushl %ds 14 | pushl $\irq # push the irq number 15 | call interrupt_request # call the central handler 16 | addl $4, %esp # pop the irq number 17 | popl %ds # pop the data segment registers off the stack 18 | popl %es 19 | popl %fs 20 | popl %gs 21 | popa 22 | iret 23 | 24 | .endm 25 | 26 | irq_handler_macro 0 27 | irq_handler_macro 1 28 | irq_handler_macro 2 29 | irq_handler_macro 3 30 | irq_handler_macro 4 31 | irq_handler_macro 5 32 | irq_handler_macro 6 33 | irq_handler_macro 7 34 | irq_handler_macro 8 35 | irq_handler_macro 9 36 | irq_handler_macro 10 37 | irq_handler_macro 11 38 | irq_handler_macro 12 39 | irq_handler_macro 13 40 | irq_handler_macro 14 41 | irq_handler_macro 15 42 | -------------------------------------------------------------------------------- /kernel/kernel/syscall.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @brief kernel/syscall.c 3 | * 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void *syscall_table[] = 12 | { 13 | [SYS_WRITE] = (void *) sys_write, 14 | [SYS_GETPID] = (void *) sys_getpid, 15 | [SYS_FORK] = (void *) sys_fork, 16 | [SYS_YIELD] = (void *) sys_yield, 17 | [SYS_EXIT] = (void *) sys_exit, 18 | [SYS_WAIT] = (void *) sys_wait, 19 | }; 20 | 21 | int sys_write(int fd, char *ptr, int len) 22 | { 23 | int i; 24 | 25 | TRACE("fd=%d, ptr=%p, len=%d", fd, ptr, len); 26 | 27 | for (i = 0; i < len; i++) { 28 | log("%c", ptr[i]); 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | int sys_getpid(void) 35 | { 36 | TRACE(); 37 | return CURRENT_THREAD->proc->pid; 38 | } 39 | 40 | int sys_yield(void) 41 | { 42 | TRACE(); 43 | reschedule(); 44 | return 0; 45 | } 46 | 47 | void bad_syscall(int syscall) { 48 | panic("Unknown syscall: %d\n", syscall); 49 | } 50 | -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # config.mk 4 | # 5 | # Project-wide build configurations (compilers, flags, etc.) 6 | # 7 | ############################################################################### 8 | 9 | ifndef ARCH 10 | $(error Must compile for a target architecture. Run 'make ARCH=foo' or \ 11 | set an ARCH environment variable) 12 | endif 13 | 14 | ifeq ($(ARCH),x86) 15 | CC := i586-elf-gcc 16 | LD := i586-elf-ld 17 | AS := i586-elf-as 18 | else 19 | $(error Unknown architecture: $(ARCH)) 20 | endif 21 | 22 | WARNINGS := \ 23 | -Wall \ 24 | -Wextra \ 25 | -Wshadow \ 26 | -Wcast-align \ 27 | -Wredundant-decls \ 28 | -Wnested-externs \ 29 | -Winline \ 30 | -Wuninitialized \ 31 | -Werror 32 | 33 | CFLAGS := -g -std=c99 -ffreestanding -D__$(ARCH)__ $(WARNINGS) 34 | 35 | %.o: %.S 36 | $(CC) $(CFLAGS) $(INCLUDES) -DASSEMBLER -c -o $@ $< 37 | 38 | %.o: %.c 39 | $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< 40 | -------------------------------------------------------------------------------- /kernel/arch/x86/bzero.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by J.T. Conklin . 3 | * Public domain. 4 | */ 5 | #include "asm_style.h" 6 | 7 | #if defined(LIBC_SCCS) 8 | RCSID("$NetBSD: bzero.S,v 1.8 1995/04/28 22:57:58 jtc Exp $") 9 | #endif 10 | 11 | 12 | ENTRY(bzero) 13 | pushl %edi 14 | movl S_ARG1,%edi 15 | movl S_ARG2,%edx 16 | 17 | cld /* set fill direction forward */ 18 | xorl %eax,%eax /* set fill data to 0 */ 19 | 20 | /* 21 | * if the string is too short, it's really not worth the overhead 22 | * of aligning to word boundries, etc. So we jump to a plain 23 | * unaligned set. 24 | */ 25 | cmpl $16,%edx 26 | jb L1 27 | 28 | movl %edi,%ecx /* compute misalignment */ 29 | negl %ecx 30 | andl $3,%ecx 31 | subl %ecx,%edx 32 | rep /* zero until word aligned */ 33 | stosb 34 | 35 | movl %edx,%ecx /* zero by words */ 36 | shrl $2,%ecx 37 | andl $3,%edx 38 | rep 39 | stosl 40 | 41 | L1: movl %edx,%ecx /* zero remainder by bytes */ 42 | rep 43 | stosb 44 | 45 | popl %edi 46 | ret 47 | -------------------------------------------------------------------------------- /user/newlib/include/strings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * strings.h 3 | * 4 | * Definitions for string operations. 5 | */ 6 | 7 | #ifndef _STRINGS_H_ 8 | #define _STRINGS_H_ 9 | 10 | #include "_ansi.h" 11 | #include 12 | 13 | #include /* for size_t */ 14 | 15 | _BEGIN_STD_C 16 | 17 | #if !defined __STRICT_ANSI__ && _POSIX_VERSION < 200809L 18 | /* 19 | * Marked LEGACY in Open Group Base Specifications Issue 6/IEEE Std 1003.1-2004 20 | * Removed from Open Group Base Specifications Issue 7/IEEE Std 1003.1-2008 21 | */ 22 | int _EXFUN(bcmp,(const void *, const void *, size_t)); 23 | void _EXFUN(bcopy,(const void *, void *, size_t)); 24 | void _EXFUN(bzero,(void *, size_t)); 25 | char *_EXFUN(index,(const char *, int)); 26 | char *_EXFUN(rindex,(const char *, int)); 27 | #endif /* ! __STRICT_ANSI__ */ 28 | 29 | int _EXFUN(ffs,(int)); 30 | int _EXFUN(strcasecmp,(const char *, const char *)); 31 | int _EXFUN(strncasecmp,(const char *, const char *, size_t)); 32 | 33 | _END_STD_C 34 | 35 | #endif /* _STRINGS_H_ */ 36 | -------------------------------------------------------------------------------- /kernel/lib/stdlib/abs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | 21 | #undef abs 22 | 23 | int abs(int val) 24 | { 25 | return val >= 0 ? val : -val; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/atomic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/atomic.h 3 | */ 4 | #ifndef __ARCH_X86_ATOMIC_H__ 5 | #define __ARCH_X86_ATOMIC_H__ 6 | 7 | #include 8 | 9 | /** 10 | * @brief Atomically perform: *(ptr) += add 11 | * 12 | * @return the old value of *(ptr) 13 | */ 14 | int __xadd(int *ptr, int add); 15 | #define atomic_add(ptr, add) __xadd((ptr), (add)) 16 | #define atomic_inc(ptr) __xadd((ptr), (1)) 17 | #define atomic_dec(ptr) __xadd((ptr), (-1)) 18 | 19 | /** 20 | * @brief Atomically perform: *(ptr) = value 21 | * 22 | * @return the old value of *(ptr) 23 | */ 24 | int __xchg(int *ptr, int new); 25 | #define atomic_xchg(ptr, new) __xchg((ptr), (new)) 26 | 27 | /** 28 | * @brief Atomically perform: if (*(ptr) == (cmp)) { *(ptr) = new; } 29 | * 30 | * @return the old value of *(ptr) 31 | */ 32 | int __cmpxchg(int *ptr, int old, int new); 33 | #define atomic_testandset(ptr, old, new) __cmpxchg((ptr), (old), (new)) 34 | 35 | static inline int atomic_get(int *ptr) 36 | { 37 | return *ptr; 38 | } 39 | 40 | #endif /* !__ARCH_X86_ATOMIC_H__ */ 41 | -------------------------------------------------------------------------------- /kernel/inc/dev/serial/8250.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEV_SERIAL_8250_H__ 2 | #define __DEV_SERIAL_8250_H__ 3 | 4 | /* 5 | * Offsets into the Serial Port I/O Space. 6 | * 7 | * The first 2 bytes can be used in 2 ways. When DLAB (Divisor Latch Access 8 | * Bit, bit 7 of SERIAL_PORT_LINE_CTL) is set, the first two bytes act 9 | * as writable registers for setting the Baud divisor. When DLAB is not set, 10 | * the first two bytes act as the DATA and IRQ registers. 11 | */ 12 | #define SERIAL_PORT_DATA 0x00 13 | #define SERIAL_PORT_IRQ 0x01 14 | #define SERIAL_PORT_BAUD_LSB 0x00 15 | #define SERIAL_PORT_BAUD_MSB 0x01 16 | #define SERIAL_PORT_FIFO_CTL 0x02 17 | #define SERIAL_PORT_IIR 0x02 18 | #define SERIAL_PORT_LINE_CTL 0x03 19 | #define SERIAL_PORT_MODEM_CTL 0x04 20 | #define SERIAL_PORT_LINE_STATUS 0x05 21 | #define SERIAL_PORT_MODEM_STATUS 0x06 22 | #define SERIAL_PORT_SRATCH 0x07 23 | 24 | int early_i8250_putchar(int c); 25 | void init_8250(void); 26 | void early_init_8250(void); 27 | 28 | #endif /* !__DEV_SERIAL_8250_H__ */ 29 | -------------------------------------------------------------------------------- /user/newlib/include/machine/setjmp-dj.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1991 DJ Delorie 3 | * All rights reserved. 4 | * 5 | * Redistribution, modification, and use in source and binary forms is permitted 6 | * provided that the above copyright notice and following paragraph are 7 | * duplicated in all such forms. 8 | * 9 | * This file is distributed WITHOUT ANY WARRANTY; without even the implied 10 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | /* Modified to use SETJMP_DJ_H rather than SETJMP_H to avoid 14 | conflicting with setjmp.h. Ian Taylor, Cygnus support, April, 15 | 1993. */ 16 | 17 | #ifndef _SETJMP_DJ_H_ 18 | #define _SETJMP_DJ_H_ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct { 25 | unsigned long eax; 26 | unsigned long ebx; 27 | unsigned long ecx; 28 | unsigned long edx; 29 | unsigned long esi; 30 | unsigned long edi; 31 | unsigned long ebp; 32 | unsigned long esp; 33 | unsigned long eip; 34 | } jmp_buf[1]; 35 | 36 | extern int setjmp(jmp_buf); 37 | extern void longjmp(jmp_buf, int); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /user/newlib/include/sys/_intsup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, 2005 by 3 | * Ralf Corsepius, Ulm/Germany. All rights reserved. 4 | * 5 | * Permission to use, copy, modify, and distribute this software 6 | * is freely granted, provided that this notice is preserved. 7 | */ 8 | 9 | #ifndef _SYS__INTSUP_H 10 | #define _SYS__INTSUP_H 11 | 12 | #include 13 | 14 | #if __GNUC_PREREQ (3, 2) 15 | /* gcc > 3.2 implicitly defines the values we are interested */ 16 | #define __STDINT_EXP(x) __##x##__ 17 | #else 18 | #define __STDINT_EXP(x) x 19 | #include 20 | #endif 21 | 22 | /* Check if "long long" is 64bit wide */ 23 | /* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */ 24 | #if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ 25 | || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) 26 | #define __have_longlong64 1 27 | #endif 28 | 29 | /* Check if "long" is 64bit or 32bit wide */ 30 | #if __STDINT_EXP(LONG_MAX) > 0x7fffffff 31 | #define __have_long64 1 32 | #elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) 33 | #define __have_long32 1 34 | #endif 35 | 36 | #endif /* _SYS__INTSUP_H */ 37 | -------------------------------------------------------------------------------- /user/newlib/include/sys/_stdint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, 2005 by 3 | * Ralf Corsepius, Ulm/Germany. All rights reserved. 4 | * 5 | * Permission to use, copy, modify, and distribute this software 6 | * is freely granted, provided that this notice is preserved. 7 | */ 8 | 9 | #ifndef _SYS__STDINT_H 10 | #define _SYS__STDINT_H 11 | 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #ifdef ___int8_t_defined 19 | typedef __int8_t int8_t ; 20 | typedef __uint8_t uint8_t ; 21 | #define __int8_t_defined 1 22 | #endif 23 | 24 | #ifdef ___int16_t_defined 25 | typedef __int16_t int16_t ; 26 | typedef __uint16_t uint16_t ; 27 | #define __int16_t_defined 1 28 | #endif 29 | 30 | #ifdef ___int32_t_defined 31 | typedef __int32_t int32_t ; 32 | typedef __uint32_t uint32_t ; 33 | #define __int32_t_defined 1 34 | #endif 35 | 36 | #ifdef ___int64_t_defined 37 | typedef __int64_t int64_t ; 38 | typedef __uint64_t uint64_t ; 39 | #define __int64_t_defined 1 40 | #endif 41 | 42 | typedef __intptr_t intptr_t; 43 | typedef __uintptr_t uintptr_t; 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif /* _SYS__STDINT_H */ 50 | -------------------------------------------------------------------------------- /user/sys/arch/x86/syscall.S: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @file user/sys/arch/x86/syscall.S 3 | # 4 | # 5 | # This is the user space entrance point into the kernel. Since protection is 6 | # a thing of hardware, entering kernel space is a highly architecture dependent 7 | # process. This is the entrace to the kernel for x86 architectures. 8 | # 9 | ############################################################################### 10 | 11 | .global __syscall 12 | __syscall: 13 | push %ebp 14 | movl %esp, %ebp 15 | 16 | # 17 | # save the callee-saved registers we need to use 18 | # 19 | pushl %esi 20 | pushl %edi 21 | 22 | # 23 | # eax: The system call to execute 24 | # ecx: first argument 25 | # edx: second argument 26 | # esi: third argument 27 | # edi: fourth argument 28 | # 29 | movl 0x8(%ebp), %eax 30 | movl 0xC(%ebp), %ecx 31 | movl 0x10(%ebp), %edx 32 | movl 0x14(%ebp), %esi 33 | movl 0x18(%ebp), %edi 34 | 35 | # 36 | # software trap into the kernel 37 | # 38 | int $0x80 39 | 40 | # 41 | # restore callee-saved registers 42 | # 43 | popl %edi 44 | popl %esi 45 | 46 | leave 47 | ret 48 | -------------------------------------------------------------------------------- /kernel/lib/string/rindex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | char *rindex(const char *s, int c) 23 | { 24 | char *it = 0; 25 | 26 | while (1) 27 | { 28 | if (*s == c) 29 | it = (char *)s; 30 | if (*s == 0) 31 | return it; 32 | s++; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /user/newlib/include/sys/wait.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_WAIT_H 2 | #define _SYS_WAIT_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #define WNOHANG 1 11 | #define WUNTRACED 2 12 | 13 | /* A status looks like: 14 | <2 bytes info> <2 bytes code> 15 | 16 | == 0, child has exited, info is the exit value 17 | == 1..7e, child has exited, info is the signal number. 18 | == 7f, child has stopped, info was the signal number. 19 | == 80, there was a core dump. 20 | */ 21 | 22 | #define WIFEXITED(w) (((w) & 0xff) == 0) 23 | #define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f)) 24 | #define WIFSTOPPED(w) (((w) & 0xff) == 0x7f) 25 | #define WEXITSTATUS(w) (((w) >> 8) & 0xff) 26 | #define WTERMSIG(w) ((w) & 0x7f) 27 | #define WSTOPSIG WEXITSTATUS 28 | 29 | pid_t wait (int *); 30 | pid_t waitpid (pid_t, int *, int); 31 | 32 | #ifdef _COMPILING_NEWLIB 33 | pid_t _wait (int *); 34 | #endif 35 | 36 | /* Provide prototypes for most of the _ names that are 37 | provided in newlib for some compilers. */ 38 | pid_t _wait (int *); 39 | 40 | #ifdef __cplusplus 41 | }; 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /user/newlib/include/wctype.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCTYPE_H_ 2 | #define _WCTYPE_H_ 3 | 4 | #include <_ansi.h> 5 | #include 6 | 7 | #define __need_wint_t 8 | #include 9 | 10 | #ifndef WEOF 11 | # define WEOF ((wint_t)-1) 12 | #endif 13 | 14 | _BEGIN_STD_C 15 | 16 | #ifndef _WCTYPE_T 17 | #define _WCTYPE_T 18 | typedef int wctype_t; 19 | #endif 20 | 21 | #ifndef _WCTRANS_T 22 | #define _WCTRANS_T 23 | typedef int wctrans_t; 24 | #endif 25 | 26 | int _EXFUN(iswalpha, (wint_t)); 27 | int _EXFUN(iswalnum, (wint_t)); 28 | int _EXFUN(iswblank, (wint_t)); 29 | int _EXFUN(iswcntrl, (wint_t)); 30 | int _EXFUN(iswctype, (wint_t, wctype_t)); 31 | int _EXFUN(iswdigit, (wint_t)); 32 | int _EXFUN(iswgraph, (wint_t)); 33 | int _EXFUN(iswlower, (wint_t)); 34 | int _EXFUN(iswprint, (wint_t)); 35 | int _EXFUN(iswpunct, (wint_t)); 36 | int _EXFUN(iswspace, (wint_t)); 37 | int _EXFUN(iswupper, (wint_t)); 38 | int _EXFUN(iswxdigit, (wint_t)); 39 | wint_t _EXFUN(towctrans, (wint_t, wctrans_t)); 40 | wint_t _EXFUN(towupper, (wint_t)); 41 | wint_t _EXFUN(towlower, (wint_t)); 42 | wctrans_t _EXFUN(wctrans, (const char *)); 43 | wctype_t _EXFUN(wctype, (const char *)); 44 | 45 | _END_STD_C 46 | 47 | #endif /* _WCTYPE_H_ */ 48 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # Operating System Makefile 4 | # 5 | # 6 | .PHONY: default kernel user tools iso clean tags 7 | 8 | default: iso 9 | 10 | # 11 | # Create an .iso (CDROM image) that can boot the os 12 | # 13 | iso: kernel user initrd boot/grub.cfg 14 | mkdir -p iso 15 | mkdir -p iso/boot 16 | mkdir -p iso/boot/grub 17 | cp kernel/KERNEL.o iso/boot/KERNEL.o 18 | cp boot/grub.cfg iso/boot/grub/grub.cfg 19 | cp initrd.img iso/boot/ 20 | grub-mkrescue -o OS.iso iso 21 | 22 | # 23 | # Create the initial ramdisk needed to use the operating system 24 | # 25 | initrd: kernel user tools 26 | tools/create_initrd initrd.img user/bin/* boot/initrd/* 27 | 28 | # 29 | # Build the kernel sources into an object file 30 | # 31 | kernel: 32 | +make -j8 -C kernel/ 33 | 34 | # 35 | # Build the user progams into executables compatable with kernel 36 | # 37 | user: 38 | +make -C user/ 39 | 40 | # 41 | # Build the tools used to build the kernel and os 42 | # 43 | tools: 44 | +make -C tools/ 45 | 46 | tags: 47 | find . -name '*.[cshS]' | xargs ctags 48 | 49 | clean: 50 | +make -C kernel/ clean 51 | +make -C user/ clean 52 | +make -C tools/ clean 53 | rm -f initrd.img 54 | rm -rf iso 55 | rm -rf OS.iso 56 | rm -rf tags 57 | -------------------------------------------------------------------------------- /kernel/lib/fmt/_printf.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file _printf.c 3 | * 4 | * @brief A putchar-agnostic printf. Yeah! 5 | * 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | static void _puts(struct printf_state *p, char *s) { 13 | while (*s) { 14 | p->putchar(*s); 15 | s++; 16 | } 17 | p->putchar('\n'); 18 | } 19 | 20 | static void _flush(struct printf_state *p) { 21 | unsigned int i; 22 | 23 | for (i = 0; i < p->index; i++) 24 | p->putchar(p->buf[i]); 25 | 26 | p->index = 0; 27 | } 28 | 29 | static void _printf_callback(char *arg, int c) { 30 | struct printf_state *p = (struct printf_state *) arg; 31 | 32 | if (c == '\n') { 33 | p->buf[p->index] = 0; 34 | _puts(p, p->buf); 35 | p->index = 0; 36 | } 37 | else if ((c == 0) || (p->index >= _PRINTF_BUFMAX)) { 38 | _flush(p); 39 | p->putchar(c); 40 | } 41 | else { 42 | p->buf[p->index] = (char) c; 43 | p->index++; 44 | } 45 | } 46 | 47 | int _vprintf(struct printf_state *p, const char *fmt, va_list args) { 48 | 49 | p->index = 0; 50 | 51 | _doprnt(fmt, args, 0, (void (*)())_printf_callback, (char *) p); 52 | 53 | if (p->index != 0) { 54 | _flush(p); 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /kernel/mm/malloc/malloc_lmm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include "malloc_internal.h" 23 | 24 | lmm_t malloc_lmm = LMM_INITIALIZER; 25 | 26 | -------------------------------------------------------------------------------- /kernel/inc/lib/stdint.h: -------------------------------------------------------------------------------- 1 | /* @file lib/stdint.h 2 | * @author matthewj S2008 3 | * @brief Standard integer type definitions 4 | */ 5 | 6 | #ifndef LIB_STDINT_H 7 | #define LIB_STDINT_H 8 | 9 | #ifndef ASSEMBLER 10 | 11 | typedef unsigned char uint8_t; 12 | typedef unsigned short uint16_t; 13 | typedef unsigned long uint32_t; 14 | typedef unsigned long long uint64_t; 15 | 16 | typedef signed char int8_t; 17 | typedef signed short int16_t; 18 | typedef signed long int32_t; 19 | typedef signed long long int64_t; 20 | 21 | typedef int intptr_t; 22 | typedef unsigned int uintptr_t; 23 | 24 | #define u8 uint8_t 25 | #define u16 uint16_t 26 | #define u32 uint32_t 27 | #define u64 uint64_t 28 | 29 | #define s8 int8_t 30 | #define s16 int16_t 31 | #define s32 int32_t 32 | #define s64 int64_t 33 | 34 | /* from the linux kernel */ 35 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 36 | 37 | /* Compile-time assertions for types.h. */ 38 | static inline void ____check_types____(void) 39 | { 40 | BUILD_BUG_ON(sizeof(u8) != 1); 41 | BUILD_BUG_ON(sizeof(u16) != 2); 42 | BUILD_BUG_ON(sizeof(u32) != 4); 43 | BUILD_BUG_ON(sizeof(u64) != 8); 44 | } 45 | 46 | #endif /* !ASSEMBLER */ 47 | 48 | #endif /* !LIB_STDINT_H */ 49 | -------------------------------------------------------------------------------- /kernel/kernel/mutex.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void mutex_aquire(struct mutex *m) 7 | { 8 | struct thread *current = CURRENT_THREAD; 9 | unsigned long flags; 10 | 11 | spin_lock_irq(&m->lock, &flags); 12 | 13 | while (m->owner) { 14 | begin_wait(&m->wait); 15 | 16 | spin_unlock_irq(&m->lock, flags); 17 | 18 | /* 19 | * I think racing with the owner releasing the mutex is 20 | * ok here. We will just reschedule when we really could 21 | * have kept running. 22 | * 23 | * This assumes make_runnable() (which sets our state to 24 | * runnable) cannot run concurrently with reschedule() 25 | * (which makes a decides whether to add us back on the 26 | * runqueue based on our state). Currently, that assumpt- 27 | * ion holds. 28 | */ 29 | reschedule(); 30 | 31 | spin_lock_irq(&m->lock, &flags); 32 | } 33 | 34 | m->owner = current; 35 | spin_unlock_irq(&m->lock, flags); 36 | } 37 | 38 | void mutex_release(struct mutex *m) 39 | { 40 | unsigned long flags; 41 | 42 | spin_lock_irq(&m->lock, &flags); 43 | 44 | m->owner = NULL; 45 | kick(&m->wait); 46 | 47 | spin_unlock_irq(&m->lock, flags); 48 | } 49 | -------------------------------------------------------------------------------- /kernel/inc/kernel/log.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file debug/log.h 3 | */ 4 | #ifndef __KERNEL_LOG_H__ 5 | #define __KERNEL_LOG_H__ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Set up logging during early boot (will not use any locks, memory 14 | * allocations, or any other features which require a full kernel 15 | * initialization. 16 | */ 17 | void early_log_init(int (*putchar)(int), int level); 18 | 19 | void log_init(void); 20 | 21 | int log(const char *fmt, ...); 22 | bool log_check(int level); 23 | 24 | #define log_level(_level, _fmt, ...) do { \ 25 | if (!log_check(_level)) \ 26 | break; \ 27 | log(_fmt, ##__VA_ARGS__); \ 28 | } while (0) 29 | 30 | #define INFO(_fmt, ...) log_level(LOG_INFO, "I "_fmt"\n", ##__VA_ARGS__) 31 | #define WARN(_fmt, ...) log_level(LOG_WARN, "W "_fmt"\n", ##__VA_ARGS__) 32 | #define ERROR(_fmt, ...) log_level(LOG_ERROR, "E "_fmt"\n", ##__VA_ARGS__) 33 | #define DEBUG(_fmt, ...) log_level(LOG_DEBUG, "D "_fmt"\n", ##__VA_ARGS__) 34 | #define FATAL(_fmt, ...) log("F "_fmt"\n", ##__VA_ARGS__) 35 | 36 | #define TRACE(_fmt, ...) DEBUG("%s("_fmt")", __func__, ##__VA_ARGS__) 37 | 38 | #endif /* !__KERNEL_LOG_H__ */ 39 | -------------------------------------------------------------------------------- /kernel/lib/string/strncmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | 21 | int 22 | strncmp(const char *s1, const char *s2, size_t n) 23 | { 24 | while (1) 25 | { 26 | if (n <= 0) 27 | return 0; 28 | if (*s1 != *s2) 29 | return *s1 - *s2; 30 | if (*s1 == 0) 31 | return 0; 32 | 33 | s1++; 34 | s2++; 35 | n--; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /kernel/kernel/loader.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/loader.c 3 | * 4 | * @brief Loading executables into memory. 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | static inline ssize_t read_header(struct vfs_file *file, char *buf, unsigned bufsz) 20 | { 21 | memset(buf, 0, bufsz); 22 | return vfs_read(file, buf, bufsz); 23 | } 24 | 25 | int load_binary(struct vfs_file *file) 26 | { 27 | #define HDRSZ 4 // increase if new binary formats use larger headers 28 | char header[HDRSZ]; 29 | ssize_t bytes; 30 | 31 | if (!(file->dirent->inode->perm & VFS_X)) { 32 | WARN("Tried to load non-executable file: %s", file->dirent->name); 33 | return EPERM; 34 | } 35 | 36 | /* 37 | * Read the first few bytes of the file to use to determine the executable 38 | * format. 39 | */ 40 | bytes = read_header(file, header, HDRSZ); 41 | 42 | if (is_elf32(header, bytes)) { 43 | return elf32_load(file); 44 | } 45 | // ... 46 | 47 | DEBUG("File %s does not match any executable formats.", file->dirent->name); 48 | return EFAULT; 49 | } 50 | -------------------------------------------------------------------------------- /kernel/lib/string/strdup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | char *strdup(const char *src) 25 | { 26 | (void)src; 27 | panic("You forgot to fix strdup!"); 28 | //char *buf = malloc(strlen(src)+1); 29 | //if (buf) 30 | //strcpy(buf, src); 31 | //return buf; 32 | return NULL; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /kernel/lib/stdlib/rand.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | 21 | static unsigned seed[2]; 22 | 23 | int 24 | rand(void) 25 | { 26 | seed[0] += 0xa859c317; 27 | seed[0] += (seed[1] << 13) | (seed[1] >> 19); 28 | seed[1] += seed[0]; 29 | return seed[0] & 0x7FFFFFFF; 30 | } 31 | 32 | void 33 | srand(unsigned new_seed) 34 | { 35 | seed[0] = seed[1] = new_seed; 36 | } 37 | -------------------------------------------------------------------------------- /kernel/mm/lmm/lmm_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | void lmm_init(lmm_t *lmm) 26 | { 27 | lmm->regions = 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /kernel/inc/kernel/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/config.h 3 | * 4 | * @brief All static kernel configuration parameters. 5 | */ 6 | #ifndef __KERNEL_CONFIG_H__ 7 | #define __KERNEL_CONFIG_H__ 8 | 9 | /* 10 | * The kernel's virtual address space. 11 | */ 12 | #define CONFIG_KERNEL_VIRTUAL_START 0x00000000 13 | #define CONFIG_KERNEL_VIRTUAL_END 0x40000000 14 | #define CONFIG_KERNEL_VIRTUAL_SIZE (CONFIG_KERNEL_VIRTUAL_END - CONFIG_KERNEL_VIRTUAL_START) 15 | 16 | #define CONFIG_KMAP_MIN_SIZE MB(128) 17 | #define CONFIG_KHEAP_MAX_END (CONFIG_KERNEL_VIRTUAL_END - CONFIG_KMAP_MIN_SIZE) 18 | 19 | /* 20 | * The user's virtual address space. 21 | */ 22 | #define CONFIG_USER_VIRTUAL_START 0x40000000 23 | #define CONFIG_USER_VIRTUAL_END 0xFFFFF000 24 | #define CONFIG_USER_VIRTUAL_SIZE (CONFIG_USER_VIRTUAL_END - CONFIG_USER_VIRTUAL_START) 25 | 26 | /* 27 | * The default frequency (times per second) to receive hardware interrupts 28 | * from the timer. 29 | */ 30 | #define CONFIG_TIMER_HZ 100 31 | 32 | #define LOG_ERROR 0 33 | #define LOG_WARN 1 34 | #define LOG_INFO 2 35 | #define LOG_DEBUG 3 36 | #define CONFIG_LOG_LEVEL LOG_INFO 37 | 38 | #endif /* !__KERNEL_CONFIG_H__ */ 39 | -------------------------------------------------------------------------------- /kernel/arch/x86/cpu.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file x86/cpu.c 3 | * 4 | * @brief General processor level enable/disable functions, low level 5 | * tweaking, etc. 6 | * 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #define GENERATE_CRX_SET_BIT_FN(_CRX_) \ 19 | void cr##_CRX_##_set_bit(int index, int bit) { \ 20 | int cr = get_cr##_CRX_(); \ 21 | set_bit(&cr, index, bit); \ 22 | set_cr##_CRX_(cr); \ 23 | } 24 | GENERATE_CRX_SET_BIT_FN(0) 25 | GENERATE_CRX_SET_BIT_FN(4) 26 | 27 | void enable_paging(void) 28 | { 29 | TRACE(); 30 | cr0_set_bit(CR0_PG, 1); 31 | } 32 | 33 | void disable_paging(void) 34 | { 35 | TRACE(); 36 | cr0_set_bit(CR0_PG, 0); 37 | } 38 | 39 | void enable_protected_mode(void) 40 | { 41 | TRACE(); 42 | cr0_set_bit(CR0_PE, 1); 43 | } 44 | 45 | void enable_real_mode(void) 46 | { 47 | TRACE(); 48 | cr0_set_bit(CR0_PE, 0); 49 | } 50 | 51 | void disable_fpu(void) 52 | { 53 | TRACE(); 54 | cr0_set_bit(CR0_EM, 1); 55 | } 56 | 57 | void enable_global_pages(void) 58 | { 59 | TRACE(); 60 | cr4_set_bit(CR4_PGE, 1); 61 | } 62 | 63 | void enable_write_protect(void) 64 | { 65 | TRACE(); 66 | cr0_set_bit(CR0_WP, 1); 67 | } 68 | -------------------------------------------------------------------------------- /kernel/inc/kernel/spinlock.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/spinlock.h 3 | */ 4 | #ifndef __KERNEL_SPINLOCK_H__ 5 | #define __KERNEL_SPINLOCK_H__ 6 | 7 | struct spinlock { 8 | /* the next ticket to hand out */ 9 | int ticket; 10 | /* the ticket of the customer currently being served */ 11 | int serving; 12 | }; 13 | 14 | #define INITIALIZED_SPINLOCK { \ 15 | .ticket = 0, \ 16 | .serving = 0, \ 17 | } 18 | 19 | static inline void spin_lock_init(struct spinlock *s) 20 | { 21 | s->ticket = 0; 22 | s->serving = 0; 23 | } 24 | 25 | /* 26 | * Does nothing except aquire and release a spin lock. 27 | * 28 | * Reasons to use this instead of spin_{lock,unlock}: 29 | * - You don't want preemption disabled during the lock. 30 | * - You don't want to potentially reschedule on unlock. 31 | */ 32 | void __spin_lock(struct spinlock *s); 33 | void __spin_unlock(struct spinlock *s); 34 | void __spin_lock_irq(struct spinlock *s, unsigned long *flags); 35 | void __spin_unlock_irq(struct spinlock *s, unsigned long flags); 36 | 37 | void spin_lock(struct spinlock *s); 38 | void spin_unlock(struct spinlock *s); 39 | void spin_lock_irq(struct spinlock *s, unsigned long *flags); 40 | void spin_unlock_irq(struct spinlock *s, unsigned long flags); 41 | 42 | #endif /* !__KERNEL_SPINLOCK_H__ */ 43 | -------------------------------------------------------------------------------- /kernel/mm/malloc/free.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include "malloc_internal.h" 23 | 24 | void _free(void *chunk_ptr) 25 | { 26 | size_t *chunk = (size_t*)chunk_ptr - 1; 27 | lmm_free(&malloc_lmm, chunk, *chunk); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /kernel/dev/ide/ide.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dev/ide/ide.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /** 10 | * @brief Initialize a new IDE controller with the following parameters. 11 | * 12 | * @param bm_offset The I/O address of the bus master I/O block. 13 | * @param irq The irq tied to this IDE. 14 | * @param ata_cmd The I/O address of the ATA command block. 15 | * @param ata_ctl The I/O address of the ATA control block. 16 | * 17 | * @return 18 | * 0 on success 19 | * ENOMEM if the kernel runs out of memory 20 | */ 21 | int ide_init(struct ide_device *ide, unsigned bm_offset, int irq, 22 | unsigned ata_cmd, unsigned ata_ctl) 23 | { 24 | int ret; 25 | 26 | /* 27 | * Initialize the ata bus 28 | */ 29 | ret = ata_bus_init(&ide->ata, irq, ata_cmd, ata_ctl); 30 | if (ret) goto cleanup_ata; 31 | 32 | /* 33 | * Initialize the bus master 34 | */ 35 | ret = pci_init_bm(&ide->bm, bm_offset); 36 | if (ret) goto cleanup_bm; 37 | 38 | return 0; 39 | cleanup_bm: 40 | ata_bus_destroy(&ide->ata); 41 | cleanup_ata: 42 | return ret; 43 | } 44 | 45 | /** 46 | * @brief Free all memory held by an ide_device struct. Do not free the 47 | * ide_device struct itself. 48 | */ 49 | void ide_destroy(struct ide_device *ide) 50 | { 51 | (void) ide; 52 | } 53 | -------------------------------------------------------------------------------- /kernel/dev/serial/serial.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dev/serial/serial.c 3 | * 4 | * @brief Serial subsystem. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | serial_port_list_t serial_ports = INITIALIZED_EMPTY_LIST; 14 | struct spinlock serial_ports_lock = INITIALIZED_SPINLOCK; 15 | 16 | void register_serial_port(struct serial_port *s) 17 | { 18 | unsigned long flags; 19 | int ret; 20 | 21 | ret = s->init(s); 22 | if (ret) 23 | return; 24 | 25 | spin_lock_irq(&serial_ports_lock, &flags); 26 | list_insert_tail(&serial_ports, s, list); 27 | spin_unlock_irq(&serial_ports_lock, flags); 28 | } 29 | 30 | struct serial_port *reserve_serial_port(const char *purpose) 31 | { 32 | struct serial_port *reserved = NULL; 33 | struct serial_port *s; 34 | unsigned long flags; 35 | 36 | spin_lock_irq(&serial_ports_lock, &flags); 37 | 38 | list_foreach(s, &serial_ports, list) { 39 | if (!s->reserved) { 40 | s->purpose = purpose; 41 | s->reserved = true; 42 | reserved = s; 43 | break; 44 | } 45 | } 46 | 47 | spin_unlock_irq(&serial_ports_lock, flags); 48 | 49 | return reserved; 50 | } 51 | 52 | void serial_putchar(struct serial_port *s, char c) 53 | { 54 | if (s->putchar) 55 | s->putchar(s, c); 56 | } 57 | -------------------------------------------------------------------------------- /kernel/mm/lmm/lmm_free_page.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | void lmm_free_page(lmm_t *lmm, void *page) 27 | { 28 | return lmm_free(lmm, page, PAGE_SIZE); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /kernel/lib/string/strcat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | 27 | char * 28 | strcat(s, add) 29 | register char *s, *add; 30 | { 31 | register char *ret = s; 32 | 33 | while (*s) s++; 34 | 35 | while ((*s++ = *add++) != 0); 36 | 37 | return ret; 38 | } 39 | -------------------------------------------------------------------------------- /kernel/lib/string/strchr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | 24 | char *strchr(const char *s, int c) 25 | { 26 | while (1) 27 | { 28 | if (*s == c) 29 | return (char*)s; 30 | if (*s == 0) 31 | return 0; 32 | s++; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /user/newlib/include/_syslist.h: -------------------------------------------------------------------------------- 1 | /* internal use only -- mapping of "system calls" for libraries that lose 2 | and only provide C names, so that we end up in violation of ANSI */ 3 | #ifndef __SYSLIST_H 4 | #define __SYSLIST_H 5 | 6 | #ifdef MISSING_SYSCALL_NAMES 7 | #define _close close 8 | #define _execve execve 9 | #define _fcntl fcntl 10 | #define _fork fork 11 | #define _fstat fstat 12 | #define _getpid getpid 13 | #define _gettimeofday gettimeofday 14 | #define _isatty isatty 15 | #define _kill kill 16 | #define _link link 17 | #define _lseek lseek 18 | #define _mkdir mkdir 19 | #define _open open 20 | #define _read read 21 | #define _sbrk sbrk 22 | #define _stat stat 23 | #define _times times 24 | #define _unlink unlink 25 | #define _wait wait 26 | #define _write write 27 | #endif /* MISSING_SYSCALL_NAMES */ 28 | 29 | #if defined MISSING_SYSCALL_NAMES || !defined HAVE_OPENDIR 30 | /* If the system call interface is missing opendir, readdir, and 31 | closedir, there is an implementation of these functions in 32 | libc/posix that is implemented using open, getdents, and close. 33 | Note, these functions are currently not in the libc/syscalls 34 | directory. */ 35 | #define _opendir opendir 36 | #define _readdir readdir 37 | #define _closedir closedir 38 | #endif /* MISSING_SYSCALL_NAMES || !HAVE_OPENDIR */ 39 | 40 | #endif /* !__SYSLIST_H_ */ 41 | -------------------------------------------------------------------------------- /kernel/mm/malloc/sfree.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | /* 22 | * Routine to free memory blocks allocated with smalloc(), smemalign(), etc. 23 | */ 24 | 25 | #include "malloc_internal.h" 26 | 27 | void _sfree(void *chunk, size_t size) 28 | { 29 | lmm_free(&malloc_lmm, chunk, size); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /kernel/inc/lib/ctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | #ifndef _FLUX_MC_CTYPE_H_ 19 | #define _FLUX_MC_CTYPE_H_ 20 | 21 | int isascii(int c); 22 | int iscntrl(int c); 23 | int isdigit(int c); 24 | int isgraph(int c); 25 | int islower(int c); 26 | int isprint(int c); 27 | int isspace(int c); 28 | int isupper(int c); 29 | int isxdigit(int c); 30 | int isalpha(int c); 31 | int isalnum(int c); 32 | int ispunct(int c); 33 | int toupper(int c); 34 | int tolower(int c); 35 | 36 | 37 | #endif /* _FLUX_MC_CTYPE_H_ */ 38 | -------------------------------------------------------------------------------- /kernel/lib/string/strrchr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | char * 26 | strrchr(const char *s, int c) 27 | { 28 | char *save; 29 | 30 | for (save = NULL; *s != '\0'; s++) 31 | if (*s == c) 32 | save = (char *)s; 33 | 34 | return save; 35 | } 36 | -------------------------------------------------------------------------------- /kernel/inc/lib/fmt/doscan.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #ifndef __DOSCAN_H_INCLUDED__ 23 | #define __DOSCAN_H_INCLUDED__ 24 | 25 | int _doscan(const char *fmt, va_list vp, 26 | int (*getc)(void *getc_arg), 27 | void (*ungetc)(int c, void *getc_arg), 28 | void *getc_arg); 29 | 30 | #endif /* __DOSCAN_H_INCLUDED__ */ 31 | -------------------------------------------------------------------------------- /kernel/mm/lmm/lmm_alloc_page.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | void *lmm_alloc_page(lmm_t *lmm, lmm_flags_t flags) 27 | { 28 | return lmm_alloc_gen(lmm, PAGE_SIZE, flags, PAGE_SIZE, 0, 29 | (vm_offset_t)0, (vm_size_t)-1); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /user/newlib/include/assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | assert.h 3 | */ 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "_ansi.h" 10 | 11 | #undef assert 12 | 13 | #ifdef NDEBUG /* required by ANSI standard */ 14 | # define assert(__e) ((void)0) 15 | #else 16 | # define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ 17 | __ASSERT_FUNC, #__e)) 18 | 19 | # ifndef __ASSERT_FUNC 20 | /* Use g++'s demangled names in C++. */ 21 | # if defined __cplusplus && defined __GNUC__ 22 | # define __ASSERT_FUNC __PRETTY_FUNCTION__ 23 | 24 | /* C99 requires the use of __func__. */ 25 | # elif __STDC_VERSION__ >= 199901L 26 | # define __ASSERT_FUNC __func__ 27 | 28 | /* Older versions of gcc don't have __func__ but can use __FUNCTION__. */ 29 | # elif __GNUC__ >= 2 30 | # define __ASSERT_FUNC __FUNCTION__ 31 | 32 | /* failed to detect __func__ support. */ 33 | # else 34 | # define __ASSERT_FUNC ((char *) 0) 35 | # endif 36 | # endif /* !__ASSERT_FUNC */ 37 | #endif /* !NDEBUG */ 38 | 39 | void _EXFUN(__assert, (const char *, int, const char *) 40 | _ATTRIBUTE ((__noreturn__))); 41 | void _EXFUN(__assert_func, (const char *, int, const char *, const char *) 42 | _ATTRIBUTE ((__noreturn__))); 43 | 44 | #if __STDC_VERSION__ >= 201112L && !defined __cplusplus 45 | # define static_assert _Static_assert 46 | #endif 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /kernel/arch/x86/backtrace.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/x86/backtrace.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern char boot_stack_bottom[]; 10 | extern char boot_stack_top[]; 11 | 12 | static inline bool on_boot_stack(void) 13 | { 14 | char *sp = (void *) get_sp(); 15 | 16 | return (boot_stack_bottom <= sp && sp < boot_stack_top); 17 | } 18 | 19 | void backtrace(void) 20 | { 21 | unsigned long *stack_start, *stack_end; 22 | unsigned long *bp = (void *) get_ebp(); 23 | 24 | if (on_boot_stack()) { 25 | stack_start = (void *) boot_stack_bottom; 26 | stack_end = (void *) boot_stack_top; 27 | INFO("early boot"); 28 | } else { 29 | stack_start = (void *) KSTACK_START; 30 | stack_end = (void *) KSTACK_END; 31 | INFO("task %d:%d", CURRENT_PROCESS->pid, CURRENT_THREAD->tid); 32 | } 33 | 34 | INFO("stack [0x%08x, 0x%08x]", (unsigned long) stack_start, 35 | (unsigned long) stack_end); 36 | 37 | while (stack_start <= bp && bp < stack_end) { 38 | unsigned long return_address = *(bp + 1); 39 | struct symbol *symbol = resolve_symbol(return_address); 40 | 41 | if (symbol) { 42 | INFO(" 0x%08x %-30s+0x%x", 43 | return_address, symbol->name, 44 | return_address - symbol->address); 45 | } else 46 | INFO(" 0x%08x ???", return_address); 47 | 48 | 49 | bp = (void *) *bp; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /kernel/lib/string/strstr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | #pragma GCC diagnostic push 19 | #pragma GCC diagnostic ignored "-Wsign-conversion" 20 | 21 | #include 22 | #include 23 | 24 | char *strstr(const char *haystack, const char *needle) 25 | { 26 | int hlen = strlen(haystack); 27 | int nlen = strlen(needle); 28 | 29 | while (hlen >= nlen) 30 | { 31 | if (!memcmp(haystack, needle, nlen)) 32 | return (void*)haystack; 33 | 34 | haystack++; 35 | hlen--; 36 | } 37 | return 0; 38 | } 39 | 40 | #pragma GCC diagnostic pop 41 | -------------------------------------------------------------------------------- /kernel/kernel/log.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/log.c 3 | * 4 | * TODO: support time-stamped log messages 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | struct logger { 19 | struct printf_state state; 20 | int level; 21 | struct serial_port *serial_port; 22 | }; 23 | 24 | static struct logger logger; 25 | 26 | int log_putchar(int c) 27 | { 28 | if (logger.serial_port) 29 | serial_putchar(logger.serial_port, (char) c); 30 | 31 | #ifdef BOCHS 32 | bochs_putchar(c); 33 | #endif 34 | 35 | return c; 36 | } 37 | 38 | void log_init(void) 39 | { 40 | logger.level = CONFIG_LOG_LEVEL; 41 | logger.state.putchar = log_putchar; 42 | 43 | /* TODO: allow other ways of logging. */ 44 | logger.serial_port = reserve_serial_port("log"); 45 | ASSERT(logger.serial_port); 46 | } 47 | 48 | void early_log_init(int (*putchar)(int), int level) 49 | { 50 | logger.level = level; 51 | logger.state.putchar = putchar; 52 | } 53 | 54 | bool log_check(int level) 55 | { 56 | return level <= logger.level; 57 | } 58 | 59 | int log(const char *fmt, ...) 60 | { 61 | va_list args; 62 | int ret; 63 | 64 | va_start(args, fmt); 65 | 66 | ret = _vprintf(&logger.state, fmt, args); 67 | 68 | va_end(args); 69 | 70 | return ret; 71 | } 72 | -------------------------------------------------------------------------------- /kernel/lib/string/memset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | #pragma GCC diagnostic push 22 | #pragma GCC diagnostic ignored "-Wconversion" 23 | 24 | #include 25 | 26 | void * 27 | memset(void *tov, int c, size_t len) 28 | { 29 | register char *to = tov; 30 | 31 | while (len-- > 0) 32 | *to++ = c; 33 | 34 | return tov; 35 | } 36 | 37 | #pragma GCC diagnostic pop 38 | -------------------------------------------------------------------------------- /kernel/mm/lmm/lmm_alloc_aligned.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | void *lmm_alloc_aligned(lmm_t *lmm, vm_size_t size, lmm_flags_t flags, 26 | int align_bits, vm_offset_t align_ofs) 27 | { 28 | return lmm_alloc_gen(lmm, size, flags, 29 | align_bits, align_ofs, 30 | (vm_offset_t)0, (vm_size_t)-1); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /user/newlib/include/argz.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. 2 | * 3 | * Permission to use, copy, modify, and distribute this software 4 | * is freely granted, provided that this notice is preserved. 5 | */ 6 | 7 | #ifndef _ARGZ_H_ 8 | #define _ARGZ_H_ 9 | 10 | #include 11 | #include 12 | 13 | #include "_ansi.h" 14 | 15 | _BEGIN_STD_C 16 | 17 | /* The newlib implementation of these functions assumes that sizeof(char) == 1. */ 18 | error_t argz_create (char *const argv[], char **argz, size_t *argz_len); 19 | error_t argz_create_sep (const char *string, int sep, char **argz, size_t *argz_len); 20 | size_t argz_count (const char *argz, size_t argz_len); 21 | void argz_extract (char *argz, size_t argz_len, char **argv); 22 | void argz_stringify (char *argz, size_t argz_len, int sep); 23 | error_t argz_add (char **argz, size_t *argz_len, const char *str); 24 | error_t argz_add_sep (char **argz, size_t *argz_len, const char *str, int sep); 25 | error_t argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len); 26 | error_t argz_delete (char **argz, size_t *argz_len, char *entry); 27 | error_t argz_insert (char **argz, size_t *argz_len, char *before, const char *entry); 28 | char * argz_next (char *argz, size_t argz_len, const char *entry); 29 | error_t argz_replace (char **argz, size_t *argz_len, const char *str, const char *with, unsigned *replace_count); 30 | 31 | _END_STD_C 32 | 33 | #endif /* _ARGZ_H_ */ 34 | -------------------------------------------------------------------------------- /user/newlib/include/tar.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tar.h 3 | */ 4 | 5 | #ifndef _TAR_H 6 | #define _TAR_H 7 | 8 | /* General definitions */ 9 | #define TMAGIC "ustar" /* ustar plus null byte. */ 10 | #define TMAGLEN 6 /* Length of the above. */ 11 | #define TVERSION "00" /* 00 without a null byte. */ 12 | #define TVERSLEN 2 /* Length of the above. */ 13 | 14 | /* Typeflag field definitions */ 15 | #define REGTYPE '0' /* Regular file. */ 16 | #define AREGTYPE '\0' /* Regular file. */ 17 | #define LNKTYPE '1' /* Link. */ 18 | #define SYMTYPE '2' /* Symbolic link. */ 19 | #define CHRTYPE '3' /* Character special. */ 20 | #define BLKTYPE '4' /* Block special. */ 21 | #define DIRTYPE '5' /* Directory. */ 22 | #define FIFOTYPE '6' /* FIFO special. */ 23 | #define CONTTYPE '7' /* Reserved. */ 24 | 25 | /* Mode field bit definitions (octal) */ 26 | #define TSUID 04000 /* Set UID on execution. */ 27 | #define TSGID 02000 /* Set GID on execution. */ 28 | #define TSVTX 01000 /* On directories, restricted deletion flag. */ 29 | #define TUREAD 00400 /* Read by owner. */ 30 | #define TUWRITE 00200 /* Write by owner. */ 31 | #define TUEXEC 00100 /* Execute/search by owner. */ 32 | #define TGREAD 00040 /* Read by group. */ 33 | #define TGWRITE 00020 /* Write by group. */ 34 | #define TGEXEC 00010 /* Execute/search by group. */ 35 | #define TOREAD 00004 /* Read by other. */ 36 | #define TOWRITE 00002 /* Write by other. */ 37 | #define TOEXEC 00001 /* Execute/search by other. */ 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /kernel/inc/lib/fmt/doprnt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #ifndef __DOPRNT_H_INCLUDED__ 23 | #define __DOPRNT_H_INCLUDED__ 24 | 25 | #include 26 | 27 | void _doprnt( 28 | register const char *fmt, 29 | va_list args, 30 | int radix, /* default radix - for '%r' */ 31 | void (*putc)(), /* character output */ 32 | char *putc_arg); /* argument for putc */ 33 | 34 | #endif /* __DOPRNT_H_INCLUDED__ */ 35 | -------------------------------------------------------------------------------- /user/progs/fork_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #define CHECK(_condition) do { \ 9 | int __condition = (_condition); \ 10 | \ 11 | if (__condition) \ 12 | break; \ 13 | \ 14 | printf("FAILED: %s [%d]\n", #_condition, __condition); \ 15 | exit(42); \ 16 | } while (0) 17 | 18 | #define NUM_CHILDREN 100 19 | 20 | void run_parent(void) 21 | { 22 | int children_reaped = 0; 23 | int status; 24 | 25 | for (; children_reaped < NUM_CHILDREN; children_reaped++) { 26 | int ret; 27 | 28 | for (;;) { 29 | ret = wait(&status); 30 | if (!ret) 31 | break; 32 | 33 | yield(); 34 | } 35 | 36 | printf("wait(): ret %d status %d\n", ret, status); 37 | } 38 | 39 | /* we should have no children left to reap */ 40 | CHECK(wait(&status) < 0); 41 | } 42 | 43 | void run_child(void) 44 | { 45 | int children_created = 1; /* we're already a child */ 46 | 47 | for (; children_created < NUM_CHILDREN; children_created++) { 48 | int ret = fork(); 49 | CHECK(ret >= 0); 50 | 51 | /* Each process forks once then exits. */ 52 | if (ret) 53 | break; 54 | } 55 | } 56 | 57 | /* chain fork a large number of children. */ 58 | int main(int argc, char **argv) 59 | { 60 | (void) argc; (void) argv; 61 | int ret; 62 | 63 | ret = fork(); 64 | CHECK(ret >= 0); 65 | 66 | if (ret) 67 | run_parent(); 68 | else 69 | run_child(); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /user/newlib/include/locale.h: -------------------------------------------------------------------------------- 1 | /* 2 | locale.h 3 | Values appropriate for the formatting of monetary and other 4 | numberic quantities. 5 | */ 6 | 7 | #ifndef _LOCALE_H_ 8 | #define _LOCALE_H_ 9 | 10 | #include "_ansi.h" 11 | 12 | #define __need_NULL 13 | #include 14 | 15 | #define LC_ALL 0 16 | #define LC_COLLATE 1 17 | #define LC_CTYPE 2 18 | #define LC_MONETARY 3 19 | #define LC_NUMERIC 4 20 | #define LC_TIME 5 21 | #define LC_MESSAGES 6 22 | 23 | _BEGIN_STD_C 24 | 25 | struct lconv 26 | { 27 | char *decimal_point; 28 | char *thousands_sep; 29 | char *grouping; 30 | char *int_curr_symbol; 31 | char *currency_symbol; 32 | char *mon_decimal_point; 33 | char *mon_thousands_sep; 34 | char *mon_grouping; 35 | char *positive_sign; 36 | char *negative_sign; 37 | char int_frac_digits; 38 | char frac_digits; 39 | char p_cs_precedes; 40 | char p_sep_by_space; 41 | char n_cs_precedes; 42 | char n_sep_by_space; 43 | char p_sign_posn; 44 | char n_sign_posn; 45 | char int_n_cs_precedes; 46 | char int_n_sep_by_space; 47 | char int_n_sign_posn; 48 | char int_p_cs_precedes; 49 | char int_p_sep_by_space; 50 | char int_p_sign_posn; 51 | }; 52 | 53 | #ifndef _REENT_ONLY 54 | char *_EXFUN(setlocale,(int category, const char *locale)); 55 | struct lconv *_EXFUN(localeconv,(void)); 56 | #endif 57 | 58 | struct _reent; 59 | char *_EXFUN(_setlocale_r,(struct _reent *, int category, const char *locale)); 60 | struct lconv *_EXFUN(_localeconv_r,(struct _reent *)); 61 | 62 | _END_STD_C 63 | 64 | #endif /* _LOCALE_H_ */ 65 | -------------------------------------------------------------------------------- /kernel/mm/malloc/smalloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | /* 22 | * Alternate version of malloc 23 | * that expects the caller to keep track of the size of the chunk. 24 | * Allocated chunks must be freed with sfree() rather than free(). 25 | */ 26 | 27 | #include 28 | #include "malloc_internal.h" 29 | 30 | void *_smalloc(size_t size) 31 | { 32 | void *chunk; 33 | 34 | if (!(chunk = lmm_alloc(&malloc_lmm, size, 0))) 35 | return NULL; 36 | 37 | return chunk; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /kernel/mm/malloc/malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | 24 | #include "malloc_internal.h" 25 | 26 | void *_malloc(size_t size) 27 | { 28 | size_t *chunk; 29 | 30 | size += sizeof(size_t); 31 | 32 | if (!(chunk = lmm_alloc(&malloc_lmm, size, 0))) 33 | return 0; 34 | 35 | *chunk = size; 36 | return chunk+1; 37 | } 38 | 39 | 40 | void * 41 | _mustmalloc(size_t size) 42 | { 43 | void *buf; 44 | 45 | buf = _malloc(size); 46 | assert(buf); 47 | 48 | return buf; 49 | } 50 | -------------------------------------------------------------------------------- /kernel/lib/string/strlen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | /* 27 | * File: limach/strlen.c 28 | * Author: Robert V. Baron at Carnegie Mellon 29 | * Date: Oct 13, 1992 30 | * Abstract: 31 | * strlen returns the number of characters in "string" preceeding 32 | * the terminating null character. 33 | */ 34 | 35 | int 36 | strlen(string) 37 | register char *string; 38 | { 39 | register char *ret = string; 40 | 41 | while (*string++); 42 | 43 | return string - 1 - ret; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /user/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # User Makefile 4 | # 5 | ############################################################################### 6 | include ../config.mk 7 | 8 | BIN = bin 9 | 10 | # 11 | # Userspace libc library and header files. 12 | # 13 | LIBC_LIBRARY = newlib/arch/$(ARCH)/libc.a 14 | LIBC_HEADERS = newlib/include 15 | 16 | INCLUDES = -I$(LIBC_HEADERS) -Iinclude 17 | 18 | 19 | # 20 | # Sys is a binary that is linked statically into all user executables. It 21 | # contains the code needed to make system calls, initializes the runtime, 22 | # etc. 23 | # 24 | SYS_SRCDIRS = sys sys/arch/$(ARCH) 25 | SYS_CFILES = $(shell find $(SYS_SRCDIRS) -maxdepth 1 -type f -name "*.c") 26 | SYS_SFILES = $(shell find $(SYS_SRCDIRS) -maxdepth 1 -type f -name "*.S") 27 | SYS_OFILES = $(patsubst %.c,%.o,$(SYS_CFILES)) $(patsubst %.S,%.o,$(SYS_SFILES)) 28 | 29 | 30 | .PHONY: all sys clean 31 | all: sys init fork_test 32 | 33 | sys: $(SYS_OFILES) $(LIBC_LIBRARY) 34 | 35 | # 36 | # PUT USER PROGRAMS BELOW THIS POINT 37 | # 38 | # - All user programs (targets) should include sys as a dependency 39 | # - List all source files needed by the program as .o files. (e.g. if 40 | # you need myprogram.c, use myprogram.o) 41 | # 42 | 43 | init: sys progs/init.o 44 | $(LD) -T user.ld $(SYS_OFILES) progs/init.o $(LIBC_LIBRARY) -o $(BIN)/$@ 45 | 46 | fork_test: sys progs/fork_test.o 47 | $(LD) -T user.ld $(SYS_OFILES) progs/fork_test.o $(LIBC_LIBRARY) -o $(BIN)/$@ 48 | 49 | clean: 50 | rm -rf $(SYS_OFILES) 51 | rm -rf $(BIN)/* 52 | rm -rf progs/*.o 53 | 54 | -------------------------------------------------------------------------------- /kernel/lib/string/strcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | /* 27 | * File: libmach_sa/strcpy.c 28 | * Author: Robert V. Baron at Carnegie Mellon 29 | * Date: Oct 13, 1992 30 | * Abstract: 31 | * strcpy copies the contents of the string "from" including 32 | * the null terminator to the string "to". A pointer to "to" 33 | * is returned. 34 | */ 35 | 36 | char * 37 | strcpy(to,from) 38 | register char *to, *from; 39 | { 40 | register char *ret = to; 41 | 42 | while ((*to++ = *from++) != 0); 43 | 44 | return ret; 45 | } 46 | -------------------------------------------------------------------------------- /user/newlib/include/search.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $ */ 2 | /* $FreeBSD: src/include/search.h,v 1.4 2002/03/23 17:24:53 imp Exp $ */ 3 | 4 | /* 5 | * Written by J.T. Conklin 6 | * Public domain. 7 | */ 8 | 9 | #ifndef _SEARCH_H_ 10 | #define _SEARCH_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | typedef struct entry { 17 | char *key; 18 | void *data; 19 | } ENTRY; 20 | 21 | typedef enum { 22 | FIND, ENTER 23 | } ACTION; 24 | 25 | typedef enum { 26 | preorder, 27 | postorder, 28 | endorder, 29 | leaf 30 | } VISIT; 31 | 32 | #ifdef _SEARCH_PRIVATE 33 | typedef struct node { 34 | char *key; 35 | struct node *llink, *rlink; 36 | } node_t; 37 | #endif 38 | 39 | struct hsearch_data 40 | { 41 | struct internal_head *htable; 42 | size_t htablesize; 43 | }; 44 | 45 | #ifndef __compar_fn_t_defined 46 | #define __compar_fn_t_defined 47 | typedef int (*__compar_fn_t) (const void *, const void *); 48 | #endif 49 | 50 | __BEGIN_DECLS 51 | int hcreate(size_t); 52 | void hdestroy(void); 53 | ENTRY *hsearch(ENTRY, ACTION); 54 | int hcreate_r(size_t, struct hsearch_data *); 55 | void hdestroy_r(struct hsearch_data *); 56 | int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *); 57 | void *tdelete(const void *__restrict, void **__restrict, __compar_fn_t); 58 | void tdestroy (void *, void (*)(void *)); 59 | void *tfind(const void *, void **, __compar_fn_t); 60 | void *tsearch(const void *, void **, __compar_fn_t); 61 | void twalk(const void *, void (*)(const void *, VISIT, int)); 62 | __END_DECLS 63 | 64 | #endif /* !_SEARCH_H_ */ 65 | -------------------------------------------------------------------------------- /kernel/mm/malloc/calloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995-1994 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | #include "malloc_internal.h" 25 | #include 26 | 27 | void * 28 | _calloc(size_t nelt, size_t eltsize) 29 | { 30 | size_t allocsize = nelt * eltsize; 31 | 32 | void *ptr = _malloc(allocsize); 33 | if (!ptr) 34 | return NULL; 35 | 36 | memset(ptr, 0, allocsize); 37 | 38 | return ptr; 39 | } 40 | 41 | void * 42 | _mustcalloc(size_t nelt, size_t eltsize) 43 | { 44 | void *buf; 45 | 46 | buf = _calloc(nelt, eltsize); 47 | assert(buf); 48 | 49 | return buf; 50 | } 51 | -------------------------------------------------------------------------------- /kernel/inc/kernel/test.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/test.h 3 | */ 4 | #ifndef __KERNEL_TEST_H__ 5 | #define __KERNEL_TEST_H__ 6 | 7 | #include 8 | #include 9 | 10 | typedef void (*test_f)(void); 11 | 12 | extern char ktest_start[], ktest_end[]; 13 | 14 | #define __test __attribute__((__section__(".test"))) __attribute__((unused)) 15 | 16 | #define BEGIN_TEST(_name) \ 17 | void _name(void); \ 18 | \ 19 | static __test test_f __##_name##_ptr = _name; \ 20 | \ 21 | void _name(void) { \ 22 | TRACE(); \ 23 | unsigned long __kmalloc_bytes_begin = kmalloc_bytes_used(); \ 24 | 25 | 26 | #define END_TEST \ 27 | if (__kmalloc_bytes_begin != kmalloc_bytes_used()) { \ 28 | panic("MEMORY LEAK: %d bytes lost.", \ 29 | kmalloc_bytes_used() - __kmalloc_bytes_begin); \ 30 | } \ 31 | } 32 | 33 | static inline void _TEST_KERNEL_(void) 34 | { 35 | test_f *functions, *f; 36 | 37 | TRACE(); 38 | 39 | functions = (test_f *) (ktest_start + 1); 40 | for (f = functions; f < (test_f *) ktest_end; f++) { 41 | (*f)(); 42 | } 43 | } 44 | 45 | #endif /* !__KERNEL_TEST_H__ */ 46 | 47 | -------------------------------------------------------------------------------- /kernel/kernel/kernel.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | extern void arch_startup(void); 32 | 33 | void kernel_main() 34 | { 35 | arch_startup(); 36 | 37 | log_init(); 38 | 39 | /* 40 | * Set up kmalloc to only allocate dynamic memory in the first 16 MB of 41 | * memory. This will allow us to use kmalloc during early startup. 42 | * 43 | * NOTE: if we use a higher half kernel we'll have to offset these 44 | * values 45 | */ 46 | kmalloc_early_init(); 47 | 48 | pages_init(); 49 | vm_init(); 50 | kmap_init(); 51 | initrd_init(); 52 | pci_init(); 53 | 54 | /////////////////////////////////////////////////////////////////////// 55 | // Temporary hack to get to userspace with some test argv/arc 56 | ////////////////////////////////////////////////////////////////////// 57 | { 58 | #define INIT "/fork_test" 59 | char *argv[4] = { INIT, "arg1", "arg2", ":)" }; 60 | int argc = 4; 61 | 62 | // TODO: pass in the name of the init binary as a parameter via the 63 | // bootloader rather than hardcopying it. 64 | run_init(INIT, argc, argv ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /kernel/kernel/irq.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/irq.c 3 | * 4 | * @brief Hardware Interrupts 5 | * 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | list_typedef(struct irq_handler) irq_handler_list_t; 20 | struct spinlock lock = INITIALIZED_SPINLOCK; 21 | 22 | struct irq_desc { 23 | irq_handler_list_t handlers; 24 | int count; 25 | } irq_descs[MAX_NUM_IRQS]; 26 | 27 | void irq_init(void) 28 | { 29 | int i; 30 | 31 | for (i = 0; i < MAX_NUM_IRQS; i++) { 32 | struct irq_desc *desc = irq_descs + i; 33 | list_init(&desc->handlers); 34 | desc->count = 0; 35 | } 36 | } 37 | 38 | void kernel_irq_handler(int irq) 39 | { 40 | struct irq_desc *desc = irq_descs + irq; 41 | struct irq_context context = { .irq = irq }; 42 | struct irq_handler *handler; 43 | unsigned long flags; 44 | 45 | spin_lock_irq(&lock, &flags); 46 | 47 | if (list_empty(&desc->handlers)) 48 | goto out; 49 | 50 | desc->count++; 51 | 52 | list_foreach(handler, &desc->handlers, link) { 53 | handler->f(&context); 54 | } 55 | 56 | out: 57 | spin_unlock_irq(&lock, flags); 58 | } 59 | 60 | void irq_exit(void) 61 | { 62 | maybe_reschedule(); 63 | } 64 | 65 | int register_irq(int irq, struct irq_handler *new_handler) 66 | { 67 | struct irq_desc *desc = irq_descs + irq; 68 | unsigned long flags; 69 | 70 | ASSERT_GREATEREQ(irq, 0); 71 | ASSERT_LESS(irq, MAX_NUM_IRQS); 72 | 73 | spin_lock_irq(&lock, &flags); 74 | 75 | list_insert_tail(&desc->handlers, new_handler, link); 76 | 77 | spin_unlock_irq(&lock, flags); 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /kernel/kernel/spinlock.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/spinlock.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | /* TODO memory barriers */ 13 | 14 | static inline void __lock(struct spinlock *s) 15 | { 16 | int my_ticket; 17 | 18 | // FIXME: spinlock rely on overflow to correctly work 19 | my_ticket = atomic_inc(&s->ticket); 20 | 21 | /* 22 | * Spin until the ticket being served equals my ticket. Hopefully 23 | * gcc doesn't optimize any of this out... 24 | */ 25 | while (my_ticket != s->serving) { 26 | panic("SMP is not supported... You should not be here!"); 27 | continue; 28 | } 29 | } 30 | 31 | static inline void __unlock(struct spinlock *s) 32 | { 33 | s->serving++; 34 | } 35 | 36 | void __spin_lock(struct spinlock *s) 37 | { 38 | __lock(s); 39 | } 40 | 41 | void __spin_unlock(struct spinlock *s) 42 | { 43 | __unlock(s); 44 | } 45 | 46 | void __spin_lock_irq(struct spinlock *s, unsigned long *flags) 47 | { 48 | disable_save_irqs(flags); 49 | __spin_lock(s); 50 | } 51 | 52 | void __spin_unlock_irq(struct spinlock *s, unsigned long flags) 53 | { 54 | __spin_unlock(s); 55 | restore_irqs(flags); 56 | } 57 | 58 | void spin_lock(struct spinlock *s) 59 | { 60 | disable_save_preemption(); 61 | __lock(s); 62 | } 63 | 64 | void spin_unlock(struct spinlock *s) 65 | { 66 | __unlock(s); 67 | restore_preemption(); 68 | } 69 | 70 | void spin_lock_irq(struct spinlock *s, unsigned long *flags) 71 | { 72 | disable_save_irqs(flags); 73 | spin_lock(s); 74 | } 75 | 76 | void spin_unlock_irq(struct spinlock *s, unsigned long flags) 77 | { 78 | spin_unlock(s); 79 | restore_irqs(flags); 80 | } 81 | -------------------------------------------------------------------------------- /user/newlib/include/wordexp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2002, 2010 by Red Hat, Incorporated. All rights reserved. 2 | * 3 | * Permission to use, copy, modify, and distribute this software 4 | * is freely granted, provided that this notice is preserved. 5 | */ 6 | 7 | #ifndef _WORDEXP_H_ 8 | #define _WORDEXP_H_ 9 | 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | struct _wordexp_t 17 | { 18 | size_t we_wordc; /* Count of words matched by words. */ 19 | char **we_wordv; /* Pointer to list of expanded words. */ 20 | size_t we_offs; /* Slots to reserve at the beginning of we_wordv. */ 21 | }; 22 | 23 | typedef struct _wordexp_t wordexp_t; 24 | 25 | #define WRDE_DOOFFS 0x0001 /* Use we_offs. */ 26 | #define WRDE_APPEND 0x0002 /* Append to output from previous call. */ 27 | #define WRDE_NOCMD 0x0004 /* Don't perform command substitution. */ 28 | #define WRDE_REUSE 0x0008 /* pwordexp points to a wordexp_t struct returned from 29 | a previous successful call to wordexp. */ 30 | #define WRDE_SHOWERR 0x0010 /* Print error messages to stderr. */ 31 | #define WRDE_UNDEF 0x0020 /* Report attempt to expand undefined shell variable. */ 32 | 33 | enum { 34 | WRDE_SUCCESS, 35 | WRDE_NOSPACE, 36 | WRDE_BADCHAR, 37 | WRDE_BADVAL, 38 | WRDE_CMDSUB, 39 | WRDE_SYNTAX, 40 | WRDE_NOSYS 41 | }; 42 | 43 | /* Note: This implementation of wordexp requires a version of bash 44 | that supports the --wordexp and --protected arguments to be present 45 | on the system. It does not support the WRDE_UNDEF flag. */ 46 | int wordexp(const char *__restrict, wordexp_t *__restrict, int); 47 | void wordfree(wordexp_t *); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* _WORDEXP_H_ */ 54 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/fork.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/x86/fork.h 3 | */ 4 | #ifndef __ARCH_X86_FORK_H__ 5 | #define __ARCH_X86_FORK_H__ 6 | 7 | #include 8 | 9 | /** 10 | * @brief This function returns twice. Once as the new thread (the argument to 11 | * this function) and once as the original caller. 12 | * 13 | * Essentially this function copies the kernel stack context of the currently 14 | * running thread (process) to the new thread. It also sets up the new thread 15 | * for a context switch. Thus this thread can added to the scheduler after 16 | * this call. The new thread can be context-switched-to after this function 17 | * returns. After the new thread is context-switched-to it will return from 18 | * this function. 19 | */ 20 | void fork_context(struct thread *new_thread); 21 | 22 | /** 23 | * @brief This function is responsible for making to_pd map the same address 24 | * space as from_pd. 25 | * 26 | * If this function succeeds, the following will be true: 27 | * 1. Any virtual address that has a present mapping in from_pd will also 28 | * have a mapping in to_pd. 29 | * 2. All kernel virtual addresses in from_pd will be mapped into to_pd by 30 | * only copying the page directory entries. 31 | * 3. All user virtual addresses in from_pd will be mapped into to_pd by 32 | * allocating a new page table for to_pd. 33 | * 4. All mapped virtual addresses will map to the _same physical page_ 34 | * in both address spaces. 35 | * 5. All userspace mappings in to_pd and from_pd will be read-only, to 36 | * support copy-on-write. 37 | * 38 | * @return 0 on success, non-0 on error 39 | */ 40 | int fork_address_space(struct entry_table *to_pd, struct entry_table *from_pd); 41 | 42 | #endif /* !__ARCH_X86_FORK_H__ */ 43 | -------------------------------------------------------------------------------- /kernel/inc/lib/assert.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file assert.h 3 | * 4 | */ 5 | #ifndef _ASSERT_H_ 6 | #define _ASSERT_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define panic(_fmt, ...) do { \ 13 | disable_irqs(); \ 14 | \ 15 | FATAL("[%s:%d %s()] "_fmt, \ 16 | __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ 17 | \ 18 | backtrace(); \ 19 | while (1) continue; \ 20 | } while (0) 21 | 22 | #define assert(expression) do { \ 23 | signed long __condition = (signed long) (expression); \ 24 | \ 25 | if (__condition) \ 26 | break; \ 27 | \ 28 | panic("Failed Assert: %s [%ld]", \ 29 | #expression, __condition); \ 30 | } while (0) 31 | 32 | #define ASSERT(expression) assert(expression) 33 | #define ASSERT_NOT_NULL(expression) ASSERT(NULL != (expression)) 34 | 35 | #define ASSERT_BINARY_OPERATOR(_left, _op, _right) do { \ 36 | signed long __left = (signed long) (_left); \ 37 | signed long __right = (signed long) (_right); \ 38 | \ 39 | if (__left _op __right) \ 40 | break; \ 41 | \ 42 | panic("Failed Assert: %s [%ld] %s %s [%ld]", \ 43 | #_left, __left, #_op, #_right, __right); \ 44 | } while (0) 45 | 46 | #define ASSERT_EQUALS(left, right) ASSERT_BINARY_OPERATOR(left, ==, right) 47 | #define ASSERT_NOTEQUALS(left, right) ASSERT_BINARY_OPERATOR(left, !=, right) 48 | #define ASSERT_LESS(left, right) ASSERT_BINARY_OPERATOR(left, <, right) 49 | #define ASSERT_LESSEQ(left, right) ASSERT_BINARY_OPERATOR(left, <=, right) 50 | #define ASSERT_GREATER(left, right) ASSERT_BINARY_OPERATOR(left, >, right) 51 | #define ASSERT_GREATEREQ(left, right) ASSERT_BINARY_OPERATOR(left, >=, right) 52 | 53 | #endif /* _ASSERT_H_ */ 54 | -------------------------------------------------------------------------------- /kernel/arch/x86/linker.ld: -------------------------------------------------------------------------------- 1 | /* The bootloader will look at this image and start execution at the symbol 2 | designated as the entry point. */ 3 | ENTRY(_start) 4 | 5 | /* Tell where the various sections of the object files will be put in the final 6 | kernel image. */ 7 | SECTIONS 8 | { 9 | /* Begin putting sections at 1 MiB, a conventional place for kernels to be 10 | loaded at by the bootloader. */ 11 | . = 1M; 12 | kimg_start = .; 13 | ktext_start = .; 14 | 15 | /* First put the multiboot header, as it is required to be put very early 16 | early in the image or the bootloader won't recognize the file format. 17 | Next we'll put the .text section. */ 18 | .text BLOCK(4K) : ALIGN(4K) 19 | { 20 | *(.multiboot) 21 | *(.intel) 22 | *(.text) 23 | PROVIDE(ktest_start = .); 24 | *(.test) 25 | PROVIDE(ktest_end = .); 26 | } 27 | 28 | ktext_end = .; 29 | krodata_start = .; 30 | 31 | /* Read-only data. */ 32 | .rodata BLOCK(4K) : ALIGN(4K) 33 | { 34 | *(.rodata) 35 | } 36 | 37 | krodata_end = .; 38 | kdata_start = .; 39 | 40 | /* Read-write data (initialized) */ 41 | .data BLOCK(4K) : ALIGN(4K) 42 | { 43 | *(.bpgdir) 44 | *(.data) 45 | *(.symbols) 46 | } 47 | 48 | kdata_end = .; 49 | kbss_start = .; 50 | 51 | /* Read-write data (uninitialized) and stack */ 52 | .bss BLOCK(4K) : ALIGN(4K) 53 | { 54 | /* align the stack */ 55 | *(.bootstrap_stack) 56 | *(COMMON) 57 | *(.bss) 58 | } 59 | 60 | kbss_end = .; 61 | kimg_end = .; 62 | 63 | /* The compiler may produce other sections, by default it will put them in 64 | a segment with the same name. Simply add stuff here as needed. */ 65 | } 66 | -------------------------------------------------------------------------------- /kernel/mm/malloc/realloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995-1994 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "malloc_internal.h" 26 | 27 | /* XX could be made smarter, so it doesn't always copy to a new block. */ 28 | void *_realloc(void *buf, size_t new_size) 29 | { 30 | vm_size_t *op; 31 | vm_size_t old_size; 32 | vm_size_t *np; 33 | 34 | if (buf == 0) 35 | return _malloc(new_size); 36 | 37 | op = (vm_size_t*)buf; 38 | old_size = *--op; 39 | 40 | new_size += sizeof(vm_size_t); 41 | if (!(np = lmm_alloc(&malloc_lmm, new_size, 0))) 42 | return NULL; 43 | 44 | memcpy(np, op, old_size < new_size ? old_size : new_size); 45 | 46 | lmm_free(&malloc_lmm, op, old_size); 47 | 48 | *np++ = new_size; 49 | return np; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /kernel/inc/mm/pages.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mm/pages.h 3 | * 4 | * The general interface for page management is quite similar to Linux 5 | * (at least version 2.4.20). 6 | * 7 | */ 8 | #ifndef __MM_PAGES_H__ 9 | #define __MM_PAGES_H__ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | void pages_init(void); 17 | 18 | struct page { 19 | int count; 20 | }; 21 | 22 | extern struct page *phys_pages; 23 | 24 | #define page_address(_page) \ 25 | ((((size_t) (_page) - (size_t) phys_pages) / sizeof(struct page)) * PAGE_SIZE) 26 | 27 | #define page_struct(_address) \ 28 | (phys_pages + ((_address) / PAGE_SIZE)) 29 | 30 | #include 31 | #define page_get(_page) (atomic_inc(&((_page)->count))) 32 | #define page_put(_page) do { \ 33 | atomic_dec(&((_page)->count)); \ 34 | ASSERT((_page)->count >= 0); \ 35 | } while (0) 36 | 37 | struct page_zone { 38 | struct page *pages; /* array of all pages in the zone */ 39 | unsigned long num_pages; /* total number of pages in the zone */ 40 | unsigned long num_free; /* number of free pages in the zone */ 41 | unsigned long index; /* allows searches to pick up where the last left off */ 42 | struct spinlock lock; 43 | }; 44 | #define MAX_ZONES 1 45 | 46 | #define ZONE_START_PAGE_ADDR(zone) \ 47 | (page_address((zone)->pages)) 48 | 49 | #define ZONE_END_PAGE_ADDR(zone) \ 50 | (page_address((zone)->pages + ((zone)->num_pages - 1))) 51 | 52 | 53 | struct page *alloc_pages_at(size_t addr, unsigned long n); 54 | 55 | struct page *alloc_pages(unsigned long n); 56 | #define alloc_page() alloc_pages(1) 57 | 58 | void free_pages(struct page *pages, unsigned long n); 59 | //FIXME: this is confusing because it's essentially the same as page_put() 60 | #define free_page(_p) free_pages(_p, 1) 61 | 62 | #endif /* !__MM_PAGES_H__ */ 63 | -------------------------------------------------------------------------------- /kernel/mm/lmm/lmm_avail.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | #pragma GCC diagnostic push 22 | #pragma GCC diagnostic ignored "-Wtype-limits" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | vm_size_t lmm_avail(lmm_t *lmm, lmm_flags_t flags) 29 | { 30 | struct lmm_region *reg; 31 | vm_size_t count; 32 | 33 | count = 0; 34 | for (reg = lmm->regions; reg; reg = reg->next) 35 | { 36 | assert((vm_offset_t)reg->nodes >= reg->min); 37 | assert((vm_offset_t)reg->nodes < reg->max); 38 | assert(reg->free >= 0); 39 | assert(reg->free <= reg->max - reg->min); 40 | 41 | /* Don't count inapplicable regions. */ 42 | if (flags & ~reg->flags) 43 | continue; 44 | 45 | count += reg->free; 46 | } 47 | return count; 48 | } 49 | 50 | #pragma GCC diagnostic pop 51 | -------------------------------------------------------------------------------- /kernel/lib/fmt/sscanf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | #pragma GCC diagnostic push 27 | #pragma GCC diagnostic ignored "-Wunused-parameter" 28 | 29 | #include 30 | #include 31 | 32 | static int 33 | readchar(arg) 34 | void *arg; 35 | { 36 | return *(*(unsigned char**)arg)++; 37 | } 38 | 39 | static void 40 | unchar(c, arg) 41 | int c; 42 | void *arg; 43 | { 44 | (*(unsigned char**)arg)--; 45 | } 46 | 47 | void vsscanf(s, fmt, args) 48 | char *s; 49 | char *fmt; 50 | va_list args; 51 | { 52 | _doscan(fmt, args, readchar, unchar, &s); 53 | } 54 | 55 | int sscanf(char *s, char *fmt, ...) 56 | { 57 | va_list args; 58 | 59 | va_start(args, fmt); 60 | vsscanf(s, fmt, args); 61 | va_end(args); 62 | 63 | return 0;/*XXX*/ 64 | } 65 | 66 | #pragma GCC diagnostic pop 67 | -------------------------------------------------------------------------------- /kernel/lib/string/strncpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | /* 27 | * File: libmach_sa/strncpy.c 28 | * Author: Mary R. Thompson at Carnegie Mellon 29 | * Date: Oct 13, 1992 30 | * Abstract: 31 | * strncpy copies "count" characters from the "from" string to 32 | * the "to" string. If "from" contains less than "count" characters 33 | * "to" will be padded with null characters until exactly "count" 34 | * characters have been written. The return value is a pointer 35 | * to the "to" string. 36 | */ 37 | 38 | char * 39 | strncpy(to, from, count) 40 | register char *to, *from; 41 | register int count; 42 | { 43 | register char *ret = to; 44 | 45 | while (count-- > 0 && (*to++ = *from++)); 46 | 47 | while (count-- > 0) 48 | *to++ = '\0'; 49 | 50 | return ret; 51 | } 52 | -------------------------------------------------------------------------------- /kernel/mm/lmm/lmm_remove_free.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | void lmm_remove_free(lmm_t *lmm, void *block, vm_size_t block_size) 27 | { 28 | vm_offset_t rstart = (vm_offset_t)block; 29 | vm_offset_t rend = rstart + block_size; 30 | assert(rend > rstart); 31 | 32 | while (rstart < rend) 33 | { 34 | vm_offset_t size; 35 | lmm_flags_t flags; 36 | void *ptr; 37 | 38 | lmm_find_free(lmm, &rstart, &size, &flags); 39 | assert(rstart >= (vm_offset_t)block); 40 | if ((size == 0) || (rstart >= rend)) 41 | break; 42 | if (rstart + size > rend) 43 | size = rend - rstart; 44 | ptr = lmm_alloc_gen(lmm, size, flags, 0, 0, 45 | rstart, size); 46 | assert((vm_offset_t)ptr == rstart); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /kernel/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Kernel Makefile 4 | # 5 | ############################################################################### 6 | include ../config.mk 7 | 8 | SRCDIRS = dev \ 9 | fs \ 10 | kernel \ 11 | lib \ 12 | mm \ 13 | arch/$(ARCH) 14 | 15 | INCDIRS = inc \ 16 | inc/lib 17 | 18 | LINKER_SCRIPT = arch/$(ARCH)/linker.ld 19 | 20 | CFILES = $(shell find $(SRCDIRS) -type f -name "*.c") 21 | SFILES = $(shell find $(SRCDIRS) -type f -name "*.S") 22 | OFILES = $(patsubst %.c,%.o,$(CFILES)) $(patsubst %.S,%.o,$(SFILES)) 23 | 24 | HFILES = $(shell find $(INCDIRS) -type f -name "*.h") 25 | INCLUDES = $(addprefix -I, $(INCDIRS)) 26 | 27 | CFLAGS += -DKDEBUG 28 | 29 | .PHONY: default clean arch kernel 30 | 31 | default: kernel 32 | 33 | kernel: $(OFILES) $(HFILES) $(LINKER_SCRIPT) symbols 34 | $(CC) -T $(LINKER_SCRIPT) -o KERNEL.o -ffreestanding -O2 -nostdlib $(OFILES) -lgcc 35 | nm -n KERNEL.o | tools/inject_symbol_table kernel/symbols.o \ 36 | $(shell tools/symbols_section_offset.sh kernel/symbols.o) 37 | $(CC) -T $(LINKER_SCRIPT) -o KERNEL.o -ffreestanding -O2 -nostdlib $(OFILES) -lgcc 38 | 39 | $(OFILES): arch 40 | 41 | # 42 | # Create a symbolic link for architecture-specific header files: 43 | # e.g inc/arch -> ../arch/x86/inc 44 | # 45 | # Note the '..' is needed so that inc/arch knows to look up in the 46 | # parent directory first. 47 | # 48 | arch: 49 | rm -f inc/arch 50 | ln -s ../arch/$(ARCH)/inc inc/arch 51 | 52 | clean: 53 | rm -f inc/arch 54 | rm -f KERNEL.o 55 | rm -f tools/inject_symbol_table 56 | rm -f $(OFILES) 57 | 58 | symbols: tools/inject_symbol_table.c 59 | gcc tools/inject_symbol_table.c -o tools/inject_symbol_table 60 | 61 | %.o: %.S 62 | $(CC) $(CFLAGS) $(INCLUDES) -DASSEMBLER -c -o $@ $< 63 | 64 | %.o: %.c 65 | $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< 66 | -------------------------------------------------------------------------------- /kernel/mm/malloc/memalign.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | #pragma GCC diagnostic push 22 | #pragma GCC diagnostic ignored "-Wsign-compare" 23 | 24 | #include 25 | #include "malloc_internal.h" 26 | 27 | void *_memalign(size_t alignment, size_t size) 28 | { 29 | unsigned shift; 30 | size_t *chunk; 31 | 32 | /* Find the alignment shift in bits. XXX use proc_ops.h */ 33 | for (shift = 0; (1 << shift) < alignment; shift++); 34 | 35 | /* 36 | * Allocate a chunk of LMM memory with the specified alignment shift 37 | * and an offset such that the memory block we return will be aligned 38 | * after we add our size field to the beginning of it. 39 | */ 40 | size += sizeof(size_t); 41 | 42 | if (!(chunk = lmm_alloc_aligned(&malloc_lmm, size, 0, shift, 43 | (1 << shift) - sizeof(size_t)))) 44 | return NULL; 45 | 46 | *chunk = size; 47 | return chunk+1; 48 | } 49 | 50 | #pragma GCC diagnostic pop 51 | -------------------------------------------------------------------------------- /kernel/inc/kernel/wait.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_WAIT_H__ 2 | #define __KERNEL_WAIT_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | struct wait { 9 | struct spinlock lock; 10 | thread_list_t threads; 11 | }; 12 | 13 | #define INITIALIZED_WAIT { \ 14 | .lock = INITIALIZED_SPINLOCK, \ 15 | .threads = INITIALIZED_EMPTY_LIST, \ 16 | } 17 | 18 | static inline void wait_init(struct wait *wait) 19 | { 20 | spin_lock_init(&wait->lock); 21 | list_init(&wait->threads); 22 | } 23 | 24 | /* 25 | * begin_wait adds the calling thread onto a queue of waiting threads 26 | * defined by the wait struct and sets the thread's state to BLOCKED. 27 | * It is intended that begin_wait is called shortly before calling 28 | * reschedule. 29 | * 30 | * begin_wait() is inherently racy with resepect to kick() because 31 | * adding a thread to the wait queue and rescheduling that thread is 32 | * not an atomic operation. 33 | * 34 | * Case 1: 35 | * Thread A Thread B 36 | * begin_wait 37 | * reschedule 38 | * kick 39 | * 40 | * This is the expected case. When Thread A calls reschedule its 41 | * state will be BLOCKED and it will not be added back onto the 42 | * runqueue (so it will not run). The call to kick will take it 43 | * off the wait queue and put it onto the runqueue. 44 | * 45 | * Case 2: 46 | * Thread A Thread B 47 | * begin_wait 48 | * kick 49 | * reschedule 50 | * 51 | * In this case Thread A will reschedule not with a BLOCKED state 52 | * but with a runnable state. The scheduler will place it back onto 53 | * the run queue and it will run sometime soon. 54 | * 55 | * kick() and reschedule() may race but the scheduler will make sure 56 | * reschedule() doesn't race with making the thread runnable. 57 | */ 58 | void begin_wait(struct wait *wait); 59 | 60 | /* 61 | * Wake up all threads on the wait queue. 62 | */ 63 | void kick(struct wait *wait); 64 | 65 | #endif /* !__KERNEL_WAIT_H__ */ 66 | -------------------------------------------------------------------------------- /kernel/inc/lib/fmt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1994 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | /**** 23 | * 24 | * Modified by David Matlack: 25 | * 26 | * Moved the following out of stdio.h and into fmt.h in order to 27 | * separate the print functionality and format functionality. 28 | * 29 | ****/ 30 | 31 | #ifndef _FMT_H_ 32 | #define _FMT_H_ 33 | 34 | int vprintf(const char *__format, va_list __vl); 35 | int sprintf(char *__dest, const char *__format, ...) 36 | __attribute__((__format__ (__printf__, 2, 3))); 37 | int snprintf(char *__dest, size_t __size, const char *__format, ...) 38 | __attribute__((__format__ (__printf__, 3, 4))); 39 | int vsprintf(char *__dest, const char *__format, va_list __vl); 40 | int vsnprintf(char *__dest, size_t __size, const char *__format, va_list __vl); 41 | int sscanf(const char *__str, const char *__format, ...) 42 | __attribute__((__format__ (__scanf__, 2, 3))); 43 | 44 | #endif /* _FLUX_MC_FMT_H_ */ 45 | -------------------------------------------------------------------------------- /user/sys/syscall.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sys/syscall.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "syscall_internal.h" 10 | 11 | #define SYSCALL_ERROR( _ret ) ({ \ 12 | int __ret = (_ret); \ 13 | \ 14 | if (__ret) \ 15 | errno = __ret; \ 16 | \ 17 | __ret ? -1 : 0; \ 18 | }) 19 | 20 | int write(int fd, char *ptr, int len) 21 | { 22 | return SYSCALL_ERROR(SYSCALL3(SYS_WRITE, fd, ptr, len)); 23 | } 24 | 25 | int getpid(void) 26 | { 27 | return SYSCALL_ERROR(SYSCALL0(SYS_GETPID)); 28 | } 29 | 30 | int fork(void) 31 | { 32 | return SYSCALL0(SYS_FORK); 33 | } 34 | 35 | int yield(void) 36 | { 37 | return SYSCALL_ERROR(SYSCALL0(SYS_YIELD)); 38 | } 39 | 40 | void exit(int status) 41 | { 42 | SYSCALL1(SYS_EXIT, status); 43 | } 44 | 45 | int wait(int *status) 46 | { 47 | return SYSCALL_ERROR(SYSCALL1(SYS_WAIT, status)); 48 | } 49 | 50 | extern char _end; /* Defined by the linker */ 51 | size_t sbrk(int incr) 52 | { 53 | static char *heap_end; 54 | char *prev_heap_end; 55 | 56 | if (heap_end == 0) { 57 | heap_end = &_end; 58 | } 59 | prev_heap_end = heap_end; 60 | #if 0 61 | if (heap_end + incr > stack_ptr) { 62 | write (1, "Heap and stack collision\n", 25); 63 | abort (); 64 | } 65 | #endif 66 | 67 | heap_end += incr; 68 | return (size_t) prev_heap_end; 69 | } 70 | 71 | int close(int fd) 72 | { 73 | (void)fd; 74 | 75 | return -1; 76 | } 77 | 78 | int fstat(int fd, struct stat *st) 79 | { 80 | (void) fd; 81 | 82 | st->st_mode = S_IFCHR; 83 | return 0; 84 | } 85 | 86 | int isatty(int fd) 87 | { 88 | (void)fd; 89 | 90 | return 1; 91 | } 92 | 93 | int lseek(int fd, int ptr, int dir) 94 | { 95 | (void)fd; 96 | (void)ptr; 97 | (void)dir; 98 | 99 | return 0; 100 | } 101 | 102 | int read(int fd, char *ptr, int len) 103 | { 104 | (void)fd; 105 | (void)ptr; 106 | (void)len; 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /kernel/arch/x86/startup.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file x86/startup.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | extern void __syscall_entry(void); 14 | 15 | extern char kernel_idt[]; 16 | extern char kernel_gdt[]; 17 | extern char kernel_tss[]; 18 | extern char boot_stack_top[]; 19 | extern char boot_stack_bottom[]; 20 | extern char boot_page_dir[]; 21 | 22 | void invalid_interrupt(void) { panic("INVALID INTERRUPT OCCURRED"); } 23 | 24 | /* x86 startup routines */ 25 | extern void init_8253(void); 26 | 27 | void arch_startup(void) 28 | { 29 | int vector; 30 | 31 | /* Try to begin logging to the serial console. */ 32 | early_init_8250(); 33 | early_log_init(early_i8250_putchar, CONFIG_LOG_LEVEL); 34 | 35 | ASSERT_EQUALS((size_t) kernel_idt, 0x10000c); 36 | ASSERT_EQUALS((size_t) kernel_gdt, 0x10080c); 37 | ASSERT_EQUALS((size_t) kernel_tss, 0x10083c); 38 | 39 | multiboot_init(); 40 | 41 | /* 42 | * Print out some symbols defined in arch/boot.S 43 | */ 44 | INFO("boot_stack: 0x%08x, 0x%08x", boot_stack_bottom, boot_stack_top); 45 | INFO("boot_page_dir: 0x%08x", boot_page_dir); 46 | 47 | disable_fpu(); 48 | 49 | /* 50 | * Install default handlers for all IDT entries so we panic before 51 | * we triple fault. 52 | */ 53 | for (vector = 0; vector < 256; vector++) { 54 | idt_exn_gate(vector, invalid_interrupt); 55 | } 56 | 57 | /* 58 | * Install handlers in the IDT for each exception type. 59 | */ 60 | for (vector = 0; vector < X86_NUM_EXCEPTIONS; vector++) { 61 | idt_exn_gate(vector, x86_exceptions[vector].handler); 62 | } 63 | 64 | /* 65 | * Install the global system call handler. 66 | */ 67 | idt_syscall_gate(0x80, __syscall_entry); 68 | 69 | /* 70 | * Initialize the interrupt controller and associated handlers. 71 | */ 72 | pic_irq_init(); 73 | 74 | /* COM Ports */ 75 | init_8250(); 76 | 77 | /* Programmable Interval Timer */ 78 | init_8253(); 79 | } 80 | -------------------------------------------------------------------------------- /kernel/inc/mm/lmm_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | * 21 | * Author: Bryan Ford, University of Utah CSL 22 | */ 23 | 24 | #ifndef _LMM_TYPES_H_ 25 | #define _LMM_TYPES_H_ 26 | 27 | /* The contents of these structures are opaque to users. */ 28 | struct lmm_region 29 | { 30 | struct lmm_region *next; 31 | 32 | /* List of free memory blocks in this region. */ 33 | struct lmm_node *nodes; 34 | 35 | /* Virtual addresses of the start and end of the memory region. */ 36 | vm_offset_t min; 37 | vm_offset_t max; 38 | 39 | /* Attributes of this memory. */ 40 | lmm_flags_t flags; 41 | 42 | /* Allocation priority of this region with respect to other regions. */ 43 | lmm_pri_t pri; 44 | 45 | /* Current amount of free space in this region in bytes. */ 46 | vm_size_t free; 47 | }; 48 | 49 | struct lmm_node 50 | { 51 | struct lmm_node *next; 52 | vm_size_t size; 53 | }; 54 | 55 | #define ALIGN_SIZE sizeof(struct lmm_node) 56 | #define ALIGN_MASK (ALIGN_SIZE - 1) 57 | 58 | #endif /* _LMM_TYPES_H_ */ 59 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/vm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file x86/vm.h 3 | */ 4 | #ifndef __X86_VM_H__ 5 | #define __X86_VM_H__ 6 | 7 | #include 8 | 9 | /** 10 | * @brief Convert the virtual address to the physical address it maps to. 11 | * 12 | * @return 13 | * The physical address is the mapping exists. 14 | * -1 (0xFFFFFFFF) otherwise. 15 | */ 16 | #define __phys(virt) to_phys((struct entry_table *) get_cr3(), (unsigned long) (virt)) 17 | 18 | /** 19 | * @brief Convert the virtual address to the page struct that it maps to. 20 | * 21 | * @return 22 | * A pointer to the page struct if the mapping exists. 23 | * NULL otherwise. 24 | */ 25 | #define __page(virt) ({ \ 26 | unsigned long phys = __phys(virt); \ 27 | phys == (unsigned long) -1 ? NULL : page_struct(phys); \ 28 | }) 29 | 30 | 31 | void *new_address_space(void); 32 | void free_address_space(void *mmu); 33 | 34 | static inline void *swap_address_space(void *new) 35 | { 36 | void *old = (void *) (get_cr3() + CONFIG_KERNEL_VIRTUAL_START); 37 | set_cr3((u32) __phys(new)); 38 | return old; 39 | } 40 | 41 | /** 42 | * @brief Map a physical page into the virtual address space. 43 | */ 44 | int mmu_map_page(void *page_dir, unsigned long virt, struct page *page, int flags); 45 | 46 | /** 47 | * @brief Unmap a virtual page and return the physical page that it was 48 | * mapping to. 49 | */ 50 | struct page *mmu_unmap_page(void *page_dir, unsigned long virt); 51 | 52 | /** 53 | * @brief Flush the contents of the TLB, invalidating all cached virtual 54 | * address lookups. 55 | */ 56 | static inline void tlb_flush(void) { 57 | set_cr3(get_cr3()); 58 | } 59 | 60 | /** 61 | * @brief Invalidate a set of pages in the TLB. This should be called 62 | * after vm_map if you want to write to or read from the pages you just 63 | * mapped. 64 | */ 65 | static inline void tlb_invalidate(unsigned long addr, size_t size) 66 | { 67 | unsigned long v; 68 | 69 | for (v = FLOOR(X86_PAGE_SIZE, addr); v < CEIL(X86_PAGE_SIZE, addr + size); v += X86_PAGE_SIZE) { 70 | __invlpg(v); 71 | } 72 | } 73 | 74 | #endif /* !__X86_VM_H__ */ 75 | -------------------------------------------------------------------------------- /kernel/arch/x86/syscall_entry.S: -------------------------------------------------------------------------------- 1 | ### 2 | # @file arch/x86/syscall.S 3 | # 4 | # @brief System call entry point on the x86 architecture. 5 | # 6 | # WARNING: WORK IN PROGRESS 7 | # ------------------------- 8 | # 9 | # System calls are entered by invoking a software interrupt (e.g. INT 0x80). 10 | # System calls invoked this way have the following ABI: 11 | # 12 | # Call 13 | # eax: The system call to execute 14 | # ecx: first argument 15 | # edx: second argument 16 | # esi: third argument 17 | # edi: fourth argument 18 | # 19 | # Return 20 | # eax: The return value of the system call 21 | # 22 | ### 23 | #include 24 | #include 25 | 26 | .extern syscall_table 27 | .extern set_thread_regs 28 | .extern return_from_syscall 29 | 30 | .global __syscall_entry 31 | __syscall_entry: 32 | 33 | PUSH_REGISTERS 34 | 35 | # 36 | # push all the possible arguments onto the stack. it doesn't matter if 37 | # the system call uses < 4 arguments. it will just ignore the bogus 38 | # values we've pushed 39 | # 40 | pushl %edi 41 | pushl %esi 42 | pushl %edx 43 | pushl %ecx 44 | 45 | pushl %eax # save the syscall number temporarily 46 | 47 | leal 0x14(%esp), %eax # load the address of the registers 48 | pushl %eax # push that address on the stack 49 | call set_thread_regs # set regs pointer in the thread struct 50 | addl $4, %esp # restore the stack 51 | 52 | popl %eax # restore the syscall number 53 | 54 | cmp $SYS_MAX, %eax # Check if the syscall number is valid. 55 | jge bad_sys 56 | 57 | # 58 | # eax is the system call we want to execute. we lookup the eax'th system 59 | # call in the syscall_table and call that address. 60 | # 61 | # TODO: sanity check eax to make sure not negative or out of bounds 62 | # 63 | movl $syscall_table, %ecx 64 | movl (%ecx, %eax, 0x4), %ecx 65 | call *%ecx 66 | jmp sys_out 67 | 68 | bad_sys: 69 | pushl %eax 70 | call bad_syscall 71 | popl %eax 72 | 73 | sys_out: 74 | popl %ecx 75 | popl %ecx 76 | popl %ecx 77 | popl %ecx 78 | 79 | pushl %eax 80 | call return_from_syscall 81 | -------------------------------------------------------------------------------- /kernel/kernel/fork.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file kernel/fork.c 3 | * 4 | * @brief Implementation of the fork system call. 5 | * 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | /* 20 | * __next_pid is the next process id to give out. It starts at 2 because 21 | * 1 is reserved for init (see kernel/init.c). 22 | */ 23 | int __next_pid = 2; 24 | 25 | int next_pid(void) 26 | { 27 | return atomic_inc(&__next_pid); 28 | } 29 | 30 | pid_t sys_fork(void) 31 | { 32 | struct thread *current = CURRENT_THREAD; 33 | struct thread *new_thread = NULL; 34 | struct process *new_process = NULL; 35 | unsigned long flags; 36 | int error; 37 | 38 | TRACE(); 39 | 40 | if (num_threads(current->proc) > 1) { 41 | /* 42 | * For POSIX specification on multithreaded fork see: 43 | * http://pubs.opengroup.org/onlinepubs/000095399/functions/fork.html 44 | */ 45 | DEBUG("Multithreaded fork() not supported at the moment."); 46 | return -1; 47 | } 48 | 49 | error = ENOMEM; 50 | 51 | new_process = fork_process_struct(CURRENT_PROCESS); 52 | if (!new_process) { 53 | goto sys_fork_fail; 54 | } 55 | 56 | new_thread = new_thread_struct(); 57 | if (!new_thread) { 58 | goto sys_fork_fail; 59 | } 60 | 61 | error = vm_space_fork(&new_process->space, ¤t->proc->space); 62 | if (error) { 63 | goto sys_fork_fail; 64 | } 65 | 66 | spin_lock_irq(&process_lock, &flags); 67 | 68 | add_thread(new_process, new_thread); 69 | add_child_process(current->proc, new_process); 70 | 71 | spin_unlock_irq(&process_lock, flags); 72 | 73 | fork_context(new_thread); 74 | 75 | INFO("Process %d:%d forked %d:%d", 76 | current->proc->pid, current->tid, 77 | new_process->pid, new_thread->tid); 78 | 79 | make_runnable(new_thread); 80 | return new_process->pid; 81 | 82 | sys_fork_fail: 83 | if (new_thread) free_thread_struct(new_thread); 84 | if (new_process) free_process_struct(new_process); 85 | return error > 0 ? -1 * error : error; 86 | } 87 | -------------------------------------------------------------------------------- /doc/vmcopy.txt: -------------------------------------------------------------------------------- 1 | 2 | Copying an Address Space 3 | 4 | Steps 5 | 1. Shallow copy the kernel mappings. 6 | HIGH SHALLOW 7 | 2. Shallow copy the read-only mappings. 8 | LOW SHALLOW 9 | 3. Copy-on-write copy the read-write mappings. 10 | LOW SHALLOW 11 | 12 | Operations 13 | - HIGH SHALLOW: Only copy page directory entries. 14 | - LOW SHALLOW: 15 | 1. For each mapping, get the physical page mapped and increment its 16 | reference counter. 17 | 2. Create page tables, if necessary, and copy page table entries. 18 | 3. For copy-on-write, mark pages as copy-on-write. 19 | 20 | Virtual Memory -- Use Cases 21 | --------------------------- 22 | 23 | 1. exec(): Load an elf into memory. For each region in the elf, memory 24 | the region in virtual memory with the right flags (e.g. read-only for 25 | the text region) and copy the elf contents to memory. 26 | 27 | 2. stack: Create a region of memory at the top of the address space. 28 | This region should be able to grow down. 29 | 30 | 3. heap: Create a region of memory starting at some address. This region 31 | should be able to grow up. 32 | --> mmap(), brk(), sbrk() 33 | 34 | 4. fork(): Copy an address space 35 | 36 | copy_address_space( from_space, to_space ) { 37 | copy_kernel_region(from_space->kernel_region, to_space->kernel_region) 38 | 39 | for (from_region : from_space->user_regions) { 40 | to_region = malloc_new_region(from_region) 41 | 42 | if (READ_WRITE(from_region)) { 43 | reserve_pages(to_region->size / PAGE_SIZE); 44 | } 45 | 46 | refcopy_region(from_space, to_space, from_region, to_region) 47 | } 48 | } 49 | 50 | Example interface for growing memory regions: 51 | 52 | grow_region(space->stack_region, PAGE_SIZE, GROW_START); 53 | grow_region(space->heap_region, PAGE_SIZE, GROW_END); 54 | GROW_START: 55 | either increase or decrease the start of the 56 | memory region (aka region->address) 57 | GROW_END: 58 | either increase or decrease the end of the memory 59 | region (aka region->address + region->size). 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /kernel/lib/string/strcmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | /* 27 | * File: limach/strcmp.c 28 | * Author: Robert V. Baron at Carnegie Mellon 29 | * Date: Oct 13, 1992 30 | * Abstract: 31 | * strcmp (s1, s2) compares the strings "s1" and "s2". 32 | * It returns 0 if the strings are identical. It returns 33 | * > 0 if the first character that differs into two strings 34 | * is larger in s1 than in s2 or if s1 is longer than s2 and 35 | * the contents are identical up to the length of s2. 36 | * It returns < 0 if the first differing character is smaller 37 | * in s1 than in s2 or if s1 is shorter than s2 and the 38 | * contents are identical upto the length of s1. 39 | */ 40 | #pragma GCC diagnostic push 41 | #pragma GCC diagnostic ignored "-Wsign-conversion" 42 | 43 | int 44 | strcmp(s1,s2) 45 | register unsigned char *s1, *s2; 46 | { 47 | register unsigned int a, b; 48 | 49 | 50 | 51 | while ( (a = *s1++), (b = *s2++), a && b) { 52 | if (a != b) 53 | return (a-b); 54 | } 55 | 56 | return a-b; 57 | } 58 | 59 | #pragma GCC diagnostic pop 60 | -------------------------------------------------------------------------------- /user/newlib/include/sys/sched.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by Joel Sherrill . 3 | * 4 | * COPYRIGHT (c) 1989-2010. 5 | * On-Line Applications Research Corporation (OAR). 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose without fee is hereby granted, provided that this entire notice 9 | * is included in all copies of any software which is or includes a copy 10 | * or modification of this software. 11 | * 12 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 13 | * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION 14 | * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS 15 | * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 16 | * 17 | * $Id$ 18 | */ 19 | 20 | 21 | #ifndef _SYS_SCHED_H_ 22 | #define _SYS_SCHED_H_ 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Scheduling Policies */ 31 | /* Open Group Specifications Issue 6 */ 32 | #if defined(__CYGWIN__) 33 | #define SCHED_OTHER 3 34 | #else 35 | #define SCHED_OTHER 0 36 | #endif 37 | 38 | #define SCHED_FIFO 1 39 | #define SCHED_RR 2 40 | 41 | #if defined(_POSIX_SPORADIC_SERVER) 42 | #define SCHED_SPORADIC 4 43 | #endif 44 | 45 | /* Scheduling Parameters */ 46 | /* Open Group Specifications Issue 6 */ 47 | 48 | struct sched_param { 49 | int sched_priority; /* Process execution scheduling priority */ 50 | 51 | #if defined(_POSIX_SPORADIC_SERVER) || defined(_POSIX_THREAD_SPORADIC_SERVER) 52 | int sched_ss_low_priority; /* Low scheduling priority for sporadic */ 53 | /* server */ 54 | struct timespec sched_ss_repl_period; 55 | /* Replenishment period for sporadic server */ 56 | struct timespec sched_ss_init_budget; 57 | /* Initial budget for sporadic server */ 58 | int sched_ss_max_repl; /* Maximum pending replenishments for */ 59 | /* sporadic server */ 60 | #endif 61 | }; 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif 68 | /* end of include file */ 69 | 70 | -------------------------------------------------------------------------------- /kernel/lib/string/memcmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | /* 27 | * File: limach/memcmp.c 28 | * Author: Robert V. Baron at Carnegie Mellon 29 | * Date: Oct 13, 1992 30 | * Abstract: 31 | * strcmp (s1, s2) compares the strings "s1" and "s2". 32 | * It returns 0 if the strings are identical. It returns 33 | * > 0 if the first character that differs into two strings 34 | * is larger in s1 than in s2 or if s1 is longer than s2 and 35 | * the contents are identical up to the length of s2. 36 | * It returns < 0 if the first differing character is smaller 37 | * in s1 than in s2 or if s1 is shorter than s2 and the 38 | * contents are identical upto the length of s1. 39 | */ 40 | #pragma GCC diagnostic push 41 | #pragma GCC diagnostic ignored "-Wsign-conversion" 42 | 43 | int 44 | memcmp(const void *s1v, const void *s2v, int size) 45 | { 46 | register const char *s1 = s1v, *s2 = s2v; 47 | register unsigned int a, b; 48 | 49 | while (size-- > 0) { 50 | if ((a = *s1++) != (b = *s2++)) 51 | return (a-b); 52 | } 53 | 54 | return 0; 55 | } 56 | 57 | #pragma GCC diagnostic push 58 | -------------------------------------------------------------------------------- /kernel/lib/stdlib/strtol.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995-1994 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | long strtol(const char *p, char **out_p, int base) 27 | { 28 | long v = 0; 29 | int is_neg = 0; 30 | 31 | while (isspace(*p)) 32 | p++; 33 | if (*p == '-') 34 | is_neg = 1, p++; 35 | else if (*p == '+') 36 | is_neg = 0; 37 | if (((base == 16) || (base == 0)) && 38 | ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) 39 | { 40 | p += 2; 41 | base = 16; 42 | } 43 | if (base == 0) 44 | { 45 | if (*p == '0') 46 | base = 8; 47 | else 48 | base = 10; 49 | } 50 | while (1) 51 | { 52 | char c = *p; 53 | if ((c >= '0') && (c <= '9') && (c - '0' < base)) 54 | v = (v * base) + (c - '0'); 55 | else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) 56 | v = (v * base) + (c - 'a' + 10); 57 | else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) 58 | v = (v * base) + (c - 'A' + 10); 59 | else 60 | break; 61 | p++; 62 | } 63 | if (is_neg) 64 | v = -v; 65 | if (out_p) *out_p = (char*)p; 66 | return v; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /kernel/lib/stdlib/strtoul.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995-1994 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | #pragma GCC diagnostic push 22 | #pragma GCC diagnostic ignored "-Wsign-conversion" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | unsigned long strtoul(const char *p, char **out_p, int base) 29 | { 30 | unsigned long v = 0; 31 | 32 | while (isspace(*p)) 33 | p++; 34 | if (((base == 16) || (base == 0)) && 35 | ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) 36 | { 37 | p += 2; 38 | base = 16; 39 | } 40 | if (base == 0) 41 | { 42 | if (*p == '0') 43 | base = 8; 44 | else 45 | base = 10; 46 | } 47 | while (1) 48 | { 49 | char c = *p; 50 | if ((c >= '0') && (c <= '9') && (c - '0' < base)) 51 | v = (v * base) + (c - '0'); 52 | else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) 53 | v = (v * base) + (c - 'a' + 10); 54 | else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) 55 | v = (v * base) + (c - 'A' + 10); 56 | else 57 | break; 58 | p++; 59 | } 60 | 61 | if (out_p) *out_p = (char*)p; 62 | return v; 63 | } 64 | 65 | #pragma GCC diagnostic pop 66 | -------------------------------------------------------------------------------- /user/newlib/include/sys/_timespec.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 1982, 1986, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 4. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)time.h 8.5 (Berkeley) 5/4/95 30 | * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp 31 | * $FreeBSD$ 32 | */ 33 | 34 | #ifndef _SYS__TIMESPEC_H_ 35 | #define _SYS__TIMESPEC_H_ 36 | 37 | #include 38 | 39 | #ifndef __time_t_defined 40 | typedef _TIME_T_ time_t; 41 | #define __time_t_defined 42 | #endif 43 | 44 | struct timespec { 45 | time_t tv_sec; /* seconds */ 46 | long tv_nsec; /* and nanoseconds */ 47 | }; 48 | 49 | #endif /* !_SYS__TIMESPEC_H_ */ 50 | -------------------------------------------------------------------------------- /user/newlib/include/stdio_ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdio_ext.h 3 | * 4 | * Definitions for I/O internal operations, originally from Solaris. 5 | */ 6 | 7 | #ifndef _STDIO_EXT_H_ 8 | #define _STDIO_EXT_H_ 9 | 10 | #ifdef __rtems__ 11 | #error " not supported" 12 | #endif 13 | 14 | #include 15 | 16 | #define FSETLOCKING_QUERY 0 17 | #define FSETLOCKING_INTERNAL 1 18 | #define FSETLOCKING_BYCALLER 2 19 | 20 | _BEGIN_STD_C 21 | 22 | void _EXFUN(__fpurge,(FILE *)); 23 | int _EXFUN(__fsetlocking,(FILE *, int)); 24 | 25 | /* TODO: 26 | 27 | void _flushlbf (void); 28 | */ 29 | 30 | #ifdef __GNUC__ 31 | 32 | _ELIDABLE_INLINE size_t 33 | __fbufsize (FILE *__fp) { return (size_t) __fp->_bf._size; } 34 | 35 | _ELIDABLE_INLINE int 36 | __freading (FILE *__fp) { return (__fp->_flags & __SRD) != 0; } 37 | 38 | _ELIDABLE_INLINE int 39 | __fwriting (FILE *__fp) { return (__fp->_flags & __SWR) != 0; } 40 | 41 | _ELIDABLE_INLINE int 42 | __freadable (FILE *__fp) { return (__fp->_flags & (__SRD | __SRW)) != 0; } 43 | 44 | _ELIDABLE_INLINE int 45 | __fwritable (FILE *__fp) { return (__fp->_flags & (__SWR | __SRW)) != 0; } 46 | 47 | _ELIDABLE_INLINE int 48 | __flbf (FILE *__fp) { return (__fp->_flags & __SLBF) != 0; } 49 | 50 | _ELIDABLE_INLINE size_t 51 | __fpending (FILE *__fp) { return __fp->_p - __fp->_bf._base; } 52 | 53 | #else 54 | 55 | size_t _EXFUN(__fbufsize,(FILE *)); 56 | int _EXFUN(__freading,(FILE *)); 57 | int _EXFUN(__fwriting,(FILE *)); 58 | int _EXFUN(__freadable,(FILE *)); 59 | int _EXFUN(__fwritable,(FILE *)); 60 | int _EXFUN(__flbf,(FILE *)); 61 | size_t _EXFUN(__fpending,(FILE *)); 62 | 63 | #ifndef __cplusplus 64 | 65 | #define __fbufsize(__fp) ((size_t) (__fp)->_bf._size) 66 | #define __freading(__fp) (((__fp)->_flags & __SRD) != 0) 67 | #define __fwriting(__fp) (((__fp)->_flags & __SWR) != 0) 68 | #define __freadable(__fp) (((__fp)->_flags & (__SRD | __SRW)) != 0) 69 | #define __fwritable(__fp) (((__fp)->_flags & (__SWR | __SRW)) != 0) 70 | #define __flbf(__fp) (((__fp)->_flags & __SLBF) != 0) 71 | #define __fpending(__fp) ((size_t) ((__fp)->_p - (__fp)->_bf._base)) 72 | 73 | #endif /* __cplusplus */ 74 | 75 | #endif /* __GNUC__ */ 76 | 77 | _END_STD_C 78 | 79 | #endif /* _STDIO_EXT_H_ */ 80 | -------------------------------------------------------------------------------- /kernel/lib/stdlib/ctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | int isascii(int c) 20 | { 21 | return ((c) >= 0) && ((c) <= 126); 22 | } 23 | 24 | int iscntrl(int c) 25 | { 26 | return ((c) < ' ') || ((c) > 126); 27 | } 28 | 29 | int isdigit(int c) 30 | { 31 | return ((c) >= '0') && ((c) <= '9'); 32 | } 33 | 34 | int isgraph(int c) 35 | { 36 | return ((c) > ' ') && ((c) <= 126); 37 | } 38 | 39 | int islower(int c) 40 | { 41 | return (c >= 'a') && (c <= 'z'); 42 | } 43 | 44 | int isprint(int c) 45 | { 46 | return ((c) >= ' ') && ((c) <= 126); 47 | } 48 | 49 | int isspace(int c) 50 | { 51 | return ((c) == ' ') || ((c) == '\f') 52 | || ((c) == '\n') || ((c) == '\r') 53 | || ((c) == '\t') || ((c) == '\v'); 54 | } 55 | 56 | int isupper(int c) 57 | { 58 | return (c >= 'A') && (c <= 'Z'); 59 | } 60 | 61 | int isxdigit(int c) 62 | { 63 | return isdigit(c) || 64 | ((c >= 'A') && (c <= 'F')) || 65 | ((c >= 'a') && (c <= 'f')); 66 | } 67 | 68 | int isalpha(int c) 69 | { 70 | return islower(c) || isupper(c); 71 | } 72 | 73 | int isalnum(int c) 74 | { 75 | return isalpha(c) || isdigit(c); 76 | } 77 | 78 | int ispunct(int c) 79 | { 80 | return isgraph(c) && !isalnum(c); 81 | } 82 | 83 | int toupper(int c) 84 | { 85 | return ((c >= 'a') && (c <= 'z')) ? (c - 'a' + 'A') : c; 86 | } 87 | 88 | int tolower(int c) 89 | { 90 | return ((c >= 'A') && (c <= 'Z')) ? (c - 'A' + 'a') : c; 91 | } 92 | -------------------------------------------------------------------------------- /kernel/arch/x86/inc/irq.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file x86/irq.h 3 | * 4 | */ 5 | #ifndef __X86_IRQ_H__ 6 | #define __X86_IRQ_H__ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | /* 16 | * 17 | * x86 Hardware Interrupts 18 | * 19 | * 8259A Input pin Interrupt Number Description 20 | * ------------------------------------------------------------------ 21 | * IRQ0 0x08 Timer 22 | * IRQ1 0x09 Keyboard 23 | * IRQ2 0x0A Cascade for 8259A Slave controller 24 | * IRQ3 0x0B Serial port 2 25 | * IRQ4 0x0C Serial port 1 26 | * IRQ5 0x0D AT systems: Parallel Port 2. PS/2 systems: reserved 27 | * IRQ6 0x0E Diskette drive 28 | * IRQ7 0x0F Parallel Port 1 29 | * IRQ8/IRQ0 0x70 CMOS Real time clock 30 | * IRQ9/IRQ1 0x71 CGA vertical retrace 31 | * IRQ10/IRQ2 0x72 Reserved 32 | * IRQ11/IRQ3 0x73 Reserved 33 | * IRQ12/IRQ4 0x74 AT systems: reserved. PS/2: auxiliary device 34 | * IRQ13/IRQ5 0x75 FPU 35 | * IRQ14/IRQ6 0x76 Hard disk controller 36 | * IRQ15/IRQ7 0x77 Reserved 37 | * 38 | */ 39 | #define MAX_NUM_IRQS 16 40 | #define IRQ_TIMER 0 41 | #define IRQ_KEYBOARD 1 42 | #define IRQ_SERIAL2 3 43 | #define IRQ_SERIAL1 4 44 | 45 | void pic_irq_init(void); 46 | 47 | #define ack_irq(irq) pic_eoi(irq) 48 | 49 | void generate_irq(int irq); 50 | 51 | #define cli() __asm__ __volatile__("cli"); 52 | #define sti() __asm__ __volatile__("sti"); 53 | 54 | #define disable_irqs() cli() 55 | #define enable_irqs() sti() 56 | 57 | static inline void disable_save_irqs(unsigned long *flags) 58 | { 59 | *flags = get_eflags() & 0x200; 60 | disable_irqs(); 61 | } 62 | 63 | static inline void restore_irqs(unsigned long flags) 64 | { 65 | if (flags & 0x200) 66 | enable_irqs(); 67 | } 68 | 69 | static inline bool irqs_enabled(void) 70 | { 71 | return get_eflags() & 0x200; 72 | } 73 | 74 | #endif /* !__X86_IRQ_H__ */ 75 | -------------------------------------------------------------------------------- /kernel/arch/x86/8253.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file arch/x86/8253.c 3 | * 4 | * @brief 8253 Programmable Interval Timer. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define PIT_FREQ_HZ 1193182 12 | 13 | #define PIT_CHANNEL0_PORT 0x40 /* IRQ 0 */ 14 | #define PIT_CHANNEL1_PORT 0x41 /* obsolete */ 15 | #define PIT_CHANNEL2_PORT 0x42 /* pc speaker */ 16 | #define PIT_COMMAND_PORT 0x43 17 | 18 | /* PIT command register format */ 19 | #define IRQ_CHANNEL (0 << 6) 20 | #define CHANNEL1 (1 << 6) 21 | #define SPEAKER_CHANNEL (2 << 6) 22 | #define READBACK (3 << 6) 23 | 24 | #define LATCH_COUNT (0 << 4) 25 | #define LOBYTE (1 << 4) 26 | #define HIBYTE (2 << 4) 27 | #define LOHIBYTE (3 << 4) 28 | 29 | #define OPMODE0 (0 << 1) /* interrupt on terminal count */ 30 | #define ONE_SHOT (1 << 1) /* hardware re-triggerable one-shot */ 31 | #define OPMODE2 (2 << 1) /* rate generator */ 32 | #define SQUARE_WAVE (3 << 1) /* square wave generator */ 33 | #define OPMODE4 (4 << 1) /* software triggered strobe */ 34 | #define OPMODE5 (5 << 1) /* hardware triggered strobe */ 35 | #define OPMODE6 (6 << 1) /* same as (2) */ 36 | #define OPMODE7 (7 << 1) /* same as (3) */ 37 | 38 | #define BINARYMODE (0 << 0) /* 0 6-bit binary */ 39 | #define BCDMODE (1 << 0) /* 1 our-digit BCD */ 40 | 41 | static void pit_irq(struct irq_context *irq) 42 | { 43 | (void) irq; 44 | 45 | timer_tick(); 46 | } 47 | 48 | static struct irq_handler pit_irq_handler = { 49 | .f = pit_irq, 50 | }; 51 | 52 | static void pit_start(struct timer *timer, int hz) 53 | { 54 | int freq_div; 55 | int ret; 56 | (void) timer; 57 | 58 | /* 59 | * Set up the timer to be fired at a specific interval 60 | */ 61 | freq_div = PIT_FREQ_HZ / hz; 62 | 63 | outb(PIT_COMMAND_PORT, IRQ_CHANNEL | LOHIBYTE | SQUARE_WAVE | BINARYMODE); 64 | outb(PIT_CHANNEL0_PORT, (freq_div >> 0) & 0xff); 65 | outb(PIT_CHANNEL0_PORT, (freq_div >> 8) & 0xff); 66 | 67 | ret = register_irq(IRQ_TIMER, &pit_irq_handler); 68 | ASSERT_EQUALS(0, ret); 69 | } 70 | 71 | static struct timer pit_8253_timer = { 72 | .start = pit_start, 73 | .name = "Programmable Interval Timer (8253)" 74 | }; 75 | 76 | void init_8253(void) 77 | { 78 | set_timer(&pit_8253_timer); 79 | } 80 | -------------------------------------------------------------------------------- /kernel/mm/memory.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mm/memory.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | size_t phys_mem_bytes; /* size of physical memory in bytes */ 12 | size_t phys_mem_pages; /* size of physical memory in pages */ 13 | 14 | char *kdirect_start; 15 | char *kdirect_end; 16 | 17 | /** 18 | * @brief Initialize basic memory contructs from the multiboot environment 19 | */ 20 | void mem_mb_init(struct multiboot_info *mb_info) 21 | { 22 | ASSERT(mb_info->flags & MULTIBOOT_INFO_MEMORY); 23 | 24 | phys_mem_bytes = MB(1) + (KB(1) * mb_info->mem_upper); 25 | phys_mem_pages = phys_mem_bytes / PAGE_SIZE; 26 | 27 | INFO("RAM: %d MB", phys_mem_bytes / MB(1)); 28 | 29 | kdirect_start = CONFIG_KERNEL_VIRTUAL_START; 30 | 31 | /* 32 | * The kernel heap starts after the kernel image in memory 33 | */ 34 | kheap_start = (char *) PAGE_ALIGN_UP(kimg_end); 35 | 36 | /* 37 | * If there are any modules installed (e.g. ramdisk) then we need to 38 | * make sure the kernel heap doesn't overwrite any modules. 39 | */ 40 | if (mb_info->flags & MULTIBOOT_INFO_MODS) { 41 | unsigned i; 42 | 43 | for (i = 0; i < mb_info->mods_count; i++) { 44 | multiboot_module_t *m; 45 | 46 | m = ((multiboot_module_t *) mb_info->mods_addr) + i; 47 | if (m->mod_end > (size_t) kheap_start) { 48 | kheap_start = 49 | (char *) PAGE_ALIGN_UP(m->mod_end); 50 | } 51 | } 52 | } 53 | 54 | /* 55 | * The kernel heap marks the end of the direct mapped pages of kernel 56 | * memory. We statically allocate some fraction of physical memory to 57 | * the kernel here. The rest goes to the user. 58 | */ 59 | kdirect_end = (char *) umin(CONFIG_KHEAP_MAX_END, 60 | CONFIG_KERNEL_VIRTUAL_START + 61 | PAGE_ALIGN_DOWN(phys_mem_bytes / 4)); 62 | 63 | kheap_end = kdirect_end; 64 | 65 | /* 66 | * The kmap region lives at the top of the kernel's virtual address 67 | * space. 68 | */ 69 | kmap_start = kdirect_end; 70 | kmap_end = (char *) CONFIG_KERNEL_VIRTUAL_END; 71 | 72 | INFO("kimg: 0x%08x - 0x%08x", kimg_start, kimg_end); 73 | INFO("kheap: 0x%08x - 0x%08x", kheap_start, kheap_end); 74 | INFO("kmap: 0x%08x - 0x%08x", kmap_start, kmap_end); 75 | } 76 | -------------------------------------------------------------------------------- /user/newlib/include/unctrl.h: -------------------------------------------------------------------------------- 1 | /* From curses.h. */ 2 | /* 3 | * Copyright (c) 1981, 1993 4 | * The Regents of the University of California. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. All advertising materials mentioning features or use of this software 15 | * must display the following acknowledgement: 16 | * This product includes software developed by the University of 17 | * California, Berkeley and its contributors. 18 | * 4. Neither the name of the University nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef _UNCTRL_H_ 36 | #define _UNCTRL_H_ 37 | 38 | #include <_ansi.h> 39 | 40 | #define unctrl(c) __unctrl[(c) & 0xff] 41 | #define unctrllen(ch) __unctrllen[(ch) & 0xff] 42 | 43 | extern __IMPORT _CONST char * _CONST __unctrl[256]; /* Control strings. */ 44 | extern __IMPORT _CONST char __unctrllen[256]; /* Control strings length. */ 45 | 46 | #endif /* _UNCTRL_H_ */ 47 | -------------------------------------------------------------------------------- /kernel/mm/lmm/README: -------------------------------------------------------------------------------- 1 | 2 | List-based Memory Manager (LMM) 3 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | 5 | This is a flexible memory allocation/management module 6 | designed along the lines of the Amiga's low level memory management system. 7 | It differs from typical Unix malloc packages 8 | in that it does not assume a Unix-like virtual memory environment, 9 | where the heap comes in one big contiguous region that can be expanded arbitrarily on demand, 10 | and where memory can be "wasted" freely because untouched pages are never paged in. 11 | As such it is intended primarily for use in OS kernels and other system-level software. 12 | 13 | The LMM has the following main features: 14 | 15 | * Very efficient use of memory. 16 | At most fourteen bytes are wasted in a given allocation 17 | (because of alignment restrictions); 18 | there is _no_ memory overhead for 8-byte aligned allocations. 19 | 20 | * Support for allocating memory with specific alignment properties. 21 | Memory can be allocated at any given power-of-two boundary, 22 | or at an arbitrary offset beyond a specified power-of-two boundary. 23 | 24 | * Support for allocations that must come from a specific address range. 25 | For example, sometimes memory needs to be allocated specifically 26 | from the first 16MB of physical memory, or from the first 1MB of memory. 27 | 28 | Its (potential) disadvantages are: 29 | 30 | * It requires the caller to remember the size of each allocated block, 31 | and pass its size back as a parameter to lmm_free(). 32 | Thus, a malloc() implemented on top of this memory manager 33 | would have to remember the size of each block somewhere. 34 | 35 | * Since it uses a sequential search through what amounts to a single linked list, 36 | allocations are not as blazingly fast 37 | as in packages that maintain separate free lists for different sizes of blocks. 38 | 39 | * It does not know how to "grow" the free list automatically 40 | (e.g. by calling sbrk() or some equivalent); 41 | if it runs out of memory, the allocation simply fails. 42 | 43 | * It is not thread-safe - i.e. it does not contain any internal serialization code. 44 | 45 | If high-speed conventional memory allocation is needed, 46 | conventional zone allocation techniques can be implemented on top of the LMM. 47 | 48 | 49 | XXX make an "LMM pool" an ADT so there can be more than one in a program? 50 | 51 | -------------------------------------------------------------------------------- /kernel/mm/malloc/malloc_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #ifndef _410KERN_MALLOC_INTERNALS_H_ 23 | #define _410KERN_MALLOC_INTERNALS_H_ 24 | 25 | #include 26 | #include 27 | 28 | extern lmm_t malloc_lmm; 29 | 30 | void *_malloc(size_t size); 31 | void *_mustmalloc(size_t size); 32 | void *_memalign(size_t alignment, size_t size); 33 | void *_calloc(size_t nelt, size_t eltsize); 34 | void *_mustcalloc(size_t nelt, size_t eltsize); 35 | void *_realloc(void *buf, size_t new_size); 36 | void _free(void *buf); 37 | 38 | /* Alternate version of the standard malloc functions that expect the 39 | caller to keep track of the size of allocated chunks. These 40 | versions are _much_ more memory-efficient when allocating many 41 | chunks naturally aligned to their (natural) size (e.g. allocating 42 | naturally-aligned pages or superpages), because normal memalign 43 | requires a prefix between each chunk which will create horrendous 44 | fragmentation and memory loss. Chunks allocated with these 45 | functions must be freed with sfree() rather than the ordinary 46 | free(). */ 47 | void *_smalloc(size_t size); 48 | void *_smemalign(size_t alignment, size_t size); 49 | void _sfree(void *buf, size_t size); 50 | 51 | #endif /* _410KERN_MALLOC_H_ */ 52 | -------------------------------------------------------------------------------- /kernel/mm/malloc/smemalign.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | /* 22 | * Alternate version of memalign 23 | * that expects the caller to keep track of the size of allocated chunks. 24 | * This version is _much_ more memory-efficient 25 | * when allocating many chunks naturally aligned to their (natural) size 26 | * (e.g. allocating naturally-aligned pages or superpages), 27 | * because normal memalign requires a prefix between each chunk 28 | * which will create horrendous fragmentation and memory loss. 29 | * Chunks allocated with this function must be freed with sfree(). 30 | */ 31 | #pragma GCC diagnostic push 32 | #pragma GCC diagnostic ignored "-Wsign-compare" 33 | 34 | #include 35 | #include "malloc_internal.h" 36 | 37 | void *_smemalign(size_t alignment, size_t size) 38 | { 39 | unsigned shift; 40 | void *chunk; 41 | 42 | /* Find the alignment shift in bits. XXX use proc_ops.h */ 43 | for (shift = 0; (1 << shift) < alignment; shift++); 44 | 45 | /* 46 | * Allocate a chunk of LMM memory with the specified alignment shift 47 | * and an offset such that the memory block we return will be aligned. 48 | */ 49 | if (!(chunk = lmm_alloc_aligned(&malloc_lmm, size, 0, shift, 0))) 50 | return NULL; 51 | 52 | return chunk; 53 | } 54 | 55 | #pragma GCC diagnostic pop 56 | -------------------------------------------------------------------------------- /user/newlib/include/sys/_types.h: -------------------------------------------------------------------------------- 1 | /* ANSI C namespace clean utility typedefs */ 2 | 3 | /* This file defines various typedefs needed by the system calls that support 4 | the C library. Basically, they're just the POSIX versions with an '_' 5 | prepended. This file lives in the `sys' directory so targets can provide 6 | their own if desired (or they can put target dependant conditionals here). 7 | */ 8 | 9 | #ifndef _SYS__TYPES_H 10 | #define _SYS__TYPES_H 11 | 12 | #include 13 | #include 14 | 15 | #ifndef __off_t_defined 16 | typedef long _off_t; 17 | #endif 18 | 19 | #ifndef __dev_t_defined 20 | typedef short __dev_t; 21 | #endif 22 | 23 | #ifndef __uid_t_defined 24 | typedef unsigned short __uid_t; 25 | #endif 26 | #ifndef __gid_t_defined 27 | typedef unsigned short __gid_t; 28 | #endif 29 | 30 | #ifndef __off64_t_defined 31 | __extension__ typedef long long _off64_t; 32 | #endif 33 | 34 | /* 35 | * We need fpos_t for the following, but it doesn't have a leading "_", 36 | * so we use _fpos_t instead. 37 | */ 38 | #ifndef __fpos_t_defined 39 | typedef long _fpos_t; /* XXX must match off_t in */ 40 | /* (and must be `long' for now) */ 41 | #endif 42 | 43 | #ifdef __LARGE64_FILES 44 | #ifndef __fpos64_t_defined 45 | typedef _off64_t _fpos64_t; 46 | #endif 47 | #endif 48 | 49 | #ifndef __ssize_t_defined 50 | #ifdef __SIZE_TYPE__ 51 | /* If __SIZE_TYPE__ is defined (gcc) we define ssize_t based on size_t. 52 | We simply change "unsigned" to "signed" for this single definition 53 | to make sure ssize_t and size_t only differ by their signedness. */ 54 | #define unsigned signed 55 | typedef __SIZE_TYPE__ _ssize_t; 56 | #undef unsigned 57 | #else 58 | #if defined(__INT_MAX__) && __INT_MAX__ == 2147483647 59 | typedef int _ssize_t; 60 | #else 61 | typedef long _ssize_t; 62 | #endif 63 | #endif 64 | #endif 65 | 66 | #define __need_wint_t 67 | #include 68 | 69 | #ifndef __mbstate_t_defined 70 | /* Conversion state information. */ 71 | typedef struct 72 | { 73 | int __count; 74 | union 75 | { 76 | wint_t __wch; 77 | unsigned char __wchb[4]; 78 | } __value; /* Value so far. */ 79 | } _mbstate_t; 80 | #endif 81 | 82 | #ifndef __flock_t_defined 83 | typedef _LOCK_RECURSIVE_T _flock_t; 84 | #endif 85 | 86 | #ifndef __iconv_t_defined 87 | /* Iconv descriptor type */ 88 | typedef void *_iconv_t; 89 | #endif 90 | 91 | #endif /* _SYS__TYPES_H */ 92 | -------------------------------------------------------------------------------- /kernel/arch/x86/pic.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file pic.c 3 | * 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | void pic_remap(u32 master_offset, u32 slave_offset) 10 | { 11 | u8 slave_irq_mask, master_irq_mask; 12 | 13 | // save the current interrupt mask 14 | master_irq_mask = inb(PIC_MASTER_DATA); 15 | slave_irq_mask = inb(PIC_SLAVE_DATA); 16 | 17 | // tell the pics that there are 3 data messages coming! 18 | outb(PIC_MASTER_CMD, PIC_INIT); 19 | iodelay(); 20 | outb(PIC_SLAVE_CMD, PIC_INIT); 21 | iodelay(); 22 | 23 | // icw2: set the vector offset 24 | outb(PIC_MASTER_DATA, master_offset); 25 | iodelay(); 26 | outb(PIC_SLAVE_DATA, slave_offset); 27 | iodelay(); 28 | 29 | // icw3: master/slaving wiring 30 | outb(PIC_MASTER_DATA, PIC_ICW3_TELL_MASTER_ABOUT_SLAVE); 31 | iodelay(); 32 | outb(PIC_SLAVE_DATA, PIC_ICW3_TELL_SLAVE_CASCADE_ID); 33 | iodelay(); 34 | 35 | // icw4: describe environment 36 | outb(PIC_MASTER_DATA, PIC_ICW4_8086); 37 | iodelay(); 38 | outb(PIC_SLAVE_DATA, PIC_ICW4_8086); 39 | iodelay(); 40 | 41 | // restore the masks 42 | outb(PIC_MASTER_DATA, master_irq_mask); 43 | outb(PIC_SLAVE_DATA, slave_irq_mask); 44 | } 45 | 46 | void pic_imr_set(u8 irq) 47 | { 48 | u32 port; 49 | u8 mask; 50 | 51 | if (irq < 8) { 52 | port = PIC_MASTER_DATA; 53 | } 54 | else { 55 | port = PIC_SLAVE_DATA; 56 | irq -= 8; 57 | } 58 | 59 | mask = inb(port) | (1 << irq); 60 | outb(port, mask); 61 | } 62 | 63 | void pic_imr_clear(u8 irq) 64 | { 65 | u32 port; 66 | u8 mask; 67 | 68 | if (irq < 8) { 69 | port = PIC_MASTER_DATA; 70 | } 71 | else { 72 | port = PIC_SLAVE_DATA; 73 | irq -= 8; 74 | } 75 | 76 | mask = inb(port) & ~(1 << irq); 77 | outb(port, mask); 78 | } 79 | 80 | static inline u16 pic_get_reg(u8 ocw3) 81 | { 82 | u8 master, slave; 83 | 84 | outb(PIC_MASTER_CMD, ocw3); 85 | master = inb(PIC_MASTER_CMD); 86 | 87 | outb(PIC_SLAVE_CMD, ocw3); 88 | slave = inb(PIC_SLAVE_CMD); 89 | 90 | return (slave << 8) | (master); 91 | } 92 | 93 | u16 pic_get_isr(void) 94 | { 95 | return pic_get_reg(PIC_READ_ISR); 96 | } 97 | 98 | u16 pic_get_irr(void) 99 | { 100 | return pic_get_reg(PIC_READ_IRR); 101 | } 102 | 103 | void pic_eoi(u8 irq) 104 | { 105 | if (irq >= 8) { 106 | outb(PIC_SLAVE_CMD, PIC_EOI); 107 | } 108 | outb(PIC_MASTER_CMD, PIC_EOI); 109 | } 110 | --------------------------------------------------------------------------------