├── .before_install.sh ├── .before_script.sh ├── .build-travis.sh ├── .gitignore ├── .travis.yml ├── Makefile ├── README.md ├── STYLE.c ├── TODO.md ├── analyze ├── build.sh ├── docs ├── bootloader.tex ├── core.tex ├── history.tex ├── intro.tex ├── license.tex ├── loader.tex ├── logo.png └── toaru_logo.svg ├── hdd ├── bin │ └── .dummy ├── dev │ └── .dummy ├── etc │ ├── .htop │ ├── .vim │ ├── color-test │ ├── game │ │ ├── 0.bmp │ │ ├── 1.bmp │ │ ├── 2.bmp │ │ ├── 3.bmp │ │ ├── 4.bmp │ │ ├── 5.bmp │ │ ├── 6.bmp │ │ ├── 7.bmp │ │ ├── map │ │ ├── remilia.bmp │ │ ├── remilia_f.bmp │ │ ├── remilia_l.bmp │ │ └── remilia_r.bmp │ ├── master.passwd │ ├── motd │ └── passwd ├── home │ ├── local │ │ └── .dummy │ └── root │ │ └── .dummy └── usr │ └── share │ ├── arrow.bmp │ ├── arrow_alpha.bmp │ ├── bs-alpha.bmp │ ├── bs.bmp │ ├── cat │ ├── edit_test │ ├── fonts │ ├── DejaVuSans-Bold.ttf │ ├── DejaVuSans-BoldOblique.ttf │ ├── DejaVuSans-Oblique.ttf │ ├── DejaVuSans.ttf │ ├── DejaVuSansMono-Bold.ttf │ ├── DejaVuSansMono-BoldOblique.ttf │ ├── DejaVuSansMono-Oblique.ttf │ ├── DejaVuSansMono.ttf │ ├── VLGothic.ttf │ └── VLPGothic.ttf │ ├── icons │ ├── AUTHORS │ ├── CONTRIBUTORS │ ├── applications-painting.png │ ├── applications-simulation.png │ ├── panel-shutdown.png │ └── utilities-terminal.png │ ├── libmath.b │ ├── logo_login.png │ ├── panel.bmp │ ├── panel.png │ ├── posix_ja.txt │ ├── snowman │ ├── ttk │ ├── active │ │ ├── ll.png │ │ ├── lm.png │ │ ├── lr.png │ │ ├── ml.png │ │ ├── mr.png │ │ ├── ul.png │ │ ├── um.png │ │ └── ur.png │ └── inactive │ │ ├── ll.png │ │ ├── lm.png │ │ ├── lr.png │ │ ├── ml.png │ │ ├── mr.png │ │ ├── ul.png │ │ ├── um.png │ │ └── ur.png │ └── wallpaper.png ├── image-builder ├── .gitignore ├── README.md ├── boot │ └── grub │ │ └── grub.cfg ├── clean-up.sh ├── create-image.sh └── fdisk.conf ├── kernel ├── cpu │ ├── gdt.c │ ├── idt.c │ ├── irq.c │ └── isrs.c ├── devices │ ├── cmos.c │ ├── fpu.c │ ├── ide.c │ ├── kbd.c │ ├── mbr.c │ ├── mouse.c │ ├── pci.c │ ├── serial.c │ └── timer.c ├── ds │ ├── list.c │ └── tree.c ├── fs │ ├── devfs.c │ ├── ext2_disk.c │ ├── ext2_ramdisk.c │ ├── nulldev.c │ ├── pipe.c │ ├── serialdev.c │ └── vfs.c ├── include │ ├── ata.h │ ├── boot.h │ ├── elf.h │ ├── ext2.h │ ├── fs.h │ ├── list.h │ ├── logging.h │ ├── mem.h │ ├── mouse.h │ ├── multiboot.h │ ├── pipe.h │ ├── process.h │ ├── shm.h │ ├── signal.h │ ├── system.h │ ├── task.h │ ├── tree.h │ ├── tss.h │ ├── types.h │ ├── va_list.h │ └── version.h ├── link.ld ├── main.c ├── mem │ ├── alloc.c │ ├── mem.c │ └── shm.c ├── misc │ ├── args.c │ ├── elf.c │ ├── kprintf.c │ ├── logging.c │ └── multiboot.c ├── start.s ├── sys │ ├── panic.c │ ├── process.c │ ├── signal.c │ ├── syscall.c │ ├── system.c │ ├── task.c │ └── version.c └── video │ └── lfb.c ├── loader ├── crtbegin.s ├── link.ld ├── syscall.c └── syscall.h ├── toaru.terminfo ├── toolchain ├── activate.sh ├── config.sh ├── install.sh ├── patches │ ├── binutils-2.22.patch │ ├── cairo-1.12.2.patch │ ├── cairo-Makefile │ ├── freetype-2.4.9.patch │ ├── gcc-4.6.0.patch │ ├── gmp-5.0.1.patch │ ├── libpng-1.5.13.patch │ ├── mpc-0.9.patch │ ├── mpfr-3.0.1.patch │ ├── newlib-1.19.0.patch │ ├── newlib │ │ ├── include │ │ │ ├── syscall.h │ │ │ └── termios.h │ │ ├── malloc.c │ │ ├── setjmp.S │ │ └── toaru │ │ │ ├── Makefile.am │ │ │ ├── Makefile.in │ │ │ ├── aclocal.m4 │ │ │ ├── bits │ │ │ └── dirent.h │ │ │ ├── configure.in │ │ │ ├── crt0.s │ │ │ ├── crti.s │ │ │ ├── crtn.s │ │ │ ├── lib.a │ │ │ ├── sys │ │ │ └── dirent.h │ │ │ └── syscalls.c │ └── pixman-0.26.2.patch ├── prepare.sh ├── rebuild-newlib.sh └── util.sh ├── userspace ├── build.py ├── core │ ├── cat.c │ ├── clear.c │ ├── cp.c │ ├── cpudet.c │ ├── echo.c │ ├── env.c │ ├── esh.c │ ├── hello.c │ ├── hostname.c │ ├── init.c │ ├── login.c │ ├── ls.c │ ├── mkdir.c │ ├── readelf.c │ ├── reboot.c │ ├── shutdown.c │ ├── sleep.c │ ├── stat.c │ ├── sysfunc.c │ ├── touch.c │ ├── uname.c │ ├── whoami.c │ └── yes.c ├── extra │ ├── bim.c │ ├── clock.c │ ├── compare.c │ ├── csnow.c │ ├── ld.c │ ├── lock.c │ ├── nyancat-animation.h │ ├── nyancat.c │ ├── serial-console.c │ ├── solver.c │ ├── telnet.h │ └── verify-write.c ├── gui │ ├── basic │ │ ├── clock-win.c │ │ ├── draw.c │ │ ├── drawlines.c │ │ ├── game.c │ │ ├── julia.c │ │ ├── plasma.c │ │ └── view.c │ ├── compositor │ │ └── compositor.c │ ├── core │ │ ├── glogin.c │ │ ├── gsession.c │ │ ├── panel.c │ │ └── wallpaper.c │ ├── demo │ │ ├── cairo-demo.c │ │ ├── make-it-snow.c │ │ └── pixman-demo.c │ ├── terminal │ │ ├── terminal-font.h │ │ ├── terminal-palette.h │ │ └── terminal.c │ └── ttk │ │ ├── lib │ │ └── ttk-core.c │ │ ├── ttk-demo.c │ │ └── ttk.h ├── lib │ ├── decorations.c │ ├── decorations.h │ ├── graphics.c │ ├── graphics.h │ ├── kbd.c │ ├── kbd.h │ ├── ldlib.c │ ├── ldlib.h │ ├── list.c │ ├── list.h │ ├── pthread.c │ ├── pthread.h │ ├── sha2.c │ ├── sha2.h │ ├── shmemfonts.c │ ├── shmemfonts.h │ ├── syscall.h │ ├── utf8decode.h │ ├── wcwidth.c │ ├── wcwidth.h │ ├── window.c │ └── window.h ├── tests │ ├── core-tests.c │ ├── test-argv.c │ ├── test-blur.c │ ├── test-borders.c │ ├── test-cpp.cpp │ ├── test-dsr.c │ ├── test-echo.c │ ├── test-env.c │ ├── test-fs.c │ ├── test-gfx.c │ ├── test-multitasking.c │ ├── test-pipe.c │ └── test-threads.c └── util │ ├── stack-overflow.c │ ├── stack-reaper.c │ ├── term_size.c │ └── thrash-process.c └── util ├── 256colres.pl ├── bin └── .git-marker ├── check-reqs ├── compiler ├── config-parser ├── cpad.sh ├── dump-colors.py ├── grab-binaries.sh ├── mk-beg ├── mk-beg-rm ├── mk-end ├── mk-end-rm ├── mk-error ├── mk-info ├── mrboots-installer.c ├── readelf.c ├── run-fullscreen.sh ├── run-tests.py └── typewriter.c /.before_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Travis before_install script 4 | sudo apt-get update 5 | sudo apt-get install clang yasm genext2fs build-essential wget libmpfr-dev libmpc-dev libgmp-dev qemu autoconf automake texinfo 6 | sudo apt-get remove kvm-ipxe 7 | 8 | -------------------------------------------------------------------------------- /.before_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Travis before_script 4 | unset CC 5 | 6 | sudo mkdir -p /home/build/osdev/toolchain 7 | 8 | sudo chmod a=rwx /home/build 9 | sudo chmod a=rwx /home/build/osdev 10 | sudo chmod a=rwx /home/build/osdev/toolchain 11 | 12 | pushd toolchain 13 | cp *.sh /home/build/osdev/toolchain/ 14 | popd 15 | 16 | pushd /home/build/osdev/toolchain 17 | wget "http://b.dakko.us/~klange/toolchain-2013-01-27.tar.gz" 18 | tar -xaf "toolchain-2013-01-27.tar.gz" 19 | . activate.sh || exit 1 20 | echo $PATH 21 | $TARGET-gcc --version 22 | popd 23 | -------------------------------------------------------------------------------- /.build-travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | unset CC 4 | pushd /home/build/osdev/toolchain 5 | . activate.sh || exit 1 6 | popd 7 | make system || exit 1 8 | make test || exit 1 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | toaruos-kernel 2 | toaruos-initrd 3 | toaruos-disk.img 4 | *.o 5 | *.swp 6 | .userspace-check 7 | .compositor-check 8 | bootloader/stage1.bin 9 | bootloader/stage2.bin 10 | initrd/boot 11 | initrd/bin/* 12 | initrd/etc 13 | hdd/boot 14 | hdd/bin/* 15 | hdd/etc/hostname 16 | hdd/lib 17 | .gdb_history 18 | bootdisk.img 19 | util/toaru-toolchain/* 20 | util/toaru-toolchain 21 | *.log 22 | *.pdf 23 | *.aux 24 | *.ilg 25 | *.idx 26 | *.ind 27 | *.out 28 | *.toc 29 | util/bin/* 30 | .passed 31 | tags 32 | toolchain/tarballs 33 | toolchain/local 34 | toolchain/build 35 | .config 36 | toaru-pdfviewer 37 | toaru-toolkit 38 | hdd/home/root/* 39 | hdd/home/local/* 40 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | before_install: ./.before_install.sh 3 | before_script: ./.before_script.sh 4 | script: ./.build-travis.sh 5 | notifications: 6 | email: false 7 | irc: 8 | channels: 9 | - "irc.freenode.org#toaruos" 10 | use_notice: true 11 | skip_join: true 12 | -------------------------------------------------------------------------------- /STYLE.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * This file is part of the ToAru Kernel and is released under 4 | * the terms of the NCSA License. 5 | * 6 | * This is an overview of the coding style for the ToAru Kernel. 7 | * Source files should include a header describing the file, but 8 | * this is not the 70s, you do not need to list the file name. 9 | * Having a set of vim: command hints at the top will ensure that 10 | * formatting remains correct. 11 | * 12 | * Tabs are assumed to be four spaces wide for the sake of line length. 13 | */ 14 | 15 | /** 16 | * Function 17 | * 18 | * Does things. 19 | * 20 | * @param argument Normal arguments should be in line with the rest 21 | * of the function, unless the line would be cumbersome 22 | * in length. Functions should, ideally, be commented 23 | * with a Doxygen-style header, like this one. 24 | * @param pointer Pointers should have their *s immediately before the 25 | * identifier, except in the case of... 26 | * @param string_array String arrays, which are separated. 27 | * @returns Stuff. 28 | */ 29 | int function(int argument, void * pointer, char * string_array[]) { 30 | /* Inline comments should use the classic C-style*/ 31 | if (condition) { 32 | /* 33 | * If a comment is sufficiently long, you should leave some 34 | * space on the top line and the bottom line. 35 | */ 36 | } else { 37 | while ((argument & stuff) || 38 | (argument & other) || 39 | (argument & more)) { 40 | /* 41 | * Multiline conditionals should be aligned with spaces 42 | * (though this may annoy you in some editors) 43 | */ 44 | } 45 | } 46 | } 47 | 48 | /* 49 | * #define'd constants should be aligned on spaces and use 50 | * uppercase names, separated with underscores. 51 | */ 52 | #define IMPORTANT_CONSTANT value 53 | #define OTHER_IMPORTANT_CONSTANT other_value 54 | 55 | /* 56 | * Similarly, variables should be aligned on spaces 57 | * and separated with underscores. 58 | */ 59 | int important_global = 1; 60 | int other_important_global = 2; 61 | 62 | /* 63 | * Structs should be typedef'd to something_t 64 | * and may be either anonymous or have internal names. 65 | */ 66 | typedef struct { 67 | int x; 68 | int y; 69 | int z; 70 | } new_type_t; 71 | 72 | void foo() { 73 | /* 74 | * NULL checks should be of the form !conditional() 75 | * as should checks for comparison to 0 76 | */ 77 | if (!bar()) { 78 | if (!strcmp(str, "value")) { 79 | /* str is "value" */ 80 | } 81 | } 82 | int a; /* Comments like this */ 83 | int b___; /* Should be aligned on spaces */ 84 | int c_____; /* And use C-style comments */ 85 | int d___; /* Values of the same type */ 86 | int e; /* Should be defined on separate lines */ 87 | } 88 | -------------------------------------------------------------------------------- /analyze: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make clean 4 | CCC_ANALYZE=yes scan-build make 5 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -f /etc/lsb-release ]; then 4 | sudo apt-get install clang yasm genext2fs build-essential wget libmpfr-dev libmpc-dev libgmp-dev qemu autoconf automake texinfo pkg-config 5 | elif [ -f /etc/fedora-release ]; then 6 | sudo yum groupinstall 'Development Tools' 7 | sudo yum groupinstall 'Development Libraries' 8 | sudo yum install clang yasm mpfr-devel libmpc-devel gmp-devel 9 | echo "Warning: Fedora is unsupported in this script. Be careful!" 10 | echo "For best results, follow the steps in the script manually." 11 | fi 12 | # Build the toolchain: 13 | unset PKG_CONFIG_LIBDIR 14 | pushd toolchain 15 | ./prepare.sh 16 | ./install.sh 17 | . activate.sh 18 | popd 19 | # Build the kernel 20 | make system # to build the kernel 21 | # XXX: Attempt to boot the kernel with qemu automatically... 22 | -------------------------------------------------------------------------------- /docs/bootloader.tex: -------------------------------------------------------------------------------- 1 | % vim:syntax=tex 2 | % x86 Bootloader 3 | 4 | \section{Bootloader} 5 | 6 | \subsection{Overview} 7 | 8 | The bootloader is unsupported. Please use a multiboot-compliant bootloader such as GRUB instead. 9 | 10 | \subsection{Goals} 11 | 12 | None. 13 | -------------------------------------------------------------------------------- /docs/core.tex: -------------------------------------------------------------------------------- 1 | % Documentation core for ToAruOS 2 | % Copyright 2011 Kevin Lange 3 | 4 | % Standard article with (centered) title page 5 | \documentclass[titlepage]{article} 6 | % Switch to a nice sans-serif font. 7 | \renewcommand*\familydefault{\sfdefault} 8 | \usepackage[margin=1in]{geometry} % Margins 9 | \usepackage{fancyhdr} % Fancy page header 10 | \usepackage{amsmath} % Extra mathemtics stuff 11 | \usepackage{listings} % Source code styling 12 | \usepackage{graphicx} % Graphics support 13 | \usepackage[overlap, CJK]{ruby} % For Japanese 14 | \usepackage{makeidx} % Indexing 15 | \usepackage[bookmarks]{hyperref} % PDF hyperlink index 16 | 17 | % Some useful macros for the documentation 18 | \newcommand{\toarutitle}{ToAruOS Kernel Documentation} 19 | \newcommand{\toaruversi}{v 0.0.1} 20 | \newcommand{\toaruautho}{Kevin Lange} 21 | 22 | % Title / Author 23 | \title{\toarutitle} 24 | \author{\toaruautho} 25 | 26 | % PDF Data 27 | \hypersetup{ 28 | pdftitle={\toarutitle}, 29 | pdfauthor={\toaruautho}, 30 | pdfkeywords={toaruos, kernel, development, documentation}, 31 | linkbordercolor=1 1 1, 32 | } 33 | 34 | % Enable indexing 35 | \makeindex 36 | 37 | % Some nice headers for the core contents. 38 | \pagestyle{fancy} 39 | \lhead{\toarutitle} 40 | \rhead{\toaruversi} 41 | 42 | % Begin document contents 43 | \begin{document} 44 | \begin{CJK}{UTF8}{goth} 45 | 46 | % Title page for documentation 47 | \begin{titlepage} 48 | \maketitle 49 | % Make sure we don't have a number here... 50 | \thispagestyle{empty} 51 | \end{titlepage} 52 | 53 | % We're now on page 1. 54 | \setcounter{page}{1} 55 | \thispagestyle{fancy} 56 | 57 | % Table of Contents 58 | \cleardoublepage 59 | \tableofcontents 60 | 61 | %% BEGIN DOCUMENT CONTENTS %% 62 | 63 | % History 64 | \clearpage 65 | \input{history.tex} 66 | 67 | % Introduction 68 | \clearpage 69 | \input{intro.tex} 70 | 71 | % Bootloader 72 | \clearpage 73 | \input{bootloader.tex} 74 | 75 | % Dynamic Linker / Loader documentation 76 | \clearpage 77 | \input{loader.tex} 78 | 79 | %% Index %% 80 | \cleardoublepage 81 | \addcontentsline{toc}{section}{Index} 82 | \printindex 83 | 84 | % License information 85 | \clearpage 86 | \input{license.tex} 87 | 88 | % Fin 89 | \end{CJK} 90 | \end{document} 91 | -------------------------------------------------------------------------------- /docs/history.tex: -------------------------------------------------------------------------------- 1 | \section{History} 2 | 3 | \subsection{Documentation History} 4 | This is the first edition of the \toarutitle. Writing of this documentation began on March 17th, 2011. This section is reserved to document future changes to this documentation. 5 | 6 | \subsubsection{Revision History} 7 | \begin{itemize} 8 | \item 2011-03-17 \emph{Documentation work begins} 9 | \item 2011-12-25 \emph{Actually bothered to expand the manual} 10 | \end{itemize} 11 | 12 | \subsection{Kernel History} 13 | For a complete history of the ToAruOS Kernel, please reference the git commit logs. 14 | 15 | \subsubsection{Revision History} 16 | \begin{itemize} 17 | \item 2011-01-15 \emph{Initial commit} 18 | \item 2011-01-20 \emph{Memory paging} 19 | \item 2011-01-28 \emph{EXT2 in-memory read support} 20 | \item 2011-02-04 \emph{Ramdisk moved to \texttt{genext2fs}} 21 | \item 2011-02-07 \emph{Kernel debug shell} 22 | \item 2011-02-10 \emph{Moved to clang for compilation} 23 | \item 2011-02-19 \emph{Serial console} 24 | \item 2011-12-25 \emph{VESA support} 25 | \end{itemize} 26 | 27 | \subsection{Userspace History} 28 | No userspace applications or libraries currently exist. 29 | -------------------------------------------------------------------------------- /docs/intro.tex: -------------------------------------------------------------------------------- 1 | % vim:syntax=tex 2 | % Kernel Documentation Introduction 3 | 4 | \section{Introduction} 5 | 6 | \subsection{The ToAruOS Project} 7 | 8 | This project was started in the winter of 2010-2011 with the goal of building, from scratch, a kernel and associated user-space designed with modern concepts and standardized hardware in mind. Throughout its development, the kernel has been expanded to include graphics support, a full-color ANSI-compatible terminal, VESA mode-switching support, EXT2 filesystem read support (to actual hard disks) and various other improvements. 9 | 10 | \subsection{Roadmap} 11 | 12 | Please see \texttt{TODO.md} in the source repository. 13 | -------------------------------------------------------------------------------- /docs/loader.tex: -------------------------------------------------------------------------------- 1 | \section{Dynamic Linker/Loader for ELF Binaries} 2 | \subsection{Overview} 3 | 4 | \subsubsection{Goal} 5 | 6 | \index{dynamic linker} 7 | To develop a stable, simplistic dynamic linker for ELF binaries and 8 | shared libraries. 9 | 10 | \subsubsection{Purpose} 11 | 12 | The purpose of this project is to facilitate understanding of the ELF 13 | binary format and its use in dynamic libraries and executables. Work 14 | from this project will be used to give the とあるOS kernel a working 15 | implementation of dynamic libraries. 16 | 17 | \subsubsection{Scope} 18 | 19 | This project will be developed for the とあるOS kernel and/or in 20 | user-space under Linux. 21 | 22 | \subsubsection{Description} 23 | 24 | The linker/loader will be built to handle 32-bit ELF binaries 25 | compiled for use with shared libraries. It will load the dynamic 26 | binaries and it associated chain of library dependencies and link 27 | the symbol tables of the binary and libraries to create an 28 | executable process image. 29 | 30 | \subsubsection{Testing} 31 | 32 | Various sample binaries are provided in \texttt{loader/tests/}. 33 | 34 | \subsubsection{Documentation} 35 | 36 | As with all other parts of the kernel, the linker/loader will eventually 37 | be documented with Doxygen, as well as with additional documentation in this 38 | chapter. 39 | 40 | \subsubsection{Schedule} 41 | 42 | The four week schedule for this project will be broken up as follows: 43 | 44 | \begin{enumerate} 45 | \item \texttt{readelf} implementation to facilitate learning the ELF binary format. 46 | \item Kernel-mode static ELF binary loading and execution. 47 | \item Loading and execuation of binaries through the linker. 48 | \item Dynamic linking and execution of binaries and libraries. 49 | \end{enumerate} 50 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/docs/logo.png -------------------------------------------------------------------------------- /hdd/bin/.dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/bin/.dummy -------------------------------------------------------------------------------- /hdd/dev/.dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/dev/.dummy -------------------------------------------------------------------------------- /hdd/etc/game/3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/3.bmp -------------------------------------------------------------------------------- /hdd/etc/game/4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/4.bmp -------------------------------------------------------------------------------- /hdd/etc/game/5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/5.bmp -------------------------------------------------------------------------------- /hdd/etc/game/6.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/6.bmp -------------------------------------------------------------------------------- /hdd/etc/game/7.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/7.bmp -------------------------------------------------------------------------------- /hdd/etc/game/remilia.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/remilia.bmp -------------------------------------------------------------------------------- /hdd/etc/game/remilia_f.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/remilia_f.bmp -------------------------------------------------------------------------------- /hdd/etc/game/remilia_l.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/remilia_l.bmp -------------------------------------------------------------------------------- /hdd/etc/game/remilia_r.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/etc/game/remilia_r.bmp -------------------------------------------------------------------------------- /hdd/etc/master.passwd: -------------------------------------------------------------------------------- 1 | root:2b64f2e3f9fee1942af9ff60d40aa5a719db33b8ba8dd4864bb4f11e25ca2bee00907de32a59429602336cac832c8f2eeff5177cc14c864dd116c8bf6ca5d9a9:0 2 | local:6f01a907513e6652020598d38516b788063624b31e9f3afe9c7c0ef4ea5ab4fd4843dd3579292de5aef626d588e678c045cb3ab4d1e49b89237380140907576c:1000 3 | -------------------------------------------------------------------------------- /hdd/etc/motd: -------------------------------------------------------------------------------- 1 | 2 |  = とあるOS ういはる [uiharu] = 3 | -------------------------------------------------------------------------------- /hdd/etc/passwd: -------------------------------------------------------------------------------- 1 | root:x:0:0:Administrator:/home/root:/bin/esh 2 | local:x:1000:1000:Local User:/home/local:/bin/esh 3 | -------------------------------------------------------------------------------- /hdd/home/local/.dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/home/local/.dummy -------------------------------------------------------------------------------- /hdd/home/root/.dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/home/root/.dummy -------------------------------------------------------------------------------- /hdd/usr/share/arrow.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/arrow.bmp -------------------------------------------------------------------------------- /hdd/usr/share/arrow_alpha.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/arrow_alpha.bmp -------------------------------------------------------------------------------- /hdd/usr/share/bs-alpha.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/bs-alpha.bmp -------------------------------------------------------------------------------- /hdd/usr/share/bs.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/bs.bmp -------------------------------------------------------------------------------- /hdd/usr/share/cat: -------------------------------------------------------------------------------- 1 | \ /\ 2 | ) ( ') 3 | ( / ) 4 | \(__)| 5 | -------------------------------------------------------------------------------- /hdd/usr/share/edit_test: -------------------------------------------------------------------------------- 1 | This file is in Unicode. 2 | このファイルはユニコードであります。 3 | Cool, eh? 4 | -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSans-Bold.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSans-BoldOblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSans-BoldOblique.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSans-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSans-Oblique.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSans.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSansMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSansMono-Bold.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSansMono-BoldOblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSansMono-BoldOblique.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSansMono-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSansMono-Oblique.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/DejaVuSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/DejaVuSansMono.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/VLGothic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/VLGothic.ttf -------------------------------------------------------------------------------- /hdd/usr/share/fonts/VLPGothic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/fonts/VLPGothic.ttf -------------------------------------------------------------------------------- /hdd/usr/share/icons/AUTHORS: -------------------------------------------------------------------------------- 1 | #################### 2 | ABOUT: # 3 | #################### 4 | elementary is designed and developed by Daniel Foré 5 | This version for Xfce is currently maintained by Simon Steinbeiß 6 | 7 | GNOME icons, Humanity icons, and elementary icons are all licensed under the GPL. 8 | 9 | This package is licensed under GNU General Public License version 2. 10 | 11 | Icons based on GNOME and other GNOME projects are licensed GPL. 12 | You can visit the GNOME website here: 13 | http://www.gnome.org/ 14 | 15 | Icons based on Tango sources or taken from the Tango project are public domain. 16 | You can visit the Tango project website here: 17 | http://tango.freedesktop.org/Tango_Desktop_Project 18 | 19 | Icons based on Humanity sources or taken from the elementary project are licensed GPL. 20 | You can visit the Humanity website here: 21 | http://launchpad.net/humanity 22 | 23 | #################### 24 | Special Thanks: # 25 | #################### 26 | 27 | The awesome Humanity team for their hard work! 28 | -------------------------------------------------------------------------------- /hdd/usr/share/icons/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Sebastian Porta 2 | Sergey "Shnatsel" Davidoff 3 | Oliver Scholtz 4 | Dennis Fisher 5 | Simon Steinbeiß 6 | Pasi Lallinaho -------------------------------------------------------------------------------- /hdd/usr/share/icons/applications-painting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/icons/applications-painting.png -------------------------------------------------------------------------------- /hdd/usr/share/icons/applications-simulation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/icons/applications-simulation.png -------------------------------------------------------------------------------- /hdd/usr/share/icons/panel-shutdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/icons/panel-shutdown.png -------------------------------------------------------------------------------- /hdd/usr/share/icons/utilities-terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/icons/utilities-terminal.png -------------------------------------------------------------------------------- /hdd/usr/share/logo_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/logo_login.png -------------------------------------------------------------------------------- /hdd/usr/share/panel.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/panel.bmp -------------------------------------------------------------------------------- /hdd/usr/share/panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/panel.png -------------------------------------------------------------------------------- /hdd/usr/share/posix_ja.txt: -------------------------------------------------------------------------------- 1 | POSIX(ポジックス、パーズィックス、Portable Operating System Interface)とは、各種UNIX OSを始めとする異なるOS実装に共通のAPIを定め、移植性の高いアプリケーションソフトウェアの開発を容易にすることを目的としてIEEEが策定したアプリケーションインタフェース規格である。POSIXという名前はリチャード・ストールマンがIEEEに提案したものである[1]。末尾の「X」はUNIX互換OSにXがつく名前が多いことからつけられた。ISO/IEC JTC 1/SC 22でISO/IEC 9945として国際規格になっている。 2 | 3 | 規格の内容はカーネルへのC言語のインタフェースであるシステムコールに留まらず、プロセス環境、ファイルとディレクトリ、システムデータベース(パスワードファイルなど)、tarのアーカイブフォーマットなど多岐にわたる。ただし、単にPOSIXといった場合は、システムコールとライブラリ関数を規定したPOSIX.1 (IEEE Std 1003.1) を指す。 4 | 5 | C言語のシステムコールとライブラリ関数を規定した有力な規格としては、他にANSI/ISO CとSUS(Single UNIX Specification、XPG4の後継)があるが、各規格の立場の違いにより、これらが含む関数の種類には差がある。集合の記号で表すと、ANSI/ISO C ⊂ POSIX.1 ⊂ SUS となる。 6 | 7 | UNIX系OS以外でも、Microsoft Windows NT系はPOSIX 1.0に準拠しているPOSIXサブシステムを搭載しており、POSIXアプリケーションをそのサブシステム上で実行できる。WTO/TBT協定では、非関税障壁として工業製品は国際規格を尊重して仕様を規定することを提唱しているため、米国政府機関のコンピュータシステム導入要件(FIPS)でPOSIX準拠であること規定したためである。Windows 2000までPOSIXサブシステムを搭載していたが、Windows XPからはServices for UNIXに同梱のInterixサブシステムに役割を譲り、Windows Server 2003 R2やWindows VistaからはSubsystem for UNIX-based Applications(SUA)となった。 8 | 9 | Linuxの国際標準を制定するにあたり、LinuxとPOSIXの差に関するTRを作成している。 10 | 11 | 最初の規格のテストスイートはアメリカ国立標準技術研究所 (NIST) が POSIX Test Suite (POSIX 1990 version) としてオープンソースで提供している。 12 | 13 | - Wikipedia contributors. POSIX. Wikipedia. August 6, 2012, 12:52 UTC. Available at: http://ja.wikipedia.org/w/index.php?title=POSIX&oldid=43639394. Accessed September 6, 2012. 14 | -------------------------------------------------------------------------------- /hdd/usr/share/snowman: -------------------------------------------------------------------------------- 1 | ☃ 2 | -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/ll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/ll.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/lm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/lm.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/lr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/lr.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/ml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/ml.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/mr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/mr.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/ul.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/ul.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/um.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/um.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/active/ur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/active/ur.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/ll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/ll.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/lm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/lm.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/lr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/lr.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/ml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/ml.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/mr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/mr.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/ul.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/ul.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/um.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/um.png -------------------------------------------------------------------------------- /hdd/usr/share/ttk/inactive/ur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/ttk/inactive/ur.png -------------------------------------------------------------------------------- /hdd/usr/share/wallpaper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/hdd/usr/share/wallpaper.png -------------------------------------------------------------------------------- /image-builder/.gitignore: -------------------------------------------------------------------------------- 1 | *.img 2 | *.vmdk 3 | *.vdi 4 | -------------------------------------------------------------------------------- /image-builder/README.md: -------------------------------------------------------------------------------- 1 | # とあるOS Disk Image Creator 2 | 3 | These scripts build disk images for とあるOS for use with your favorite non-multiboot emulator. 4 | 5 | ## Usage 6 | 7 | Get a full working build of とあるOS, then clone this repository and run: 8 | 9 | sudo ./create-image.sh /path/to/your/toaru/source 10 | 11 | Let it do its magic and you should have a `toaru-disk.img` that you can boot from. 12 | -------------------------------------------------------------------------------- /image-builder/boot/grub/grub.cfg: -------------------------------------------------------------------------------- 1 | insmod vbe 2 | insmod vga 3 | insmod video_bochs 4 | insmod video_cirrus 5 | set root='(hd0,msdos1)' 6 | 7 | menuentry 'Graphical Mode' { 8 | multiboot /boot/toaruos-kernel vid=preset,1024,768 hdd=0 9 | set gfxpayload=1024x768x32 10 | boot 11 | } 12 | 13 | menuentry 'Graphical Terminal' { 14 | multiboot /boot/toaruos-kernel vid=preset,1024,768 single hdd=0 15 | set gfxpayload=1024x768x32 16 | boot 17 | } 18 | 19 | menuentry 'VGA Terminal' { 20 | multiboot /boot/toaruos-kernel vgaterm hdd=0 21 | set gfxpayload=text 22 | boot 23 | } 24 | 25 | menuentry 'Debug Mode' { 26 | multiboot /boot/toaruos-kernel kernel-term=0 vgaterm hdd=0 27 | set gfxpayload=text 28 | boot 29 | } 30 | -------------------------------------------------------------------------------- /image-builder/clean-up.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Cleaning up" 4 | umount /mnt 5 | kpartx -d /dev/mapper/hda 6 | dmsetup remove hda 7 | losetup -d /dev/loop1 8 | -------------------------------------------------------------------------------- /image-builder/create-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $EUID -ne 0 ]]; then 4 | echo -e "\033[1;31mYou're going to need to run this as root\033[0m" 1>&2 5 | echo "Additionally, verify that /dev/loop4 is available and that" 1>&2 6 | echo "/mnt is available for mounting; otherwise, modify the script" 1>&2 7 | echo "to use alternative loop devices or mount points as needed." 1>&2 8 | exit 1 9 | fi 10 | 11 | if [[ $# -lt 1 ]]; then 12 | echo "I need a path to a compiled とあるOS source directory as an argument, try again." 1>&2 13 | exit 1 14 | fi 15 | 16 | DISK=toaru-disk.img 17 | SRCDIR=$1 18 | BOOT=./boot 19 | 20 | echo "I will create partitioned, ext2 disk image at $DISK from files in $SRCDIR as well as boot scripts in $BOOT" 21 | read -p "Is this correct? (Y/n)" 22 | if [ "$REPLY" == "n" ] ; then 23 | echo "Oh, okay, never mind then." 24 | exit 25 | fi 26 | 27 | # Create a 1GiB blank disk image. 28 | dd if=/dev/zero of=$DISK bs=4096 count=262144 29 | 30 | echo "Partitioning..." 31 | # Partition it with fdisk. 32 | cat fdisk.conf | fdisk $DISK 33 | 34 | echo "Done partition." 35 | 36 | # Here's where we need to be root. 37 | losetup /dev/loop1 toaru-disk.img 38 | 39 | IMAGE_SIZE=`wc -c < $DISK` 40 | IMAGE_SIZE_SECTORS=`expr $IMAGE_SIZE / 512` 41 | MAPPER_LINE="0 $IMAGE_SIZE_SECTORS linear 7:1 0" 42 | 43 | echo "$MAPPER_LINE" | dmsetup create hda 44 | 45 | kpartx -a /dev/mapper/hda 46 | 47 | mkfs.ext2 /dev/mapper/hda1 48 | 49 | mount /dev/mapper/hda1 /mnt 50 | 51 | echo "Installing main files." 52 | cp -r $SRCDIR/hdd/* /mnt/ 53 | 54 | echo "Installing boot files." 55 | mkdir -p /mnt/boot 56 | cp -r $BOOT/* /mnt/boot/ 57 | 58 | echo "Installing kernel." 59 | cp -r $SRCDIR/toaruos-kernel /mnt/boot/ 60 | 61 | echo "Installing grub." 62 | grub-install --boot-directory=/mnt/boot /dev/loop1 63 | 64 | ./clean-up.sh 65 | 66 | echo "Done. You can boot the disk image with qemu now." 67 | -------------------------------------------------------------------------------- /image-builder/fdisk.conf: -------------------------------------------------------------------------------- 1 | o 2 | n 3 | p 4 | 1 5 | 6 | 7 | a 8 | 1 9 | w 10 | q 11 | 12 | 13 | -------------------------------------------------------------------------------- /kernel/cpu/gdt.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Global Descriptor Tables module 4 | * 5 | * Part of the ToAruOS Kernel 6 | * (C) 2011 Kevin Lange 7 | */ 8 | #include 9 | #include 10 | 11 | static void write_tss(int32_t, uint16_t, uint32_t); 12 | tss_entry_t tss_entry; 13 | 14 | /* 15 | * Global Descriptor Table Entry 16 | */ 17 | struct gdt_entry { 18 | /* Limits */ 19 | unsigned short limit_low; 20 | /* Segment address */ 21 | unsigned short base_low; 22 | unsigned char base_middle; 23 | /* Access modes */ 24 | unsigned char access; 25 | unsigned char granularity; 26 | unsigned char base_high; 27 | } __attribute__((packed)); 28 | 29 | /* 30 | * GDT pointer 31 | */ 32 | struct gdt_ptr { 33 | unsigned short limit; 34 | unsigned int base; 35 | } __attribute__((packed)); 36 | 37 | struct gdt_entry gdt[6]; 38 | struct gdt_ptr gp; 39 | 40 | /** 41 | * (ASM) gdt_flush 42 | * Reloads the segment registers 43 | */ 44 | extern void gdt_flush(); 45 | 46 | /** 47 | * Set a GDT descriptor 48 | * 49 | * @param num The number for the descriptor to set. 50 | * @param base Base address 51 | * @param limit Limit 52 | * @param access Access permissions 53 | * @param gran Granularity 54 | */ 55 | void 56 | gdt_set_gate( 57 | int num, 58 | unsigned long base, 59 | unsigned long limit, 60 | unsigned char access, 61 | unsigned char gran 62 | ) { 63 | /* Base Address */ 64 | gdt[num].base_low = (base & 0xFFFF); 65 | gdt[num].base_middle = (base >> 16) & 0xFF; 66 | gdt[num].base_high = (base >> 24) & 0xFF; 67 | /* Limits */ 68 | gdt[num].limit_low = (limit & 0xFFFF); 69 | gdt[num].granularity = (limit >> 16) & 0X0F; 70 | /* Granularity */ 71 | gdt[num].granularity |= (gran & 0xF0); 72 | /* Access flags */ 73 | gdt[num].access = access; 74 | } 75 | 76 | /* 77 | * gdt_install 78 | * Install the kernel's GDTs 79 | */ 80 | void 81 | gdt_install() { 82 | /* GDT pointer and limits */ 83 | gp.limit = (sizeof(struct gdt_entry) * 6) - 1; 84 | gp.base = (unsigned int)&gdt; 85 | /* NULL */ 86 | gdt_set_gate(0, 0, 0, 0, 0); 87 | /* Code segment */ 88 | gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); 89 | /* Data segment */ 90 | gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); 91 | /* User code */ 92 | gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); 93 | /* User data */ 94 | gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); 95 | write_tss(5, 0x10, 0x0); 96 | /* Go go go */ 97 | gdt_flush(); 98 | tss_flush(); 99 | } 100 | 101 | /** 102 | * Write a TSS (we only do this once) 103 | */ 104 | static void 105 | write_tss( 106 | int32_t num, 107 | uint16_t ss0, 108 | uint32_t esp0 109 | ) { 110 | uintptr_t base = (uintptr_t)&tss_entry; 111 | uintptr_t limit = base + sizeof(tss_entry); 112 | 113 | /* Add the TSS descriptor to the GDT */ 114 | gdt_set_gate(num, base, limit, 0xE9, 0x00); 115 | 116 | memset(&tss_entry, 0x0, sizeof(tss_entry)); 117 | 118 | tss_entry.ss0 = ss0; 119 | tss_entry.esp0 = esp0; 120 | /* Zero out the descriptors */ 121 | tss_entry.cs = 0x0b; 122 | tss_entry.ss = 123 | tss_entry.ds = 124 | tss_entry.es = 125 | tss_entry.fs = 126 | tss_entry.gs = 0x13; 127 | tss_entry.iomap_base = sizeof(tss_entry); 128 | } 129 | 130 | /** 131 | * Set the kernel stack. 132 | * 133 | * @param stack Pointer to a the stack pointer for the kernel. 134 | */ 135 | void 136 | set_kernel_stack( 137 | uintptr_t stack 138 | ) { 139 | tss_entry.esp0 = stack; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /kernel/cpu/idt.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Interrupt Descriptor Tables 4 | * 5 | */ 6 | #include 7 | #include 8 | 9 | /* 10 | * IDT Entry 11 | */ 12 | struct idt_entry { 13 | unsigned short base_low; 14 | unsigned short sel; 15 | unsigned char zero; 16 | unsigned char flags; 17 | unsigned short base_high; 18 | } __attribute__((packed)); 19 | 20 | /* 21 | * IDT pointer 22 | */ 23 | struct idt_ptr { 24 | unsigned short limit; 25 | uintptr_t base; 26 | } __attribute__((packed)); 27 | 28 | struct idt_entry idt[256]; 29 | struct idt_ptr idtp; 30 | 31 | extern void idt_load(); 32 | 33 | /* 34 | * idt_set_gate 35 | * Set an IDT gate 36 | */ 37 | void 38 | idt_set_gate( 39 | unsigned char num, 40 | unsigned long base, 41 | unsigned short sel, 42 | unsigned char flags 43 | ) { 44 | idt[num].base_low = (base & 0xFFFF); 45 | idt[num].base_high = (base >> 16) & 0xFFFF; 46 | idt[num].sel = sel; 47 | idt[num].zero = 0; 48 | idt[num].flags = flags | 0x60; 49 | } 50 | 51 | /* 52 | * idt_install 53 | * Install the IDTs 54 | */ 55 | void 56 | idt_install() { 57 | idtp.limit = (sizeof(struct idt_entry) * 256) - 1; 58 | idtp.base = (uintptr_t)&idt; 59 | memset(&idt, 0, sizeof(struct idt_entry) * 256); 60 | 61 | idt_load(); 62 | } 63 | -------------------------------------------------------------------------------- /kernel/cpu/irq.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Interrupt Requests 4 | * 5 | */ 6 | #include 7 | #include 8 | 9 | extern void _irq0(); 10 | extern void _irq1(); 11 | extern void _irq2(); 12 | extern void _irq3(); 13 | extern void _irq4(); 14 | extern void _irq5(); 15 | extern void _irq6(); 16 | extern void _irq7(); 17 | extern void _irq8(); 18 | extern void _irq9(); 19 | extern void _irq10(); 20 | extern void _irq11(); 21 | extern void _irq12(); 22 | extern void _irq13(); 23 | extern void _irq14(); 24 | extern void _irq15(); 25 | 26 | static irq_handler_t irq_routines[16] = { NULL }; 27 | 28 | /* 29 | * Install an interupt handler for a hardware device. 30 | */ 31 | void 32 | irq_install_handler( 33 | int irq, 34 | irq_handler_t handler 35 | ) { 36 | irq_routines[irq] = handler; 37 | } 38 | 39 | /* 40 | * Remove an interrupt handler for a hardware device. 41 | */ 42 | void 43 | irq_uninstall_handler( 44 | int irq 45 | ) { 46 | irq_routines[irq] = 0; 47 | } 48 | 49 | /* 50 | * Remap interrupt handlers 51 | */ 52 | void 53 | irq_remap() { 54 | outportb(0x20, 0x11); 55 | outportb(0xA0, 0x11); 56 | outportb(0x21, 0x20); 57 | outportb(0xA1, 0x28); 58 | outportb(0x21, 0x04); 59 | outportb(0xA1, 0x02); 60 | outportb(0x21, 0x01); 61 | outportb(0xA1, 0x01); 62 | outportb(0x21, 0x0); 63 | outportb(0xA1, 0x0); 64 | } 65 | 66 | void 67 | irq_gates() { 68 | idt_set_gate(32, (unsigned)_irq0, 0x08, 0x8E); 69 | idt_set_gate(33, (unsigned)_irq1, 0x08, 0x8E); 70 | idt_set_gate(34, (unsigned)_irq2, 0x08, 0x8E); 71 | idt_set_gate(35, (unsigned)_irq3, 0x08, 0x8E); 72 | idt_set_gate(36, (unsigned)_irq4, 0x08, 0x8E); 73 | idt_set_gate(37, (unsigned)_irq5, 0x08, 0x8E); 74 | idt_set_gate(38, (unsigned)_irq6, 0x08, 0x8E); 75 | idt_set_gate(39, (unsigned)_irq7, 0x08, 0x8E); 76 | idt_set_gate(40, (unsigned)_irq8, 0x08, 0x8E); 77 | idt_set_gate(41, (unsigned)_irq9, 0x08, 0x8E); 78 | idt_set_gate(42, (unsigned)_irq10, 0x08, 0x8E); 79 | idt_set_gate(43, (unsigned)_irq11, 0x08, 0x8E); 80 | idt_set_gate(44, (unsigned)_irq12, 0x08, 0x8E); 81 | idt_set_gate(45, (unsigned)_irq13, 0x08, 0x8E); 82 | idt_set_gate(46, (unsigned)_irq14, 0x08, 0x8E); 83 | idt_set_gate(47, (unsigned)_irq15, 0x08, 0x8E); 84 | } 85 | 86 | /* 87 | * Set up interrupt handler for hardware devices. 88 | */ 89 | void 90 | irq_install() { 91 | irq_remap(); 92 | irq_gates(); 93 | IRQ_RES; 94 | } 95 | 96 | void irq_ack(int irq_no) { 97 | if (irq_no >= 12) { 98 | outportb(0xA0, 0x20); 99 | } 100 | outportb(0x20, 0x20); 101 | } 102 | 103 | void 104 | irq_handler(struct regs *r) { 105 | IRQ_OFF; 106 | void (*handler)(struct regs *r); 107 | if (r->int_no > 47 || r->int_no < 32) { 108 | handler = NULL; 109 | } else { 110 | handler = irq_routines[r->int_no - 32]; 111 | } 112 | if (handler) { 113 | handler(r); 114 | } else { 115 | irq_ack(r->int_no - 32); 116 | } 117 | IRQ_RES; 118 | } 119 | -------------------------------------------------------------------------------- /kernel/devices/cmos.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * CMOS Driver 4 | * 5 | * Part of the ToAruOS Kernel 6 | * (C) 2011 Kevin Lange 7 | */ 8 | 9 | #include 10 | 11 | /* CMOS values are stored like so: 12 | * Say it's 8:42 AM, then the values are stored as: 13 | * 0x08, 0x42... why this was a good idea, I have no 14 | * clue, but that's how it usually is. 15 | * 16 | * This function will convert between this "BCD" format 17 | * and regular decimal integers. */ 18 | #define from_bcd(val) ((val / 16) * 10 + (val & 0xf)) 19 | 20 | void 21 | cmos_dump( 22 | uint16_t * values 23 | ) { 24 | uint16_t index; 25 | for (index = 0; index < 128; ++index) { 26 | outportb(0x70, index); 27 | values[index] = inportb(0x71); 28 | } 29 | } 30 | 31 | /** 32 | * Get the current month and day. 33 | * 34 | * @param month Pointer to a short to store the month 35 | * @param day Pointer to a short to store the day 36 | */ 37 | void 38 | get_date( 39 | uint16_t * month, 40 | uint16_t * day 41 | ) { 42 | uint16_t values[128]; /* CMOS dump */ 43 | cmos_dump(values); 44 | 45 | *month = from_bcd(values[8]); 46 | *day = from_bcd(values[7]); 47 | } 48 | 49 | /** 50 | * Get the current time. 51 | * 52 | * @param hours Pointer to a short to store the current hour (/24) 53 | * @param minutes Pointer to a short to store the current minute 54 | * @param seconds Pointer to a short to store the current second 55 | */ 56 | void 57 | get_time( 58 | uint16_t * hours, 59 | uint16_t * minutes, 60 | uint16_t * seconds 61 | ) { 62 | uint16_t values[128]; /* CMOS dump */ 63 | cmos_dump(values); 64 | 65 | *hours = from_bcd(values[4]); 66 | *minutes = from_bcd(values[2]); 67 | *seconds = from_bcd(values[0]); 68 | } 69 | 70 | uint32_t secs_of_years(int years) { 71 | uint32_t days = 0; 72 | years += 2000; 73 | while (years > 1969) { 74 | days += 365; 75 | if (years % 4 == 0) { 76 | if (years % 100 == 0) { 77 | if (years % 400 == 0) { 78 | days++; 79 | } 80 | } else { 81 | days++; 82 | } 83 | } 84 | years--; 85 | } 86 | return days * 86400; 87 | } 88 | 89 | uint32_t secs_of_month(int months, int year) { 90 | year += 2000; 91 | 92 | uint32_t days = 0; 93 | switch(months) { 94 | case 11: 95 | days += 30; 96 | case 10: 97 | days += 31; 98 | case 9: 99 | days += 30; 100 | case 8: 101 | days += 31; 102 | case 7: 103 | days += 31; 104 | case 6: 105 | days += 30; 106 | case 5: 107 | days += 31; 108 | case 4: 109 | days += 30; 110 | case 3: 111 | days += 31; 112 | case 2: 113 | days += 28; 114 | if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) { 115 | days++; 116 | } 117 | case 1: 118 | days += 31; 119 | default: 120 | break; 121 | } 122 | return days * 86400; 123 | } 124 | 125 | int 126 | gettimeofday(struct timeval * t, void *z) { 127 | uint16_t values[128]; 128 | cmos_dump(values); 129 | 130 | /* Math Time */ 131 | uint32_t time = secs_of_years(from_bcd(values[9]) - 1) + 132 | secs_of_month(from_bcd(values[8]) - 1, from_bcd(values[9])) + 133 | (from_bcd(values[7]) - 1) * 86400 + 134 | (from_bcd(values[4])) * 3600 + 135 | (from_bcd(values[2])) * 60 + 136 | from_bcd(values[0]) + 137 | 0; 138 | t->tv_sec = time; 139 | t->tv_usec = 0; 140 | return 0; 141 | } 142 | 143 | uint32_t now() { 144 | struct timeval t; 145 | gettimeofday(&t, NULL); 146 | return t.tv_sec; 147 | } 148 | 149 | -------------------------------------------------------------------------------- /kernel/devices/fpu.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Tiny FPU enable module. 4 | * 5 | * Part of the ToAruOS Kernel 6 | * (C) 2011 Kevin Lange ... 7 | * To whatever possible level this short of a code chunk 8 | * can be considered copyrightable in your jurisdiction. 9 | */ 10 | #include 11 | #include 12 | 13 | /** 14 | * Set the FPU control word 15 | * 16 | * @param cw What to set the control word to. 17 | */ 18 | void 19 | set_fpu_cw(const uint16_t cw) { 20 | asm volatile("fldcw %0" :: "m"(cw)); 21 | } 22 | 23 | /** 24 | * Enable the FPU 25 | * 26 | * We are assuming that we have one to begin with, but since we 27 | * only really operate on 686 machines, we do, so we're not 28 | * going to bother checking. 29 | */ 30 | void 31 | enable_fpu() { 32 | debug_print(NOTICE, "Enabling floating-point arithmetic unit"); 33 | size_t cr4; 34 | asm volatile ("mov %%cr4, %0" : "=r"(cr4)); 35 | cr4 |= 0x200; 36 | asm volatile ("mov %0, %%cr4" :: "r"(cr4)); 37 | set_fpu_cw(0x37F); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /kernel/devices/kbd.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Low-level keyboard interrupt driver. 4 | * 5 | * Creates a device file (keyboard_pipe) that can be read 6 | * to retreive keyboard events. 7 | * 8 | * Part of the ToAruOS Kernel 9 | * Copyright 2011-2012 Kevin Lange 10 | * 11 | * TODO: Move this to a server 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #define KEY_DEVICE 0x60 21 | #define KEY_PENDING 0x64 22 | 23 | #define KEYBOARD_NOTICES 0 24 | #define KEYBOARD_IRQ 1 25 | 26 | fs_node_t * keyboard_pipe; 27 | 28 | void keyboard_handler(struct regs *r) { 29 | unsigned char scancode; 30 | keyboard_wait(); 31 | scancode = inportb(KEY_DEVICE); 32 | irq_ack(KEYBOARD_IRQ); 33 | 34 | putch(scancode); 35 | } 36 | 37 | /* 38 | * Install the keyboard driver and initialize the 39 | * pipe device for userspace. 40 | */ 41 | void keyboard_install() { 42 | debug_print(NOTICE, "Initializing PS/2 keyboard driver"); 43 | 44 | /* Create a device pipe */ 45 | keyboard_pipe = make_pipe(128); 46 | current_process->fds->entries[0] = keyboard_pipe; 47 | 48 | /* Install the interrupt handler */ 49 | irq_install_handler(KEYBOARD_IRQ, keyboard_handler); 50 | } 51 | 52 | void keyboard_reset_ps2() { 53 | uint8_t tmp = inportb(0x61); 54 | outportb(0x61, tmp | 0x80); 55 | outportb(0x61, tmp & 0x7F); 56 | inportb(KEY_DEVICE); 57 | } 58 | 59 | /* 60 | * Wait on the keyboard. 61 | */ 62 | void keyboard_wait() { 63 | while(inportb(KEY_PENDING) & 2); 64 | } 65 | 66 | /* 67 | * Add a character to the device buffer. 68 | */ 69 | void putch(unsigned char c) { 70 | uint8_t buf[2]; 71 | buf[0] = c; 72 | buf[1] = '\0'; 73 | write_fs(keyboard_pipe, 0, 1, buf); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /kernel/devices/mbr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SECTORSIZE 512 6 | #define DISK_PORT 0x1F0 7 | 8 | mbr_t mbr; 9 | 10 | int read_partition_map(int device) { 11 | 12 | ide_init(DISK_PORT); 13 | 14 | ide_read_sector(DISK_PORT, 0, 0, (uint8_t *)&mbr); 15 | 16 | if (mbr.signature[0] == 0x55 && mbr.signature[1] == 0xAA) { 17 | debug_print(INFO, "Partition table found."); 18 | 19 | for (int i = 0; i < 4; ++i) { 20 | if (mbr.partitions[i].status & 0x80) { 21 | debug_print(NOTICE, "Partition #%d: @%d+%d", i+1, mbr.partitions[i].lba_first_sector, mbr.partitions[i].sector_count); 22 | } else { 23 | debug_print(NOTICE, "Partition #%d: inactive", i+1); 24 | } 25 | } 26 | 27 | return 0; 28 | } else { 29 | debug_print(ERROR, "Did not find partition table."); 30 | debug_print(ERROR, "Signature was 0x%x 0x%x instead of 0x55 0xAA", mbr.signature[0], mbr.signature[1]); 31 | 32 | debug_print(ERROR, "Parsing anyone yields:"); 33 | 34 | for (int i = 0; i < 4; ++i) { 35 | if (mbr.partitions[i].status & 0x80) { 36 | debug_print(NOTICE, "Partition #%d: @%d+%d", i+1, mbr.partitions[i].lba_first_sector, mbr.partitions[i].sector_count); 37 | } else { 38 | debug_print(NOTICE, "Partition #%d: inactive", i+1); 39 | } 40 | } 41 | 42 | 43 | } 44 | 45 | return 1; 46 | } 47 | -------------------------------------------------------------------------------- /kernel/devices/mouse.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * Mouse driver 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | uint8_t mouse_cycle = 0; 10 | int8_t mouse_byte[3]; 11 | 12 | #define PACKETS_IN_PIPE 1024 13 | #define DISCARD_POINT 32 14 | 15 | #define MOUSE_IRQ 12 16 | 17 | #define MOUSE_PORT 0x60 18 | #define MOUSE_STATUS 0x64 19 | #define MOUSE_ABIT 0x02 20 | #define MOUSE_BBIT 0x01 21 | #define MOUSE_WRITE 0xD4 22 | #define MOUSE_F_BIT 0x20 23 | #define MOUSE_V_BIT 0x08 24 | 25 | fs_node_t * mouse_pipe; 26 | 27 | void mouse_wait(uint8_t a_type) { 28 | uint32_t timeout = 100000; 29 | if (!a_type) { 30 | while (--timeout) { 31 | if ((inportb(MOUSE_STATUS) & MOUSE_BBIT) == 1) { 32 | return; 33 | } 34 | } 35 | debug_print(INFO, "mouse timeout"); 36 | return; 37 | } else { 38 | while (--timeout) { 39 | if (!((inportb(MOUSE_STATUS) & MOUSE_ABIT))) { 40 | return; 41 | } 42 | } 43 | debug_print(INFO, "mouse timeout"); 44 | return; 45 | } 46 | } 47 | 48 | void mouse_write(uint8_t write) { 49 | mouse_wait(1); 50 | outportb(MOUSE_STATUS, MOUSE_WRITE); 51 | mouse_wait(1); 52 | outportb(MOUSE_PORT, write); 53 | } 54 | 55 | uint8_t mouse_read() { 56 | mouse_wait(0); 57 | char t = inportb(MOUSE_PORT); 58 | return t; 59 | } 60 | 61 | 62 | void mouse_handler(struct regs *r) { 63 | uint8_t status = inportb(MOUSE_STATUS); 64 | while (status & MOUSE_BBIT) { 65 | int8_t mouse_in = inportb(MOUSE_PORT); 66 | if (status & MOUSE_F_BIT) { 67 | switch (mouse_cycle) { 68 | case 0: 69 | mouse_byte[0] = mouse_in; 70 | if (!(mouse_in & MOUSE_V_BIT)) return; 71 | ++mouse_cycle; 72 | break; 73 | case 1: 74 | mouse_byte[1] = mouse_in; 75 | ++mouse_cycle; 76 | break; 77 | case 2: 78 | mouse_byte[2] = mouse_in; 79 | /* We now have a full mouse packet ready to use */ 80 | if (mouse_byte[0] & 0x80 || mouse_byte[0] & 0x40) { 81 | /* x/y overflow? bad packet! */ 82 | break; 83 | } 84 | mouse_device_packet_t packet; 85 | packet.magic = MOUSE_MAGIC; 86 | packet.x_difference = mouse_byte[1]; 87 | packet.y_difference = mouse_byte[2]; 88 | packet.buttons = 0; 89 | if (mouse_byte[0] & 0x01) { 90 | packet.buttons |= LEFT_CLICK; 91 | } 92 | if (mouse_byte[0] & 0x02) { 93 | packet.buttons |= RIGHT_CLICK; 94 | } 95 | if (mouse_byte[0] & 0x04) { 96 | packet.buttons |= MIDDLE_CLICK; 97 | } 98 | mouse_cycle = 0; 99 | 100 | mouse_device_packet_t bitbucket; 101 | while (pipe_size(mouse_pipe) > (DISCARD_POINT * sizeof(packet))) { 102 | read_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&bitbucket); 103 | } 104 | write_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&packet); 105 | break; 106 | } 107 | } 108 | status = inportb(MOUSE_STATUS); 109 | } 110 | irq_ack(MOUSE_IRQ); 111 | } 112 | 113 | void mouse_install() { 114 | debug_print(NOTICE, "Initializing PS/2 mouse interface"); 115 | uint8_t status; 116 | IRQ_OFF; 117 | mouse_pipe = make_pipe(sizeof(mouse_device_packet_t) * PACKETS_IN_PIPE); 118 | mouse_wait(1); 119 | outportb(MOUSE_STATUS, 0xA8); 120 | mouse_wait(1); 121 | outportb(MOUSE_STATUS, 0x20); 122 | mouse_wait(0); 123 | status = inportb(0x60) | 2; 124 | mouse_wait(1); 125 | outportb(MOUSE_STATUS, 0x60); 126 | mouse_wait(1); 127 | outportb(MOUSE_PORT, status); 128 | mouse_write(0xF6); 129 | mouse_read(); 130 | mouse_write(0xF4); 131 | mouse_read(); 132 | IRQ_RES; 133 | irq_install_handler(MOUSE_IRQ, mouse_handler); 134 | } 135 | -------------------------------------------------------------------------------- /kernel/devices/pci.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * ToAruOS PCI Initialization 4 | */ 5 | 6 | #include 7 | 8 | #define PCI_CONFIG_ADDRESS 0xCF8 9 | #define PCI_CONFIG_DATA 0xCFC 10 | 11 | void 12 | pci_install() { 13 | /* Do nothing */ 14 | } 15 | 16 | /* 17 | * Read a PCI config value for the given bus/slot/function/offset 18 | */ 19 | uint16_t 20 | pci_read_word( 21 | uint32_t bus, 22 | uint32_t slot, 23 | uint32_t func, 24 | uint16_t offset 25 | ) { 26 | uint32_t address = (uint32_t)((bus << 16) || (slot << 11) | 27 | (func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000)); 28 | outportl(PCI_CONFIG_ADDRESS, address); 29 | return (uint16_t)((inportl(PCI_CONFIG_DATA) >> ((offset & 2) * 8)) & 0xFFFF); 30 | } 31 | 32 | /* 33 | * Write a PCI config value for the given bus/slot/function/offset 34 | */ 35 | void 36 | pci_write_word( 37 | uint32_t bus, 38 | uint32_t slot, 39 | uint32_t func, 40 | uint16_t offset, 41 | uint32_t data 42 | ) { 43 | uint32_t address = (uint32_t)((bus << 16) || (slot << 11) | 44 | (func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000)); 45 | outportl(PCI_CONFIG_ADDRESS, address); 46 | outportl(PCI_CONFIG_DATA, data); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /kernel/devices/serial.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Serial Port Driver 4 | */ 5 | #include 6 | #include 7 | 8 | #if 0 9 | void serial_handler_a(struct regs *r) { 10 | char serial = serial_recv(SERIAL_PORT_A); 11 | irq_ack(SERIAL_IRQ); 12 | if (serial == 13) serial = '\n'; 13 | kprintf("%c", serial); 14 | serial_send(SERIAL_PORT_B, serial); 15 | } 16 | void serial_handler_b(struct regs *r) { 17 | char serial = serial_recv(SERIAL_PORT_B); 18 | irq_ack(SERIAL_IRQ - 1); 19 | serial_send(SERIAL_PORT_A, serial); 20 | } 21 | #endif 22 | 23 | void serial_enable(int device) { 24 | outportb(device + 1, 0x00); 25 | outportb(device + 3, 0x80); /* Enable divisor mode */ 26 | outportb(device + 0, 0x03); /* Div Low: 03 Set the port to 38400 bps */ 27 | outportb(device + 1, 0x00); /* Div High: 00 */ 28 | outportb(device + 3, 0x03); 29 | outportb(device + 2, 0xC7); 30 | outportb(device + 4, 0x0B); 31 | } 32 | 33 | void 34 | serial_install() { 35 | debug_print(NOTICE, "Installing serial communication driver"); 36 | 37 | serial_enable(SERIAL_PORT_A); 38 | serial_enable(SERIAL_PORT_B); 39 | 40 | #if 0 41 | irq_install_handler(SERIAL_IRQ, serial_handler_a); /* Install the serial input handler */ 42 | irq_install_handler(SERIAL_IRQ - 1, serial_handler_b); /* Install the serial input handler */ 43 | outportb(SERIAL_PORT_A + 1, 0x01); /* Enable interrupts on receive */ 44 | outportb(SERIAL_PORT_B + 1, 0x01); /* Enable interrupts on receive */ 45 | #endif 46 | } 47 | 48 | int serial_rcvd(int device) { 49 | return inportb(device + 5) & 1; 50 | } 51 | 52 | char serial_recv(int device) { 53 | while (serial_rcvd(device) == 0) ; 54 | return inportb(device); 55 | } 56 | 57 | char serial_recv_async(int device) { 58 | return inportb(device); 59 | } 60 | 61 | int serial_transmit_empty(int device) { 62 | return inportb(device + 5) & 0x20; 63 | } 64 | 65 | void serial_send(int device, char out) { 66 | while (serial_transmit_empty(device) == 0); 67 | outportb(device, out); 68 | } 69 | 70 | void serial_string(int device, char * out) { 71 | for (uint32_t i = 0; i < strlen(out); ++i) { 72 | serial_send(device, out[i]); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /kernel/devices/timer.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Programmable Interrupt Timer 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | #define PIT_A 0x40 10 | #define PIT_B 0x41 11 | #define PIT_C 0x42 12 | #define PIT_CONTROL 0x43 13 | 14 | #define PIT_MASK 0xFF 15 | #define PIT_SCALE 1193180 16 | #define PIT_SET 0x36 17 | 18 | #define TIMER_IRQ 0 19 | 20 | #define SUBTICKS_PER_TICK 100 21 | 22 | /* 23 | * Set the phase (in hertz) for the Programmable 24 | * Interrupt Timer (PIT). 25 | */ 26 | void 27 | timer_phase( 28 | int hz 29 | ) { 30 | int divisor = PIT_SCALE / hz; 31 | outportb(PIT_CONTROL, PIT_SET); 32 | outportb(PIT_A, divisor & PIT_MASK); 33 | outportb(PIT_A, (divisor >> 8) & PIT_MASK); 34 | } 35 | 36 | /* 37 | * Internal timer counters 38 | */ 39 | unsigned long timer_ticks = 0; 40 | unsigned char timer_subticks = 0; 41 | 42 | /* 43 | * IRQ handler for when the timer fires 44 | */ 45 | void 46 | timer_handler( 47 | struct regs *r 48 | ) { 49 | if (++timer_subticks == SUBTICKS_PER_TICK) { 50 | timer_ticks++; 51 | timer_subticks = 0; 52 | } 53 | irq_ack(TIMER_IRQ); 54 | 55 | wakeup_sleepers(timer_ticks, timer_subticks); 56 | switch_task(1); 57 | } 58 | 59 | void relative_time(unsigned long seconds, unsigned long subseconds, unsigned long * out_seconds, unsigned long * out_subseconds) { 60 | if (subseconds + timer_subticks > SUBTICKS_PER_TICK) { 61 | *out_seconds = timer_ticks + seconds + 1; 62 | *out_subseconds = (subseconds + timer_subticks) - SUBTICKS_PER_TICK; 63 | } else { 64 | *out_seconds = timer_ticks + seconds; 65 | *out_subseconds = timer_subticks + subseconds; 66 | } 67 | } 68 | 69 | /* 70 | * Device installer for the PIT 71 | */ 72 | void timer_install() { 73 | debug_print(NOTICE,"Initializing interval timer"); 74 | irq_install_handler(TIMER_IRQ, timer_handler); 75 | timer_phase(100); /* 100Hz */ 76 | } 77 | 78 | -------------------------------------------------------------------------------- /kernel/fs/devfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ToAruOS DevFS 3 | * 4 | */ 5 | #include 6 | #include 7 | 8 | uint32_t read_devfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 9 | uint32_t write_devfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 10 | void open_devfs(fs_node_t *node, uint8_t read, uint8_t write); 11 | void close_devfs(fs_node_t *node); 12 | struct dirent *readdir_devfs(fs_node_t *node, uint32_t index); 13 | fs_node_t *finddir_devfs(fs_node_t *node, char *name); 14 | 15 | fs_node_t * devfs_root; 16 | 17 | /* 18 | * Install the DevFS to the given path. 19 | * Path should be `/dev` 20 | */ 21 | void 22 | devfs_install(char * path) { 23 | fs_node_t * dev_node = kopen(path,0); 24 | kprintf("Installing devfs... %s\n", dev_node->name); 25 | } 26 | 27 | /* 28 | * These functions require that the requested node have a valid handler of their own 29 | * and are not part of the devfs natively 30 | */ 31 | uint32_t read_devfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { 32 | return -1; 33 | } 34 | uint32_t write_devfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { 35 | return -1; 36 | } 37 | 38 | 39 | fs_node_t * 40 | devfs_create_keyboard() { 41 | return NULL; 42 | } 43 | 44 | /* 45 | * vim:noexpandtab 46 | * vim:tabstop=4 47 | * vim:shiftwidth=4 48 | */ 49 | -------------------------------------------------------------------------------- /kernel/fs/nulldev.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * Null Device 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | uint32_t read_null(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 9 | uint32_t write_null(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 10 | void open_null(fs_node_t *node, uint8_t read, uint8_t write); 11 | void close_null(fs_node_t *node); 12 | 13 | uint32_t read_null(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { 14 | if (size < 1) { 15 | return 0; 16 | } 17 | memset(buffer, 0x00, 1); 18 | return 1; 19 | } 20 | 21 | uint32_t write_null(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { 22 | return size; 23 | } 24 | 25 | void open_null(fs_node_t * node, uint8_t read, uint8_t write) { 26 | return; 27 | } 28 | 29 | void close_null(fs_node_t * node) { 30 | return; 31 | } 32 | 33 | fs_node_t * null_device_create() { 34 | fs_node_t * fnode = malloc(sizeof(fs_node_t)); 35 | fnode->inode = 0; 36 | strcpy(fnode->name, "null"); 37 | fnode->uid = 0; 38 | fnode->gid = 0; 39 | fnode->flags = 0; 40 | fnode->read = read_null; 41 | fnode->write = write_null; 42 | fnode->open = open_null; 43 | fnode->close = close_null; 44 | fnode->readdir = NULL; 45 | fnode->finddir = NULL; 46 | return fnode; 47 | } 48 | -------------------------------------------------------------------------------- /kernel/fs/serialdev.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Serial communication device 4 | * 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | uint32_t read_serial(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 11 | uint32_t write_serial(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 12 | void open_serial(fs_node_t *node, uint8_t read, uint8_t write); 13 | void close_serial(fs_node_t *node); 14 | 15 | uint32_t read_serial(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { 16 | if (size < 1) { 17 | return 0; 18 | } 19 | memset(buffer, 0x00, 1); 20 | uint32_t collected = 0; 21 | while (collected < size) { 22 | if (serial_rcvd(node->inode) == 0) 23 | return collected; 24 | buffer[collected] = serial_recv(node->inode); 25 | collected++; 26 | } 27 | return collected; 28 | } 29 | 30 | uint32_t write_serial(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { 31 | uint32_t sent = 0; 32 | while (sent < size) { 33 | serial_send(node->inode, buffer[sent]); 34 | sent++; 35 | } 36 | return size; 37 | } 38 | 39 | void open_serial(fs_node_t * node, uint8_t read, uint8_t write) { 40 | return; 41 | } 42 | 43 | void close_serial(fs_node_t * node) { 44 | return; 45 | } 46 | 47 | fs_node_t * serial_device_create(int device) { 48 | fs_node_t * fnode = malloc(sizeof(fs_node_t)); 49 | fnode->inode = device; 50 | strcpy(fnode->name, "serial"); 51 | fnode->uid = 0; 52 | fnode->gid = 0; 53 | fnode->flags = 0; 54 | fnode->read = read_serial; 55 | fnode->write = write_serial; 56 | fnode->open = open_serial; 57 | fnode->close = close_serial; 58 | fnode->readdir = NULL; 59 | fnode->finddir = NULL; 60 | 61 | fnode->atime = now(); 62 | fnode->mtime = fnode->atime; 63 | fnode->ctime = fnode->atime; 64 | 65 | return fnode; 66 | } 67 | -------------------------------------------------------------------------------- /kernel/include/boot.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | #ifndef BOOT_H 4 | #define BOOT_H 5 | /* 6 | * Boot Information Types 7 | * Used in the kernel boot process to determine 8 | * how we booted and where we can get BIOS 9 | * information from that bootloader. 10 | * 11 | */ 12 | #include 13 | 14 | /* 15 | * Multiboot 16 | * A format managed by GNU and used in GRUB. 17 | * Also supported natively by QEMU and a few 18 | * other emulators. 19 | */ 20 | #include 21 | 22 | #endif /* BOOT_H */ 23 | -------------------------------------------------------------------------------- /kernel/include/elf.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * ELF Binary Executable headers 4 | * 5 | */ 6 | 7 | #ifndef _ELF_H 8 | #define _ELF_H 9 | 10 | /* 11 | * Different bits of our build environment 12 | * require different header files for definitions 13 | */ 14 | #ifdef _KERNEL_ 15 | # include 16 | #else 17 | # ifdef BOOTLOADER 18 | # include 19 | # else 20 | # include 21 | # endif 22 | #endif 23 | 24 | /* 25 | * Unless otherwise stated, the definitions herein 26 | * are sourced from the Portable Formats Specification, 27 | * version 1.1 - ELF: Executable and Linkable Format 28 | */ 29 | 30 | /* 31 | * ELF Magic Signature 32 | */ 33 | #define ELFMAG0 0x7f 34 | #define ELFMAG1 'E' 35 | #define ELFMAG2 'L' 36 | #define ELFMAG3 'F' 37 | #define EI_NIDENT 16 38 | 39 | /* 40 | * ELF Datatypes 41 | */ 42 | typedef uint32_t Elf32_Word; 43 | typedef uint32_t Elf32_Addr; 44 | typedef uint32_t Elf32_Off; 45 | typedef uint32_t Elf32_Sword; 46 | typedef uint16_t Elf32_Half; 47 | 48 | /* 49 | * ELF Header 50 | */ 51 | typedef struct { 52 | unsigned char e_ident[EI_NIDENT]; 53 | Elf32_Half e_type; 54 | Elf32_Half e_machine; 55 | Elf32_Word e_version; 56 | Elf32_Addr e_entry; 57 | Elf32_Off e_phoff; 58 | Elf32_Off e_shoff; 59 | Elf32_Word e_flags; 60 | Elf32_Half e_ehsize; 61 | Elf32_Half e_phentsize; 62 | Elf32_Half e_phnum; 63 | Elf32_Half e_shentsize; 64 | Elf32_Half e_shnum; 65 | Elf32_Half e_shstrndx; 66 | } Elf32_Header; 67 | 68 | /* 69 | * e_type 70 | */ 71 | 72 | #define ET_NONE 0 /* No file type */ 73 | #define ET_REL 1 /* Relocatable file */ 74 | #define ET_EXEC 2 /* Executable file */ 75 | #define ET_DYN 3 /* Shared object file */ 76 | #define ET_CORE 4 /* Core file */ 77 | #define ET_LOPROC 0xff0 /* [Processor Specific] */ 78 | #define ET_HIPROC 0xfff /* [Processor Specific] */ 79 | 80 | /* 81 | * Machine types 82 | */ 83 | #define EM_NONE 0 84 | #define EM_386 3 85 | 86 | #define EV_NONE 0 87 | #define EV_CURRENT 1 88 | 89 | /** Program Header */ 90 | typedef struct { 91 | Elf32_Word p_type; 92 | Elf32_Off p_offset; 93 | Elf32_Addr p_vaddr; 94 | Elf32_Addr p_paddr; 95 | Elf32_Word p_filesz; 96 | Elf32_Word p_flags; 97 | Elf32_Word p_align; 98 | } Elf32_Phdr; 99 | 100 | /* p_type values */ 101 | #define PT_NULL 0 /* Unused, skip me */ 102 | #define PT_LOAD 1 /* Loadable segment */ 103 | #define PT_DYNAMIC 2 /* Dynamic linking information */ 104 | #define PT_INTERP 3 /* Interpreter (null-terminated string, pathname) */ 105 | #define PT_NOTE 4 /* Auxillary information */ 106 | #define PT_SHLIB 5 /* Reserved. */ 107 | #define PT_PHDR 6 /* Oh, it's me. Hello! Back-reference to the header table itself */ 108 | #define PT_LOPROC 0x70000000 109 | #define PT_HIPROC 0x7FFFFFFF 110 | 111 | 112 | /** Section Header */ 113 | typedef struct { 114 | Elf32_Word sh_name; 115 | Elf32_Word sh_type; 116 | Elf32_Word sh_flags; 117 | Elf32_Addr sh_addr; 118 | Elf32_Off sh_offset; 119 | Elf32_Word sh_size; 120 | Elf32_Word sh_link; 121 | Elf32_Word sh_info; 122 | Elf32_Word sh_addralign; 123 | Elf32_Word sh_entsize; 124 | } Elf32_Shdr; 125 | 126 | typedef struct { 127 | uint32_t id; 128 | uintptr_t ptr; 129 | } Elf32_auxv; 130 | 131 | /* sh_type values */ 132 | #define SHT_NONE 0 133 | #define SHT_PROGBITS 1 134 | #define SHT_SYMTAB 2 135 | #define SHT_STRTAB 3 136 | #define SHT_NOBITS 8 137 | 138 | 139 | #endif /* _ELF_H*/ 140 | 141 | 142 | /* 143 | * vim:noexpandtab 144 | * vim:tabstop=4 145 | */ 146 | -------------------------------------------------------------------------------- /kernel/include/fs.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | #ifndef FS_H 4 | #define FS_H 5 | 6 | #define PATH_SEPARATOR '/' 7 | #define PATH_SEPARATOR_STRING "/" 8 | #define PATH_UP ".." 9 | #define PATH_DOT "." 10 | 11 | #define FS_FILE 0x01 12 | #define FS_DIRECTORY 0x02 13 | #define FS_CHARDEVICE 0x04 14 | #define FS_BLOCKDEVICE 0x08 15 | #define FS_PIPE 0x10 16 | #define FS_SYMLINK 0x20 17 | #define FS_MOUNTPOINT 0x40 18 | 19 | #define _IFMT 0170000 /* type of file */ 20 | #define _IFDIR 0040000 /* directory */ 21 | #define _IFCHR 0020000 /* character special */ 22 | #define _IFBLK 0060000 /* block special */ 23 | #define _IFREG 0100000 /* regular */ 24 | #define _IFLNK 0120000 /* symbolic link */ 25 | #define _IFSOCK 0140000 /* socket */ 26 | #define _IFIFO 0010000 /* fifo */ 27 | 28 | struct fs_node; 29 | 30 | typedef uint32_t (*read_type_t) (struct fs_node *, uint32_t, uint32_t, uint8_t *); 31 | typedef uint32_t (*write_type_t) (struct fs_node *, uint32_t, uint32_t, uint8_t *); 32 | typedef void (*open_type_t) (struct fs_node *, uint8_t read, uint8_t write); 33 | typedef void (*close_type_t) (struct fs_node *); 34 | typedef struct dirent *(*readdir_type_t) (struct fs_node *, uint32_t); 35 | typedef struct fs_node *(*finddir_type_t) (struct fs_node *, char *name); 36 | typedef void (*create_type_t) (struct fs_node *, char *name, uint16_t permission); 37 | typedef void (*mkdir_type_t) (struct fs_node *, char *name, uint16_t permission); 38 | 39 | typedef struct fs_node { 40 | char name[256]; // The filename. 41 | uint32_t mask; // The permissions mask. 42 | uint32_t uid; // The owning user. 43 | uint32_t gid; // The owning group. 44 | uint32_t flags; // Flags (node type, etc). 45 | uint32_t inode; // Inode number. 46 | uint32_t length; // Size of the file, in byte. 47 | uint32_t impl; // Used to keep track which fs it belongs to. 48 | read_type_t read; 49 | write_type_t write; 50 | open_type_t open; 51 | close_type_t close; 52 | readdir_type_t readdir; 53 | finddir_type_t finddir; 54 | create_type_t create; 55 | mkdir_type_t mkdir; 56 | struct fs_node *ptr; // Used by mountpoints and symlinks. 57 | uint32_t offset; 58 | int32_t shared_with; 59 | uint32_t atime; 60 | uint32_t mtime; 61 | uint32_t ctime; 62 | } fs_node_t; 63 | 64 | struct dirent { 65 | uint32_t ino; // Inode number. 66 | char name[256]; // The filename. 67 | }; 68 | 69 | struct stat { 70 | uint16_t st_dev; 71 | uint16_t st_ino; 72 | uint32_t st_mode; 73 | uint16_t st_nlink; 74 | uint16_t st_uid; 75 | uint16_t st_gid; 76 | uint16_t st_rdev; 77 | uint32_t st_size; 78 | uint32_t st_atime; 79 | uint32_t __unused1; 80 | uint32_t st_mtime; 81 | uint32_t __unused2; 82 | uint32_t st_ctime; 83 | uint32_t __unused3; 84 | }; 85 | 86 | extern fs_node_t *fs_root; 87 | extern fs_node_t * null_device_create(); 88 | extern fs_node_t * serial_device_create(int device); 89 | 90 | uint32_t read_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 91 | uint32_t write_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); 92 | void open_fs(fs_node_t *node, uint8_t read, uint8_t write); 93 | void close_fs(fs_node_t *node); 94 | struct dirent *readdir_fs(fs_node_t *node, uint32_t index); 95 | fs_node_t *finddir_fs(fs_node_t *node, char *name); 96 | int mkdir_fs(char *name, uint16_t permission); 97 | int create_file_fs(char *name, uint16_t permission); 98 | fs_node_t *kopen(char *filename, uint32_t flags); 99 | char *canonicalize_path(char *cwd, char *input); 100 | fs_node_t *clone_fs(fs_node_t * source); 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /kernel/include/list.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * General-purpose list implementations. 4 | */ 5 | #ifndef LIST_H 6 | #define LIST_H 7 | 8 | #include 9 | 10 | typedef struct node { 11 | struct node * next; 12 | struct node * prev; 13 | void * value; 14 | } __attribute__((packed)) node_t; 15 | 16 | typedef struct { 17 | node_t * head; 18 | node_t * tail; 19 | size_t length; 20 | } __attribute__((packed)) list_t; 21 | 22 | void list_destroy(list_t * list); 23 | void list_free(list_t * list); 24 | void list_append(list_t * list, node_t * item); 25 | void list_insert(list_t * list, void * item); 26 | list_t * list_create(); 27 | node_t * list_find(list_t * list, void * value); 28 | void list_remove(list_t * list, size_t index); 29 | void list_delete(list_t * list, node_t * node); 30 | node_t * list_pop(list_t * list); 31 | node_t * list_dequeue(list_t * list); 32 | list_t * list_copy(list_t * original); 33 | void list_merge(list_t * target, list_t * source); 34 | 35 | void list_append_after(list_t * list, node_t * before, node_t * node); 36 | void list_insert_after(list_t * list, node_t * before, void * item); 37 | 38 | #define foreach(i, list) for (node_t * i = list->head; i != NULL; i = i->next) 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /kernel/include/logging.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGGING_H 2 | #define LOGGING_H 3 | 4 | typedef enum { 5 | INFO = 0, /* Unimportant */ 6 | NOTICE, /* Important, but not bad */ 7 | WARNING, /* Not what was expected, but still okay */ 8 | ERROR, /* This is bad... */ 9 | CRITICAL /* Shit */ 10 | } log_type_t; 11 | 12 | log_type_t debug_level; 13 | void _debug_print(char * title, int line_no, log_type_t level, char *fmt, ...); 14 | 15 | #ifndef MODULE_NAME 16 | #define MODULE_NAME __FILE__ 17 | #endif 18 | 19 | #ifndef QUIET 20 | #define debug_print(level, ...) _debug_print(MODULE_NAME, __LINE__, level, __VA_ARGS__) 21 | #else 22 | #define debug_print(level, ...) 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /kernel/include/mem.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | 4 | 5 | #ifndef __MEM_H 6 | #define __MEM_H 7 | 8 | #include 9 | 10 | 11 | extern uintptr_t heap_end; 12 | 13 | extern void set_frame(uintptr_t frame_addr); 14 | extern void clear_frame(uintptr_t frame_addr); 15 | extern uint32_t test_frame(uintptr_t frame_addr); 16 | extern uint32_t first_frame(); 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /kernel/include/mouse.h: -------------------------------------------------------------------------------- 1 | #ifndef MOUSE_DEVICE_H 2 | #define MOUSE_DEVICE_H 3 | 4 | typedef enum { 5 | LEFT_CLICK = 0x01, 6 | RIGHT_CLICK = 0x02, 7 | MIDDLE_CLICK = 0x04 8 | } mouse_click_t; 9 | 10 | typedef struct { 11 | uint32_t magic; 12 | int8_t x_difference; 13 | int8_t y_difference; 14 | mouse_click_t buttons; 15 | } mouse_device_packet_t; 16 | 17 | #define MOUSE_MAGIC 0xFEED1234 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /kernel/include/multiboot.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | #ifndef SYSTEM_H 4 | #define SYSTEM_H 5 | 6 | #include 7 | 8 | #define MULTIBOOT_MAGIC 0x1BADB002 9 | #define MULTIBOOT_EAX_MAGIC 0x2BADB002 10 | #define MULTIBOOT_FLAG_MEM 0x001 11 | #define MULTIBOOT_FLAG_DEVICE 0x002 12 | #define MULTIBOOT_FLAG_CMDLINE 0x004 13 | #define MULTIBOOT_FLAG_MODS 0x008 14 | #define MULTIBOOT_FLAG_AOUT 0x010 15 | #define MULTIBOOT_FLAG_ELF 0x020 16 | #define MULTIBOOT_FLAG_MMAP 0x040 17 | #define MULTIBOOT_FLAG_CONFIG 0x080 18 | #define MULTIBOOT_FLAG_LOADER 0x100 19 | #define MULTIBOOT_FLAG_APM 0x200 20 | #define MULTIBOOT_FLAG_VBE 0x400 21 | 22 | struct multiboot 23 | { 24 | uintptr_t flags; 25 | uintptr_t mem_lower; 26 | uintptr_t mem_upper; 27 | uintptr_t boot_device; 28 | uintptr_t cmdline; 29 | uintptr_t mods_count; 30 | uintptr_t mods_addr; 31 | uintptr_t num; 32 | uintptr_t size; 33 | uintptr_t addr; 34 | uintptr_t shndx; 35 | uintptr_t mmap_length; 36 | uintptr_t mmap_addr; 37 | uintptr_t drives_length; 38 | uintptr_t drives_addr; 39 | uintptr_t config_table; 40 | uintptr_t boot_loader_name; 41 | uintptr_t apm_table; 42 | uintptr_t vbe_control_info; 43 | uintptr_t vbe_mode_info; 44 | uintptr_t vbe_mode; 45 | uintptr_t vbe_interface_seg; 46 | uintptr_t vbe_interface_off; 47 | uintptr_t vbe_interface_len; 48 | } __attribute__ ((packed)); 49 | 50 | typedef struct { 51 | uint16_t attributes; 52 | uint8_t winA, winB; 53 | uint16_t granularity; 54 | uint16_t winsize; 55 | uint16_t segmentA, segmentB; 56 | uint32_t realFctPtr; 57 | uint16_t pitch; 58 | 59 | uint16_t Xres, Yres; 60 | uint8_t Wchar, Ychar, planes, bpp, banks; 61 | uint8_t memory_model, bank_size, image_pages; 62 | uint8_t reserved0; 63 | 64 | uint8_t red_mask, red_position; 65 | uint8_t green_mask, green_position; 66 | uint8_t blue_mask, blue_position; 67 | uint8_t rsv_mask, rsv_position; 68 | uint8_t directcolor_attributes; 69 | 70 | uint32_t physbase; 71 | uint32_t reserved1; 72 | uint16_t reserved2; 73 | } __attribute__ ((packed)) vbe_info_t; 74 | 75 | struct multiboot *copy_multiboot(struct multiboot *mboot_ptr); 76 | void dump_multiboot(struct multiboot *mboot_ptr); 77 | char * ramdisk; 78 | struct multiboot * mboot_ptr; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /kernel/include/pipe.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Pipe 4 | */ 5 | 6 | #ifndef PIPE_H 7 | #define PIPE_H 8 | 9 | #include 10 | 11 | typedef struct _pipe_device { 12 | uint8_t * buffer; 13 | size_t write_ptr; 14 | size_t read_ptr; 15 | size_t size; 16 | size_t refcount; 17 | uint8_t volatile lock; 18 | list_t * wait_queue; 19 | } pipe_device_t; 20 | 21 | fs_node_t * make_pipe(size_t size); 22 | size_t pipe_size(fs_node_t * node); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /kernel/include/shm.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | 4 | #ifndef SHM_H 5 | #define SHM_H 6 | 7 | #include 8 | 9 | #define SHM_PATH_SEPARATOR "." 10 | 11 | /* Types */ 12 | struct shm_node; 13 | 14 | typedef struct { 15 | struct shm_node * parent; 16 | volatile uint8_t lock; 17 | int32_t ref_count; 18 | 19 | uint32_t num_frames; 20 | uintptr_t *frames; 21 | } shm_chunk_t; 22 | 23 | typedef struct shm_node { 24 | char name[256]; 25 | shm_chunk_t * chunk; 26 | } shm_node_t; 27 | 28 | typedef struct { 29 | shm_chunk_t * chunk; 30 | uint8_t volatile lock; 31 | 32 | uint32_t num_vaddrs; 33 | uintptr_t *vaddrs; 34 | } shm_mapping_t; 35 | 36 | /* Syscalls */ 37 | extern void * shm_obtain (char * path, size_t * size); 38 | extern int shm_release (char * path); 39 | 40 | /* Other exposed functions */ 41 | extern void shm_install (); 42 | extern void shm_release_all (process_t * proc); 43 | 44 | //extern void shm_debug_frame(uintptr_t vaddr); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /kernel/include/signal.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | 4 | #ifndef SIGNAL_H 5 | #define SIGNAL_H 6 | 7 | #ifdef _KERNEL_ 8 | # include 9 | void return_from_signal_handler(); 10 | void fix_signal_stacks(); 11 | #else 12 | # include 13 | #endif 14 | 15 | /* Signal names (from the Unix specification on signals) */ 16 | #define SIGHUP 1 /* Hangup */ 17 | #define SIGINT 2 /* Interupt */ 18 | #define SIGQUIT 3 /* Quit */ 19 | #define SIGILL 4 /* Illegal instruction */ 20 | #define SIGTRAP 5 /* A breakpoint or trace instruction has been reached */ 21 | #define SIGABRT 6 /* Another process has requested that you abort */ 22 | #define SIGEMT 7 /* Emulation trap XXX */ 23 | #define SIGFPE 8 /* Floating-point arithmetic exception */ 24 | #define SIGKILL 9 /* You have been stabbed repeated with a large knife */ 25 | #define SIGBUS 10 /* Bus error (device error) */ 26 | #define SIGSEGV 11 /* Segmentation fault */ 27 | #define SIGSYS 12 /* Bad system call */ 28 | #define SIGPIPE 13 /* Attempted to read or write from a broken pipe */ 29 | #define SIGALRM 14 /* This is your wakeup call. */ 30 | #define SIGTERM 15 /* You have been Schwarzenegger'd */ 31 | #define SIGUSR1 16 /* User Defined Signal #1 */ 32 | #define SIGUSR2 17 /* User Defined Signal #2 */ 33 | #define SIGCHLD 18 /* Child status report */ 34 | #define SIGPWR 19 /* We need moar powah! */ 35 | #define SIGWINCH 20 /* Your containing terminal has changed size */ 36 | #define SIGURG 21 /* An URGENT! event (On a socket) */ 37 | #define SIGPOLL 22 /* XXX OBSOLETE; socket i/o possible */ 38 | #define SIGSTOP 23 /* Stopped (signal) */ 39 | #define SIGTSTP 24 /* ^Z (suspend) */ 40 | #define SIGCONT 25 /* Unsuspended (please, continue) */ 41 | #define SIGTTIN 26 /* TTY input has stopped */ 42 | #define SIGTTOUT 27 /* TTY output has stopped */ 43 | #define SIGVTALRM 28 /* Virtual timer has expired */ 44 | #define SIGPROF 29 /* Profiling timer expired */ 45 | #define SIGXCPU 30 /* CPU time limit exceeded */ 46 | #define SIGXFSZ 31 /* File size limit exceeded */ 47 | #define SIGWAITING 32 /* Herp */ 48 | #define SIGDIAF 33 /* Die in a fire */ 49 | #define SIGHATE 34 /* The sending process does not like you */ 50 | #define SIGWINEVENT 35 /* Window server event */ 51 | #define SIGCAT 36 /* Everybody loves cats */ 52 | 53 | #define NUMSIGNALS 36 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /kernel/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | 6 | 7 | typedef struct page { 8 | uint32_t present:1; 9 | uint32_t rw:1; 10 | uint32_t user:1; 11 | uint32_t accessed:1; 12 | uint32_t dirty:1; 13 | uint32_t unused:7; 14 | uint32_t frame:20; 15 | } __attribute__((packed)) page_t; 16 | 17 | typedef struct page_table { 18 | page_t pages[1024]; 19 | } page_table_t; 20 | 21 | typedef struct page_directory { 22 | page_table_t *tables[1024]; /* 1024 pointers to page tables... */ 23 | uintptr_t physical_tables[1024]; /* Physical addresses of the tables */ 24 | uintptr_t physical_address; /* The physical address of physical_tables */ 25 | 26 | int32_t ref_count; 27 | } page_directory_t; 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /kernel/include/tree.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * General-purpose tree implementation 4 | */ 5 | #ifndef TREE_H 6 | #define TREE_H 7 | 8 | #include 9 | #include 10 | 11 | typedef struct tree_node { 12 | void * value; 13 | list_t * children; 14 | struct tree_node * parent; 15 | } tree_node_t; 16 | 17 | typedef struct { 18 | size_t nodes; 19 | tree_node_t * root; 20 | } tree_t; 21 | 22 | typedef uint8_t (*tree_comparator_t) (void *, void *); 23 | 24 | tree_t * tree_create(); 25 | void tree_set_root(tree_t * tree, void * value); 26 | void tree_node_destroy(tree_node_t * node); 27 | void tree_destroy(tree_t * tree); 28 | void tree_free(tree_t * tree); 29 | tree_node_t * tree_node_create(void * value); 30 | void tree_node_insert_child_node(tree_t * tree, tree_node_t * parent, tree_node_t * node); 31 | tree_node_t * tree_node_insert_child(tree_t * tree, tree_node_t * parent, void * value); 32 | tree_node_t * tree_node_find_parent(tree_node_t * haystack, tree_node_t * needle); 33 | void tree_node_parent_remove(tree_t * tree, tree_node_t * parent, tree_node_t * node); 34 | void tree_node_remove(tree_t * tree, tree_node_t * node); 35 | void tree_remove(tree_t * tree, tree_node_t * node); 36 | tree_node_t * tree_find(tree_t * tree, void * value, tree_comparator_t comparator); 37 | void tree_break_off(tree_t * tree, tree_node_t * node); 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /kernel/include/tss.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | #ifndef _TSS_H 4 | #define _TSS_H 5 | 6 | extern void tss_flush(); 7 | 8 | struct tss_entry_s { 9 | uintptr_t previous; 10 | uint32_t esp0; 11 | uint32_t ss0; 12 | uint32_t esp1; 13 | uint32_t ss1; 14 | uint32_t esp2; 15 | uint32_t ss2; 16 | uint32_t cr3; 17 | uint32_t eip; 18 | uint32_t eflags; 19 | uint32_t eax; 20 | uint32_t ecx; 21 | uint32_t edx; 22 | uint32_t ebx; 23 | uint32_t esp; 24 | uint32_t ebp; 25 | uint32_t esi; 26 | uint32_t edi; 27 | uint32_t es; 28 | uint32_t cs; 29 | uint32_t ss; 30 | uint32_t ds; 31 | uint32_t fs; 32 | uint32_t gs; 33 | uint32_t ldt; 34 | uint16_t trap; 35 | uint16_t iomap_base; 36 | } __attribute__ ((packed)); 37 | 38 | #endif /* _TSS_H */ 39 | 40 | -------------------------------------------------------------------------------- /kernel/include/types.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | #ifndef TYPES_H 4 | #define TYPES_H 5 | 6 | /* Types */ 7 | 8 | #define NULL ((void *)0UL) 9 | 10 | #ifndef BOOTLOADER 11 | typedef unsigned long uintptr_t; 12 | #else 13 | typedef unsigned short uintptr_t; 14 | #endif 15 | typedef unsigned long size_t; 16 | typedef signed int int32_t; 17 | typedef unsigned int uint32_t; 18 | typedef unsigned short uint16_t; 19 | typedef signed short int16_t; 20 | typedef unsigned char uint8_t; 21 | typedef signed char int8_t; 22 | typedef unsigned long long uint64_t; 23 | 24 | 25 | #define CHAR_BIT 8 26 | #define INT32_MAX 0x7fffffffL 27 | #define UINT32_MAX 0xffffffffL 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /kernel/include/va_list.h: -------------------------------------------------------------------------------- 1 | #ifndef VA_LIST_H 2 | #define VA_LIST_H 3 | 4 | typedef __builtin_va_list va_list; 5 | #define va_start(ap,last) __builtin_va_start(ap, last) 6 | #define va_end(ap) __builtin_va_end(ap) 7 | #define va_arg(ap,type) __builtin_va_arg(ap,type) 8 | #define va_copy(dest, src) __builtin_va_copy(dest,src) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /kernel/include/version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | 4 | char * __kernel_name; 5 | char * __kernel_version_format; 6 | 7 | int __kernel_version_major; 8 | int __kernel_version_minor; 9 | int __kernel_version_lower; 10 | 11 | char * __kernel_version_suffix; 12 | char * __kernel_version_codename; 13 | 14 | char * __kernel_arch; 15 | 16 | char * __kernel_build_date; 17 | char * __kernel_build_time; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /kernel/link.ld: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * Kernel linker script for x86 3 | */ 4 | OUTPUT_FORMAT(elf32-i386) 5 | ENTRY(start) 6 | phys = 0x00100000; 7 | SECTIONS 8 | { 9 | /* 10 | * Actual code 11 | */ 12 | .text phys : AT(phys) { 13 | code = .; 14 | *(.text) 15 | *(.rodata) 16 | . = ALIGN(4096); 17 | } 18 | /* 19 | * Kernel data 20 | */ 21 | .data : AT(phys + (data - code)) 22 | { 23 | data = .; 24 | *(.data) 25 | . = ALIGN(4096); 26 | } 27 | /* 28 | * Statically defined, uninitialized values 29 | */ 30 | .bss : AT(phys + (bss - code)) 31 | { 32 | bss = .; 33 | *(.bss) 34 | . = ALIGN(4096); 35 | } 36 | /* 37 | * End of kernel. 38 | */ 39 | end = .; 40 | /* 41 | * Get rid of unnecessary GCC bits. 42 | */ 43 | /DISCARD/ : 44 | { 45 | *(.comment) 46 | *(.eh_frame) 47 | *(.note.gnu.build-id) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /kernel/misc/logging.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Kernel Logging Facility 4 | * 5 | * Maintains a log in-memory as well as to serial (unless 6 | * told not to). 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | log_type_t debug_level = NOTICE; 15 | 16 | static char * c_messages[] = { 17 | "\033[1;34mINFO", 18 | "\033[1;35mNOTICE", 19 | "\033[1;33mWARNING", 20 | "\033[1;31mERROR", 21 | "\033[1;37;41mCRITICAL" 22 | }; 23 | 24 | 25 | void _debug_print(char * title, int line_no, log_type_t level, char *fmt, ...) { 26 | if (level >= debug_level) { 27 | va_list args; 28 | va_start(args, fmt); 29 | char buffer[1024]; 30 | vasprintf(buffer, fmt, args); 31 | va_end(args); 32 | 33 | kprintf("[%10d.%2d:%s:%d] %s\033[0m: %s\n", timer_ticks, timer_subticks, title, line_no, c_messages[level], buffer); 34 | 35 | } 36 | /* else ignore */ 37 | } 38 | 39 | -------------------------------------------------------------------------------- /kernel/misc/multiboot.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Multiboot (GRUB) handler 4 | */ 5 | #include 6 | #include 7 | 8 | char * ramdisk = NULL; 9 | struct multiboot * mboot_ptr = NULL; 10 | 11 | struct multiboot * 12 | copy_multiboot( 13 | struct multiboot *mboot_ptr 14 | ) { 15 | struct multiboot *new_header = (struct multiboot *)kmalloc(sizeof(struct multiboot)); 16 | memcpy(new_header, mboot_ptr, sizeof(struct multiboot)); 17 | return new_header; 18 | } 19 | 20 | void 21 | dump_multiboot( 22 | struct multiboot *mboot_ptr 23 | ) { 24 | kprintf("MULTIBOOT header at 0x%x:\n", (uintptr_t)mboot_ptr); 25 | kprintf("Flags : 0x%x ", mboot_ptr->flags); 26 | kprintf("Mem Lo: 0x%x ", mboot_ptr->mem_lower); 27 | kprintf("Mem Hi: 0x%x ", mboot_ptr->mem_upper); 28 | kprintf("Boot d: 0x%x\n", mboot_ptr->boot_device); 29 | kprintf("cmdlin: 0x%x ", mboot_ptr->cmdline); 30 | kprintf("Mods : 0x%x ", mboot_ptr->mods_count); 31 | kprintf("Addr : 0x%x ", mboot_ptr->mods_addr); 32 | kprintf("Syms : 0x%x\n", mboot_ptr->num); 33 | kprintf("Syms : 0x%x ", mboot_ptr->size); 34 | kprintf("Syms : 0x%x ", mboot_ptr->addr); 35 | kprintf("Syms : 0x%x ", mboot_ptr->shndx); 36 | kprintf("MMap : 0x%x\n", mboot_ptr->mmap_length); 37 | kprintf("Addr : 0x%x ", mboot_ptr->mmap_addr); 38 | kprintf("Drives: 0x%x ", mboot_ptr->drives_length); 39 | kprintf("Addr : 0x%x ", mboot_ptr->drives_addr); 40 | kprintf("Config: 0x%x\n", mboot_ptr->config_table); 41 | kprintf("Loader: 0x%x ", mboot_ptr->boot_loader_name); 42 | kprintf("APM : 0x%x ", mboot_ptr->apm_table); 43 | kprintf("VBE Co: 0x%x ", mboot_ptr->vbe_control_info); 44 | kprintf("VBE Mo: 0x%x\n", mboot_ptr->vbe_mode_info); 45 | kprintf("VBE In: 0x%x ", mboot_ptr->vbe_mode); 46 | kprintf("VBE se: 0x%x ", mboot_ptr->vbe_interface_seg); 47 | kprintf("VBE of: 0x%x ", mboot_ptr->vbe_interface_off); 48 | kprintf("VBE le: 0x%x\n", mboot_ptr->vbe_interface_len); 49 | if (mboot_ptr->flags & (1 << 2)) { 50 | kprintf("Started with: %s\n", (char *)mboot_ptr->cmdline); 51 | } 52 | if (mboot_ptr->flags & (1 << 9)) { 53 | kprintf("Booted from: %s\n", (char *)mboot_ptr->boot_loader_name); 54 | } 55 | if (mboot_ptr->flags & (1 << 0)) { 56 | kprintf("%dkB lower memory\n", mboot_ptr->mem_lower); 57 | kprintf("%dkB higher memory ", mboot_ptr->mem_upper); 58 | int mem_mb = mboot_ptr->mem_upper / 1024; 59 | kprintf("(%dMB)\n", mem_mb); 60 | } 61 | if (mboot_ptr->flags & (1 << 3)) { 62 | kprintf("Found %d module(s).\n", mboot_ptr->mods_count); 63 | if (mboot_ptr->mods_count > 0) { 64 | uint32_t i; 65 | for (i = 0; i < mboot_ptr->mods_count; ++i ) { 66 | uint32_t module_start = *((uint32_t*)mboot_ptr->mods_addr + 8 * i); 67 | uint32_t module_end = *(uint32_t*)(mboot_ptr->mods_addr + 8 * i + 4); 68 | kprintf("Module %d is at 0x%x:0x%x\n", i+1, module_start, module_end); 69 | } 70 | } 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /kernel/sys/panic.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Panic functions 4 | */ 5 | #include 6 | 7 | void kernel_halt() { 8 | kprintf("\n System Halted!\n\n"); 9 | 10 | while (1) { 11 | IRQ_OFF; 12 | PAUSE; 13 | } 14 | } 15 | 16 | void halt_and_catch_fire(char * error_message, const char * file, int line, struct regs * regs) { 17 | IRQ_OFF; 18 | kprintf("\033[1;37;44m"); 19 | kprintf("HACF: %s\n", error_message); 20 | kprintf("Proc: %d\n", getpid()); 21 | kprintf("File: %s\n", file); 22 | kprintf("Line: %d\n", line); 23 | if (regs) { 24 | kprintf("Registers at interrupt:\n"); 25 | kprintf("eax=0x%x ebx=0x%x\n", regs->eax, regs->ebx); 26 | kprintf("ecx=0x%x edx=0x%x\n", regs->ecx, regs->edx); 27 | kprintf("esp=0x%x ebp=0x%x\n", regs->esp, regs->ebp); 28 | kprintf("Error code: 0x%x\n", regs->err_code); 29 | kprintf("EFLAGS: 0x%x\n", regs->eflags); 30 | kprintf("User ESP: 0x%x\n", regs->useresp); 31 | kprintf("eip=0x%x\n", regs->eip); 32 | } 33 | kprintf("This process has been descheduled.\n"); 34 | kprintf("\033[0m"); 35 | kexit(1); 36 | } 37 | 38 | void assert_failed(const char *file, uint32_t line, const char *desc) { 39 | IRQ_OFF; 40 | kprintf("Kernel Assertion Failed: %s\n", desc); 41 | kprintf("File: %s\n", file); 42 | kprintf("Line: %d\n", line); 43 | kernel_halt(); 44 | } 45 | -------------------------------------------------------------------------------- /kernel/sys/signal.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Signal Handling 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | void enter_signal_handler(uintptr_t location, int signum, uintptr_t stack) { 10 | IRQ_OFF; 11 | asm volatile( 12 | "mov %2, %%esp\n" 13 | "pushl %1\n" /* argument count */ 14 | "pushl $" STRSTR(SIGNAL_RETURN) "\n" 15 | "mov $0x23, %%ax\n" /* Segment selector */ 16 | "mov %%ax, %%ds\n" 17 | "mov %%ax, %%es\n" 18 | "mov %%ax, %%fs\n" 19 | "mov %%ax, %%gs\n" 20 | "mov %%esp, %%eax\n" /* Stack -> EAX */ 21 | "pushl $0x23\n" /* Segment selector again */ 22 | "pushl %%eax\n" 23 | "pushf\n" /* Push flags */ 24 | "popl %%eax\n" /* Fix the Interrupt flag */ 25 | "orl $0x200, %%eax\n" 26 | "pushl %%eax\n" 27 | "pushl $0x1B\n" 28 | "pushl %0\n" /* Push the entry point */ 29 | "iret\n" 30 | : : "m"(location), "m"(signum), "r"(stack) : "%ax", "%esp", "%eax"); 31 | 32 | kprintf("Failed to jump to signal handler!\n"); 33 | } 34 | 35 | static uint8_t volatile lock; 36 | static uint8_t volatile lock_b; 37 | 38 | void handle_signal(process_t * proc, signal_t * sig) { 39 | uintptr_t handler = sig->handler; 40 | uintptr_t signum = sig->signum; 41 | free(sig); 42 | 43 | if (proc->finished) { 44 | return; 45 | } 46 | 47 | if (signum == 0 || signum > NUMSIGNALS) { 48 | /* Ignore */ 49 | return; 50 | } 51 | 52 | if (!handler) { 53 | kprintf("[debug] Process %d killed by unhandled signal (%d).\n", proc->id, signum); 54 | kexit(128 + signum); 55 | __builtin_unreachable(); 56 | return; 57 | } 58 | 59 | if (handler == 1) /* Ignore */ { 60 | return; 61 | } 62 | 63 | uintptr_t stack = 0xFFFF0000; 64 | if (proc->syscall_registers->useresp < 0x10000100) { 65 | stack = proc->image.user_stack; 66 | } else { 67 | stack = proc->syscall_registers->useresp; 68 | } 69 | 70 | /* Not marked as ignored, must call signal */ 71 | enter_signal_handler(handler, signum, stack); 72 | 73 | } 74 | 75 | list_t * rets_from_sig; 76 | 77 | void return_from_signal_handler() { 78 | #if 0 79 | kprintf("[debug] Return From Signal for process %d\n", current_process->id); 80 | #endif 81 | 82 | if (__builtin_expect(!rets_from_sig, 0)) { 83 | rets_from_sig = list_create(); 84 | } 85 | 86 | spin_lock(&lock); 87 | list_insert(rets_from_sig, (process_t *)current_process); 88 | spin_unlock(&lock); 89 | 90 | switch_next(); 91 | } 92 | 93 | void fix_signal_stacks() { 94 | uint8_t redo_me = 0; 95 | if (rets_from_sig) { 96 | spin_lock(&lock_b); 97 | while (rets_from_sig->head) { 98 | spin_lock(&lock); 99 | node_t * n = list_dequeue(rets_from_sig); 100 | spin_unlock(&lock); 101 | if (!n) { 102 | continue; 103 | } 104 | process_t * p = n->value; 105 | free(n); 106 | if (p == current_process) { 107 | redo_me = 1; 108 | continue; 109 | } 110 | p->thread.esp = p->signal_state.esp; 111 | p->thread.eip = p->signal_state.eip; 112 | p->thread.ebp = p->signal_state.ebp; 113 | memcpy((void *)(p->image.stack - KERNEL_STACK_SIZE), p->signal_kstack, KERNEL_STACK_SIZE); 114 | free(p->signal_kstack); 115 | p->signal_kstack = NULL; 116 | make_process_ready(p); 117 | } 118 | spin_unlock(&lock_b); 119 | } 120 | if (redo_me) { 121 | spin_lock(&lock); 122 | list_insert(rets_from_sig, (process_t *)current_process); 123 | spin_unlock(&lock); 124 | switch_next(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /kernel/sys/version.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | 4 | #include 5 | 6 | /* Kernel name. If you change this, you're not 7 | * my friend any more. */ 8 | char * __kernel_name = "toaru"; 9 | 10 | /* This really shouldn't change, and if it does, 11 | * always ensure it still has the correct arguments 12 | * when used as a vsprintf() format. */ 13 | char * __kernel_version_format = "%d.%d.%d-%s"; 14 | 15 | /* Version numbers X.Y.Z */ 16 | int __kernel_version_major = 0; 17 | int __kernel_version_minor = 4; 18 | int __kernel_version_lower = 3; 19 | 20 | /* Kernel build suffix, which doesn't necessarily 21 | * mean anything, but can be used to distinguish 22 | * between different features included while 23 | * building multiple kernels. */ 24 | char * __kernel_version_suffix = "dev"; 25 | 26 | /* The release codename. 27 | * 28 | * History: 29 | * * 0.0.X+ are part of the "uiharu" family 30 | */ 31 | char * __kernel_version_codename = "uiharu"; 32 | 33 | /* Build architecture (should probably not be 34 | * here as a string, but rather some sort of 35 | * preprocessor macro, or pulled from a script) */ 36 | char * __kernel_arch = "i686"; 37 | 38 | /* Rebuild from clean to reset these. */ 39 | char * __kernel_build_date = __DATE__; 40 | char * __kernel_build_time = __TIME__; 41 | 42 | -------------------------------------------------------------------------------- /loader/crtbegin.s: -------------------------------------------------------------------------------- 1 | ; ToAruOS User CRT0 2 | BITS 32 3 | 4 | global _start 5 | _start: ; Global entry point 6 | pop eax ; Our stack is slightly off 7 | extern main ; 8 | call main ; call C main function 9 | mov ebx, eax ; return value from main 10 | mov eax, 0x0 ; sys_exit 11 | int 0x7F ; syscall 12 | _wait: ; wait until we've been deschuled 13 | hlt 14 | jmp _wait 15 | 16 | ; vim:syntax=nasm 17 | ; vim:noexpandtab 18 | ; vim:tabstop=4 19 | ; vim:shiftwidth=4 20 | -------------------------------------------------------------------------------- /loader/link.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * Userspace Application Linker Script 3 | * 2011, ToAruOS 4 | */ 5 | OUTPUT_FORMAT(elf32-i386) 6 | ENTRY(_start) 7 | STARTUP(loader/crtbegin.o) 8 | INPUT(loader/syscall.o) 9 | phys = 0x02000000; 10 | SECTIONS 11 | { 12 | /* 13 | * Actual code 14 | */ 15 | .text phys : AT(phys) { 16 | code = .; 17 | *(.text) 18 | *(.rodata) 19 | . = ALIGN(4096); 20 | } 21 | /* 22 | * Kernel data 23 | */ 24 | .data : AT(phys + (data - code)) 25 | { 26 | data = .; 27 | *(.data) 28 | . = ALIGN(4096); 29 | } 30 | /* 31 | * Statically defined, uninitialized values 32 | */ 33 | .bss : AT(phys + (bss - code)) 34 | { 35 | bss = .; 36 | *(.bss) 37 | . = ALIGN(4096); 38 | } 39 | /* 40 | * Get rid of unnecessary GCC bits. 41 | */ 42 | /DISCARD/ : 43 | { 44 | *(.comment) 45 | *(.eh_frame) 46 | *(.note.gnu.build-id) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /loader/syscall.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | DEFN_SYSCALL1(exit, 0, int) 4 | DEFN_SYSCALL1(print, 1, const char *) 5 | DEFN_SYSCALL3(open, 2, const char *, int, int) 6 | DEFN_SYSCALL3(read, 3, int, char *, int) 7 | DEFN_SYSCALL3(write, 4, int, char *, int) 8 | DEFN_SYSCALL1(close, 5, int) 9 | DEFN_SYSCALL2(gettimeofday, 6, void *, void *) 10 | DEFN_SYSCALL3(execve, 7, char *, char **, char **) 11 | DEFN_SYSCALL0(fork, 8) 12 | DEFN_SYSCALL0(getpid, 9) 13 | DEFN_SYSCALL1(sbrk, 10, int) 14 | 15 | DEFN_SYSCALL1(wait, 17, int) 16 | 17 | DEFN_SYSCALL0(getgraphicswidth, 18) 18 | DEFN_SYSCALL0(getgraphicsheight, 19) 19 | DEFN_SYSCALL0(getgraphicsdepth, 20) 20 | 21 | DEFN_SYSCALL0(getuid, 23) 22 | DEFN_SYSCALL1(setuid, 24, unsigned int) 23 | 24 | DEFN_SYSCALL3(readdir, 27, int, int, void *) 25 | -------------------------------------------------------------------------------- /loader/syscall.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/loader/syscall.h -------------------------------------------------------------------------------- /toaru.terminfo: -------------------------------------------------------------------------------- 1 | toaru|toaruos framebuffer terminal, 2 | mc5i, 3 | xenl, 4 | cols#128, lines#45, 5 | colors#256, it#8, ncv#18, pairs#32767, npc, am, 6 | ind=^J, cr=^M, 7 | nel=^J, ht=^I, 8 | cud1=^J, 9 | cuf1=\E[C, 10 | cuu1=\E[A, 11 | cub1=^H, 12 | home=\E[H, clear=\E[H\E[2J, 13 | hpa=\E[%i%p1%dG, 14 | cup=\E[%i%p1%d;%p2%dH, 15 | ed=\E[J, el=\E[K, 16 | setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, 17 | setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, 18 | setb@, 19 | setf@, 20 | rev=\E[7m, sgr0=\E[0m, 21 | smso=\E[7m, rmso=\E[m, 22 | sgr=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p6%t;1%;%?%p7%t;8%;%?%p9%t;11%;m, 23 | op=\E[39;49m, 24 | bold=\E[1m, 25 | kcuu1=\E[A, 26 | kcud1=\E[B, 27 | kcuf1=\E[C, 28 | kcub1=\E[D, 29 | kent=\E0M, 30 | cuu=\E[%p1%dA, 31 | cud=\E[%p1%dB, 32 | cuf=\E[%p1%dC, 33 | cub=\E[%p1%dD, 34 | indn=\E[%p1%dS, 35 | rin=\E[%p1%dT, 36 | ri=\E[T, 37 | sc=\E[s, 38 | rc=\E[u, 39 | 40 | toaru-small|toaruos windowed terminal at 80x24, 41 | use=toaru, 42 | cols#80, lines#24, 43 | -------------------------------------------------------------------------------- /toolchain/activate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | . $DIR/config.sh 5 | 6 | export PATH="$DIR/local/bin:$PATH" 7 | export PKG_CONFIG_LIBDIR="$PREFIX/$TARGET/lib/pkgconfig" 8 | export TOOLCHAIN="$PREFIX/$TARGET" 9 | -------------------------------------------------------------------------------- /toolchain/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | PREFIX=$DIR/local 6 | TARGET=i686-pc-toaru 7 | -------------------------------------------------------------------------------- /toolchain/patches/binutils-2.22.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/bfd/config.bfd new/bfd/config.bfd 2 | --- original/bfd/config.bfd 2011-07-28 17:35:13.000000000 -0500 3 | +++ new/bfd/config.bfd 2012-05-16 20:51:26.000000000 -0500 4 | @@ -674,6 +674,10 @@ case "${targ}" in 5 | targ_defvec=bfd_elf32_i386_vec 6 | targ_selfvecs=i386chaos_vec 7 | ;; 8 | + i[3-7]86-*-toaru*) 9 | + targ_defvec=bfd_elf32_i386_vec 10 | + ;; 11 | + 12 | 13 | i860-*-mach3* | i860-*-osf1* | i860-*-coff*) 14 | targ_defvec=i860coff_vec 15 | diff -rupN original/config.sub new/config.sub 16 | --- original/config.sub 2011-06-06 05:36:06.000000000 -0500 17 | +++ new/config.sub 2012-05-16 20:49:18.000000000 -0500 18 | @@ -1323,6 +1323,7 @@ case $os in 19 | | -sym* | -kopensolaris* \ 20 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 21 | | -aos* | -aros* \ 22 | + | -toaru* \ 23 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 24 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 25 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 26 | diff -rupN original/gas/configure.tgt new/gas/configure.tgt 27 | --- original/gas/configure.tgt 2011-06-20 08:23:21.000000000 -0500 28 | +++ new/gas/configure.tgt 2012-05-16 20:51:49.000000000 -0500 29 | @@ -228,6 +228,7 @@ case ${generic_target} in 30 | i386-*-chaos) fmt=elf ;; 31 | i386-*-rdos*) fmt=elf ;; 32 | i386-*-darwin*) fmt=macho ;; 33 | + i386-*-toaru*) fmt=elf ;; 34 | 35 | i860-*-*) fmt=elf endian=little ;; 36 | 37 | diff -rupN original/ld/configure.tgt new/ld/configure.tgt 38 | --- original/ld/configure.tgt 2011-11-21 03:29:37.000000000 -0600 39 | +++ new/ld/configure.tgt 2012-05-16 20:49:58.000000000 -0500 40 | @@ -195,6 +195,7 @@ x86_64-*-linux-*) targ_emul=elf_x86_64 41 | targ_extra_libpath="elf_i386 elf32_x86_64 elf_l1om elf_k1om" 42 | tdir_i386linux=`echo ${targ_alias}aout | sed -e 's/x86_64/i386/'` 43 | tdir_elf_i386=`echo ${targ_alias} | sed -e 's/x86_64/i386/'` ;; 44 | +i[3-7]86-*-toaru*) targ_emul=toaru_i386 ;; 45 | i[3-7]86-*-sysv[45]*) targ_emul=elf_i386 ;; 46 | i[3-7]86-*-solaris2*) targ_emul=elf_i386_sol2 47 | targ_extra_emuls="elf_i386_ldso elf_i386 elf_x86_64_sol2 elf_x86_64 elf_l1om elf_k1om" 48 | diff -rupN original/ld/emulparams/toaru_i386.sh new/ld/emulparams/toaru_i386.sh 49 | --- original/ld/emulparams/toaru_i386.sh 1969-12-31 18:00:00.000000000 -0600 50 | +++ new/ld/emulparams/toaru_i386.sh 2012-05-16 20:48:40.000000000 -0500 51 | @@ -0,0 +1,16 @@ 52 | +SCRIPT_NAME=elf 53 | +ELFSIZE=32 54 | +OUTPUT_FORMAT=elf32-i386 55 | +NO_RELA_RELOCS=yes 56 | +TEXT_START_ADDR=0x02000000 57 | +MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" 58 | +COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" 59 | +ARCH=i386 60 | +MACHINE= 61 | +NOP=0x90909090 62 | +TEMPLATE_NAME=elf32 63 | +GENERATE_SHLIB_SCRIPT=yes 64 | +GENERATE_PIE_SCRIPT=yes 65 | +NO_SMALL_DATA=yes 66 | +SEPARATE_GOTPLT=12 67 | +IREL_IN_PLT= 68 | diff -rupN original/ld/Makefile.in new/ld/Makefile.in 69 | --- original/ld/Makefile.in 2011-07-22 15:22:37.000000000 -0500 70 | +++ new/ld/Makefile.in 2012-05-16 20:50:54.000000000 -0500 71 | @@ -2627,6 +2627,9 @@ eelf32xtensa.c: $(srcdir)/emulparams/elf 72 | eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \ 73 | $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} 74 | ${GENSCRIPTS} elf_i386 "$(tdir_elf_i386)" 75 | +etoaru_i386.c: $(srcdir)/emulparams/toaru_i386.sh \ 76 | + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} 77 | + ${GENSCRIPTS} toaru_i386 "$(tdir_toaru_i386)" 78 | eelf_i386_be.c: $(srcdir)/emulparams/elf_i386_be.sh \ 79 | $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} 80 | ${GENSCRIPTS} elf_i386_be "$(tdir_elf_i386_be)" 81 | -------------------------------------------------------------------------------- /toolchain/patches/cairo-1.12.2.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/build/config.sub new/build/config.sub 2 | --- original/build/config.sub 2012-03-08 15:09:13.000000000 -0500 3 | +++ new/build/config.sub 2012-05-17 11:40:42.308339450 -0400 4 | @@ -1338,6 +1338,7 @@ case $os in 5 | | -sym* | -kopensolaris* \ 6 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 7 | | -aos* | -aros* \ 8 | + | -toaru* \ 9 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 10 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 11 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 12 | -------------------------------------------------------------------------------- /toolchain/patches/cairo-Makefile: -------------------------------------------------------------------------------- 1 | derp: 2 | @echo "lol" 3 | 4 | all: derp 5 | install: derp 6 | distclean: derp 7 | clean: derp 8 | -------------------------------------------------------------------------------- /toolchain/patches/freetype-2.4.9.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/builds/unix/config.sub new/builds/unix/config.sub 2 | --- original/builds/unix/config.sub 2012-03-08 15:09:13.000000000 -0500 3 | +++ new/builds/unix/config.sub 2012-05-17 11:40:42.308339450 -0400 4 | @@ -1343,6 +1343,7 @@ case $os in 5 | | -sym* | -kopensolaris* \ 6 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 7 | | -aos* | -aros* \ 8 | + | -toaru* \ 9 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 10 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 11 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 12 | -------------------------------------------------------------------------------- /toolchain/patches/gmp-5.0.1.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/configfsf.sub new/configfsf.sub 2 | --- original/configfsf.sub 2010-02-06 06:43:13.000000000 -0600 3 | +++ new/configfsf.sub 2012-04-23 16:18:31.000000000 -0500 4 | @@ -1252,6 +1252,7 @@ case $os in 5 | | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ 6 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 7 | | -aos* \ 8 | + | -toaru* \ 9 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 10 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 11 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 12 | -------------------------------------------------------------------------------- /toolchain/patches/libpng-1.5.13.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/config.sub new/config.sub 2 | --- original/config.sub 2012-03-08 15:09:13.000000000 -0500 3 | +++ new/config.sub 2012-05-17 11:40:42.308339450 -0400 4 | @@ -1338,6 +1338,7 @@ case $os in 5 | | -sym* | -kopensolaris* \ 6 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 7 | | -aos* | -aros* \ 8 | + | -toaru* \ 9 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 10 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 11 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 12 | -------------------------------------------------------------------------------- /toolchain/patches/mpc-0.9.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/config.sub new/config.sub 2 | --- original/config.sub 2011-01-18 07:09:45.000000000 -0600 3 | +++ new/config.sub 2012-04-23 18:49:45.000000000 -0500 4 | @@ -1290,6 +1290,7 @@ case $os in 5 | | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ 6 | | -sym* | -kopensolaris* \ 7 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 8 | + | -toaru* \ 9 | | -aos* | -aros* \ 10 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 11 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 12 | -------------------------------------------------------------------------------- /toolchain/patches/mpfr-3.0.1.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/config.sub new/config.sub 2 | --- original/config.sub 2011-04-04 05:19:46.000000000 -0500 3 | +++ new/config.sub 2012-04-23 18:46:38.000000000 -0500 4 | @@ -1291,6 +1291,7 @@ case $os in 5 | | -sym* | -kopensolaris* \ 6 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 7 | | -aos* | -aros* \ 8 | + | -toaru* \ 9 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 10 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 11 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 12 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/setjmp.S: -------------------------------------------------------------------------------- 1 | /* This is file is a merger of SETJMP.S and LONGJMP.S */ 2 | /* 3 | * This file was modified to use the __USER_LABEL_PREFIX__ and 4 | * __REGISTER_PREFIX__ macros defined by later versions of GNU cpp by 5 | * Joel Sherrill (joel@OARcorp.com) 6 | * Slight change: now includes i386mach.h for this (Werner Almesberger) 7 | * 8 | * Copyright (C) 1991 DJ Delorie 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms is permitted 12 | * provided that the above copyright notice and following paragraph are 13 | * duplicated in all such forms. 14 | * 15 | * This file is distributed WITHOUT ANY WARRANTY; without even the implied 16 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | */ 18 | 19 | /* 20 | ** jmp_buf: 21 | ** eax ebx ecx edx esi edi ebp esp eip 22 | ** 0 4 8 12 16 20 24 28 32 23 | */ 24 | 25 | #include "i386mach.h" 26 | 27 | .global SYM (setjmp) 28 | .global SYM (longjmp) 29 | SOTYPE_FUNCTION(setjmp) 30 | SOTYPE_FUNCTION(longjmp) 31 | 32 | SYM (setjmp): 33 | 34 | pushl ebp 35 | movl esp,ebp 36 | 37 | pushl edi 38 | movl 8 (ebp),edi 39 | 40 | movl eax,0 (edi) 41 | movl ebx,4 (edi) 42 | movl ecx,8 (edi) 43 | movl edx,12 (edi) 44 | movl esi,16 (edi) 45 | 46 | movl -4 (ebp),eax 47 | movl eax,20 (edi) 48 | 49 | movl 0 (ebp),eax 50 | movl eax,24 (edi) 51 | 52 | movl esp,eax 53 | addl $12,eax 54 | movl eax,28 (edi) 55 | 56 | movl 4 (ebp),eax 57 | movl eax,32 (edi) 58 | 59 | popl edi 60 | movl $0,eax 61 | leave 62 | ret 63 | 64 | SYM (longjmp): 65 | pushl ebp 66 | movl esp,ebp 67 | 68 | movl 8(ebp),edi /* get jmp_buf */ 69 | movl 12(ebp),eax /* store retval in j->eax */ 70 | testl eax,eax 71 | jne 0f 72 | incl eax 73 | 0: 74 | movl eax,0(edi) 75 | 76 | movl 24(edi),ebp 77 | 78 | /*__CLI */ 79 | movl 28(edi),esp 80 | 81 | pushl 32(edi) 82 | 83 | movl 0(edi),eax 84 | movl 4(edi),ebx 85 | movl 8(edi),ecx 86 | movl 12(edi),edx 87 | movl 16(edi),esi 88 | movl 20(edi),edi 89 | /*__STI */ 90 | 91 | ret 92 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = cygnus 2 | INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) 3 | AM_CCASFLAGS = $(INCLUDES) 4 | 5 | noinst_LIBRARIES = lib.a 6 | 7 | lib_a_SOURCES = syscalls.c 8 | lib_a_CCASFLAGS = $(AM_CCASFLAGS) 9 | lib_a_CFLAGS = $(AM_CFLAGS) 10 | 11 | all: crt0.o crti.o crtn.o 12 | 13 | ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. 14 | CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host 15 | 16 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/bits/dirent.h: -------------------------------------------------------------------------------- 1 | #ifndef DIRENT_H 2 | 3 | #include 4 | 5 | typedef struct dirent { 6 | uint32_t d_ino; 7 | char d_name[256]; 8 | } dirent; 9 | 10 | typedef struct DIR { 11 | int fd; 12 | int cur_entry; 13 | } DIR; 14 | 15 | DIR * opendir (const char * dirname); 16 | int closedir (DIR * dir); 17 | struct dirent * readdir (DIR * dirp); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/configure.in: -------------------------------------------------------------------------------- 1 | AC_PREREQ(2.59) 2 | AC_INIT([newlib], [NEWLIB_VERSION]) 3 | AC_CONFIG_SRCDIR([crt0.s]) 4 | AC_CONFIG_SRCDIR([crti.s]) 5 | AC_CONFIG_SRCDIR([crtn.s]) 6 | AC_CONFIG_AUX_DIR(../../../..) 7 | NEWLIB_CONFIGURE(../../..) 8 | AC_CONFIG_FILES([Makefile]) 9 | AC_OUTPUT 10 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/crt0.s: -------------------------------------------------------------------------------- 1 | ; ToAruOS User CRT0 2 | BITS 32 3 | 4 | global _start 5 | _start: ; Global entry point 6 | pop eax ; Our stack is slightly off 7 | extern pre_main ; 8 | call pre_main ; call C main function 9 | mov ebx, eax ; return value from main 10 | mov eax, 0x0 ; sys_exit 11 | int 0x7F ; syscall 12 | _wait: ; wait until we've been deschuled 13 | hlt 14 | jmp _wait 15 | 16 | ; vim:syntax=nasm 17 | ; vim:noexpandtab 18 | ; vim:tabstop=4 19 | ; vim:shiftwidth=4 20 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/crti.s: -------------------------------------------------------------------------------- 1 | ; ToAruOS User CRT0 2 | BITS 32 3 | 4 | section .init 5 | global _init 6 | _init: 7 | push ebp 8 | ; .init goes here 9 | 10 | section .fini 11 | global _fini 12 | _fini: 13 | push ebp 14 | ; .fini goes here 15 | 16 | ; vim:syntax=nasm 17 | ; vim:noexpandtab 18 | ; vim:tabstop=4 19 | ; vim:shiftwidth=4 20 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/crtn.s: -------------------------------------------------------------------------------- 1 | ; ToAruOS User CRT0 2 | BITS 32 3 | 4 | section .init 5 | ; .init goes here 6 | pop ebp 7 | ret 8 | 9 | section .fini 10 | ; .fini goes here 11 | pop ebp 12 | ret 13 | 14 | ; vim:syntax=nasm 15 | ; vim:noexpandtab 16 | ; vim:tabstop=4 17 | ; vim:shiftwidth=4 18 | -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/lib.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/toolchain/patches/newlib/toaru/lib.a -------------------------------------------------------------------------------- /toolchain/patches/newlib/toaru/sys/dirent.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /toolchain/patches/pixman-0.26.2.patch: -------------------------------------------------------------------------------- 1 | diff -rupN original/config.sub new/config.sub 2 | --- original/config.sub 2012-03-08 15:09:13.000000000 -0500 3 | +++ new/config.sub 2012-05-17 11:40:42.308339450 -0400 4 | @@ -1338,6 +1338,7 @@ case $os in 5 | | -sym* | -kopensolaris* \ 6 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 7 | | -aos* | -aros* \ 8 | + | -toaru* \ 9 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 10 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 11 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 12 | diff -rupN original/pixman/pixman-utils.c new/pixman/pixman-utils.c 13 | --- original/pixman/pixman-utils.c 2012-06-29 11:25:17.000000000 -0700 14 | +++ new/pixman/pixman-utils.c 2012-09-16 01:35:44.000000000 -0700 15 | @@ -41,7 +41,10 @@ 16 | } cache [N_CACHED_FAST_PATHS]; 17 | } cache_t; 18 | 19 | -PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache); 20 | +//PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache); 21 | +// 22 | + 23 | +cache_t fast_path_cache; 24 | 25 | pixman_bool_t 26 | _pixman_lookup_composite_function (pixman_implementation_t *toplevel, 27 | @@ -60,7 +63,7 @@ 28 | int i; 29 | 30 | /* Check cache for fast paths */ 31 | - cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache); 32 | + cache = &fast_path_cache; //PIXMAN_GET_THREAD_LOCAL (fast_path_cache); 33 | 34 | for (i = 0; i < N_CACHED_FAST_PATHS; ++i) 35 | { 36 | -------------------------------------------------------------------------------- /toolchain/prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Toolchain Installer for Debian-like systems. If you're running 4 | # something else, you're pretty much on your own. 5 | 6 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 7 | 8 | . $DIR/util.sh 9 | 10 | function deleteUnusedGCC () { 11 | # If you are running from the non-core GCC, run this function delete the stuff we don't care about 12 | rm -r $1/boehm-gc $1/gcc/ada $1/gcc/go $1/gcc/java $1/gcc/objc $1/gcc/objcp $1/gcc/testsuite $1/gnattools $1/libada $1/libffi $1/libgo $1/libjava $1/libobjc 13 | } 14 | 15 | pushd "$DIR" > /dev/null 16 | 17 | if [ ! -d tarballs ]; then 18 | mkdir tarballs 19 | fi 20 | pushd tarballs > /dev/null 21 | $INFO "wget" "Pulling source packages..." 22 | grab "gcc" "http://gcc.petsads.us/releases/gcc-4.6.0" "gcc-core-4.6.0.tar.gz" 23 | grab "g++" "http://gcc.petsads.us/releases/gcc-4.6.0" "gcc-g++-4.6.0.tar.gz" 24 | #grab "mpc" "http://www.multiprecision.org/mpc/download" "mpc-0.9.tar.gz" 25 | #grab "mpfr" "http://www.mpfr.org/mpfr-3.0.1" "mpfr-3.0.1.tar.gz" 26 | #grab "gmp" "ftp://ftp.gmplib.org/pub/gmp-5.0.1" "gmp-5.0.1.tar.gz" 27 | grab "binutils" "http://ftp.gnu.org/gnu/binutils" "binutils-2.22.tar.gz" 28 | grab "newlib" "https://github.com/downloads/klange/osdev" "newlib-1.19.0.tar.gz" 29 | grab "freetype" "http://download.savannah.gnu.org/releases/freetype" "freetype-2.4.9.tar.gz" 30 | grab "zlib" "http://zlib.net" "zlib-1.2.7.tar.gz" 31 | grab "libpng" "https://github.com/downloads/klange/osdev" "libpng-1.5.13.tar.gz" 32 | grab "pixman" "http://www.cairographics.org/releases" "pixman-0.26.2.tar.gz" 33 | grab "cairo" "http://www.cairographics.org/releases" "cairo-1.12.2.tar.xz" 34 | $INFO "wget" "Pulled source packages." 35 | rm -rf "binutils-2.22" "freetype-2.4.9" "gcc-4.6.0" "gmp-5.0.1" "libpng-1.5.13" "mpc-0.9" "mpfr-3.0.1" "newlib-1.19.0" "zlib-1.2.7" "pixman-0.28.2" 36 | $INFO "tar" "Decompressing..." 37 | deco "gcc" "gcc-core-4.6.0.tar.gz" 38 | deco "g++" "gcc-g++-4.6.0.tar.gz" 39 | #deco "mpc" "mpc-0.9.tar.gz" 40 | #deco "mpfr" "mpfr-3.0.1.tar.gz" 41 | #deco "gmp" "gmp-5.0.1.tar.gz" 42 | deco "binutils" "binutils-2.22.tar.gz" 43 | deco "newlib" "newlib-1.19.0.tar.gz" 44 | deco "freetype" "freetype-2.4.9.tar.gz" 45 | deco "zlib" "zlib-1.2.7.tar.gz" 46 | deco "libpng" "libpng-1.5.13.tar.gz" 47 | deco "pixman" "pixman-0.26.2.tar.gz" 48 | deco "cairo" "cairo-1.12.2.tar.xz" 49 | $INFO "tar" "Decompressed source packages." 50 | $INFO "patch" "Patching..." 51 | patc "gcc" "gcc-4.6.0" 52 | #patc "mpc" "mpc-0.9" 53 | #patc "mpfr" "mpfr-3.0.1" 54 | #patc "gmp" "gmp-5.0.1" 55 | patc "binutils" "binutils-2.22" 56 | patc "newlib" "newlib-1.19.0" 57 | patc "freetype" "freetype-2.4.9" 58 | patc "libpng" "libpng-1.5.13" 59 | patc "pixman" "pixman-0.26.2" 60 | patc "cairo" "cairo-1.12.2" 61 | $INFO "patch" "Patched third-party software." 62 | $INFO "--" "Running additional bits..." 63 | #deleteUnusedGCC "gcc-4.6.0" 64 | installNewlibStuff "newlib-1.19.0" 65 | popd > /dev/null 66 | 67 | mkdir build 68 | mkdir local 69 | 70 | popd > /dev/null 71 | -------------------------------------------------------------------------------- /toolchain/rebuild-newlib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | . $DIR/config.sh 5 | . $DIR/util.sh 6 | 7 | pushd tarballs > /dev/null 8 | rm -rf "newlib-1.19.0" 9 | deco "newlib" "newlib-1.19.0.tar.gz" 10 | patc "newlib" "newlib-1.19.0" 11 | installNewlibStuff "newlib-1.19.0" 12 | popd > /dev/null 13 | 14 | pushd build 15 | if [ ! -d newlib ]; then 16 | mkdir newlib 17 | fi 18 | pushd $DIR/tarballs/newlib-1.19.0/newlib/libc/sys 19 | autoconf || bail 20 | pushd toaru 21 | autoreconf || bail 22 | yasm -f elf -o crt0.o crt0.s || bail 23 | yasm -f elf -o crti.o crti.s || bail 24 | yasm -f elf -o crtn.o crtn.s || bail 25 | cp crt0.o ../ 26 | cp crt0.o /tmp/__toaru_crt0.o 27 | cp crti.o ../ 28 | cp crti.o /tmp/__toaru_crti.o 29 | cp crtn.o ../ 30 | cp crtn.o /tmp/__toaru_crtn.o 31 | popd 32 | popd 33 | pushd newlib 34 | mkdir -p $TARGET/newlib/libc/sys 35 | cp /tmp/__toaru_crt0.o $TARGET/newlib/libc/sys/crt0.o 36 | rm /tmp/__toaru_crt0.o 37 | cp /tmp/__toaru_crti.o $TARGET/newlib/libc/sys/crti.o 38 | rm /tmp/__toaru_crti.o 39 | cp /tmp/__toaru_crtn.o $TARGET/newlib/libc/sys/crtn.o 40 | rm /tmp/__toaru_crtn.o 41 | $DIR/tarballs/newlib-1.19.0/configure --target=$TARGET --prefix=$PREFIX || bail 42 | make || bail 43 | make install || bail 44 | cp -r $DIR/patches/newlib/include/* $PREFIX/$TARGET/include/ 45 | cp $TARGET/newlib/libc/sys/crt*.o $PREFIX/$TARGET/lib/ 46 | popd 47 | popd 48 | -------------------------------------------------------------------------------- /toolchain/util.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | BEG=$DIR/../util/mk-beg 4 | END=$DIR/../util/mk-end 5 | INFO=$DIR/../util/mk-info 6 | 7 | function grab () { 8 | $BEG "wget" "Pulling $1... [$2/$3]" 9 | if [ ! -f "$3" ]; then 10 | wget -q "$2/$3" 11 | $END "wget" "$1" 12 | else 13 | $END "-" "Already have a $1" 14 | fi 15 | } 16 | 17 | function deco () { 18 | $BEG "tar" "Un-archiving $1..." 19 | tar -xf $2 20 | $END "tar" "$1" 21 | } 22 | 23 | function patc () { 24 | $BEG "patch" "Patching $1..." 25 | pushd "$2" > /dev/null 26 | patch -p1 < ../../patches/$2.patch > /dev/null 27 | popd > /dev/null 28 | $END "patch" "$1" 29 | } 30 | 31 | function installNewlibStuff () { 32 | cp -r ../patches/newlib/toaru $1/newlib/libc/sys/toaru 33 | cp -r ../patches/newlib/include/* $1/newlib/libc/sys/toaru/ 34 | # dlmalloc 35 | cp -r ../patches/newlib/malloc.c $1/newlib/libc/stdlib/malloc.c 36 | cp -r ../patches/newlib/setjmp.S $1/newlib/libc/machine/i386/setjmp.S 37 | } 38 | 39 | function bail () { 40 | echo -e "\033[1;31mBuild failed. Please check the logs above to see what went wrong.\033[0m" 41 | exit 1 42 | } 43 | 44 | -------------------------------------------------------------------------------- /userspace/core/cat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cat 3 | * 4 | * Concatenates files together to standard output. 5 | * In a supporting terminal, you can then pipe 6 | * standard out to another file or other useful 7 | * things like that. 8 | */ 9 | #include 10 | 11 | #define CHUNK_SIZE 4096 12 | 13 | int main(int argc, char ** argv) { 14 | int ret = 0; 15 | 16 | for (int i = 1; i < argc; ++i) { 17 | FILE * fd; 18 | if (argc > 1) { 19 | fd = fopen(argv[i], "r"); 20 | if (!fd) { 21 | fprintf(stderr, "%s: %s: no such file or directory\n", argv[0], argv[1]); 22 | ret = 1; 23 | continue; 24 | } 25 | } 26 | 27 | size_t length; 28 | 29 | fseek(fd, 0, SEEK_END); 30 | length = ftell(fd); 31 | fseek(fd, 0, SEEK_SET); 32 | 33 | char buf[CHUNK_SIZE]; 34 | while (length > CHUNK_SIZE) { 35 | fread( buf, 1, CHUNK_SIZE, fd); 36 | fwrite(buf, 1, CHUNK_SIZE, stdout); 37 | fflush(stdout); 38 | length -= CHUNK_SIZE; 39 | } 40 | if (length > 0) { 41 | fread( buf, 1, length, fd); 42 | fwrite(buf, 1, length, stdout); 43 | fflush(stdout); 44 | } 45 | 46 | fclose(fd); 47 | } 48 | 49 | return ret; 50 | } 51 | 52 | /* 53 | * vim:tabstop=4 54 | * vim:noexpandtab 55 | * vim:shiftwidth=4 56 | */ 57 | -------------------------------------------------------------------------------- /userspace/core/clear.c: -------------------------------------------------------------------------------- 1 | /* 2 | * clear 3 | * 4 | * Clears the terminal. 5 | * This is a very dumb version and probably only works 6 | * within the toaruOS terminal, but it might also work 7 | * with an xterm or similar. 8 | */ 9 | #include 10 | 11 | int main(int argc, char ** argv) { 12 | printf("\033[H\033[2J"); 13 | fflush(stdout); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /userspace/core/cp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cp 3 | */ 4 | #include 5 | 6 | #define CHUNK_SIZE 4096 7 | 8 | int main(int argc, char ** argv) { 9 | 10 | FILE * fd; 11 | FILE * fout; 12 | if (argc < 3) { 13 | fprintf(stderr, "usage: %s [source] [destination]\n", argv[0]); 14 | return 1; 15 | } 16 | fd = fopen(argv[1], "r"); 17 | if (!fd) { 18 | fprintf(stderr, "%s: %s: no such file or directory\n", argv[0], argv[1]); 19 | return 1; 20 | } 21 | fout = fopen(argv[2], "w"); 22 | 23 | size_t length; 24 | 25 | fseek(fd, 0, SEEK_END); 26 | length = ftell(fd); 27 | fseek(fd, 0, SEEK_SET); 28 | 29 | char buf[CHUNK_SIZE]; 30 | while (length > CHUNK_SIZE) { 31 | fread( buf, 1, CHUNK_SIZE, fd); 32 | fwrite(buf, 1, CHUNK_SIZE, fout); 33 | length -= CHUNK_SIZE; 34 | } 35 | if (length > 0) { 36 | fread( buf, 1, length, fd); 37 | fwrite(buf, 1, length, fout); 38 | } 39 | 40 | fclose(fd); 41 | fclose(fout); 42 | 43 | return 0; 44 | } 45 | 46 | /* 47 | * vim:tabstop=4 48 | * vim:noexpandtab 49 | * vim:shiftwidth=4 50 | */ 51 | -------------------------------------------------------------------------------- /userspace/core/echo.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * echo 4 | * 5 | * Prints its arguments (with some processing, ask --help) 6 | * to standard out. 7 | */ 8 | #include 9 | #include 10 | 11 | void usage() { 12 | printf("echo [-n] [-e] [STRING]...\n" 13 | " -n do not output a new line at the end\n" 14 | " -e process escape sequences\n"); 15 | } 16 | 17 | int main(int argc, char ** argv) { 18 | int start = 1; 19 | int use_newline = 1; 20 | int process_escapes = 0; 21 | 22 | for (int i = start; i < argc; ++i) { 23 | if (argv[i][0] != '-') { 24 | start = i; 25 | break; 26 | } else { 27 | if (argv[i][1] == 'h') { 28 | usage(); 29 | return 1; 30 | } else if (argv[i][1] == 'n') { 31 | use_newline = 0; 32 | } else if (argv[i][1] == 'e') { 33 | process_escapes = 1; 34 | } 35 | } 36 | } 37 | 38 | for (int i = start; i < argc; ++i) { 39 | if (process_escapes) { 40 | for (int j = 0; j < strlen(argv[i]) - 1; ++j) { 41 | if (argv[i][j] == '\\') { 42 | if (argv[i][j+1] == 'e') { 43 | argv[i][j] = '\033'; 44 | for (int k = j + 1; k < strlen(argv[i]); ++k) { 45 | argv[i][k] = argv[i][k+1]; 46 | } 47 | } 48 | if (argv[i][j+1] == 'n') { 49 | argv[i][j] = '\n'; 50 | for (int k = j + 1; k < strlen(argv[i]); ++k) { 51 | argv[i][k] = argv[i][k+1]; 52 | } 53 | } 54 | } 55 | } 56 | } 57 | printf("%s",argv[i]); 58 | if (i != argc - 1) { 59 | printf(" "); 60 | } 61 | } 62 | 63 | if (use_newline) { 64 | printf("\n"); 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /userspace/core/env.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char ** argv) { 4 | unsigned int x = 0; 5 | unsigned int nulls = 0; 6 | for (x = 0; 1; ++x) { 7 | if (!argv[x]) { 8 | ++nulls; 9 | if (nulls == 2) { 10 | break; 11 | } 12 | continue; 13 | } 14 | if (nulls == 1) { 15 | printf("%s\n", argv[x]); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /userspace/core/hello.c: -------------------------------------------------------------------------------- 1 | /* vim:tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * prints "Hello World!" to standard out. 4 | */ 5 | #include 6 | 7 | int main(int argc, char ** argv) { 8 | printf("Hello World!\n"); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /userspace/core/hostname.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * hostname 4 | * 5 | * Prints or sets the system hostname. 6 | */ 7 | #include 8 | #include 9 | 10 | #define ROOT_UID 0 11 | 12 | int main(int argc, char * argv[]) { 13 | if (argc < 2) { 14 | char tmp[256]; 15 | syscall_gethostname(tmp); 16 | printf("%s\n", tmp); 17 | return 0; 18 | } else { 19 | if (syscall_getuid() != ROOT_UID) { 20 | fprintf(stderr,"Must be root to set hostname.\n"); 21 | return 1; 22 | } else { 23 | syscall_sethostname(argv[1]); 24 | FILE * file = fopen("/etc/hostname", "w"); 25 | if (!file) { 26 | return 1; 27 | } else { 28 | fprintf(file, "%s\n", argv[1]); 29 | fclose(file); 30 | return 0; 31 | } 32 | } 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /userspace/core/init.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * init 4 | * 5 | * Provides the standard boot routines and 6 | * calls the user session (compositor / terminal) 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define DEFAULT_HOSTNAME "toaru-test" 16 | 17 | /* Set the hostname to whatever is in /etc/hostname */ 18 | void set_hostname() { 19 | FILE * _host_file = fopen("/etc/hostname", "r"); 20 | if (!_host_file) { 21 | /* No /etc/hostname, use the default */ 22 | syscall_sethostname(DEFAULT_HOSTNAME); 23 | } else { 24 | char buf[256]; 25 | fgets(buf, 255, _host_file); 26 | if (buf[strlen(buf)-1] == '\n') { 27 | buf[strlen(buf)-1] = '\0'; 28 | } 29 | syscall_sethostname(buf); 30 | setenv("HOST", buf, 1); 31 | fclose(_host_file); 32 | } 33 | } 34 | 35 | void start_terminal(char * arg) { 36 | int pid = fork(); 37 | if (!pid) { 38 | char * tokens[] = { 39 | "/bin/terminal", 40 | "-F", 41 | arg, 42 | NULL 43 | }; 44 | int i = execvp(tokens[0], tokens); 45 | exit(0); 46 | } else { 47 | syscall_wait(pid); 48 | } 49 | } 50 | 51 | void start_terminal_no_freetype(char * arg) { 52 | int pid = fork(); 53 | if (!pid) { 54 | char * tokens[] = { 55 | "/bin/terminal", 56 | "-Fkb", 57 | arg, 58 | NULL 59 | }; 60 | int i = execv(tokens[0], tokens); 61 | exit(0); 62 | } else { 63 | syscall_wait(pid); 64 | } 65 | } 66 | 67 | void start_vga_terminal(char * arg) { 68 | int pid = fork(); 69 | if (!pid) { 70 | char * tokens[] = { 71 | "/bin/terminal", 72 | "-Vl", 73 | arg, 74 | NULL 75 | }; 76 | int i = execvp(tokens[0], tokens); 77 | exit(0); 78 | } else { 79 | syscall_wait(pid); 80 | } 81 | } 82 | 83 | void start_compositor() { 84 | int pid = fork(); 85 | if (!pid) { 86 | char * _tokens[] = { 87 | "/bin/compositor", 88 | NULL 89 | }; 90 | execvp(_tokens[0], _tokens); 91 | 92 | exit(0); 93 | } else { 94 | syscall_wait(pid); 95 | } 96 | } 97 | 98 | 99 | int main(int argc, char * argv[]) { 100 | /* Hostname */ 101 | set_hostname(); 102 | if (argc > 1) { 103 | char * args = NULL; 104 | if (argc > 2) { 105 | args = argv[2]; 106 | } 107 | if (!strcmp(argv[1],"--single")) { 108 | start_terminal(args); 109 | return 0; 110 | } else if (!strcmp(argv[1], "--vga")) { 111 | start_vga_terminal(args); 112 | return 0; 113 | } else if (!strcmp(argv[1], "--special")) { 114 | start_terminal_no_freetype(args); 115 | return 0; 116 | } 117 | } 118 | start_compositor(); 119 | } 120 | -------------------------------------------------------------------------------- /userspace/core/login.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Login Service 4 | * 5 | * Provides the user with a login prompt and starts their session. 6 | * 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "lib/sha2.h" 18 | 19 | uint32_t child = 0; 20 | 21 | void sig_int(int sig) { 22 | /* Pass onto the shell */ 23 | if (child) { 24 | syscall_send_signal(child, sig); 25 | } 26 | /* Else, ignore */ 27 | } 28 | 29 | void sig_segv(int sig) { 30 | printf("Segmentation fault.\n"); 31 | exit(127 + sig); 32 | /* no return */ 33 | } 34 | 35 | int checkUserPass(char * user, char * pass) { 36 | 37 | /* Generate SHA512 */ 38 | char hash[SHA512_DIGEST_STRING_LENGTH]; 39 | SHA512_Data(pass, strlen(pass), hash); 40 | 41 | /* Open up /etc/master.passwd */ 42 | 43 | FILE * passwd = fopen("/etc/master.passwd", "r"); 44 | char line[2048]; 45 | 46 | while (fgets(line, 2048, passwd) != NULL) { 47 | 48 | line[strlen(line)-1] = '\0'; 49 | 50 | char *p, *tokens[4], *last; 51 | int i = 0; 52 | for ((p = strtok_r(line, ":", &last)); p; 53 | (p = strtok_r(NULL, ":", &last)), i++) { 54 | if (i < 511) tokens[i] = p; 55 | } 56 | tokens[i] = NULL; 57 | 58 | if (strcmp(tokens[0],user) != 0) { 59 | continue; 60 | } 61 | if (!strcmp(tokens[1],hash)) { 62 | fclose(passwd); 63 | return atoi(tokens[2]); 64 | } 65 | } 66 | fclose(passwd); 67 | return -1; 68 | 69 | } 70 | 71 | int main(int argc, char ** argv) { 72 | 73 | /* TODO: uname() */ 74 | char * _uname = malloc(sizeof(char) * 1024); 75 | syscall_kernel_string_XXX(_uname); 76 | 77 | fprintf(stdout, "\n%s\n\n", _uname); 78 | 79 | syscall_signal(2, sig_int); 80 | syscall_signal(11, sig_segv); 81 | 82 | while (1) { 83 | char * username = malloc(sizeof(char) * 1024); 84 | char * password = malloc(sizeof(char) * 1024); 85 | 86 | /* TODO: gethostname() */ 87 | char _hostname[256]; 88 | syscall_gethostname(_hostname); 89 | 90 | fprintf(stdout, "%s login: ", _hostname); 91 | fflush(stdout); 92 | fgets(username, 1024, stdin); 93 | username[strlen(username)-1] = '\0'; 94 | 95 | fprintf(stdout, "password: \033[1001z"); 96 | fflush(stdout); 97 | fgets(password, 1024, stdin); 98 | password[strlen(password)-1] = '\0'; 99 | fprintf(stdout, "\033[1002z\n"); 100 | 101 | int uid = checkUserPass(username, password); 102 | 103 | if (uid < 0) { 104 | fprintf(stdout, "\nLogin failed.\n"); 105 | continue; 106 | } 107 | 108 | pid_t pid = getpid(); 109 | 110 | uint32_t f = fork(); 111 | if (getpid() != pid) { 112 | /* TODO: Read appropriate shell from /etc/passwd */ 113 | char * args[] = { 114 | "/bin/esh", 115 | NULL 116 | }; 117 | syscall_setuid(uid); 118 | int i = execvp(args[0], args); 119 | } else { 120 | child = f; 121 | syscall_wait(f); 122 | } 123 | child = 0; 124 | free(username); 125 | free(password); 126 | } 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /userspace/core/mkdir.c: -------------------------------------------------------------------------------- 1 | /* vim:tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * mkdir 4 | * 5 | * Create a directory. 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char ** argv) { 12 | if (argc < 2) { 13 | fprintf(stderr, "%s: expected argument\n", argv[0]); 14 | return 1; 15 | } 16 | 17 | syscall_mkdir(argv[1], 0x00); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /userspace/core/reboot.c: -------------------------------------------------------------------------------- 1 | /* 2 | * reboot 3 | * 4 | * Reboot the system. 5 | */ 6 | #include 7 | #include 8 | 9 | int main(int argc, char ** argv) { 10 | printf("uid is %d\n", syscall_getuid()); 11 | if (syscall_reboot() < 0) { 12 | printf("%s: need to be root.\n", argv[0]); 13 | } 14 | return 1; 15 | } 16 | -------------------------------------------------------------------------------- /userspace/core/shutdown.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char * argv[]) { 5 | printf("Shutting down...\n"); 6 | /* Nothing to actually do for shutdown, sadly */ 7 | __asm__ __volatile__ ("outw %1, %0" : : "dN" ((uint16_t)0xB004), "a" ((uint16_t)0x2000)); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /userspace/core/sleep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Sleep 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); 9 | 10 | int main(int argc, char ** argv) { 11 | int ret = 0; 12 | 13 | char * arg = strdup(argv[1]); 14 | 15 | float time = atof(arg); 16 | 17 | unsigned int seconds = (unsigned int)time; 18 | unsigned int subsecs = (unsigned int)((time - (float)seconds) * 100); 19 | 20 | ret = syscall_nanosleep(seconds, subsecs); 21 | 22 | return ret; 23 | } 24 | 25 | /* 26 | * vim:tabstop=4 27 | * vim:noexpandtab 28 | * vim:shiftwidth=4 29 | */ 30 | -------------------------------------------------------------------------------- /userspace/core/stat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * stat 3 | * 4 | * Displays information on a file's inode. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | int main(int argc, char ** argv) { 14 | if (argc < 2) { 15 | fprintf(stderr,"%s: expected argument\n", argv[0]); 16 | return 1; 17 | } 18 | 19 | FILE * fd = stdin; 20 | fd = fopen(argv[1], "r"); 21 | if (!fd) { 22 | return 1; 23 | } 24 | fclose(fd); 25 | 26 | struct stat _stat; 27 | stat(argv[1], &_stat); 28 | 29 | printf("0x%x bytes\n", _stat.st_size); 30 | 31 | if (S_ISDIR(_stat.st_mode)) { 32 | printf("Is a directory.\n"); 33 | } else if (S_ISFIFO(_stat.st_mode)) { 34 | printf("Is a pipe.\n"); 35 | } else if (_stat.st_mode & 0111) { 36 | printf("Is executable.\n"); 37 | } 38 | 39 | struct stat * f = &_stat; 40 | 41 | printf("st_mode 0x%x %d\n", (uint32_t)f->st_mode , sizeof(f->st_mode )); 42 | printf("st_nlink 0x%x %d\n", (uint32_t)f->st_nlink , sizeof(f->st_nlink )); 43 | printf("st_uid 0x%x %d\n", (uint32_t)f->st_uid , sizeof(f->st_uid )); 44 | printf("st_gid 0x%x %d\n", (uint32_t)f->st_gid , sizeof(f->st_gid )); 45 | printf("st_rdev 0x%x %d\n", (uint32_t)f->st_rdev , sizeof(f->st_rdev )); 46 | printf("st_size 0x%x %d\n", (uint32_t)f->st_size , sizeof(f->st_size )); 47 | 48 | printf("0x%x\n", ((uint32_t *)f)[0]); 49 | 50 | return 0; 51 | } 52 | 53 | /* 54 | * vim:tabstop=4 55 | * vim:noexpandtab 56 | * vim:shiftwidth=4 57 | */ 58 | -------------------------------------------------------------------------------- /userspace/core/sysfunc.c: -------------------------------------------------------------------------------- 1 | /* vim:tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * sysfunc 4 | * 5 | * Executes an "extended system function" which 6 | * is basically just a super-syscall. 7 | */ 8 | #include 9 | #include 10 | 11 | int main(int argc, char ** argv) { 12 | if (argc < 2) return 1; 13 | return syscall_system_function(atoi(argv[1]), &argv[2]); 14 | } 15 | -------------------------------------------------------------------------------- /userspace/core/touch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * touch 3 | * 4 | * Creates a file or updates its last-modified date. 5 | * (in theory) 6 | */ 7 | #include 8 | #include 9 | 10 | int main(int argc, char * argv[]) { 11 | if (argc < 2) { 12 | fprintf(stderr, "%s: argument expected\n", argv[0]); 13 | return 1; 14 | } 15 | 16 | FILE * f = fopen(argv[1], "w"); 17 | fclose(f); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /userspace/core/uname.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * uname 4 | * 5 | * Prints the kernel version information. 6 | */ 7 | #include 8 | #include 9 | 10 | int main(int argc, char * argv[]) { 11 | char _uname[1024]; 12 | syscall_kernel_string_XXX(_uname); 13 | 14 | fprintf(stdout, "%s\n", _uname); 15 | } 16 | -------------------------------------------------------------------------------- /userspace/core/whoami.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Who Am I? 4 | * 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define LINE_LEN 4096 12 | 13 | int main(int argc, char ** argv) { 14 | FILE * passwd = fopen("/etc/passwd", "r"); 15 | char line[LINE_LEN]; 16 | 17 | int uid = syscall_getuid(); 18 | 19 | while (fgets(line, LINE_LEN, passwd) != NULL) { 20 | 21 | line[strlen(line)-1] = '\0'; 22 | 23 | char *p, *tokens[10], *last; 24 | int i = 0; 25 | for ((p = strtok_r(line, ":", &last)); p; 26 | (p = strtok_r(NULL, ":", &last)), i++) { 27 | if (i < 511) tokens[i] = p; 28 | } 29 | tokens[i] = NULL; 30 | 31 | if (atoi(tokens[2]) == uid) { 32 | printf("%s\n", tokens[0]); 33 | } 34 | } 35 | fclose(passwd); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /userspace/core/yes.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * yes 4 | * 5 | * Continually prints its first argument, followed by a newline. 6 | */ 7 | #include 8 | 9 | int main(int argc, char * argv[]) { 10 | char * yes_string = "y"; 11 | if (argc > 1) { 12 | yes_string = argv[1]; 13 | } 14 | while (1) { 15 | printf("%s\n", yes_string); 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /userspace/extra/clock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * clock 3 | * 4 | * Displays the current time in the upper right corner 5 | * of your terminal session; forks on startup. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main(int argc, char ** argv) { 18 | if (!fork()) { 19 | struct timeval now; 20 | int last = 0; 21 | struct tm * timeinfo; 22 | char buffer[80]; 23 | while (1) { 24 | syscall_gettimeofday(&now, NULL); //time(NULL); 25 | if (now.tv_sec != last) { 26 | last = now.tv_sec; 27 | timeinfo = localtime((time_t *)&now.tv_sec); 28 | strftime(buffer, 80, "%H:%M:%S", timeinfo); 29 | printf("\033[s\033[1;200H\033[9D%s\033[u", buffer); 30 | fflush(stdout); 31 | } 32 | } 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /userspace/extra/compare.c: -------------------------------------------------------------------------------- 1 | /* 2 | * compare 3 | * 4 | * Compares two files and prints out some 5 | * statistics on how they differ. 6 | * 7 | * This is *NOT* diff. 8 | */ 9 | #include 10 | #include 11 | 12 | #define CHUNK_SIZE 1024 13 | 14 | int main(int argc, char * argv[]) { 15 | if (argc < 3) { 16 | fprintf(stderr, "Need two files to compare.\n"); 17 | return 1; 18 | } 19 | 20 | FILE * a = fopen(argv[1], "r"); 21 | FILE * b = fopen(argv[2], "r"); 22 | size_t lengtha, lengthb; 23 | 24 | fseek(a, 0, SEEK_END); 25 | lengtha = ftell(a); 26 | fseek(a, 0, SEEK_SET); 27 | 28 | fseek(b, 0, SEEK_END); 29 | lengthb = ftell(b); 30 | fseek(b, 0, SEEK_SET); 31 | 32 | fprintf(stderr,"[%d bytes and %d bytes]\n", lengtha, lengthb); 33 | 34 | char bufa[CHUNK_SIZE]; 35 | char bufb[CHUNK_SIZE]; 36 | 37 | int chunk = 0; 38 | size_t read = 0; 39 | 40 | while (read < lengtha) { 41 | memset(bufa, 0x0, CHUNK_SIZE); 42 | memset(bufb, 0x0, CHUNK_SIZE); 43 | fread(bufa, 1, CHUNK_SIZE, a); 44 | fread(bufb, 1, CHUNK_SIZE, b); 45 | size_t different = 0; 46 | for (int i = 0; i < CHUNK_SIZE; ++i) { 47 | if (bufa[i] != bufb[i]) 48 | different++; 49 | } 50 | 51 | if (different > 0) { 52 | printf("Chunk %d has %d differing bytes.\n", chunk, different); 53 | } 54 | 55 | read += CHUNK_SIZE; 56 | chunk++; 57 | } 58 | 59 | fclose(a); 60 | fclose(b); 61 | 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /userspace/extra/lock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * lock 3 | * 4 | * CLI screen locker. Useful for a single-user 5 | * terminal-only session. 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | void sig_int(int sig) { 15 | /* Ignore */ 16 | } 17 | 18 | void main(int argc, char * argv[]) { 19 | syscall_signal(2, sig_int); 20 | 21 | char * password_a = malloc(sizeof(char) * 1024); 22 | char * password_b = malloc(sizeof(char) * 1024); 23 | 24 | printf("\033[H\033[2J"); 25 | 26 | fprintf(stdout, "Enter a lock password: \033[1001z"); 27 | fflush(stdout); 28 | fgets(password_a, 1024, stdin); 29 | password_a[strlen(password_a)-1] = '\0'; 30 | fprintf(stdout, "\033[1002z\n"); 31 | 32 | uint32_t failures = 0; 33 | 34 | do { 35 | printf("\033[H\033[2J"); 36 | if (failures > 0) { 37 | printf("\n\033[1;41;33mIncorrect password. (%d failure%s)\033[0m\n", failures, (failures > 1 ? "s" : "")); 38 | } 39 | printf("\n\033[1;31mSystem is locked.\033[0m\n\n"); 40 | fprintf(stdout, "Enter password to unlock: \033[1001z"); 41 | fflush(stdout); 42 | fgets(password_b, 1024, stdin); 43 | password_b[strlen(password_b)-1] = '\0'; 44 | fprintf(stdout, "\033[1002z\n"); 45 | failures++; 46 | } while (strcmp(password_a, password_b) != 0); 47 | } 48 | -------------------------------------------------------------------------------- /userspace/extra/serial-console.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cat 3 | * 4 | * Concatenates files together to standard output. 5 | * In a supporting terminal, you can then pipe 6 | * standard out to another file or other useful 7 | * things like that. 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lib/pthread.h" 14 | #include "../kernel/include/signal.h" 15 | 16 | DEFN_SYSCALL1(serial, 44, int); 17 | int fd = 0; 18 | 19 | int child_pid = 0; 20 | 21 | void *print_serial_stuff(void * garbage) { 22 | child_pid = gettid(); 23 | while (1) { 24 | char buf[1024]; 25 | size_t size = read(fd, buf, 1024); 26 | 27 | for (int i = 0; i < size; ++i) { 28 | char x = buf[i]; 29 | fputc(x, stdout); 30 | } 31 | if (size) fflush(stdout); 32 | } 33 | 34 | pthread_exit(garbage); 35 | } 36 | 37 | int main(int argc, char ** argv) { 38 | int device = 0x2F8; 39 | pthread_t receive_thread; 40 | pthread_t flush_thread; 41 | 42 | if (argc > 1) { 43 | if (!strcmp(argv[1], "com1")) { 44 | device = 0x3F8; 45 | } else if (!strcmp(argv[1], "com2")) { 46 | device = 0x2F8; 47 | } else { 48 | fprintf(stderr, "Unrecognized com device, try com1 or com2; default is com2.\n"); 49 | return 1; 50 | } 51 | } 52 | 53 | printf("\033[1560z"); 54 | fflush(stdout); 55 | 56 | fd = syscall_serial(device); 57 | pthread_create(&receive_thread, NULL, print_serial_stuff, NULL); 58 | 59 | while (1) { 60 | char c = fgetc(stdin); 61 | if (c == 27) { 62 | char x = fgetc(stdin); 63 | if (x == ']') { 64 | while (1) { 65 | printf("serial-console>\033[1561z "); 66 | fflush(stdout); 67 | 68 | char line[1024]; 69 | fgets(line, 1024, stdin); 70 | 71 | int i = strlen(line); 72 | line[i-1] = '\0'; 73 | 74 | if (!strcmp(line, "quit")) { 75 | syscall_send_signal(child_pid, SIGKILL); 76 | printf("Waiting for threads to shut down...\n"); 77 | syscall_wait(child_pid); 78 | 79 | printf("Exiting.\n"); 80 | return 0; 81 | } else if (!strcmp(line, "continue")) { 82 | printf("\033[1560z"); 83 | fflush(stdout); 84 | break; 85 | } 86 | } 87 | } else { 88 | ungetc(x, stdin); 89 | } 90 | } 91 | char buf[1] = {c}; 92 | write(fd, buf, 1); 93 | } 94 | 95 | close(fd); 96 | return 0; 97 | } 98 | 99 | /* 100 | * vim:tabstop=4 101 | * vim:noexpandtab 102 | * vim:shiftwidth=4 103 | */ 104 | -------------------------------------------------------------------------------- /userspace/extra/telnet.h: -------------------------------------------------------------------------------- 1 | #ifndef TELNET_H 2 | #define TELNET_H 3 | 4 | /* Telnet Defines */ 5 | #define IAC 255 6 | #define DONT 254 7 | #define DO 253 8 | #define WONT 252 9 | #define WILL 251 10 | 11 | #define SE 240 // Subnegotiation End 12 | #define NOP 241 // No Operation 13 | #define DM 242 // Data Mark 14 | #define BRK 243 // Break 15 | #define IP 244 // Interrupt process 16 | #define AO 245 // Abort output 17 | #define AYT 246 // Are You There 18 | #define EC 247 // Erase Character 19 | #define EL 248 // Erase Line 20 | #define GA 249 // Go Ahead 21 | #define SB 250 // Subnegotiation Begin 22 | 23 | #define BINARY 0 // 8-bit data path 24 | #define ECHO 1 // echo 25 | #define RCP 2 // prepare to reconnect 26 | #define SGA 3 // suppress go ahead 27 | #define NAMS 4 // approximate message size 28 | #define STATUS 5 // give status 29 | #define TM 6 // timing mark 30 | #define RCTE 7 // remote controlled transmission and echo 31 | #define NAOL 8 // negotiate about output line width 32 | #define NAOP 9 // negotiate about output page size 33 | #define NAOCRD 10 // negotiate about CR disposition 34 | #define NAOHTS 11 // negotiate about horizontal tabstops 35 | #define NAOHTD 12 // negotiate about horizontal tab disposition 36 | #define NAOFFD 13 // negotiate about formfeed disposition 37 | #define NAOVTS 14 // negotiate about vertical tab stops 38 | #define NAOVTD 15 // negotiate about vertical tab disposition 39 | #define NAOLFD 16 // negotiate about output LF disposition 40 | #define XASCII 17 // extended ascii character set 41 | #define LOGOUT 18 // force logout 42 | #define BM 19 // byte macro 43 | #define DET 20 // data entry terminal 44 | #define SUPDUP 21 // supdup protocol 45 | #define SUPDUPOUTPUT 22 // supdup output 46 | #define SNDLOC 23 // send location 47 | #define TTYPE 24 // terminal type 48 | #define EOR 25 // end or record 49 | #define TUID 26 // TACACS user identification 50 | #define OUTMRK 27 // output marking 51 | #define TTYLOC 28 // terminal location number 52 | #define VT3270REGIME 29 // 3270 regime 53 | #define X3PAD 30 // X.3 PAD 54 | #define NAWS 31 // window size 55 | #define TSPEED 32 // terminal speed 56 | #define LFLOW 33 // remote flow control 57 | #define LINEMODE 34 // Linemode option 58 | #define XDISPLOC 35 // X Display Location 59 | #define OLD_ENVIRON 36 // Old - Environment variables 60 | #define AUTHENTICATION 37 // Authenticate 61 | #define ENCRYPT 38 // Encryption option 62 | #define NEW_ENVIRON 39 // New - Environment variables 63 | #define TN3270E 40 // TN3270E 64 | #define XAUTH 41 // XAUTH 65 | #define CHARSET 42 // CHARSET 66 | #define RSP 43 // Telnet Remote Serial Port 67 | #define COM_PORT_OPTION 44 // Com Port Control Option 68 | #define SUPPRESS_LOCAL_ECHO 45 // Telnet Suppress Local Echo 69 | #define TLS 46 // Telnet Start TLS 70 | #define KERMIT 47 // KERMIT 71 | #define SEND_URL 48 // SEND-URL 72 | #define FORWARD_X 49 // FORWARD_X 73 | #define PRAGMA_LOGON 138 // TELOPT PRAGMA LOGON 74 | #define SSPI_LOGON 139 // TELOPT SSPI LOGON 75 | #define PRAGMA_HEARTBEAT 140 // TELOPT PRAGMA HEARTBEAT 76 | #define EXOPL 255 // Extended-Options-List 77 | #define NOOPT 0 78 | 79 | #define IS 0 80 | #define SEND 1 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /userspace/extra/verify-write.c: -------------------------------------------------------------------------------- 1 | /* 2 | * verify-write 3 | * 4 | * A dangerous tool to write to a file and verified it worked. 5 | */ 6 | #include 7 | #include 8 | 9 | #define CHUNK_SIZE 1024 10 | 11 | int main(int argc, char * argv[]) { 12 | if (argc < 3) { 13 | printf("Expected two arguments, the file to read, and the filename to write out to.\nTry again, maybe?\n"); 14 | return -1; 15 | } 16 | FILE * input = fopen(argv[1], "r"); 17 | FILE * output = fopen(argv[2], "w"); 18 | size_t length; 19 | 20 | fseek(input, 0, SEEK_END); 21 | length = ftell(input); 22 | fseek(input, 0, SEEK_SET); 23 | 24 | char buf[CHUNK_SIZE]; 25 | while (length > CHUNK_SIZE) { 26 | fread( buf, 1, CHUNK_SIZE, input); 27 | fwrite(buf, 1, CHUNK_SIZE, output); 28 | fflush(output); 29 | length -= CHUNK_SIZE; 30 | } 31 | if (length > 0) { 32 | fread( buf, 1, length, input); 33 | fwrite(buf, 1, length, output); 34 | fflush(output); 35 | } 36 | 37 | fclose(output); 38 | fclose(input); 39 | 40 | char * args[] = {"/bin/compare", argv[1], argv[2], NULL }; 41 | execvp(args[0], args); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /userspace/gui/basic/drawlines.c: -------------------------------------------------------------------------------- 1 | /* 2 | * drawlines 3 | * 4 | * Test application to draw lines to a window. 5 | */ 6 | #include 7 | #include 8 | 9 | #include "lib/window.h" 10 | #include "lib/graphics.h" 11 | 12 | int left, top, width, height; 13 | window_t * wina; 14 | gfx_context_t * ctx; 15 | 16 | int32_t min(int32_t a, int32_t b) { 17 | return (a < b) ? a : b; 18 | } 19 | 20 | int32_t max(int32_t a, int32_t b) { 21 | return (a > b) ? a : b; 22 | } 23 | 24 | void resize_callback(window_t * window) { 25 | width = window->width; 26 | height = window->height; 27 | reinit_graphics_window(ctx, wina); 28 | draw_fill(ctx, rgb(0,0,0)); 29 | } 30 | 31 | 32 | int main (int argc, char ** argv) { 33 | left = 100; 34 | top = 100; 35 | width = 500; 36 | height = 500; 37 | 38 | setup_windowing(); 39 | resize_window_callback = resize_callback; 40 | 41 | /* Do something with a window */ 42 | wina = window_create(left, top, width, height); 43 | assert(wina); 44 | 45 | ctx = init_graphics_window(wina); 46 | draw_fill(ctx, rgb(0,0,0)); 47 | 48 | int exit = 0; 49 | while (!exit) { 50 | w_keyboard_t * kbd = poll_keyboard_async(); 51 | if (kbd != NULL) { 52 | if (kbd->key == 'q') 53 | exit = 1; 54 | free(kbd); 55 | } 56 | 57 | draw_line(ctx, rand() % width, rand() % width, rand() % height, rand() % height, rgb(rand() % 255,rand() % 255,rand() % 255)); 58 | } 59 | 60 | teardown_windowing(); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /userspace/gui/basic/plasma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * test-gfx 3 | * 4 | * Windowed graphical test application. 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | #include "lib/window.h" 11 | #include "lib/graphics.h" 12 | #include "lib/decorations.h" 13 | 14 | #define dist(a,b,c,d) sqrt((double)(((a) - (c)) * ((a) - (c)) + ((b) - (d)) * ((b) - (d)))) 15 | 16 | window_t * wina; 17 | 18 | uint16_t win_width; 19 | uint16_t win_height; 20 | 21 | uint16_t off_x; 22 | uint16_t off_y; 23 | 24 | gfx_context_t * ctx; 25 | 26 | void redraw_borders() { 27 | render_decorations(wina, ctx, "Graphics Test"); 28 | } 29 | 30 | void resize_callback(window_t * window) { 31 | win_width = window->width - decor_width(); 32 | win_height = window->height - decor_height(); 33 | reinit_graphics_window(ctx, wina); 34 | draw_fill(ctx, rgb(0,0,0)); 35 | redraw_borders(); 36 | flip(ctx); 37 | } 38 | 39 | uint32_t hsv_to_rgb(int h, float s, float v) { 40 | float c = v * s; 41 | float hp = (float)h / 42.6666666f; 42 | float x = c * (1.0 - fabs(fmod(hp, 2) - 1.0)); 43 | float m = v - c; 44 | float rp, gp, bp; 45 | if (hp < 1.0) { rp = c; gp = x; bp = 0; } 46 | else if (hp < 2.0) { rp = x; gp = c; bp = 0; } 47 | else if (hp < 3.0) { rp = 0; gp = c; bp = x; } 48 | else if (hp < 4.0) { rp = 0; gp = x; bp = c; } 49 | else if (hp < 5.0) { rp = x; gp = 0; bp = c; } 50 | else if (hp < 6.0) { rp = c; gp = 0; bp = x; } 51 | else { rp = 0; gp = 0; bp = 0; } 52 | return rgb((rp + m) * 255, (gp + m) * 255, (bp + m) * 255); 53 | } 54 | 55 | int main (int argc, char ** argv) { 56 | char * _windowed = getenv("DISPLAY"); 57 | if (_windowed) { 58 | setup_windowing(); 59 | resize_window_callback = resize_callback; 60 | 61 | win_width = 500; 62 | win_height = 500; 63 | 64 | init_decorations(); 65 | 66 | off_x = decor_left_width; 67 | off_y = decor_top_height; 68 | 69 | /* Do something with a window */ 70 | wina = window_create(300, 300, win_width + decor_width(), win_height + decor_height()); 71 | assert(wina); 72 | ctx = init_graphics_window_double_buffer(wina); 73 | } else { 74 | ctx = init_graphics_fullscreen_double_buffer(); 75 | win_width = ctx->width; 76 | win_height = ctx->height; 77 | 78 | off_x = 0; 79 | off_y = 0; 80 | } 81 | 82 | draw_fill(ctx, rgb(0,0,0)); 83 | redraw_borders(); 84 | flip(ctx); 85 | 86 | double time; 87 | 88 | /* Generate a palette */ 89 | uint32_t palette[256]; 90 | for (int x = 0; x < 256; ++x) { 91 | palette[x] = hsv_to_rgb(x,1.0,1.0); 92 | } 93 | 94 | while (1) { 95 | if (_windowed) { 96 | w_keyboard_t * kbd = poll_keyboard_async(); 97 | if (kbd) { 98 | char ch = kbd->key; 99 | free(kbd); 100 | if (ch == 'q') { 101 | goto done; 102 | break; 103 | } 104 | } 105 | } 106 | 107 | time += 1.0; 108 | 109 | int w = win_width; 110 | int h = win_height; 111 | 112 | for (int x = 0; x < win_width; ++x) { 113 | for (int y = 0; y < win_height; ++y) { 114 | double value = sin(dist(x + time, y, 128.0, 128.0) / 8.0) 115 | + sin(dist(x, y, 64.0, 64.0) / 8.0) 116 | + sin(dist(x, y + time / 7, 192.0, 64) / 7.0) 117 | + sin(dist(x, y, 192.0, 100.0) / 8.0); 118 | GFX(ctx, x + off_x, y + off_y) = palette[(int)((value + 4) * 32)]; 119 | } 120 | } 121 | redraw_borders(); 122 | flip(ctx); 123 | } 124 | done: 125 | 126 | if (_windowed) { 127 | teardown_windowing(); 128 | } 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /userspace/gui/basic/view.c: -------------------------------------------------------------------------------- 1 | /* 2 | * view 3 | * 4 | * Displays bitmap images in windows 5 | */ 6 | #include 7 | 8 | #include "lib/window.h" 9 | #include "lib/graphics.h" 10 | 11 | sprite_t * sprites[128]; 12 | sprite_t alpha_tmp; 13 | gfx_context_t * ctx; 14 | 15 | void init_sprite(int i, char * filename, char * alpha) { 16 | sprites[i] = malloc(sizeof(sprite_t)); 17 | load_sprite(sprites[i], filename); 18 | if (alpha) { 19 | sprites[i]->alpha = 1; 20 | load_sprite(&alpha_tmp, alpha); 21 | sprites[i]->masks = alpha_tmp.bitmap; 22 | } else { 23 | sprites[i]->alpha = 0; 24 | } 25 | sprites[i]->blank = 0x0; 26 | } 27 | 28 | int main (int argc, char ** argv) { 29 | if (argc < 2) { 30 | printf("usage: %s file\n", argv[0]); 31 | return -1; 32 | } 33 | 34 | int left = 30; 35 | int top = 30; 36 | 37 | if (strstr(argv[1], ".png")) { 38 | sprites[0] = malloc(sizeof(sprite_t)); 39 | load_sprite_png(sprites[0], argv[1]); 40 | } else { 41 | init_sprite(0, argv[1], NULL); 42 | } 43 | 44 | int width = sprites[0]->width; 45 | int height = sprites[0]->height; 46 | 47 | setup_windowing(); 48 | 49 | /* Do something with a window */ 50 | window_t * wina = window_create(left, top, width, height); 51 | ctx = init_graphics_window(wina); 52 | draw_fill(ctx, rgb(0,0,0)); 53 | 54 | if (sprites[0]->alpha == ALPHA_EMBEDDED) { 55 | draw_fill(ctx, rgba(0,0,0,0)); 56 | window_enable_alpha(wina); 57 | } 58 | 59 | draw_sprite(ctx, sprites[0], 0, 0); 60 | 61 | while (1) { 62 | w_keyboard_t * kbd = poll_keyboard(); 63 | if (kbd != NULL) { 64 | if (kbd->key == 'q') { 65 | break; 66 | } 67 | free(kbd); 68 | } 69 | } 70 | 71 | teardown_windowing(); 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /userspace/gui/core/gsession.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define LINE_LEN 1024 7 | 8 | void set_username() { 9 | FILE * passwd = fopen("/etc/passwd", "r"); 10 | char line[LINE_LEN]; 11 | 12 | int uid = syscall_getuid(); 13 | 14 | while (fgets(line, LINE_LEN, passwd) != NULL) { 15 | 16 | line[strlen(line)-1] = '\0'; 17 | 18 | char *p, *tokens[10], *last; 19 | int i = 0; 20 | for ((p = strtok_r(line, ":", &last)); p; 21 | (p = strtok_r(NULL, ":", &last)), i++) { 22 | if (i < 511) tokens[i] = p; 23 | } 24 | tokens[i] = NULL; 25 | 26 | if (atoi(tokens[2]) == uid) { 27 | setenv("USER", tokens[0], 1); 28 | } 29 | } 30 | fclose(passwd); 31 | } 32 | 33 | void set_homedir() { 34 | char * user = getenv("USER"); 35 | if (user) { 36 | char path[512]; 37 | sprintf(path,"/home/%s", user); 38 | setenv("HOME",path,1); 39 | } else { 40 | setenv("HOME","/",1); 41 | } 42 | } 43 | 44 | void set_path() { 45 | setenv("PATH", "/bin", 0); 46 | } 47 | 48 | int main(int argc, char * argv[]) { 49 | /* Starts a graphical session and then spins waiting for a kill (logout) signal */ 50 | 51 | /* Load some session variables */ 52 | set_username(); 53 | set_homedir(); 54 | set_path(); 55 | 56 | int _wallpaper_pid = fork(); 57 | if (!_wallpaper_pid) { 58 | char * args[] = {"/bin/wallpaper", NULL}; 59 | execvp(args[0], args); 60 | } 61 | int _panel_pid = fork(); 62 | if (!_panel_pid) { 63 | char * args[] = {"/bin/panel", NULL}; 64 | execvp(args[0], args); 65 | } 66 | 67 | syscall_wait(_panel_pid); 68 | 69 | printf("Session leader has exited. Sending INT signals to %d.\n", _wallpaper_pid); 70 | 71 | syscall_send_signal(_wallpaper_pid, 2); 72 | 73 | printf("Waiting on wallpaper.\n"); 74 | syscall_wait(_wallpaper_pid); 75 | 76 | printf("Session has ended.\n"); 77 | 78 | } 79 | -------------------------------------------------------------------------------- /userspace/gui/demo/cairo-demo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "lib/window.h" 6 | #include "lib/graphics.h" 7 | 8 | window_t * window; 9 | gfx_context_t * ctx; 10 | 11 | void render() { 12 | draw_fill(ctx, rgba(0,0,0,127)); 13 | 14 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, window->width); 15 | cairo_surface_t * surface = cairo_image_surface_create_for_data(ctx->buffer, CAIRO_FORMAT_ARGB32, window->width, window->height, stride); 16 | cairo_t * cr = cairo_create(surface); 17 | 18 | cairo_set_line_width (cr, 6); 19 | 20 | cairo_rectangle (cr, 12, 12, 232, 70); 21 | cairo_new_sub_path (cr); cairo_arc (cr, 64, 64, 40, 0, 2*M_PI); 22 | cairo_new_sub_path (cr); cairo_arc_negative (cr, 192, 64, 40, 0, -2*M_PI); 23 | 24 | cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); 25 | cairo_set_source_rgb (cr, 0, 0.7, 0); cairo_fill_preserve (cr); 26 | cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); 27 | 28 | cairo_translate (cr, 0, 128); 29 | cairo_rectangle (cr, 12, 12, 232, 70); 30 | cairo_new_sub_path (cr); cairo_arc (cr, 64, 64, 40, 0, 2*M_PI); 31 | cairo_new_sub_path (cr); cairo_arc_negative (cr, 192, 64, 40, 0, -2*M_PI); 32 | 33 | cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING); 34 | cairo_set_source_rgb (cr, 0, 0, 0.9); cairo_fill_preserve (cr); 35 | cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); 36 | 37 | cairo_surface_flush(surface); 38 | cairo_destroy(cr); 39 | cairo_surface_flush(surface); 40 | cairo_surface_destroy(surface); 41 | } 42 | 43 | void resize_callback(window_t * win) { 44 | reinit_graphics_window(ctx, window); 45 | render(); 46 | } 47 | 48 | 49 | int main(int argc, char * argv[]) { 50 | setup_windowing(); 51 | 52 | int width = 500; 53 | int height = 500; 54 | 55 | resize_window_callback = resize_callback; 56 | window = window_create(100,100,500,500); 57 | ctx = init_graphics_window(window); 58 | draw_fill(ctx, rgba(0,0,0,127)); 59 | window_enable_alpha(window); 60 | 61 | render(); 62 | 63 | while (1) { 64 | w_keyboard_t * kbd = poll_keyboard(); 65 | if (kbd != NULL) { 66 | if (kbd->key == 'q') { 67 | break; 68 | } 69 | free(kbd); 70 | } 71 | } 72 | 73 | 74 | teardown_windowing(); 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /userspace/gui/demo/pixman-demo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "lib/window.h" 5 | #include "lib/graphics.h" 6 | 7 | int main(int argc, char * argv[]) { 8 | setup_windowing(); 9 | 10 | #define WIDTH 400 11 | #define HEIGHT 400 12 | #define TILE_SIZE 25 13 | 14 | window_t * window = window_create(100,100,WIDTH,HEIGHT); 15 | gfx_context_t * ctx = init_graphics_window(window); 16 | window_enable_alpha(window); 17 | draw_fill(ctx, rgba(0,0,0,255)); 18 | 19 | pixman_image_t *checkerboard; 20 | pixman_image_t *destination; 21 | #define D2F(d) (pixman_double_to_fixed(d)) 22 | pixman_transform_t trans = { { 23 | { D2F (-1.96830), D2F (-1.82250), D2F (512.12250)}, 24 | { D2F (0.00000), D2F (-7.29000), D2F (1458.00000)}, 25 | { D2F (0.00000), D2F (-0.00911), D2F (0.59231)}, 26 | }}; 27 | int i, j; 28 | 29 | checkerboard = pixman_image_create_bits (PIXMAN_a8r8g8b8, 30 | WIDTH, HEIGHT, 31 | NULL, 0); 32 | 33 | destination = pixman_image_create_bits (PIXMAN_a8r8g8b8, 34 | WIDTH, HEIGHT, 35 | NULL, 0); 36 | 37 | for (i = 0; i < HEIGHT / TILE_SIZE; ++i) 38 | { 39 | for (j = 0; j < WIDTH / TILE_SIZE; ++j) 40 | { 41 | double u = (double)(j + 1) / (WIDTH / TILE_SIZE); 42 | double v = (double)(i + 1) / (HEIGHT / TILE_SIZE); 43 | pixman_color_t black = { 0, 0, 0, 0xffff }; 44 | pixman_color_t white = { 45 | v * 0xffff, 46 | u * 0xffff, 47 | (1 - (double)u) * 0xffff, 48 | 0xffff }; 49 | pixman_color_t *c; 50 | pixman_image_t *fill; 51 | 52 | if ((j & 1) != (i & 1)) 53 | c = &black; 54 | else 55 | c = &white; 56 | 57 | fill = pixman_image_create_solid_fill (c); 58 | 59 | pixman_image_composite (PIXMAN_OP_SRC, fill, NULL, checkerboard, 60 | 0, 0, 0, 0, j * TILE_SIZE, i * TILE_SIZE, 61 | TILE_SIZE, TILE_SIZE); 62 | } 63 | } 64 | 65 | pixman_image_set_transform (checkerboard, &trans); 66 | pixman_image_set_filter (checkerboard, PIXMAN_FILTER_BEST, NULL, 0); 67 | pixman_image_set_repeat (checkerboard, PIXMAN_REPEAT_NONE); 68 | 69 | pixman_image_composite (PIXMAN_OP_SRC, 70 | checkerboard, NULL, destination, 71 | 0, 0, 0, 0, 0, 0, 72 | WIDTH, HEIGHT); 73 | 74 | printf("Going for native draw.\n"); 75 | 76 | uint32_t * buf = pixman_image_get_data(destination); 77 | memcpy(ctx->buffer,buf,WIDTH*HEIGHT*4); 78 | 79 | while (1) { 80 | w_keyboard_t * kbd = poll_keyboard(); 81 | if (kbd != NULL) { 82 | if (kbd->key == 'q') { 83 | break; 84 | } 85 | free(kbd); 86 | } 87 | } 88 | 89 | teardown_windowing(); 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /userspace/gui/ttk/ttk-demo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Toolkit Demo and Development Application 4 | * 5 | */ 6 | #include 7 | #include 8 | 9 | #include "gui/ttk/ttk.h" 10 | 11 | int main (int argc, char ** argv) { 12 | 13 | ttk_initialize(); 14 | ttk_window_t * main_window = ttk_window_new("TTK Demo", 500, 500); 15 | 16 | return ttk_run(main_window); 17 | } 18 | -------------------------------------------------------------------------------- /userspace/gui/ttk/ttk.h: -------------------------------------------------------------------------------- 1 | #ifndef _TTK_H 2 | #define _TTK_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include FT_FREETYPE_H 10 | #include FT_CACHE_H 11 | 12 | #include "lib/window.h" 13 | #include "lib/graphics.h" 14 | #include "lib/decorations.h" 15 | #include "lib/shmemfonts.h" 16 | 17 | typedef struct ttk_window { 18 | window_t * core_window; 19 | gfx_context_t * core_context; 20 | char * title; 21 | cairo_surface_t * cairo_surface; 22 | uint16_t width; /* internal space */ 23 | uint16_t height; 24 | uint16_t off_x; /* decor_left_width */ 25 | uint16_t off_y; /* decor_top_height */ 26 | } ttk_window_t; 27 | 28 | #define TTK_BACKGROUND_DEFAULT 204,204,204 29 | #define TTK_DEFAULT_X 300 30 | #define TTK_DEFAULT_Y 300 31 | 32 | void cairo_rounded_rectangle(cairo_t * cr, double x, double y, double width, double height, double radius); 33 | void ttk_redraw_borders(ttk_window_t * window); 34 | void _ttk_draw_button(cairo_t * cr, int x, int y, int width, int height); 35 | void _ttk_draw_button_hover(cairo_t * cr, int x, int y, int width, int height); 36 | void _ttk_draw_button_select(cairo_t * cr, int x, int y, int width, int height); 37 | void _ttk_draw_button_disabled(cairo_t * cr, int x, int y, int width, int height); 38 | void _ttk_draw_menu(cairo_t * cr, int x, int y, int width); 39 | void ttk_window_draw(ttk_window_t * window); 40 | void ttk_resize_callback(window_t * window); 41 | void ttk_focus_callback(window_t * window); 42 | void ttk_initialize(); 43 | ttk_window_t * ttk_window_new(char * title, uint16_t width, uint16_t height); 44 | void ttk_quit(); 45 | int ttk_run(ttk_window_t * window); 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /userspace/lib/decorations.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Decoration Library Headers 4 | * 5 | */ 6 | 7 | #ifndef DECORATIONS_H 8 | #define DECORATIONS_H 9 | 10 | #include "graphics.h" 11 | #include "window.h" 12 | 13 | uint32_t decor_top_height; 14 | uint32_t decor_bottom_height; 15 | uint32_t decor_left_width; 16 | uint32_t decor_right_width; 17 | 18 | /* 19 | * Render decorations to a window. A buffer pointer is 20 | * provided so that you may render in double-buffered mode. 21 | * 22 | * Run me at least once for each window, and any time you may need to 23 | * redraw them. 24 | */ 25 | void render_decorations(window_t * window, gfx_context_t * ctx, char * title); 26 | void render_decorations_inactive(window_t * window, gfx_context_t * ctx, char * title); 27 | 28 | /* 29 | * Run me once to set things up 30 | */ 31 | void init_decorations(); 32 | 33 | uint32_t decor_width(); 34 | uint32_t decor_height(); 35 | 36 | #endif /* DECORATION_H */ 37 | -------------------------------------------------------------------------------- /userspace/lib/graphics.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | #ifndef LIB_GRAPHICS_H 4 | #define LIB_GRAPHICS_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define GFX_W(ctx) ((ctx)->width) /* Display width */ 13 | #define GFX_H(ctx) ((ctx)->height) /* Display height */ 14 | #define GFX_B(ctx) ((ctx)->depth / 8) /* Display byte depth */ 15 | 16 | #define _RED(color) ((color & 0x00FF0000) / 0x10000) 17 | #define _GRE(color) ((color & 0x0000FF00) / 0x100) 18 | #define _BLU(color) ((color & 0x000000FF) / 0x1) 19 | #define _ALP(color) ((color & 0xFF000000) / 0x1000000) 20 | 21 | /* 22 | * Macros make verything easier. 23 | */ 24 | #define GFX(ctx,x,y) *((uint32_t *)&((ctx)->backbuffer)[(GFX_W(ctx) * (y) + (x)) * GFX_B(ctx)]) 25 | #define SPRITE(sprite,x,y) sprite->bitmap[sprite->width * (y) + (x)] 26 | #define SMASKS(sprite,x,y) sprite->masks[sprite->width * (y) + (x)] 27 | 28 | typedef struct sprite { 29 | uint16_t width; 30 | uint16_t height; 31 | uint32_t * bitmap; 32 | uint32_t * masks; 33 | uint32_t blank; 34 | uint8_t alpha; 35 | } sprite_t; 36 | 37 | typedef struct context { 38 | uint16_t width; 39 | uint16_t height; 40 | uint16_t depth; 41 | uint32_t size; 42 | char * buffer; 43 | char * backbuffer; 44 | } gfx_context_t; 45 | 46 | gfx_context_t * init_graphics_fullscreen(); 47 | gfx_context_t * init_graphics_fullscreen_double_buffer(); 48 | 49 | #define ALPHA_OPAQUE 0 50 | #define ALPHA_MASK 1 51 | #define ALPHA_EMBEDDED 2 52 | #define ALPHA_INDEXED 3 53 | 54 | uint32_t rgb(uint8_t r, uint8_t g, uint8_t b); 55 | uint32_t rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a); 56 | uint32_t alpha_blend(uint32_t bottom, uint32_t top, uint32_t mask); 57 | uint32_t alpha_blend_rgba(uint32_t bottom, uint32_t top); 58 | 59 | void flip(gfx_context_t * ctx); 60 | void clear_buffer(gfx_context_t * ctx); 61 | 62 | gfx_context_t * init_graphics_sprite(sprite_t * sprite); 63 | sprite_t * create_sprite(size_t width, size_t height, int alpha); 64 | 65 | void blur_context(gfx_context_t * _dst, gfx_context_t * _src, double amount); 66 | void sprite_free(sprite_t * sprite); 67 | 68 | void load_sprite(sprite_t * sprite, char * filename); 69 | int load_sprite_png(sprite_t * sprite, char * file); 70 | void draw_sprite(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_t y); 71 | void draw_line(gfx_context_t * ctx, int32_t x0, int32_t x1, int32_t y0, int32_t y1, uint32_t color); 72 | void draw_line_thick(gfx_context_t * ctx, int32_t x0, int32_t x1, int32_t y0, int32_t y1, uint32_t color, char thickness); 73 | void draw_fill(gfx_context_t * ctx, uint32_t color); 74 | 75 | void draw_sprite_scaled(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_t y, uint16_t width, uint16_t height); 76 | 77 | void context_to_png(FILE * file, gfx_context_t * ctx); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /userspace/lib/kbd.h: -------------------------------------------------------------------------------- 1 | #ifndef KBD_H 2 | #define KBD_H 3 | 4 | #define KBD_NORMAL 0 5 | #define KBD_ESC_A 1 6 | #define KBD_ESC_B 2 7 | #define KBD_FUNC 3 8 | 9 | #define KEY_NONE 0 10 | #define KEY_BACKSPACE 8 11 | #define KEY_CTRL_C 3 12 | #define KEY_CTRL_L 12 13 | #define KEY_CTRL_R 18 14 | #define KEY_ESCAPE 27 15 | #define KEY_NORMAL_MAX 256 16 | #define KEY_ARROW_UP 257 17 | #define KEY_ARROW_DOWN 258 18 | #define KEY_ARROW_RIGHT 259 19 | #define KEY_ARROW_LEFT 260 20 | #define KEY_BAD_STATE -1 21 | 22 | #define KEY_LEFT_CTRL 1001 23 | #define KEY_LEFT_SHIFT 1002 24 | #define KEY_LEFT_ALT 1003 25 | #define KEY_LEFT_SUPER 1004 26 | 27 | #define KEY_RIGHT_CTRL 1011 28 | #define KEY_RIGHT_SHIFT 1012 29 | #define KEY_RIGHT_ALT 1013 30 | #define KEY_RIGHT_SUPER 1014 31 | 32 | #define KEY_F1 2001 33 | #define KEY_F2 2002 34 | #define KEY_F3 2003 35 | #define KEY_F4 2004 36 | #define KEY_F5 2005 37 | #define KEY_F6 2006 38 | #define KEY_F7 2007 39 | #define KEY_F8 2008 40 | #define KEY_F9 2009 41 | #define KEY_F10 2010 42 | #define KEY_F11 2011 43 | #define KEY_F12 2012 44 | 45 | #define KEY_PAGE_DOWN 2013 46 | #define KEY_PAGE_UP 2014 47 | 48 | #define KEY_SCANCODE_F1 0x3b 49 | #define KEY_SCANCODE_F2 0x3c 50 | #define KEY_SCANCODE_F3 0x3d 51 | #define KEY_SCANCODE_F4 0x3e 52 | #define KEY_SCANCODE_F5 0x3f 53 | #define KEY_SCANCODE_F6 0x40 54 | #define KEY_SCANCODE_F7 0x41 55 | #define KEY_SCANCODE_F8 0x42 56 | #define KEY_SCANCODE_F9 0x43 57 | #define KEY_SCANCODE_F10 0x44 58 | #define KEY_SCANCODE_F11 0x57 59 | #define KEY_SCANCODE_F12 0x58 60 | 61 | #define KEY_MOD_LEFT_CTRL 0x01 62 | #define KEY_MOD_LEFT_SHIFT 0x02 63 | #define KEY_MOD_LEFT_ALT 0x04 64 | #define KEY_MOD_LEFT_SUPER 0x08 65 | 66 | #define KEY_MOD_RIGHT_CTRL 0x10 67 | #define KEY_MOD_RIGHT_SHIFT 0x20 68 | #define KEY_MOD_RIGHT_ALT 0x40 69 | #define KEY_MOD_RIGHT_SUPER 0x80 70 | 71 | #define KEY_ACTION_DOWN 0x01 72 | #define KEY_ACTION_UP 0x02 73 | 74 | typedef unsigned int kbd_key_t; 75 | typedef unsigned int kbd_mod_t; 76 | typedef unsigned char kbd_act_t; 77 | 78 | typedef struct { 79 | kbd_key_t keycode; 80 | kbd_mod_t modifiers; 81 | kbd_act_t action; 82 | 83 | unsigned char key; /* Key as a raw code, ready for reading, or \0 if it's not a good down strike / was a modifier change / etc/. */ 84 | } key_event_t; 85 | 86 | int k_ctrl; 87 | int k_shift; 88 | int k_alt; 89 | int k_super; 90 | 91 | int kl_ctrl; 92 | int kl_shift; 93 | int kl_alt; 94 | int kl_super; 95 | 96 | int kr_ctrl; 97 | int kr_shift; 98 | int kr_alt; 99 | int kr_super; 100 | 101 | kbd_key_t kbd_key(unsigned char c); 102 | int kbd_state; 103 | int kbd_scancode(unsigned char c, key_event_t * event); 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /userspace/lib/ldlib.c: -------------------------------------------------------------------------------- 1 | #include "ldlib.h" 2 | 3 | -------------------------------------------------------------------------------- /userspace/lib/ldlib.h: -------------------------------------------------------------------------------- 1 | #ifndef LDLIB_H 2 | #define LDLIB_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /userspace/lib/list.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * General-purpose list implementations. 4 | */ 5 | #include 6 | #include "list.h" 7 | 8 | void list_destroy(list_t * list) { 9 | /* Free all of the contents of a list */ 10 | node_t * n = list->head; 11 | while (n) { 12 | free(n->value); 13 | n = n->next; 14 | } 15 | } 16 | 17 | void list_free(list_t * list) { 18 | /* Free the actual structure of a list */ 19 | node_t * n = list->head; 20 | while (n) { 21 | node_t * s = n->next; 22 | free(n); 23 | n = s; 24 | } 25 | } 26 | 27 | void list_append(list_t * list, node_t * node) { 28 | /* Insert a node onto the end of a list */ 29 | if (!list->tail) { 30 | list->head = node; 31 | } else { 32 | list->tail->next = node; 33 | node->prev = list->tail; 34 | } 35 | list->tail = node; 36 | list->length++; 37 | } 38 | 39 | void list_insert(list_t * list, void * item) { 40 | /* Insert an item into a list */ 41 | node_t * node = malloc(sizeof(node_t)); 42 | node->value = item; 43 | node->next = NULL; 44 | node->prev = NULL; 45 | list_append(list, node); 46 | } 47 | 48 | list_t * list_create() { 49 | /* Create a fresh list */ 50 | list_t * out = malloc(sizeof(list_t)); 51 | out->head = NULL; 52 | out->tail = NULL; 53 | out->length = 0; 54 | return out; 55 | } 56 | 57 | node_t * list_find(list_t * list, void * value) { 58 | foreach(item, list) { 59 | if (item->value == value) { 60 | return item; 61 | } 62 | } 63 | return NULL; 64 | } 65 | 66 | void list_remove(list_t * list, size_t index) { 67 | /* remove index from the list */ 68 | if (index > list->length) return; 69 | size_t i = 0; 70 | node_t * n = list->head; 71 | while (i < index) { 72 | n = n->next; 73 | i++; 74 | } 75 | list_delete(list, n); 76 | } 77 | 78 | void list_delete(list_t * list, node_t * node) { 79 | /* remove node from the list */ 80 | if (node == list->head) { 81 | list->head = node->next; 82 | } 83 | if (node == list->tail) { 84 | list->tail = node->prev; 85 | } 86 | if (node->prev) { 87 | node->prev->next = node->next; 88 | } 89 | if (node->next) { 90 | node->next->prev = node->prev; 91 | } 92 | list->length--; 93 | } 94 | 95 | node_t * list_pop(list_t * list) { 96 | /* Remove and return the last value in the list 97 | * If you don't need it, you still probably want to free it! 98 | * Try free(list_pop(list)); ! 99 | * */ 100 | if (!list->tail) return NULL; 101 | node_t * out = list->tail; 102 | list_delete(list, list->tail); 103 | return out; 104 | } 105 | 106 | node_t * list_dequeue(list_t * list) { 107 | if (!list->head) return NULL; 108 | node_t * out = list->head; 109 | list_delete(list, list->head); 110 | return out; 111 | } 112 | 113 | list_t * list_copy(list_t * original) { 114 | /* Create a new copy of original */ 115 | list_t * out = list_create(); 116 | node_t * node = original->head; 117 | while (node) { 118 | list_insert(out, node->value); 119 | } 120 | return out; 121 | } 122 | 123 | void list_merge(list_t * target, list_t * source) { 124 | /* Destructively merges source into target */ 125 | if (target->tail) { 126 | target->tail->next = source->head; 127 | } else { 128 | target->head = source->head; 129 | } 130 | if (source->tail) { 131 | target->tail = source->tail; 132 | } 133 | target->length += source->length; 134 | free(source); 135 | } 136 | -------------------------------------------------------------------------------- /userspace/lib/list.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * General-purpose list implementations. 4 | */ 5 | #ifndef LIST_H 6 | #define LIST_H 7 | 8 | #include 9 | 10 | typedef struct node { 11 | struct node * next; 12 | struct node * prev; 13 | void * value; 14 | } __attribute__((packed)) node_t; 15 | 16 | typedef struct { 17 | node_t * head; 18 | node_t * tail; 19 | size_t length; 20 | } __attribute__((packed)) list_t; 21 | 22 | void list_destroy(list_t * list); 23 | void list_free(list_t * list); 24 | void list_append(list_t * list, node_t * item); 25 | void list_insert(list_t * list, void * item); 26 | list_t * list_create(); 27 | node_t * list_find(list_t * list, void * value); 28 | void list_remove(list_t * list, size_t index); 29 | void list_delete(list_t * list, node_t * node); 30 | node_t * list_pop(list_t * list); 31 | node_t * list_dequeue(list_t * list); 32 | list_t * list_copy(list_t * original); 33 | void list_merge(list_t * target, list_t * source); 34 | 35 | #define foreach(i, list) for (node_t * i = list->head; i != NULL; i = i->next) 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /userspace/lib/pthread.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pthread.h" 5 | 6 | #define PTHREAD_STACK_SIZE 10240 7 | 8 | int clone(uintptr_t a,uintptr_t b,void* c) { 9 | return syscall_clone(a,b,c); 10 | } 11 | int gettid() { 12 | return syscall_gettid(); 13 | } 14 | 15 | int pthread_create(pthread_t * thread, pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) { 16 | char * stack = malloc(PTHREAD_STACK_SIZE); 17 | uintptr_t stack_top = (uintptr_t)stack + PTHREAD_STACK_SIZE; 18 | thread->stack = stack; 19 | thread->id = clone(stack_top, (uintptr_t)start_routine, arg); 20 | return 0; 21 | } 22 | 23 | void pthread_exit(void * value) { 24 | /* Perform nice cleanup */ 25 | #if 0 26 | /* XXX: LOCK */ 27 | free(stack); 28 | /* XXX: Return value!? */ 29 | #endif 30 | __asm__ ("jmp 0xFFFFB00F"); /* Force thread exit */ 31 | } 32 | -------------------------------------------------------------------------------- /userspace/lib/pthread.h: -------------------------------------------------------------------------------- 1 | #ifndef PTHREAD_H 2 | #define PTHREAD_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct { 8 | uint32_t id; 9 | char * stack; 10 | void * ret_val; 11 | } pthread_t; 12 | typedef unsigned int pthread_attr_t; 13 | 14 | int pthread_create(pthread_t * thread, pthread_attr_t * attr, void *(*start_routine)(void *), void * arg); 15 | void pthread_exit(void * value); 16 | 17 | int clone(uintptr_t,uintptr_t,void*); 18 | int gettid(); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /userspace/lib/shmemfonts.h: -------------------------------------------------------------------------------- 1 | #ifndef SHMEMFONTS_H 2 | #define SHMEMFONTS_H 3 | 4 | #include "graphics.h" 5 | #include "window.h" 6 | 7 | void init_shmemfonts(); 8 | void draw_string(gfx_context_t * ctx, int x, int y, uint32_t fg, char * string); 9 | uint32_t draw_string_width(char * string); 10 | void draw_string_shadow(gfx_context_t * ctx, int x, int y, uint32_t fg, char * string, uint32_t shadow_color, int darkness, int offset_x, int offset_y, double radius); 11 | void set_font_size(int size); 12 | void set_text_opacity(float new_opacity); 13 | void set_font_face(int face_num); 14 | char * shmem_font_name(int i); 15 | 16 | #define FONT_SANS_SERIF 0 17 | #define FONT_SANS_SERIF_BOLD 1 18 | #define FONT_SANS_SERIF_ITALIC 2 19 | #define FONT_SANS_SERIF_BOLD_ITALIC 3 20 | #define FONT_MONOSPACE 4 21 | #define FONT_MONOSPACE_BOLD 5 22 | #define FONT_MONOSPACE_ITALIC 6 23 | #define FONT_MONOSPACE_BOLD_ITALIC 7 24 | #define FONT_JAPANESE 8 25 | 26 | #define FONTS_TOTAL 9 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /userspace/lib/syscall.h: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | */ 3 | #ifndef LIB_GRAPHICS_H 4 | #define LIB_GRAPHICS_H 5 | 6 | 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /userspace/lib/utf8decode.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2008-2009 Bjoern Hoehrmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | */ 23 | 24 | #ifndef UTF_DECODER_H 25 | #define UTF_DECODER_H 26 | 27 | #include 28 | 29 | #define UTF8_ACCEPT 0 30 | #define UTF8_REJECT 1 31 | 32 | static const uint8_t utf8d[] = { 33 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f 34 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f 35 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f 36 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f 37 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f 38 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf 39 | 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df 40 | 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef 41 | 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff 42 | 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 43 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 44 | 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 45 | 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 46 | 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 47 | }; 48 | 49 | static uint32_t inline 50 | decode(uint32_t* state, uint32_t* codep, uint32_t byte) { 51 | uint32_t type = utf8d[byte]; 52 | 53 | *codep = (*state != UTF8_ACCEPT) ? 54 | (byte & 0x3fu) | (*codep << 6) : 55 | (0xff >> type) & (byte); 56 | 57 | *state = utf8d[256 + *state*16 + type]; 58 | return *state; 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /userspace/lib/wcwidth.h: -------------------------------------------------------------------------------- 1 | #ifndef MK_WCWIDTH 2 | #define MK_WCWIDTH 3 | 4 | int mk_wcwidth_cjk(wchar_t ucs); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /userspace/tests/core-tests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define INFO(...) notice("INFO", __VA_ARGS__) 6 | #define WARN(...) notice("WARN", __VA_ARGS__) 7 | #define DONE(...) notice("DONE", __VA_ARGS__) 8 | #define PASS(...) notice("PASS", __VA_ARGS__) 9 | #define FAIL(...) notice("FAIL", __VA_ARGS__) 10 | #define FATAL(...) notice("FATAL", __VA_ARGS__) 11 | 12 | void notice(char * type, char * fmt, ...) { 13 | va_list argp; 14 | va_start(argp, fmt); 15 | /* core-tests header */ 16 | syscall_print("core-tests : "); 17 | syscall_print(type); 18 | syscall_print(" : "); 19 | /* end core-tests header */ 20 | char buffer[1024]; 21 | vsnprintf(buffer, 1024, fmt, argp); 22 | syscall_print(buffer); 23 | syscall_print("\n"); 24 | } 25 | 26 | int main(int argc, char * argv[]) { 27 | INFO("Hello world!"); 28 | 29 | DONE("Finished tests!"); 30 | } 31 | -------------------------------------------------------------------------------- /userspace/tests/test-argv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Argument processing test tool. 3 | * 4 | * Usage: 5 | * Run as ./argv-tester herp derp etc. 6 | * Evaluate the arguments as they are printed to verify 7 | * they match the input that you provided. 8 | */ 9 | #include 10 | 11 | int main(int argc, char * argv[]) { 12 | printf("argc = %d\n", argc); 13 | for (int i = 0; i < argc; ++i) { 14 | printf("%p argv[%d]= %s\n", argv[i], i, argv[i]); 15 | } 16 | printf("continuing until I hit a 0\n"); 17 | int i = argc; 18 | while (1) { 19 | printf("argv[%d] = 0x%x\n", i, argv[i]); 20 | if (argv[i] == 0) { 21 | break; 22 | } 23 | i++; 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /userspace/tests/test-blur.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "lib/window.h" 4 | #include "lib/graphics.h" 5 | #include "lib/shmemfonts.h" 6 | 7 | gfx_context_t * ctx; 8 | window_t * window; 9 | 10 | #define INPUT_SIZE 512 11 | char input_buffer[INPUT_SIZE] = {0}; 12 | int input_collected = 0; 13 | 14 | void display() { 15 | gfx_context_t * tmp_c, * out_c; 16 | sprite_t * tmp_s, * out_s; 17 | 18 | tmp_s = create_sprite(window->width, window->height, ALPHA_EMBEDDED); 19 | tmp_c = init_graphics_sprite(tmp_s); 20 | 21 | out_s = create_sprite(window->width, window->height, ALPHA_EMBEDDED); 22 | out_c = init_graphics_sprite(out_s); 23 | 24 | draw_fill(tmp_c, rgba(0,0,0,0)); 25 | draw_string(tmp_c, 20, 20, rgb(0,0,0), input_buffer); 26 | 27 | blur_context(out_c, tmp_c, 3); 28 | 29 | draw_string(out_c, 19, 19, rgb(255,255,255), input_buffer); 30 | 31 | draw_fill(ctx, rgba(0,0,0,0)); 32 | 33 | draw_sprite(ctx, out_s, 0, 0); 34 | 35 | draw_sprite(ctx, out_s, 0, 20); 36 | draw_sprite(ctx, out_s, 0, 20); 37 | 38 | draw_sprite(ctx, out_s, 0, 40); 39 | draw_sprite(ctx, out_s, 0, 40); 40 | draw_sprite(ctx, out_s, 0, 40); 41 | 42 | draw_sprite(ctx, out_s, 0, 60); 43 | draw_sprite(ctx, out_s, 0, 60); 44 | draw_sprite(ctx, out_s, 0, 60); 45 | draw_sprite(ctx, out_s, 0, 60); 46 | 47 | sprite_free(tmp_s); 48 | free(tmp_c); 49 | 50 | sprite_free(out_s); 51 | free(out_c); 52 | 53 | flip(ctx); 54 | } 55 | 56 | void resize_callback(window_t * win) { 57 | reinit_graphics_window(ctx, window); 58 | 59 | display(); 60 | } 61 | 62 | int buffer_put(char c) { 63 | if (c == 8) { 64 | /* Backspace */ 65 | if (input_collected > 0) { 66 | input_collected--; 67 | input_buffer[input_collected] = '\0'; 68 | } 69 | return 0; 70 | } 71 | if (c < 10 || (c > 10 && c < 32) || c > 126) { 72 | return 0; 73 | } 74 | input_buffer[input_collected] = c; 75 | input_collected++; 76 | input_buffer[input_collected] = '\0'; 77 | if (input_collected == INPUT_SIZE - 1) { 78 | return 1; 79 | } 80 | return 0; 81 | } 82 | 83 | int main(int argc, char * argv[]) { 84 | setup_windowing(); 85 | 86 | resize_window_callback = resize_callback; 87 | window = window_create(40, 40, 200, 120); 88 | ctx = init_graphics_window_double_buffer(window); 89 | 90 | window_enable_alpha(window); 91 | 92 | init_shmemfonts(); 93 | 94 | buffer_put('$'); 95 | display(); 96 | 97 | int playing = 1; 98 | while (playing) { 99 | 100 | char ch = 0; 101 | w_keyboard_t * kbd; 102 | do { 103 | kbd = poll_keyboard(); 104 | if (kbd != NULL) { 105 | if ((kbd->event.modifiers & KEY_MOD_LEFT_ALT) && (kbd->event.keycode == KEY_F4)) { 106 | playing = 0; 107 | break; 108 | } 109 | if (kbd->key) { 110 | buffer_put(kbd->key); 111 | display(); 112 | } 113 | free(kbd); 114 | } 115 | } while (kbd != NULL); 116 | } 117 | 118 | teardown_windowing(); 119 | 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /userspace/tests/test-borders.c: -------------------------------------------------------------------------------- 1 | /* 2 | * view 3 | * 4 | * Displays bitmap images in windows 5 | */ 6 | #include 7 | 8 | #include "lib/window.h" 9 | #include "lib/graphics.h" 10 | #include "lib/shmemfonts.h" 11 | 12 | int u_height = 33; 13 | int ul_width = 10; 14 | int ur_width = 10; 15 | 16 | int ml_width = 6; 17 | int mr_width = 6; 18 | 19 | int l_height = 9; 20 | int ll_width = 9; 21 | int lr_width = 9; 22 | 23 | int llx_offset = 3; 24 | int lly_offset = 3; 25 | int lrx_offset = 3; 26 | int lry_offset = 3; 27 | 28 | int border_top = 33; 29 | int border_bottom = 6; 30 | int border_left = 6; 31 | int border_right = 6; 32 | 33 | #define TEXT_OFFSET 24 34 | 35 | window_t * wina; 36 | sprite_t * sprites[8]; 37 | gfx_context_t * ctx; 38 | 39 | int width = 700; 40 | int height = 500; 41 | 42 | void init_sprite_png(int id, char * path) { 43 | sprites[id] = malloc(sizeof(sprite_t)); 44 | load_sprite_png(sprites[id], path); 45 | } 46 | 47 | char * title = "テストアプリケーション Test Application ☃"; 48 | 49 | void redraw_borders() { 50 | draw_sprite(ctx, sprites[0], 0, 0); 51 | for (int i = 0; i < width - (ul_width + ur_width); ++i) { 52 | draw_sprite(ctx, sprites[1], i + ul_width, 0); 53 | } 54 | draw_sprite(ctx, sprites[2], width - ur_width, 0); 55 | for (int i = 0; i < height - (u_height + l_height); ++i) { 56 | draw_sprite(ctx, sprites[3], 0, i + u_height); 57 | draw_sprite(ctx, sprites[4], width - mr_width, i + u_height); 58 | } 59 | draw_sprite(ctx, sprites[5], 0, height - l_height); 60 | for (int i = 0; i < width - (ll_width + lr_width); ++i) { 61 | draw_sprite(ctx, sprites[6], i + ll_width, height - l_height); 62 | } 63 | draw_sprite(ctx, sprites[7], width - lr_width, height - l_height); 64 | 65 | set_font_face(FONT_SANS_SERIF_BOLD); 66 | set_font_size(12); 67 | 68 | int title_offset = (width / 2) - (draw_string_width(title) / 2); 69 | draw_string(ctx, title_offset, TEXT_OFFSET, rgb(226,226,226), title); 70 | 71 | } 72 | 73 | void redraw_interior() { 74 | for (int i = border_top; i < height - (border_bottom); ++i) { 75 | draw_line(ctx, border_left, width - border_right - 1, i, i, rgb(240,240,240)); 76 | } 77 | } 78 | 79 | void resize_callback(window_t * window) { 80 | width = window->width; 81 | height = window->height; 82 | reinit_graphics_window(ctx, wina); 83 | draw_fill(ctx, rgba(0,0,0,0)); 84 | redraw_borders(); 85 | redraw_interior(); 86 | } 87 | 88 | int main (int argc, char ** argv) { 89 | 90 | int left = 30; 91 | int top = 30; 92 | 93 | init_sprite_png(0, "/usr/share/ttk/active/ul.png"); 94 | init_sprite_png(1, "/usr/share/ttk/active/um.png"); 95 | init_sprite_png(2, "/usr/share/ttk/active/ur.png"); 96 | init_sprite_png(3, "/usr/share/ttk/active/ml.png"); 97 | init_sprite_png(4, "/usr/share/ttk/active/mr.png"); 98 | init_sprite_png(5, "/usr/share/ttk/active/ll.png"); 99 | init_sprite_png(6, "/usr/share/ttk/active/lm.png"); 100 | init_sprite_png(7, "/usr/share/ttk/active/lr.png"); 101 | 102 | setup_windowing(); 103 | resize_window_callback = resize_callback; 104 | 105 | init_shmemfonts(); 106 | 107 | /* Do something with a window */ 108 | wina = window_create(left, top, width, height); 109 | ctx = init_graphics_window(wina); 110 | 111 | draw_fill(ctx, rgba(0,0,0,0)); 112 | window_enable_alpha(wina); 113 | 114 | redraw_borders(); 115 | redraw_interior(); 116 | 117 | while (1) { 118 | w_keyboard_t * kbd = poll_keyboard(); 119 | if (kbd != NULL) { 120 | if (kbd->key == 'q') { 121 | break; 122 | } 123 | free(kbd); 124 | } 125 | } 126 | 127 | teardown_windowing(); 128 | 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /userspace/tests/test-cpp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | cout << "hello world!\n"; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /userspace/tests/test-dsr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (int argc, char * argv) { 4 | printf("I'm going to move the cursor here >"); 5 | fflush(stdout); 6 | printf("\033[6n"); 7 | fflush(stdout); 8 | int x, y; 9 | scanf("\033[%d;%dR", &y, &x); 10 | printf("\n\nThe cursor was at %d, %d\n", x, y); 11 | printf("I will now put ◯ where the cursor was.\n"); 12 | char derp[1]; 13 | gets(derp); 14 | printf("\033[%d;%dH◯\n\n\n\n", y, x); 15 | 16 | printf("Done!\n"); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /userspace/tests/test-echo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * echo-test 3 | * 4 | * Prints a test string to standard out 5 | * that includes various bits of ANSI 6 | * escape sequences. 7 | */ 8 | #include 9 | 10 | int main(int argc, char ** argv) { 11 | 12 | printf("\n\033[1mBold \033[0m\033[3mItalic \033[1mBold+Italic\033[0m\033[0m \033[4mUnderline\033[0m \033[9mX-Out\033[0m \033[1;3;4;9mEverything\033[0m\n"); 13 | 14 | return 0; 15 | } 16 | 17 | /* 18 | * vim:tabstop=4 19 | * vim:noexpandtab 20 | * vim:shiftwidth=4 21 | */ 22 | -------------------------------------------------------------------------------- /userspace/tests/test-env.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char * argv) { 5 | printf("hello world\n"); 6 | char * term = getenv("TERM"); 7 | if (term) { 8 | printf("TERM=%s\n", term); 9 | } else { 10 | printf("TERM is not set.\n"); 11 | } 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /userspace/tests/test-fs.c: -------------------------------------------------------------------------------- 1 | /* vim:tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * File System Test Suite 4 | * (incomplete) 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char ** argv) { 11 | printf("= Begin File System Testing =\n"); 12 | 13 | int fd = creat("/test.log", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 14 | 15 | printf("File descriptor generator: %d\n", fd); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /userspace/tests/test-gfx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * test-gfx 3 | * 4 | * Windowed graphical test application. 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | #include "lib/window.h" 11 | #include "lib/graphics.h" 12 | #include "lib/decorations.h" 13 | 14 | sprite_t * sprites[128]; 15 | sprite_t alpha_tmp; 16 | window_t * wina; 17 | 18 | uint16_t win_width; 19 | uint16_t win_height; 20 | 21 | gfx_context_t * ctx; 22 | 23 | int center_x(int x) { 24 | return (win_width - x) / 2; 25 | } 26 | 27 | int center_y(int y) { 28 | return (win_height - y) / 2; 29 | } 30 | 31 | void init_sprite(int i, char * filename, char * alpha) { 32 | sprites[i] = malloc(sizeof(sprite_t)); 33 | load_sprite(sprites[i], filename); 34 | if (alpha) { 35 | sprites[i]->alpha = 1; 36 | load_sprite(&alpha_tmp, alpha); 37 | sprites[i]->masks = alpha_tmp.bitmap; 38 | } else { 39 | sprites[i]->alpha = 0; 40 | } 41 | sprites[i]->blank = 0x0; 42 | } 43 | 44 | void darken(gfx_context_t * ctx) { 45 | for (uint16_t y = 0; y < ctx->height; ++y) { 46 | for (uint16_t x = 0; x < ctx->width; ++x) { 47 | GFX(ctx, x, y) = alpha_blend(GFX(ctx,x,y), rgb(0,0,0), rgb(1,0,0)); 48 | } 49 | } 50 | } 51 | 52 | void resize_callback(window_t * window) { 53 | win_width = window->width; 54 | win_height = window->height; 55 | reinit_graphics_window(ctx, wina); 56 | draw_fill(ctx, rgb(0,0,0)); 57 | } 58 | 59 | int main (int argc, char ** argv) { 60 | setup_windowing(); 61 | resize_window_callback = resize_callback; 62 | 63 | int width = 600; 64 | int height = 400; 65 | 66 | win_width = width; 67 | win_height = height; 68 | 69 | init_decorations(); 70 | 71 | 72 | /* Do something with a window */ 73 | wina = window_create(300, 300, width, height); 74 | assert(wina); 75 | ctx = init_graphics_window_double_buffer(wina); 76 | 77 | draw_fill(ctx, rgb(0,0,0)); 78 | flip(ctx); 79 | 80 | init_sprite(1, "/usr/share/bs.bmp", "/usr/share/bs-alpha.bmp"); 81 | 82 | flip(ctx); 83 | 84 | 85 | uint32_t i = 0; 86 | 87 | while (1) { 88 | ++i; 89 | double herp = cos((double)i * 0.01) + 1.5; 90 | double derp = sin((double)i * 0.01) + 1.5; 91 | char ch = 0; 92 | w_keyboard_t * kbd = poll_keyboard_async(); 93 | if (kbd) { 94 | ch = kbd->key; 95 | free(kbd); 96 | if (ch == 'q') { 97 | goto done; 98 | break; 99 | } 100 | } 101 | darken(ctx); 102 | draw_sprite_scaled(ctx, sprites[1], center_x(sprites[1]->width * herp), center_y(sprites[1]->height * derp), sprites[1]->width * herp, sprites[1]->height * derp); 103 | render_decorations(wina, ctx, "Graphics Test"); 104 | flip(ctx); 105 | } 106 | done: 107 | 108 | #if 1 109 | teardown_windowing(); 110 | #endif 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /userspace/tests/test-multitasking.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 noexpandtab shiftwidth=4 2 | * 3 | * Multitasking Thrasher 4 | * 5 | * Useful for testing that multitasking still works. 6 | * Starts up a bunch of threads, lets them do stuff, 7 | * cleans them up, etc. 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | int main(int argc, char ** argv) { 19 | int nthreads = 2, base_pid = getpid(), npid = -1; 20 | 21 | if (argc > 1) { 22 | /* Read some arguments */ 23 | int c; 24 | while ((c = getopt(argc, argv, "n:")) != -1) { 25 | switch (c) { 26 | case 'n': 27 | nthreads = atoi(optarg); 28 | break; 29 | default: 30 | break; 31 | } 32 | } 33 | } 34 | 35 | printf("I am pid %d\n", base_pid); 36 | printf("Starting %d threads.\n", nthreads); 37 | 38 | for (int i = 0; i < nthreads; ++i) { 39 | int pid = fork(); 40 | if (!pid) { 41 | while (1) { 42 | printf("%c", i + 'A'); 43 | fflush(stdout); 44 | } 45 | } else { 46 | npid = pid; 47 | } 48 | } 49 | 50 | printf("Done.\n"); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /userspace/tests/test-pipe.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * pipe test 3 | * 4 | * Makes a pipe. Pipes stuff to it. Yeah. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc, char ** argv) { 15 | int fd = syscall_mkpipe(); 16 | printf("%d <- pipe\n", fd); 17 | int pid = getpid(); 18 | uint32_t f = fork(); 19 | if (getpid() != pid) { 20 | char buf[512]; 21 | int r = read(fd, buf, 13); 22 | printf("[%d] %s\n", r, buf); 23 | return 0; 24 | } else { 25 | char * buf = "Hello world!"; 26 | write(fd, buf, strlen(buf) + 1); 27 | return 0; 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /userspace/tests/test-threads.c: -------------------------------------------------------------------------------- 1 | /* 2 | * threadtest 3 | * 4 | * A class concurreny failure demonstration. 5 | * Append -l to use locks. 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lib/pthread.h" 14 | 15 | #define NUM_THREADS 5 16 | #define VALUE 0x1000000 17 | #define CHECKPOINT 0x03FFFFF 18 | 19 | volatile uint32_t result = 0; 20 | int8_t use_locks = 0; 21 | 22 | volatile uint8_t the_lock = 0; 23 | 24 | void spin_lock(uint8_t volatile * lock) { 25 | while(__sync_lock_test_and_set(lock, 0x01)) { 26 | ;; /* oh god */ 27 | } 28 | } 29 | 30 | void spin_unlock(uint8_t volatile * lock) { 31 | __sync_lock_release(lock); 32 | } 33 | 34 | void *print_pid(void * garbage) { 35 | int i; 36 | printf("I am a thread and my pid is %d but my tid is %d and my stack is at %p\n", getpid(), gettid(), &i); 37 | 38 | for (uint32_t i = 0; i < VALUE; ++i) { 39 | if (use_locks) { 40 | spin_lock(&the_lock); 41 | } 42 | if (!(result & CHECKPOINT)) { 43 | printf("[%d] Checkpoint: %x\n", gettid(), result); 44 | } 45 | result++; 46 | if (use_locks) { 47 | spin_unlock(&the_lock); 48 | } 49 | } 50 | 51 | pthread_exit(garbage); 52 | } 53 | 54 | int main(int argc, char * argv[]) { 55 | if (argc > 1) { 56 | if (!strcmp(argv[1], "-l")) { 57 | use_locks = 1; 58 | } 59 | } 60 | pthread_t thread[NUM_THREADS]; 61 | printf("I am the main process and my pid is %d and my tid is also %d\n", getpid(), gettid()); 62 | 63 | printf("Attempting to %s calculate %d!\n", 64 | (use_locks) ? "(safely)" : "(unsafely)", 65 | NUM_THREADS * VALUE); 66 | 67 | for (int i = 0; i < NUM_THREADS; ++i) { 68 | pthread_create(&thread[i], NULL, print_pid, NULL); 69 | } 70 | 71 | for (int i = 0; i < NUM_THREADS; ++i) { 72 | syscall_wait(thread[i].id); 73 | } 74 | 75 | printf("Done. Result of %scomputation was %d %s!!\n", 76 | (use_locks) ? "" : "(definitely unsafe) ", 77 | result, 78 | (result == NUM_THREADS * VALUE) ? "(yay, that's right!)" : "(boo, that's wrong!)"); 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /userspace/util/stack-overflow.c: -------------------------------------------------------------------------------- 1 | /* vim: tabstop=4 shiftwidth=4 noexpandtab 2 | * 3 | * Sample application which triggers a stack overflow 4 | * by means of a simple infinitely recursive function. 5 | */ 6 | #include 7 | #include 8 | 9 | void overflow() { 10 | int i[1024] = {0xff}; 11 | printf("Stack is at 0x%x\n", &i); 12 | overflow(); 13 | } 14 | 15 | int main(int argc, char ** argv) { 16 | overflow(); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /userspace/util/stack-reaper.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char ** argv) { 4 | printf("Exploring the stack...\n"); 5 | unsigned int x = 0; 6 | unsigned int nulls = 0; 7 | while (1) { 8 | if (!argv[x]) { ++nulls; } 9 | printf("argv[%.2d] = [%p] %s\n", x, argv[x], argv[x]); 10 | ++x; 11 | if (nulls == 2) { break; } 12 | } 13 | printf("[ELF AuxV]\n"); 14 | while (1) { 15 | printf("auxv[%.2d] = %.2d -> 0x%x\n", x, (unsigned int)argv[x], (unsigned int)argv[x+1]); 16 | if (argv[x] == 0) { break; } /* AT_NULL, technically, but that's 0 */ 17 | x += 2; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /userspace/util/term_size.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char * argv[]) { 4 | printf("\033[1003z"); 5 | fflush(stdout); 6 | int width, height; 7 | scanf("%d,%d", &width, &height); 8 | printf("Terminal is %dx%d\n", width, height); 9 | } 10 | -------------------------------------------------------------------------------- /userspace/util/thrash-process.c: -------------------------------------------------------------------------------- 1 | /* 2 | * thrash-process 3 | * Creates a lot of processes. 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int main(int argc, char ** argv) { 13 | int quiet = 0; 14 | if (argc > 1) { 15 | if (!strcmp(argv[1],"-q")) { 16 | printf("I'll be quiet...\n"); 17 | quiet = 1; 18 | } 19 | } 20 | for (int j = 0; j < 1024; ++j) { 21 | volatile int k = fork(); 22 | if (!quiet) 23 | printf("I am %d, I got %d\n", getpid(), k); 24 | if (k == 0) { 25 | if (!quiet || !(j % 10)) 26 | printf("I am %d\n", getpid()); 27 | return 0; 28 | } else { 29 | if (!quiet) 30 | printf("Waiting on %d\n", k); 31 | syscall_wait(k); 32 | } 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /util/256colres.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl 2 | # $XTermId: 256colres.pl,v 1.16 2007/06/08 23:58:37 tom Exp $ 3 | # ----------------------------------------------------------------------------- 4 | # this file is part of xterm 5 | # 6 | # Copyright 1999-2002,2007 by Thomas E. Dickey 7 | # 8 | # All Rights Reserved 9 | # 10 | # Permission is hereby granted, free of charge, to any person obtaining a 11 | # copy of this software and associated documentation files (the 12 | # "Software"), to deal in the Software without restriction, including 13 | # without limitation the rights to use, copy, modify, merge, publish, 14 | # distribute, sublicense, and/or sell copies of the Software, and to 15 | # permit persons to whom the Software is furnished to do so, subject to 16 | # the following conditions: 17 | # 18 | # The above copyright notice and this permission notice shall be included 19 | # in all copies or substantial portions of the Software. 20 | # 21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 | # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 25 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name(s) of the above copyright 30 | # holders shall not be used in advertising or otherwise to promote the 31 | # sale, use or other dealings in this Software without prior written 32 | # authorization. 33 | # ----------------------------------------------------------------------------- 34 | 35 | # Construct a header file defining default resources for the 256-color model 36 | # of xterm. This is modeled after the 256colors2.pl script. 37 | 38 | # use the resources for colors 0-15 - usually more-or-less a 39 | # reproduction of the standard ANSI colors, but possibly more 40 | # pleasing shades 41 | 42 | # Modified by Kevin Lange for use in the ToAruOS Kernel video 43 | # terminal drivers (for compatibility with the xterm 256 color palette) 44 | 45 | use strict; 46 | 47 | our ( $line1, $line2, $line3 ); 48 | our ( $red, $green, $blue, $gray ); 49 | our ( $level, $code, @steps ); 50 | 51 | $line3="\t\t\t\t 0x%2.2x%2.2x%2.2x,\n"; 52 | 53 | # colors 16-231 are a 6x6x6 color cube 54 | for ($red = 0; $red < 6; $red++) { 55 | for ($green = 0; $green < 6; $green++) { 56 | for ($blue = 0; $blue < 6; $blue++) { 57 | $code = 16 + ($red * 36) + ($green * 6) + $blue; 58 | printf($line3, 59 | ($red ? ($red * 40 + 55) : 0), 60 | ($green ? ($green * 40 + 55) : 0), 61 | ($blue ? ($blue * 40 + 55) : 0)); 62 | } 63 | } 64 | } 65 | 66 | # colors 232-255 are a grayscale ramp, intentionally leaving out 67 | # black and white 68 | $code=232; 69 | for ($gray = 0; $gray < 24; $gray++) { 70 | $level = ($gray * 10) + 8; 71 | $code = 232 + $gray; 72 | printf($line3, 73 | $level, $level, $level); 74 | } 75 | -------------------------------------------------------------------------------- /util/bin/.git-marker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevej/osdev/9b745b5de0ba198d3ba245de62453012f346d5af/util/bin/.git-marker -------------------------------------------------------------------------------- /util/check-reqs: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Build Dependencies Checker 3 | # ToAruOS Kernel / Userspace 4 | 5 | function INFO { 6 | echo -e "\033[34;1minfo\033[0m $1" >&2 7 | } 8 | 9 | function WARN { 10 | echo -e "\033[33;1mwarning\033[0m $1" >&2 11 | } 12 | 13 | function ERROR { 14 | echo -e "\033[31;1merror\033[0m $1" >&2 15 | } 16 | 17 | function BAIL { 18 | exit 1 19 | } 20 | 21 | INFO "Checking for required tools (one-time check)..." 22 | 23 | if [ -z `which clang` ] ; then 24 | WARN "Missing clang" 25 | if [ -z `which gcc` ] ; then 26 | WARN "Missing gcc" 27 | if [ -z `which cc` ] ; then 28 | ERROR "No compiler found" 29 | BAIL 30 | fi 31 | fi 32 | fi 33 | 34 | if [ -z `which genext2fs` ] ; then 35 | ERROR "Missing genext2fs" 36 | INFO "You can probably get it from a package of the same name." 37 | BAIL 38 | fi 39 | 40 | if [ -z `which qemu-system-i386` ] ; then 41 | ERROR "Missing qemu" 42 | INFO "You can probably install it from a package of the same name." 43 | fi 44 | -------------------------------------------------------------------------------- /util/compiler: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -n `which clang` ]] ; then 4 | echo "clang -fcolor-diagnostics" 5 | elif [[ -n `which gcc` ]] ; then 6 | echo "gcc" 7 | else 8 | echo "cc" 9 | fi 10 | -------------------------------------------------------------------------------- /util/config-parser: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Set some defaults 4 | RESOLUTION="1024x768" 5 | ENABLE_KVM=true 6 | EMU_MEMORY=1024 7 | FULLSCREEN=false 8 | ENABLE_SERIAL=true 9 | ENABLE_GRAPHICS=true 10 | BORDERLESS=true 11 | SINGLE=false 12 | DEBUG_SERIAL=false 13 | 14 | # Load the config file 15 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 16 | if [ -e "$DIR/../.config" ]; then 17 | . "$DIR/../.config" 18 | fi 19 | 20 | # Parse some things 21 | ENABLEKVM="" 22 | if [ $ENABLE_KVM == true ]; then 23 | ENABLEKVM="-enable-kvm" 24 | fi 25 | 26 | FULL_SCREEN="" 27 | if [ $FULLSCREEN == true ]; then 28 | FULL_SCREEN="-full-screen" 29 | fi 30 | 31 | SERIAL="" 32 | if [ $ENABLE_SERIAL ]; then 33 | SERIAL="-serial stdio" 34 | fi 35 | 36 | RESPARSED=`echo $RESOLUTION | sed 's/x/,,/'` 37 | GRAPHICS="vid=qemu=$RESPARSED" 38 | if [ $ENABLE_GRAPHICS == false ]; then 39 | GRAPHICS="vgaterm" 40 | fi 41 | 42 | BORDERS="-no-frame" 43 | if [ $BORDERLESS == false ]; then 44 | BORDERS="" 45 | fi 46 | 47 | if [ $SINGLE == true ]; then 48 | GRAPHICS="$GRAPHICS single" 49 | fi 50 | 51 | if [ $DEBUG_SERIAL == true ]; then 52 | GRAPHICS="$GRAPHICS logtoserial=0" 53 | fi 54 | 55 | # Generate the QEMU arguments list 56 | echo "-kernel toaruos-kernel -m $EMU_MEMORY $ENABLEKVM $FULL_SCREEN $SERIAL -vga std -rtc base=localtime -hda toaruos-disk.img -k en-us $BORDERS -append \"$GRAPHICS hdd\"" 57 | -------------------------------------------------------------------------------- /util/cpad.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function cpad { 4 | word="$1" 5 | while [ ${#word} -lt $2 ]; do 6 | word="$word$3"; 7 | if [ ${#word} -lt $2 ]; then 8 | word="$3$word" 9 | fi; 10 | done; 11 | echo "$word"; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /util/dump-colors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | for i in range(256): 4 | print str(i) + "\t\x1b[48;5;" + str(i) + "m \x1b[0m" 5 | -------------------------------------------------------------------------------- /util/grab-binaries.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | BINARIES="http://dl.dropbox.com/u/44305966/toaru-bin-current.tar.gz" 5 | 6 | $DIR/mk-beg "wget" "Pulling binaries..." 7 | wget --quiet -O /tmp/`whoami`-toaru-bin.tar.gz "$BINARIES" 8 | $DIR/mk-end "wget" "Binaries retreived!" 9 | 10 | $DIR/mk-beg "tar" "Extracting binaries..." 11 | tar -xf /tmp/`whoami`-toaru-bin.tar.gz -C $DIR/../hdd/bin/ 12 | $DIR/mk-end "tar" "Binaries extracted." 13 | 14 | $DIR/mk-beg "rm" "Removing hard disk image to ensure rebuild..." 15 | rm -f $DIR/../toaruos-disk.img 2>/dev/null 16 | $DIR/mk-end "rm" "Hard disk image removed." 17 | 18 | $DIR/mk-beg "rm" "Cleaning up..." 19 | rm /tmp/`whoami`-toaru-bin.tar.gz 20 | $DIR/mk-end "rm" "Cleaned up." 21 | 22 | $DIR/mk-info " --- Done!" 23 | -------------------------------------------------------------------------------- /util/mk-beg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | . "$DIR/cpad.sh" 5 | 6 | echo -n > /tmp/.`whoami`-build-errors 7 | 8 | CMD=`cpad "$1" 8 " "` 9 | echo -e -n "\033[32m${CMD}${2}\033[0m" 10 | -------------------------------------------------------------------------------- /util/mk-beg-rm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | . "$DIR/cpad.sh" 5 | 6 | echo -n > /tmp/.`whoami`-build-errors 7 | 8 | CMD=`cpad "$1" 8 " "` 9 | echo -e -n "\033[31m${CMD}${2}\033[0m" 10 | -------------------------------------------------------------------------------- /util/mk-end: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | . "$DIR/cpad.sh" 5 | 6 | CMD=`cpad "$1" 8 " "` 7 | if [[ -s /tmp/.`whoami`-build-errors ]] ; then 8 | echo -e -n "\r\033[1;33m${CMD}${2}\033[0m\n" 9 | cat /tmp/.`whoami`-build-errors 10 | else 11 | echo -e -n "\r\033[1;32m${CMD}${2}\033[0m\033[K\n" 12 | fi 13 | -------------------------------------------------------------------------------- /util/mk-end-rm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | . "$DIR/cpad.sh" 5 | 6 | CMD=`cpad "$1" 8 " "` 7 | echo -e -n "\r\033[1;31m${CMD}${2}\033[0m\033[K\n" 8 | -------------------------------------------------------------------------------- /util/mk-error: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\033[1;31m! Fatal error encountered.\033[0m" 4 | cat /tmp/.`whoami`-build-errors 5 | 6 | exit 1 7 | -------------------------------------------------------------------------------- /util/mk-info: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | . "$DIR/cpad.sh" 5 | 6 | 7 | CMD=`cpad "$1" 8 " "` 8 | echo -e -n "\r\033[1;34m${CMD}${2}\033[0m\n" 9 | -------------------------------------------------------------------------------- /util/run-fullscreen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script to start at full screen resolution 3 | 4 | RAM=1024 5 | KVM="-enable-kvm" 6 | FULLSCREEN="-no-frame" 7 | RESOLUTION=`xrandr -q|perl -F'\s|,' -lane "/^Sc/&&print join '',@F[8..10]" | sed 's/x/=/'` 8 | 9 | qemu-system-i386 -kernel toaruos-kernel -m $RAM -k en-us -append "vid=qemu=$RESOLUTION hdd" -serial stdio -vga std -hda toaruos-disk.img $KVM $FULLSCREEN 10 | -------------------------------------------------------------------------------- /util/run-tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import subprocess, sys 3 | 4 | q = subprocess.Popen(['qemu-system-i386', '-kernel', 'toaruos-kernel', '-m', '256', 5 | '-serial', 'stdio', '-vga', 'std', '-hda', 'toaruos-disk.img', 6 | '-vnc', ':1', '-append', 'vgaterm hdd start=/bin/core-tests logtoserial=10'], 7 | stdout=subprocess.PIPE) 8 | 9 | passes = 0 10 | failures = 0 11 | result = 0 12 | 13 | def process_line(line): 14 | global passes, failures 15 | data = line.strip().split(" : ") 16 | if data[1] == "FAIL": 17 | color = "1;31" 18 | text = "fail" 19 | failures += 1 20 | elif data[1] == "WARN": 21 | color = "1;33" 22 | text = "warn" 23 | elif data[1] == "PASS": 24 | color = "1;32" 25 | text = "pass" 26 | passes += 1 27 | elif data[1] == "INFO": 28 | color = "1;34" 29 | text = "info" 30 | elif data[1] == "DONE": 31 | color = "1;36" 32 | text = "Done!" 33 | elif data[1] == "FATAL": 34 | color = "1;37;41" 35 | text = "FATAL ERROR ECOUNTERED" 36 | print "\033[%sm%s\033[0m %s" % (color, text, data[2]) 37 | if data[1] == "FATAL": 38 | return 2 39 | elif data[1] == "DONE": 40 | return 1 41 | return 0 42 | 43 | 44 | def log_line(line): 45 | print >>sys.stderr, line.strip() 46 | 47 | while q.poll() == None: 48 | line = q.stdout.readline() 49 | if line: 50 | if line.startswith("core-tests :"): 51 | result = process_line(line) 52 | if result > 0: 53 | q.kill() 54 | try: 55 | subprocess.call(["stty","echo"]) 56 | except: 57 | pass 58 | if result == 2: 59 | sys.exit(2) 60 | else: 61 | log_line(line) 62 | 63 | print "\033[1mTest completed. \033[1;32m%d passes\033[0m, \033[1;31m%d failures\033[0m." % (passes, failures) 64 | 65 | if failures > 0: 66 | sys.exit(1) 67 | -------------------------------------------------------------------------------- /util/typewriter.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char ** argv) { 7 | if (argc < 3) { return -1; } 8 | FILE * f = fopen(argv[2],"r"); 9 | char * buffer = malloc(sizeof(char) * 1); 10 | while (!feof(f)) { 11 | fread(buffer, 1, 1, f); 12 | printf("%c", buffer[0]); 13 | fflush(stdout); 14 | usleep(atoi(argv[1])); 15 | } 16 | fclose(f); 17 | return 0; 18 | } 19 | --------------------------------------------------------------------------------