├── .gitignore ├── src ├── test-user │ ├── check │ │ ├── echo.d │ │ │ ├── stdio_scanf.txt │ │ │ ├── stdio_printf.txt │ │ │ └── unistd_fork.txt │ │ ├── echo │ │ ├── unistd_mkdir │ │ ├── unistd_rmdir │ │ └── unistd_write │ ├── dirent.t │ ├── utsname.t │ ├── termios.t │ ├── fixture │ │ ├── mkdir_tmp │ │ ├── write_until_disk_full │ │ ├── copy_test_target │ │ ├── copy_usr_share │ │ ├── copy_sbin_unistd_execve │ │ └── copy_sbin_unistd_fcntl_F_SETFD │ ├── stdio_printf.c │ ├── signal.t │ ├── stdio.t │ ├── utsname_uname.c │ ├── unistd_execve.h │ ├── stdio_scanf.c │ ├── unistd_execve.c │ ├── unistd_rmdir.c │ ├── unistd_execve_failed.c │ ├── unistd_exit.c │ ├── unistd_open_ENOSPC.c │ ├── unistd_open_O_CREAT.c │ ├── unistd_execve_new.c │ ├── unistd_write_ENOSPC.c │ ├── unistd_getcwd.c │ ├── unistd_mkdir.c │ ├── unistd_write.c │ ├── signal_kill.c │ ├── unistd_wait.c │ ├── unistd_open_O_EXCL.c │ ├── signal_SIGSEGV.c │ ├── unistd_fcntl_F_SETFL.c │ ├── unistd_open.c │ ├── unistd_unlink.c │ ├── unistd_ioctl_TIOCGWINSZ.c │ ├── share │ │ └── alice.txt │ ├── unistd_open_O_TRUNC.c │ ├── unistd_pipe2.c │ ├── unistd_pipe_EPIPE.c │ ├── signal_sigaction.c │ ├── unistd_fork.c │ ├── unistd_fcntl_F_SETFD_new.c │ ├── unistd_pipe_SIGPIPE.c │ ├── unistd_pipe.c │ ├── unistd_fcntl_F_SETFD.c │ ├── unistd_open_O_APPEND.c │ ├── termios_tcgetattr.c │ ├── dirent_readdir.c │ ├── kernel.c │ ├── unistd_read.c │ ├── test.h │ ├── unistd_syscall_EFAULT.c │ ├── alice_text.h │ └── termios_tcsetattr.c ├── kernel │ ├── lib │ │ ├── bitset.c │ │ ├── libgen.h │ │ ├── extension.h │ │ ├── setjmp.h │ │ ├── arithmetic.h │ │ ├── setjmp.s │ │ ├── arithmetic.c │ │ ├── bitset.h │ │ ├── limits.h │ │ ├── type.h │ │ ├── stdarg.h │ │ ├── string.h │ │ ├── libgen.c │ │ ├── list.c │ │ ├── list.h │ │ ├── signal.h │ │ └── signal.c │ ├── syscall.h │ ├── timer.h │ ├── superblock.h │ ├── mmc.h │ ├── buddy.h │ ├── io.h │ ├── tty.h │ ├── block.h │ ├── kernel.c │ ├── mmu.h │ ├── slab.h │ ├── gic.h │ ├── asm │ │ ├── mmu.s │ │ └── system.s │ ├── uart.h │ ├── fs.h │ ├── logger.h │ ├── user.h │ ├── aeabi.c │ ├── elf.h │ ├── dentry.h │ ├── pipe.h │ ├── file.h │ ├── system.h │ ├── page.h │ ├── timer.c │ ├── minix.h │ ├── page.c │ ├── superblock.c │ ├── gic.c │ ├── inode.h │ ├── logger.c │ ├── tty.c │ └── block.c ├── test-kernel │ ├── lib │ │ ├── libgen.t │ │ ├── stdarg.t │ │ ├── arithmetic.t │ │ ├── bitset.t │ │ ├── list.t │ │ ├── signal.t │ │ ├── string.t │ │ ├── libgen.c │ │ ├── arithmetic.c │ │ ├── stdarg.c │ │ └── bitset.c │ ├── superblock.t │ ├── elf.t │ ├── block.t │ ├── fs.t │ ├── fixture │ │ └── copy_sbin_init │ ├── dentry.t │ ├── inode.t │ ├── test.h │ ├── superblock.c │ ├── fs.c │ ├── kernel.c │ ├── block.c │ ├── test.c │ └── elf.c ├── init │ └── init.c └── crt │ ├── start.s │ └── runtime.c ├── tool ├── travis-ci │ ├── build │ ├── before-install │ └── before-script ├── umount ├── coop │ ├── lib │ │ ├── coop.rb │ │ └── coop │ │ │ ├── statistics.rb │ │ │ ├── resource.rb │ │ │ ├── message_parser.rb │ │ │ ├── message │ │ │ ├── fixture.rb │ │ │ └── check.rb │ │ │ ├── cyanurus.rb │ │ │ ├── entry_parser.rb │ │ │ ├── serial.rb │ │ │ ├── session.rb │ │ │ ├── qemu.rb │ │ │ └── test.rb │ └── bin │ │ └── coop ├── gen_config ├── cc └── mount ├── .gdbinit ├── .gitmodules ├── Makefile ├── .travis.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /src/test-user/check/echo.d/stdio_scanf.txt: -------------------------------------------------------------------------------- 1 | G 123 null 2 | -------------------------------------------------------------------------------- /src/test-user/check/echo.d/stdio_printf.txt: -------------------------------------------------------------------------------- 1 | Hello, World! 2 | -------------------------------------------------------------------------------- /tool/travis-ci/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -exu 4 | 5 | make -j4 6 | make test 7 | -------------------------------------------------------------------------------- /.gdbinit: -------------------------------------------------------------------------------- 1 | # for cyanurus 2 | 3 | file build/kernel/cyanurus.elf 4 | target remote localhost:1234 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/musl"] 2 | path = src/musl 3 | url = git://git.musl-libc.org/musl 4 | -------------------------------------------------------------------------------- /src/test-user/check/echo.d/unistd_fork.txt: -------------------------------------------------------------------------------- 1 | A?: data 2 | A?: heap 3 | A?: stack 4 | ?B: data 5 | ?B: heap 6 | ?B: stack 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | COMMANDS = all clean clobber test copy run pty debug-run debug-pty 2 | 3 | .PHONY: $(COMMANDS) 4 | 5 | $(COMMANDS): 6 | $(MAKE) -C build $@ 7 | -------------------------------------------------------------------------------- /tool/travis-ci/before-install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -exu 4 | 5 | sudo apt-get install -y pkg-config fuse 6 | sudo modprobe fuse 7 | sudo chmod 666 /dev/fuse 8 | sudo chown root:$USER /etc/fuse.conf 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | cache: ccache 3 | dist: trusty 4 | sudo: required 5 | 6 | before_install: 7 | - tool/travis-ci/before-install 8 | 9 | before_script: 10 | - tool/travis-ci/before-script 11 | 12 | script: 13 | - tool/travis-ci/build 14 | -------------------------------------------------------------------------------- /src/kernel/lib/bitset.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "lib/bitset.h" 18 | -------------------------------------------------------------------------------- /src/test-kernel/lib/libgen.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | TEST(test_dirname); 18 | TEST(test_basename); 19 | -------------------------------------------------------------------------------- /src/test-kernel/superblock.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $shutdown 19 | */ 20 | TEST(test_superblock_init); 21 | -------------------------------------------------------------------------------- /src/test-kernel/lib/stdarg.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | TEST(test_stdarg_snprintf_0); 18 | TEST(test_stdarg_snprintf_1); 19 | -------------------------------------------------------------------------------- /src/test-user/dirent.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $fixture copy_test_target 19 | */ 20 | TEST(dirent_readdir); 21 | -------------------------------------------------------------------------------- /src/test-user/utsname.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $fixture copy_test_target 19 | */ 20 | TEST(utsname_uname); 21 | -------------------------------------------------------------------------------- /src/test-kernel/elf.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $fixture copy_sbin_init 19 | $shutdown 20 | */ 21 | TEST(test_elf); 22 | -------------------------------------------------------------------------------- /src/test-kernel/lib/arithmetic.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | TEST(test_add_overflow_unsigned_long); 18 | TEST(test_add_overflow_long_long); 19 | -------------------------------------------------------------------------------- /src/init/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | int main(void) { 20 | printf("%s\n", "Hello, World!"); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /src/test-kernel/block.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $shutdown 19 | */ 20 | TEST(test_block_read); 21 | 22 | /* 23 | $shutdown 24 | */ 25 | TEST(test_block_write); 26 | -------------------------------------------------------------------------------- /src/crt/start.s: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | .text 18 | .code 32 19 | 20 | .global _start 21 | _start: 22 | MOV r0, sp 23 | BL __cstart 24 | -------------------------------------------------------------------------------- /src/test-user/check/echo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ECHO_EXPECTED="${SOURCE_PATH}/check/echo.d/${TEST_NAME}.txt" 18 | 19 | diff -u - ${ECHO_EXPECTED} <&0 1>&2 20 | -------------------------------------------------------------------------------- /tool/umount: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2016 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | if type fusermount >/dev/null 2>&1 ; then 20 | exec fusermount -u "$@" 21 | else 22 | exec umount "$@" 23 | fi 24 | -------------------------------------------------------------------------------- /src/test-user/termios.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $fixture copy_test_target 19 | */ 20 | TEST(termios_tcgetattr); 21 | 22 | /* 23 | $fixture copy_test_target 24 | */ 25 | TEST(termios_tcsetattr); 26 | -------------------------------------------------------------------------------- /src/kernel/lib/libgen.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_LIBGEN_H_ 18 | #define _CYANURUS_LIB_LIBGEN_H_ 19 | 20 | char *dirname(char *path); 21 | char *basename(char *path); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/test-user/fixture/mkdir_tmp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | mkdir -p disk 20 | ${ROOT_PATH}/tool/mount disk.img disk 21 | 22 | mkdir -p disk/tmp 23 | ${ROOT_PATH}/tool/umount disk 24 | -------------------------------------------------------------------------------- /src/kernel/syscall.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_SYSCALL_H_ 18 | #define _CYANURUS_SYSCALL_H_ 19 | 20 | #include "lib/type.h" 21 | #include "process.h" 22 | 23 | void syscall_handler(void); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/kernel/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_TIMER_H_ 18 | #define _CYANURUS_TIMER_H_ 19 | 20 | void timer_enable(void); 21 | int timer_is_masked(void); 22 | void timer_clear_interrupt(void); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/test-kernel/fs.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $fixture copy_sbin_init 19 | $shutdown 20 | */ 21 | TEST(test_fs_check_path); 22 | 23 | /* 24 | $fixture copy_sbin_init 25 | $shutdown 26 | */ 27 | TEST(test_fs_lstat64); 28 | -------------------------------------------------------------------------------- /src/test-user/stdio_printf.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | int main(void) { 21 | TEST_START(); 22 | 23 | printf("%s\n", "Hello, World!"); 24 | 25 | TEST_CHECK(); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/kernel/lib/extension.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_EXTENSION_H_ 18 | #define _CYANURUS_LIB_EXTENSION_H_ 19 | 20 | #define _cleanup_(x) __attribute__((cleanup(x))) 21 | #define noreturn __attribute__((noreturn)) 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/test-user/fixture/write_until_disk_full: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2016 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | mkdir -p disk 20 | ${ROOT_PATH}/tool/mount disk.img disk 21 | 22 | yes > disk/full 2>/dev/null || true 23 | ${ROOT_PATH}/tool/umount disk 24 | -------------------------------------------------------------------------------- /src/test-kernel/lib/bitset.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | TEST(test_bitset_sizeof); 18 | TEST(test_bitset_mask); 19 | TEST(test_bitset_slot); 20 | TEST(test_bitset_nslots); 21 | TEST(test_bitset_add); 22 | TEST(test_bitset_remove); 23 | TEST(test_bitset_test); 24 | -------------------------------------------------------------------------------- /src/kernel/superblock.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_FS_SUPERBLOCK_H_ 18 | #define _CYANURUS_FS_SUPERBLOCK_H_ 19 | 20 | #include "minix.h" 21 | 22 | extern struct minix3_superblock superblock; 23 | void superblock_init(void); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/kernel/lib/setjmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_SETJMP_H_ 18 | #define _CYANURUS_LIB_SETJMP_H_ 19 | 20 | // r4 - lr 21 | typedef unsigned long jmp_buf[11]; 22 | 23 | int setjmp(jmp_buf env); 24 | void longjmp(jmp_buf env, int val); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/test-user/fixture/copy_test_target: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | mkdir -p disk 20 | ${ROOT_PATH}/tool/mount disk.img disk 21 | 22 | mkdir -p disk/sbin 23 | cp $BUILD_PATH/$TEST_NAME disk/sbin 24 | 25 | ${ROOT_PATH}/tool/umount disk 26 | -------------------------------------------------------------------------------- /src/test-user/signal.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $fixture copy_test_target 19 | */ 20 | TEST(signal_sigaction); 21 | 22 | /* 23 | $fixture copy_test_target 24 | */ 25 | TEST(signal_kill); 26 | 27 | /* 28 | $fixture copy_test_target 29 | */ 30 | TEST(signal_SIGSEGV); 31 | -------------------------------------------------------------------------------- /src/kernel/mmc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_MMC_H_ 18 | #define _CYANURUS_MMC_H_ 19 | 20 | void mmc_init(void); 21 | 22 | int mmc_write(uint64_t address, size_t size, const void *data); 23 | int mmc_read(uint64_t address, size_t size, void *data); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/test-kernel/fixture/copy_sbin_init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | mkdir -p disk 20 | ${ROOT_PATH}/tool/mount disk.img disk 21 | 22 | mkdir -p disk/sbin 23 | cp $BUILD_PATH/../init/init disk/sbin 24 | 25 | ${ROOT_PATH}/tool/umount disk 26 | -------------------------------------------------------------------------------- /src/test-user/fixture/copy_usr_share: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | mkdir -p disk 20 | ${ROOT_PATH}/tool/mount disk.img disk 21 | 22 | mkdir -p disk/usr/share 23 | cp -r ${SOURCE_PATH}/share/* disk/usr/share 24 | 25 | ${ROOT_PATH}/tool/umount disk 26 | -------------------------------------------------------------------------------- /src/kernel/buddy.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_BUDDY_H_ 18 | #define _CYANURUS_BUDDY_H_ 19 | 20 | #include "page.h" 21 | #include "lib/type.h" 22 | 23 | void buddy_init(void); 24 | struct page *buddy_alloc(size_t size); 25 | void buddy_free(struct page *page); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/kernel/io.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_IO_H_ 18 | #define _CYANURUS_IO_H_ 19 | 20 | #include "lib/list.h" 21 | #include "lib/unix.h" 22 | 23 | #define io_read32(a) (*((volatile uint32_t *)(a))) 24 | #define io_write32(a, v) (*((volatile uint32_t *)(a)) = (v)) 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/kernel/tty.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_TTY_H_ 18 | #define _CYANURUS_TTY_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | void tty_init(void); 23 | void tty_resume(void); 24 | ssize_t tty_read(void *data, size_t size); 25 | ssize_t tty_write(const void *data, size_t size); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/test-kernel/lib/list.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | TEST(test_list_init); 18 | TEST(test_list_add); 19 | TEST(test_list_concat_0); 20 | TEST(test_list_concat_1); 21 | TEST(test_list_remove); 22 | TEST(test_list_empty); 23 | TEST(test_list_length); 24 | TEST(test_list_foreach); 25 | TEST(test_list_foreach_safe); 26 | -------------------------------------------------------------------------------- /src/kernel/lib/arithmetic.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_ARITHMETIC_H_ 18 | #define _CYANURUS_LIB_ARITHMETIC_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | bool add_overflow_unsigned_long(unsigned long a, unsigned long b); 23 | bool add_overflow_long_long(long long a, long long b); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/test-kernel/lib/signal.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | TEST(test_sigemptyset); 18 | TEST(test_sigfillset); 19 | TEST(test_sigaddset); 20 | TEST(test_sigdelset); 21 | TEST(test_sigismember); 22 | TEST(test_sigisemptyset); 23 | TEST(test_signotset); 24 | TEST(test_sigorset); 25 | TEST(test_sigandset); 26 | TEST(test_sigpeekset); 27 | -------------------------------------------------------------------------------- /src/kernel/lib/setjmp.s: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | .text 18 | .code 32 19 | 20 | .global setjmp 21 | setjmp: 22 | STMIA r0, {r4-lr} 23 | MOV r0, #0 24 | BX lr 25 | 26 | .global longjmp 27 | longjmp: 28 | LDMIA r0, {r4-lr} 29 | MOV r0, r1 30 | BX lr 31 | -------------------------------------------------------------------------------- /src/test-user/fixture/copy_sbin_unistd_execve: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | mkdir -p disk 20 | ${ROOT_PATH}/tool/mount disk.img disk 21 | 22 | mkdir -p disk/sbin 23 | cp $BUILD_PATH/unistd_execve disk/sbin 24 | cp $BUILD_PATH/unistd_execve_new disk/sbin 25 | 26 | ${ROOT_PATH}/tool/umount disk 27 | -------------------------------------------------------------------------------- /src/test-user/stdio.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $fixture copy_test_target 19 | $check echo 20 | $disable_echo_on_check 21 | */ 22 | TEST(stdio_printf); 23 | 24 | /* 25 | $fixture copy_test_target 26 | $check echo 27 | $disable_echo_on_check 28 | :stdin __EOF__ 29 | G 123 null 30 | 31 | __EOF__ 32 | */ 33 | TEST(stdio_scanf); 34 | -------------------------------------------------------------------------------- /src/test-user/check/unistd_mkdir: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | fail() { 20 | ${ROOT_PATH}/tool/umount disk 21 | exit 1 22 | } 23 | 24 | mkdir -p disk 25 | ${ROOT_PATH}/tool/mount disk.img disk 26 | 27 | test -d disk/tmp || fail 28 | test -d disk/sbin || fail 29 | 30 | ${ROOT_PATH}/tool/umount disk 31 | -------------------------------------------------------------------------------- /src/test-user/check/unistd_rmdir: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | fail() { 20 | ${ROOT_PATH}/tool/umount disk 21 | exit 1 22 | } 23 | 24 | mkdir -p disk 25 | ${ROOT_PATH}/tool/mount disk.img disk 26 | 27 | test ! -d disk/tmp || fail 28 | test -d disk/sbin || fail 29 | 30 | ${ROOT_PATH}/tool/umount disk 31 | -------------------------------------------------------------------------------- /src/test-user/fixture/copy_sbin_unistd_fcntl_F_SETFD: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | mkdir -p disk 20 | ${ROOT_PATH}/tool/mount disk.img disk 21 | 22 | mkdir -p disk/sbin 23 | cp $BUILD_PATH/unistd_fcntl_F_SETFD disk/sbin 24 | cp $BUILD_PATH/unistd_fcntl_F_SETFD_new disk/sbin 25 | 26 | ${ROOT_PATH}/tool/umount disk 27 | -------------------------------------------------------------------------------- /src/test-user/utsname_uname.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int main(void) { 22 | struct utsname uts; 23 | TEST_START(); 24 | 25 | TEST_ASSERT(uname(&uts) == 0); 26 | TEST_ASSERT(strcmp(uts.sysname, "Cyanurus") == 0); 27 | 28 | TEST_SUCCEED(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/test-user/unistd_execve.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_TEST_USER_UNISTD_EXECVE_H_ 18 | #define _CYANURUS_TEST_USER_UNISTD_EXECVE_H_ 19 | 20 | static char *av[] = { 21 | "ONE", 22 | "TWO", 23 | "THREE", 24 | NULL, 25 | }; 26 | 27 | static char *ep[] = { 28 | "PATH=/bin", 29 | "TERM=vt100", 30 | NULL, 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /tool/coop/lib/coop.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | module Coop 20 | class InvalidFormat < StandardError; end 21 | class ValidationError < StandardError; end 22 | class FixtureError < StandardError; end 23 | class AbortSelect < Exception; end 24 | 25 | Message = Struct.new(:name, :body) 26 | end 27 | 28 | require 'coop/application' 29 | -------------------------------------------------------------------------------- /src/kernel/lib/arithmetic.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "lib/arithmetic.h" 18 | #include "lib/limits.h" 19 | 20 | bool add_overflow_unsigned_long(unsigned long a, unsigned long b) { 21 | return a > ULONG_MAX - b; 22 | } 23 | 24 | bool add_overflow_long_long(long long a, long long b) { 25 | return (b > 0 && a > LLONG_MAX - b) || (b < 0 && a < LLONG_MIN - b); 26 | } 27 | -------------------------------------------------------------------------------- /src/kernel/block.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_FS_BLOCK_H_ 18 | #define _CYANURUS_FS_BLOCK_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | #define BLOCK_SIZE (1024*4) 23 | 24 | typedef uint16_t block_index; 25 | 26 | void block_init(void); 27 | void block_read(block_index index, void *data); 28 | void block_write(block_index index, const void *data); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/test-kernel/lib/string.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | TEST(test_strlen); 18 | TEST(test_strnlen); 19 | TEST(test_strcmp); 20 | TEST(test_strncmp); 21 | TEST(test_strcpy); 22 | TEST(test_strncpy); 23 | TEST(test_memcpy); 24 | TEST(test_memset); 25 | TEST(test_memcmp); 26 | TEST(test_strcat); 27 | TEST(test_strncat); 28 | TEST(test_strchr); 29 | TEST(test_strrchr); 30 | TEST(test_strchrnul); 31 | -------------------------------------------------------------------------------- /src/test-user/check/unistd_write: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | EXPECTED="${SOURCE_PATH}/share/alice.txt" 20 | 21 | fail() { 22 | ${ROOT_PATH}/tool/umount disk 23 | exit 1 24 | } 25 | 26 | mkdir -p disk 27 | ${ROOT_PATH}/tool/mount disk.img disk 28 | 29 | diff -u disk/tmp/alice.txt ${EXPECTED} 1>&2 || fail 30 | ${ROOT_PATH}/tool/umount disk 31 | -------------------------------------------------------------------------------- /src/test-user/stdio_scanf.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int main(void) { 22 | int i; 23 | char s[512], c; 24 | 25 | TEST_START(); 26 | 27 | scanf("%c %d %s", &c, &i, s); 28 | 29 | TEST_ASSERT(c == 'G'); 30 | TEST_ASSERT(i == 123); 31 | TEST_ASSERT(!strcmp(s, "null")); 32 | 33 | TEST_CHECK(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /src/kernel/kernel.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "system.h" 18 | #include "process.h" 19 | #include "logger.h" 20 | 21 | static void run_init(void) { 22 | system_init(); 23 | 24 | if (process_create("/sbin/init") < 0) { 25 | logger_fatal("could not create process"); 26 | system_halt(); 27 | } 28 | 29 | process_switch(); 30 | } 31 | 32 | void kernel_main(void) { 33 | run_init(); 34 | } 35 | -------------------------------------------------------------------------------- /src/test-user/unistd_execve.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "unistd_execve.h" 23 | 24 | int main(int argc, char *argv[]) { 25 | TEST_START(); 26 | 27 | TEST_ASSERT(argc == 1); 28 | TEST_ASSERT(strlen(argv[0]) > 0); 29 | 30 | execve("/sbin/unistd_execve_new", av, ep); 31 | 32 | TEST_FAIL(); 33 | } 34 | -------------------------------------------------------------------------------- /tool/travis-ci/before-script: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -exu 4 | 5 | QEMU_VERSION="2.5.1.1" 6 | QEMU_FILENAME="qemu-${QEMU_VERSION}.tar.bz2" 7 | QEMU_URL="http://wiki.qemu-project.org/download/${QEMU_FILENAME}" 8 | 9 | RUBY_VERSION="2.3.1" 10 | RUBY_FILENAME="ruby-${RUBY_VERSION}.tar.bz2" 11 | RUBY_URL="https://rubies.travis-ci.org/ubuntu/14.04/x86_64/${RUBY_FILENAME}" 12 | 13 | FUSE_MFS_TAG="v0.4" 14 | FUSE_MFS_FILENAME="fuse-mfs_0.4-d25f058_amd64.deb" 15 | FUSE_MFS_URL="https://github.com/redcap97/fuse-mfs/releases/download/${FUSE_MFS_TAG}/${FUSE_MFS_FILENAME}" 16 | 17 | wget ${QEMU_URL} 18 | tar jxf ${QEMU_FILENAME} 19 | pushd $(basename ${QEMU_FILENAME} .tar.bz2) 20 | ./configure --target-list=arm-softmmu,arm-linux-user 21 | make -j4 22 | sudo make install 23 | popd 24 | 25 | wget ${RUBY_URL} 26 | sudo tar jxf ${RUBY_FILENAME} --strip-components=1 -C /usr 27 | 28 | wget ${FUSE_MFS_URL} 29 | sudo dpkg -i ${FUSE_MFS_FILENAME} 30 | 31 | sudo apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi 32 | -------------------------------------------------------------------------------- /src/kernel/mmu.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_MMU_H_ 18 | #define _CYANURUS_MMU_H_ 19 | 20 | #include "lib/type.h" 21 | #include "process.h" 22 | 23 | void mmu_init(void); 24 | int mmu_destroy(pid_t pid); 25 | int mmu_alloc(pid_t pid, uint32_t addr, size_t size); 26 | pid_t mmu_set_ttb(pid_t pid); 27 | 28 | // implemented in asm/lib.S 29 | void mmu_enable(void); 30 | void mmu_disable(void); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/kernel/slab.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_SLAB_H_ 18 | #define _CYANURUS_SLAB_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | void slab_cache_init(void); 23 | struct slab_cache *slab_cache_create(const char *name, size_t size); 24 | void slab_cache_destroy(struct slab_cache *cache); 25 | void *slab_cache_alloc(struct slab_cache *cache); 26 | void slab_cache_free(struct slab_cache *cache, void *obj); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/test-kernel/dentry.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $shutdown 19 | */ 20 | TEST(test_dentry_init); 21 | 22 | /* 23 | $shutdown 24 | */ 25 | TEST(test_dentry_lookup_0); 26 | 27 | /* 28 | $fixture copy_sbin_init 29 | $shutdown 30 | */ 31 | TEST(test_dentry_lookup_1); 32 | 33 | /* 34 | $shutdown 35 | */ 36 | TEST(test_dentry_link); 37 | 38 | /* 39 | $fixture copy_sbin_init 40 | $shutdown 41 | */ 42 | TEST(test_dentry_unlink); 43 | -------------------------------------------------------------------------------- /src/test-user/unistd_rmdir.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int main(void) { 22 | TEST_START(); 23 | 24 | TEST_ASSERT(rmdir("/tmp") == 0); 25 | 26 | TEST_ASSERT(rmdir("/tmp") == -1); 27 | TEST_ASSERT(errno == ENOENT); 28 | 29 | TEST_ASSERT(rmdir("/sbin") == -1); 30 | TEST_ASSERT(errno == ENOTEMPTY); 31 | 32 | TEST_CHECK(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/test-user/unistd_execve_failed.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "unistd_execve.h" 23 | 24 | int main(int argc, char *argv[]) { 25 | TEST_START(); 26 | 27 | TEST_ASSERT(argc == 1); 28 | TEST_ASSERT(strlen(argv[0]) > 0); 29 | TEST_ASSERT(execve("/sbin/command_not_found", av, ep) < 0); 30 | 31 | TEST_SUCCEED(); 32 | } 33 | -------------------------------------------------------------------------------- /src/test-kernel/inode.t: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | $shutdown 19 | */ 20 | TEST(test_inode_create_0); 21 | 22 | /* 23 | $shutdown 24 | */ 25 | TEST(test_inode_create_1); 26 | 27 | /* 28 | $shutdown 29 | */ 30 | TEST(test_inode_create_2); 31 | 32 | /* 33 | $shutdown 34 | */ 35 | TEST(test_inode_create_3); 36 | 37 | /* 38 | $shutdown 39 | */ 40 | TEST(test_inode_destroy_0); 41 | 42 | /* 43 | $shutdown 44 | */ 45 | TEST(test_inode_destroy_1); 46 | -------------------------------------------------------------------------------- /src/kernel/gic.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_GIC_H_ 18 | #define _CYANURUS_GIC_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | #define IRQ_TIMER01 34 23 | #define IRQ_TIMER23 35 24 | 25 | #define IRQ_UART0 37 26 | #define IRQ_UART1 38 27 | #define IRQ_UART2 39 28 | #define IRQ_UART3 40 29 | 30 | void gic_init(void); 31 | void gic_enable_irq(int id); 32 | uint32_t gic_interrupt_acknowledge(void); 33 | void gic_end_of_interrupt(uint32_t irq); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /tool/gen_config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2015 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | cat < 18 | #include 19 | #include 20 | 21 | int main(void) { 22 | int status; 23 | pid_t pid; 24 | 25 | TEST_START(); 26 | 27 | pid = fork(); 28 | TEST_ASSERT(pid >= 0); 29 | 30 | if (!pid) { 31 | _exit(15); 32 | } 33 | wait(&status); 34 | 35 | TEST_ASSERT(WIFEXITED(status)); 36 | TEST_ASSERT(WEXITSTATUS(status) == 15); 37 | 38 | TEST_SUCCEED(); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/test-user/unistd_open_ENOSPC.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define DATA_FILE "/tmp/data.txt" 26 | 27 | int main(void) { 28 | TEST_START(); 29 | 30 | TEST_ASSERT(open(DATA_FILE, O_WRONLY | O_CREAT, 0644) == -1); 31 | TEST_ASSERT(errno == ENOSPC); 32 | 33 | TEST_SUCCEED(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /src/kernel/asm/mmu.s: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | .text 18 | .code 32 19 | 20 | .global mmu_enable 21 | mmu_enable: 22 | @ SCTLR 23 | MRC p15, 0, r0, c1, c0, 0 24 | ORR r0, r0, #0x1 25 | MCR p15, 0, r0, c1, c0, 0 26 | BX lr 27 | 28 | .global mmu_disable 29 | mmu_disable: 30 | @ SCTLR 31 | MRC p15, 0, r0, c1, c0, 0 32 | BIC r0, r0, #0x1 33 | MCR p15, 0, r0, c1, c0, 0 34 | BX lr 35 | -------------------------------------------------------------------------------- /src/kernel/uart.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_UART_H_ 18 | #define _CYANURUS_UART_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | int uart_can_recv(void); 23 | int uart_can_send(void); 24 | int uart_recv(void); 25 | int uart_send(int c); 26 | int uart_getc(void); 27 | int uart_putc(int c); 28 | ssize_t uart_read(void *data, size_t size); 29 | ssize_t uart_write(const void *data, size_t size); 30 | void uart_set_interrupt(int flags); 31 | void uart_clear_interrupt(int flags); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/kernel/fs.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_FS_H_ 18 | #define _CYANURUS_FS_H_ 19 | 20 | #include "lib/type.h" 21 | #include "lib/unix.h" 22 | #include "file.h" 23 | 24 | void fs_init(void); 25 | int fs_create(const char *path, int flags, mode_t mode); 26 | int fs_unlink(const char *path); 27 | int fs_mkdir(const char *path, mode_t mode); 28 | int fs_rmdir(const char *path); 29 | int fs_lstat64(const char *path, struct stat64 *buf); 30 | int fs_fstat64(const struct file *file, struct stat64 *buf); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/kernel/logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LOGGER_H_ 18 | #define _CYANURUS_LOGGER_H_ 19 | 20 | enum logger_level { 21 | LOGGER_LEVEL_DEBUG, 22 | LOGGER_LEVEL_INFO, 23 | LOGGER_LEVEL_WARN, 24 | LOGGER_LEVEL_ERROR, 25 | LOGGER_LEVEL_FATAL, 26 | }; 27 | 28 | int logger_debug(const char *format, ...); 29 | int logger_info(const char *format, ...); 30 | int logger_warn(const char *format, ...); 31 | int logger_error(const char *format, ...); 32 | int logger_fatal(const char *format, ...); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/kernel/user.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_USER_H_ 18 | #define _CYANURUS_USER_H_ 19 | 20 | #define USER_ADDRESS_START ((uint8_t*)0x00010000) 21 | #define USER_ADDRESS_END ((uint8_t*)0x60000000) 22 | #define IS_USER_ADDRESSS(address) ((uint8_t*)(address) >= USER_ADDRESS_START && (uint8_t*)(address) < USER_ADDRESS_END) 23 | 24 | #define BRK_ADDRESS_END ((uint8_t*)0x10000000) 25 | #define IS_EXECUTABLE_ADDRESS(address) ((uint8_t*)(address) >= USER_ADDRESS_START && (uint8_t*)(address) < BRK_ADDRESS_END) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/test-user/unistd_open_O_CREAT.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define DATA_FILE "/tmp/data.txt" 26 | 27 | int main(void) { 28 | TEST_START(); 29 | 30 | TEST_ASSERT(open(DATA_FILE, O_WRONLY) == -1); 31 | TEST_ASSERT(errno == ENOENT); 32 | 33 | TEST_ASSERT(open(DATA_FILE, O_WRONLY | O_CREAT, 0644) >= 0); 34 | 35 | TEST_SUCCEED(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /src/test-user/unistd_execve_new.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "unistd_execve.h" 23 | 24 | extern char **environ; 25 | 26 | int main(int argc, char *argv[]) { 27 | int i; 28 | 29 | TEST_ASSERT(argc == 3); 30 | 31 | for (i = 0; av[i]; ++i) { 32 | TEST_ASSERT(strcmp(av[i], argv[i]) == 0); 33 | } 34 | 35 | for (i = 0; ep[i]; ++i) { 36 | TEST_ASSERT(strcmp(ep[i], environ[i]) == 0); 37 | } 38 | 39 | TEST_SUCCEED(); 40 | } 41 | -------------------------------------------------------------------------------- /src/test-user/unistd_write_ENOSPC.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define DATA_FILE "/full" 26 | 27 | int main(void) { 28 | int fd; 29 | TEST_START(); 30 | 31 | fd = open(DATA_FILE, O_APPEND | O_WRONLY); 32 | TEST_ASSERT(fd >= 0); 33 | 34 | TEST_ASSERT(write(fd, "full", 4) == -1); 35 | TEST_ASSERT(errno == ENOSPC); 36 | 37 | TEST_SUCCEED(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /src/test-user/unistd_getcwd.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | int main(void) { 23 | char buf[1024]; 24 | TEST_START(); 25 | 26 | TEST_ASSERT(getcwd(buf, sizeof(buf)) == buf); 27 | TEST_ASSERT(!strcmp(getcwd(buf, sizeof(buf)), "/")); 28 | 29 | TEST_ASSERT(getcwd(buf, 0) == NULL); 30 | TEST_ASSERT(errno == EINVAL); 31 | 32 | TEST_ASSERT(getcwd(buf, 1) == NULL); 33 | TEST_ASSERT(errno == ERANGE); 34 | 35 | TEST_SUCCEED(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /tool/cc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2014 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | ROOT_PATH="$(dirname $0)/.." 20 | SOURCE_PATH="${ROOT_PATH}/src" 21 | BUILD_PATH="${ROOT_PATH}/build" 22 | 23 | CC="arm-none-eabi-gcc" 24 | 25 | CFLAGS_ARCH="-march=armv7-a -mfloat-abi=soft -marm" 26 | CFLAGS_LIBS="-L ${SOURCE_PATH}/musl/lib" 27 | CFLAGS="${CFLAGS_ARCH} -nostdinc -nostdlib -fno-builtin -static ${CFLAGS_LIBS}" 28 | 29 | export C_INCLUDE_PATH="${SOURCE_PATH}/musl/include" 30 | exec ${CC} ${CFLAGS} -T ${BUILD_PATH}/ldscript/user.ld "$@" ${BUILD_PATH}/crt/crt0.o -lc -lgcc 31 | -------------------------------------------------------------------------------- /src/test-user/unistd_mkdir.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | int main(void) { 23 | TEST_START(); 24 | 25 | TEST_ASSERT(mkdir("/tmp", 0755) == 0); 26 | 27 | TEST_ASSERT(mkdir("/tmp", 0755) == -1); 28 | TEST_ASSERT(errno == EEXIST); 29 | 30 | TEST_ASSERT(mkdir("/sbin", 0755) == -1); 31 | TEST_ASSERT(errno == EEXIST); 32 | 33 | TEST_ASSERT(mkdir("/usr/local", 0755) == -1); 34 | TEST_ASSERT(errno == ENOENT); 35 | 36 | TEST_CHECK(); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/test-user/unistd_write.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "alice_text.h" 25 | 26 | int main(void) { 27 | int fd; 28 | TEST_START(); 29 | 30 | fd = open("/tmp/alice.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644); 31 | TEST_ASSERT(fd >= 0); 32 | 33 | TEST_ASSERT(write(fd, ALICE_TEXT, strlen(ALICE_TEXT)) == (ssize_t)strlen(ALICE_TEXT)); 34 | TEST_ASSERT(!close(fd)); 35 | 36 | TEST_CHECK(); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/crt/runtime.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | extern char **environ; 22 | int main(int argc, char **argv, char **envp); 23 | 24 | void __aeabi_memset(void *buf, size_t size, int c) { 25 | memset(buf, c, size); 26 | } 27 | 28 | void __aeabi_memcpy(void *dest, const void *src, size_t size) { 29 | memcpy(dest, src, size); 30 | } 31 | 32 | void __cstart(long *stack) { 33 | int argc = *stack; 34 | char **argv = (void*)(stack + 1); 35 | environ = &argv[argc + 1]; 36 | exit(main(argc, argv, environ)); 37 | } 38 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/statistics.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | class Coop::Statistics 20 | def initialize(io) 21 | @io = io 22 | 23 | @success = 0 24 | @failure = 0 25 | end 26 | 27 | def succeed(name) 28 | @success += 1 29 | @io.puts "[success] #{name}" 30 | end 31 | 32 | def fail(name, reason) 33 | @failure += 1 34 | @io.puts "[failure] #{name} #{reason}" 35 | end 36 | 37 | def report 38 | @io.puts "#{@success} success, #{@failure} failure" 39 | end 40 | 41 | def success? 42 | @failure == 0 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /src/test-user/signal_kill.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | int main(void) { 24 | int st; 25 | pid_t pid; 26 | 27 | TEST_START(); 28 | 29 | pid = fork(); 30 | TEST_ASSERT(pid >= 0); 31 | 32 | if (!pid) { 33 | kill(getpid(), SIGKILL); 34 | while(1); 35 | } 36 | wait(&st); 37 | 38 | TEST_ASSERT(!WIFEXITED(st)); 39 | 40 | TEST_ASSERT(WIFSIGNALED(st)); 41 | TEST_ASSERT(WTERMSIG(st) == SIGKILL); 42 | 43 | TEST_SUCCEED(); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/test-user/unistd_wait.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | int main(void) { 23 | int status; 24 | pid_t pid; 25 | 26 | TEST_START(); 27 | 28 | TEST_ASSERT(wait(&status) == -1); 29 | TEST_ASSERT(errno == ECHILD); 30 | 31 | pid = fork(); 32 | TEST_ASSERT(pid >= 0); 33 | 34 | if (!pid) { 35 | _exit(1); 36 | } 37 | 38 | TEST_ASSERT(wait(&status) == pid); 39 | TEST_ASSERT(WIFEXITED(status)); 40 | TEST_ASSERT(WEXITSTATUS(status) == 1); 41 | 42 | TEST_SUCCEED(); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /src/kernel/aeabi.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "system.h" 18 | #include "lib/string.h" 19 | 20 | void __aeabi_memset(void *buf, size_t size, int c) { 21 | memset(buf, c, size); 22 | } 23 | 24 | void __aeabi_memcpy(void *dest, const void *src, size_t size) { 25 | memcpy(dest, src, size); 26 | } 27 | 28 | void __aeabi_memclr(void *dest, size_t n) { 29 | memset(dest, 0, n); 30 | } 31 | 32 | void __aeabi_memclr8(void *dest, size_t n) { 33 | memset(dest, 0, n); 34 | } 35 | 36 | void __aeabi_ldiv0(void) { 37 | system_halt(); 38 | } 39 | 40 | void __aeabi_idiv0(void) { 41 | system_halt(); 42 | } 43 | -------------------------------------------------------------------------------- /src/test-user/unistd_open_O_EXCL.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define DATA_FILE "/tmp/data.txt" 26 | 27 | int main(void) { 28 | int fd; 29 | TEST_START(); 30 | 31 | fd = open(DATA_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644); 32 | TEST_ASSERT(fd >= 0); 33 | close(fd); 34 | 35 | TEST_ASSERT(open(DATA_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644) == -1); 36 | TEST_ASSERT(errno == EEXIST); 37 | 38 | TEST_SUCCEED(); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/kernel/lib/bitset.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_BITSET_H_ 18 | #define _CYANURUS_LIB_BITSET_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | typedef uint32_t bitset; 23 | 24 | #define bitset_mask(n) (1U << ((n) % (sizeof(bitset) * 8))) 25 | #define bitset_slot(n) ((n) / (sizeof(bitset) * 8)) 26 | #define bitset_nslots(n) (((n) + (sizeof(bitset) * 8) - 1) / (sizeof(bitset) * 8)) 27 | #define bitset_add(p, n) ((p)[bitset_slot(n)] |= bitset_mask(n)) 28 | #define bitset_remove(p, n) ((p)[bitset_slot(n)] &= ~bitset_mask(n)) 29 | #define bitset_test(p, n) ((p)[bitset_slot(n)] & bitset_mask(n)) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/kernel/elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_ELF_H_ 18 | #define _CYANURUS_ELF_H_ 19 | 20 | #include "lib/type.h" 21 | #include "page.h" 22 | 23 | struct elf_segment { 24 | struct page *page; 25 | uint32_t addr; 26 | uint32_t file_size; 27 | uint32_t memory_size; 28 | }; 29 | 30 | struct elf_executable { 31 | uint32_t entry_point; 32 | 33 | struct elf_segment text; 34 | struct elf_segment data; 35 | }; 36 | 37 | int elf_load(const char *path, struct elf_executable *executable); 38 | void elf_copy(struct elf_executable *executable); 39 | void elf_release(struct elf_executable *executable); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/test-user/signal_SIGSEGV.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | void trap_sigsegv(int sig) { 23 | (void)sig; 24 | TEST_SUCCEED(); 25 | } 26 | 27 | void set_signal_handler(void) { 28 | struct sigaction sa; 29 | memset(&sa, 0, sizeof(struct sigaction)); 30 | 31 | sigemptyset(&sa.sa_mask); 32 | sa.sa_handler = trap_sigsegv; 33 | sigaction(SIGSEGV, &sa, NULL); 34 | } 35 | 36 | int main(void) { 37 | volatile char *s = NULL; 38 | 39 | TEST_START(); 40 | 41 | set_signal_handler(); 42 | *s = '!'; 43 | 44 | TEST_FAIL(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cyanurus 2 | 3 | [![Build Status](https://travis-ci.org/redcap97/cyanurus.svg?branch=master)](https://travis-ci.org/redcap97/cyanurus) 4 | 5 | Cyanurus is a Unix-like operating system for ARMv7-A. 6 | 7 | ![Screen Capture](https://cloud.githubusercontent.com/assets/928237/11782406/3c520650-a2b4-11e5-917e-372b7f7cb689.gif) 8 | 9 | ## How to Run 10 | 11 | Cyanurus kernel and rootfs image are available at below link: 12 | 13 | https://github.com/redcap97/cyanurus/releases/download/v0.3.1/cyanurus-0.3.1.tar.xz 14 | 15 | QEMU is required to run Cyanurus. Please type following command: 16 | 17 | ``` 18 | qemu-system-arm -M vexpress-a9 -m 1G -nographic -drive if=sd,file=rootfs.img,format=raw -kernel cyanurus.elf 19 | ``` 20 | 21 | Cyanurus is also able to run on docker containers. Please type following command: 22 | 23 | ``` 24 | docker run -it --rm redcap97/cyanurus 25 | ``` 26 | 27 | ## Build Dependencies 28 | 29 | ### Required 30 | 31 | * GNU Make 32 | * GCC (arm-none-eabi) 33 | * Binutils (arm-none-eabi) 34 | * Ruby 35 | * QEMU (qemu-img, qemu-system-arm) 36 | * [fuse-mfs](https://github.com/redcap97/fuse-mfs) 37 | 38 | ### Optional 39 | 40 | * Clang 41 | * GDB (arm-none-eabi) 42 | 43 | ## License 44 | 45 | Licensed under the Apache License v2.0. 46 | -------------------------------------------------------------------------------- /src/kernel/lib/limits.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_LIMITS_H_ 18 | #define _CYANURUS_LIB_LIMITS_H_ 19 | 20 | #define CHAR_BIT 8 21 | #define SCHAR_MIN (-128) 22 | #define SCHAR_MAX 127 23 | #define UCHAR_MAX 255 24 | #define SHRT_MIN (-1-0x7fff) 25 | #define SHRT_MAX 0x7fff 26 | #define USHRT_MAX 0xffff 27 | #define INT_MIN (-1-0x7fffffff) 28 | #define INT_MAX 0x7fffffff 29 | #define UINT_MAX 0xffffffffU 30 | #define LONG_MIN (-LONG_MAX-1) 31 | #define LONG_MAX 0x7fffffffL 32 | #define ULONG_MAX (2UL*LONG_MAX+1) 33 | #define LLONG_MIN (-LLONG_MAX-1) 34 | #define LLONG_MAX 0x7fffffffffffffffLL 35 | #define ULLONG_MAX (2ULL*LLONG_MAX+1) 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/kernel/lib/type.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_TYPE_H_ 18 | #define _CYANURUS_LIB_TYPE_H_ 19 | 20 | #define NULL ((void *)0) 21 | 22 | #define SEEK_SET 0 23 | #define SEEK_CUR 1 24 | #define SEEK_END 2 25 | 26 | #define bool _Bool 27 | #define true 1 28 | #define false 0 29 | 30 | typedef char int8_t; 31 | typedef short int16_t; 32 | typedef int int32_t; 33 | typedef long long int64_t; 34 | 35 | typedef unsigned char uint8_t; 36 | typedef unsigned short uint16_t; 37 | typedef unsigned int uint32_t; 38 | typedef unsigned long long uint64_t; 39 | 40 | typedef unsigned long size_t; 41 | typedef long ssize_t; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/kernel/dentry.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_FS_DENTRY_H_ 18 | #define _CYANURUS_FS_DENTRY_H_ 19 | 20 | #include "inode.h" 21 | #include "minix.h" 22 | #include "lib/list.h" 23 | 24 | #define PATH_MAX 1024 25 | #define DF_FLAGS_LOAD (1 << 0) 26 | 27 | struct dentry { 28 | char name[NAME_MAX]; 29 | uint32_t flags; 30 | uint32_t nentries; 31 | struct inode *inode; 32 | struct dentry *parent; 33 | struct list children; 34 | struct list sibling; 35 | }; 36 | 37 | void dentry_init(void); 38 | struct dentry *dentry_lookup(const char *path); 39 | int dentry_link(struct dentry *dentry, const char *path, struct inode *inode); 40 | int dentry_unlink(struct dentry *dentry); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/kernel/lib/stdarg.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_STDARG_H_ 18 | #define _CYANURUS_LIB_STDARG_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | #define EOF (-1) 23 | 24 | typedef __builtin_va_list va_list; 25 | 26 | #define va_start(ap, last) __builtin_va_start(ap, last) 27 | #define va_end(ap) __builtin_va_end(ap) 28 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 29 | #define va_copy(dest, src) __builtin_va_copy(dest, src) 30 | 31 | int snprintf(char *str, size_t size, const char *format, ...); 32 | int vsnprintf(char *str, size_t size, const char *format, va_list ap); 33 | int vsprintf(char *str, const char *format, va_list ap); 34 | int sprintf(char *str, const char *format, ...); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /tool/coop/bin/coop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | #coding: utf-8 3 | 4 | =begin 5 | Copyright 2014 Akira Midorikawa 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | =end 19 | 20 | $LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', 'lib')) 21 | 22 | require 'coop' 23 | 24 | options = {} 25 | opt = OptionParser.new 26 | opt.on('--root PATH') {|v| options[:root_path] = v } 27 | opt.on('--source PATH') {|v| options[:source_path] = v } 28 | args = opt.parse!(ARGV) 29 | 30 | app = Coop::Application.new(options) 31 | 32 | case args[0] 33 | when 'run' 34 | app.run 35 | when 'list_entry_files' 36 | app.list_entry_files 37 | when 'dump_entries' 38 | app.dump_entries 39 | else 40 | STDOUT.puts "USAGE: #{$0} [--root PATH] [--source PATH] " 41 | exit(1) 42 | end 43 | 44 | exit(2) unless app.success? 45 | -------------------------------------------------------------------------------- /src/kernel/pipe.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_PIPE_H_ 18 | #define _CYANURUS_PIPE_H_ 19 | 20 | #include "lib/type.h" 21 | #include "page.h" 22 | #include "process.h" 23 | 24 | struct pipe { 25 | struct page *page; 26 | size_t offset; 27 | size_t length; 28 | size_t readers; 29 | size_t writers; 30 | struct process_waitq readers_waitq; 31 | struct process_waitq writers_waitq; 32 | }; 33 | 34 | void pipe_init(void); 35 | struct pipe *pipe_create(void); 36 | ssize_t pipe_read(struct pipe *pipe, void *data, size_t size); 37 | ssize_t pipe_write(struct pipe *pipe, const void *data, size_t size); 38 | void pipe_countup(struct pipe *pipe, int flags); 39 | void pipe_release(struct pipe *pipe, int flags); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/test-user/unistd_fcntl_F_SETFL.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | int main(int argc, char *argv[]) { 26 | int fd; 27 | 28 | (void)argc; 29 | (void)argv; 30 | 31 | TEST_START(); 32 | 33 | fd = open("/tmp/alice.txt", O_CREAT | O_WRONLY | O_TRUNC | O_APPEND, 0644); 34 | TEST_ASSERT(fd >= 0); 35 | 36 | TEST_ASSERT(fcntl(fd, F_GETFL) == (O_APPEND | O_WRONLY)); 37 | TEST_ASSERT(fcntl(fd, F_SETFL, O_APPEND | O_NOATIME | O_CLOEXEC | O_RDWR) == 0); 38 | TEST_ASSERT(fcntl(fd, F_GETFL) == (O_APPEND | O_NOATIME | O_WRONLY)); 39 | 40 | TEST_SUCCEED(); 41 | } 42 | -------------------------------------------------------------------------------- /src/kernel/file.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_FILE_H_ 18 | #define _CYANURUS_FILE_H_ 19 | 20 | #include 21 | #include 22 | 23 | #define FILE_FOR_READ(file) (((file)->flags & O_ACCMODE) == O_RDWR || ((file)->flags & O_ACCMODE) == O_RDONLY) 24 | #define FILE_FOR_WRITE(file) (((file)->flags & O_ACCMODE) == O_RDWR || ((file)->flags & O_ACCMODE) == O_WRONLY) 25 | 26 | enum file_type { 27 | FF_UNUSED = 0, 28 | FF_TTY, 29 | FF_INODE, 30 | FF_PIPE, 31 | }; 32 | 33 | struct file { 34 | enum file_type type; 35 | union { 36 | struct dentry *dentry; 37 | struct termios *termios; 38 | struct pipe *pipe; 39 | }; 40 | mode_t flags; 41 | size_t offset; 42 | size_t count; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/test-kernel/test.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_TEST_H_ 18 | #define _CYANURUS_TEST_H_ 19 | 20 | #define TEST(name) void name(void) 21 | 22 | #define TEST_FAIL() \ 23 | test_fail(__FILE__, __LINE__, __func__) 24 | 25 | #define TEST_ASSERT(expr) \ 26 | if (!(expr)) { \ 27 | TEST_FAIL(); \ 28 | } 29 | 30 | struct test_entry { 31 | const char *name; 32 | void (*func)(void); 33 | }; 34 | 35 | #define TEST_ENTRY(entry) { #entry, entry } 36 | #define TEST_ENTRY_NULL { NULL, NULL } 37 | 38 | void test_run(void (*func)(void)); 39 | void test_fail(const char *file, unsigned int line, const char *func); 40 | 41 | void test_message_start(const char *name); 42 | void test_message_stop(void); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/test-user/unistd_open.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | static void check_O_RDONLY(void) { 26 | TEST_ASSERT(open("/", O_RDONLY) >= 0); 27 | } 28 | 29 | static void check_O_WRONLY(void) { 30 | TEST_ASSERT(open("/", O_WRONLY) == -1); 31 | TEST_ASSERT(errno == EISDIR); 32 | } 33 | 34 | static void check_O_RDWR(void) { 35 | TEST_ASSERT(open("/", O_RDWR) == -1); 36 | TEST_ASSERT(errno == EISDIR); 37 | } 38 | 39 | int main(void) { 40 | TEST_START(); 41 | 42 | check_O_RDONLY(); 43 | check_O_WRONLY(); 44 | check_O_RDWR(); 45 | 46 | TEST_SUCCEED(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /src/test-user/unistd_unlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define DATA_FILE "/tmp/data.txt" 25 | 26 | int main(void) { 27 | int fd; 28 | struct stat st; 29 | TEST_START(); 30 | 31 | TEST_ASSERT(unlink(DATA_FILE) == -1); 32 | TEST_ASSERT(errno == ENOENT); 33 | 34 | fd = open(DATA_FILE, O_WRONLY | O_CREAT, 0644); 35 | TEST_ASSERT(fd >= 0); 36 | close(fd); 37 | 38 | TEST_ASSERT(stat(DATA_FILE, &st) == 0); 39 | TEST_ASSERT(unlink(DATA_FILE) == 0); 40 | 41 | TEST_ASSERT(stat(DATA_FILE, &st) == -1); 42 | TEST_ASSERT(errno == ENOENT); 43 | 44 | TEST_SUCCEED(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/resource.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | require 'fileutils' 20 | require 'tmpdir' 21 | 22 | class Coop::Resource 23 | attr_reader :dir 24 | 25 | def self.create 26 | new.tap(&:prepare) 27 | end 28 | 29 | def initialize 30 | @dir = Dir.mktmpdir('coop') 31 | end 32 | 33 | def sock 34 | File.join(@dir, 'sock') 35 | end 36 | 37 | def disk 38 | File.join(@dir, 'disk.img') 39 | end 40 | 41 | def prepare 42 | options = {out: '/dev/null'} 43 | 44 | system('qemu-img', 'create', '-f', 'raw', disk, '64M', options) 45 | system('mkfs.mfs', '-B', '4096', disk, options) 46 | end 47 | 48 | def release 49 | if Dir.exists?(@dir) 50 | FileUtils.remove_entry_secure(@dir) 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /src/test-user/unistd_ioctl_TIOCGWINSZ.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define WS_ROW 24 26 | #define WS_COL 80 27 | 28 | int main(void) { 29 | struct winsize wsz; 30 | int fd; 31 | TEST_START(); 32 | 33 | fd = open("/a.txt", O_CREAT|O_WRONLY|O_TRUNC, 0644); 34 | TEST_ASSERT(ioctl(fd, TIOCGWINSZ, &wsz) == -1); 35 | TEST_ASSERT(errno == ENOTTY); 36 | 37 | TEST_ASSERT(ioctl(100, TIOCGWINSZ, &wsz) == -1); 38 | TEST_ASSERT(errno == EBADF); 39 | 40 | TEST_ASSERT(ioctl(0, TIOCGWINSZ, &wsz) == 0); 41 | TEST_ASSERT(wsz.ws_row == WS_ROW); 42 | TEST_ASSERT(wsz.ws_col == WS_COL); 43 | 44 | TEST_SUCCEED(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/message_parser.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | class Coop::MessageParser 20 | def self.parse(str, eol: "\n") 21 | i = str.index(eol) 22 | return unless i 23 | 24 | line = str.slice(0, i) 25 | 26 | case line[0] 27 | when "$" 28 | str.slice!(0, i + eol.size) 29 | name, arg = line.split(' ', 2) 30 | 31 | Coop::Message.new(name[1..-1], arg) 32 | when ":" 33 | name, sig = line.split(' ') 34 | last = eol + sig + eol 35 | 36 | n = str.index(last) 37 | return unless n 38 | 39 | lines = str.slice((i + eol.size), n - (i + eol.size)) 40 | str.slice!(0, n + last.size) 41 | 42 | Coop::Message.new(name[1..-1], lines) 43 | else 44 | raise Coop::InvalidFormat, line.inspect 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /src/test-user/share/alice.txt: -------------------------------------------------------------------------------- 1 | Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice, "without pictures or conversations?" 2 | So she was considering in her own mind, (as well as she could, for the hot day made her feel very sleepy and stupid,) whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a white rabbit with pink eyes ran close by her. 3 | There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, "Oh dear! Oh dear! I shall be too late!" (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural;) but when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and, burning with curiosity, she ran across the field after it, and was just in time to see it pop down a large rabbit-hole under the hedge. 4 | In another moment down went Alice after it, never once considering how in the world she was to get out again. 5 | -------------------------------------------------------------------------------- /src/test-user/unistd_open_O_TRUNC.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define DATA_FILE "/tmp/data.txt" 25 | 26 | int main(void) { 27 | int fd; 28 | struct stat st; 29 | 30 | TEST_START(); 31 | 32 | fd = open(DATA_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644); 33 | TEST_ASSERT(fd >= 0); 34 | TEST_ASSERT(write(fd, "aaaa", 4) == 4); 35 | close(fd); 36 | 37 | TEST_ASSERT(stat(DATA_FILE, &st) == 0); 38 | TEST_ASSERT(st.st_size == 4); 39 | 40 | fd = open(DATA_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644); 41 | TEST_ASSERT(fd >= 0); 42 | close(fd); 43 | 44 | TEST_ASSERT(stat(DATA_FILE, &st) == 0); 45 | TEST_ASSERT(st.st_size == 0); 46 | 47 | TEST_SUCCEED(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/message/fixture.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | class Coop::Message::Fixture 20 | def initialize(app, session) 21 | @root_path = app.root_path 22 | @source_path = app.source_path 23 | @resource = session.resource 24 | end 25 | 26 | def dispatch(test, name) 27 | unless /\A[A-Za-z0-9_]+\z/ =~ name 28 | raise ArgumentError, "Invalid name: #{name}" 29 | end 30 | 31 | env = { 32 | 'TEST_NAME' => test, 33 | 'BUILD_PATH' => Dir.getwd, 34 | 'ROOT_PATH' => @root_path, 35 | 'SOURCE_PATH' => @source_path, 36 | } 37 | 38 | command = File.join(@source_path, 'fixture', name) 39 | 40 | Dir.chdir(@resource.dir) do 41 | raise Coop::FixtureError, "fixture error: #{command}" unless system(env, command) 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /src/test-user/unistd_pipe2.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | int main(int argc, char *argv[]) { 24 | int pipefd[2]; 25 | struct stat stat; 26 | char *av[] = { NULL }; 27 | char *ep[] = { NULL }; 28 | 29 | if (argc == 0) { 30 | TEST_ASSERT(fstat(3, &stat) < 0); 31 | TEST_ASSERT(fstat(4, &stat) < 0); 32 | 33 | TEST_SUCCEED(); 34 | return 0; 35 | } else { 36 | TEST_START(); 37 | 38 | TEST_ASSERT(pipe2(pipefd, O_CLOEXEC) == 0); 39 | 40 | TEST_ASSERT(pipefd[0] == 3); 41 | TEST_ASSERT(pipefd[1] == 4); 42 | 43 | TEST_ASSERT(fstat(3, &stat) == 0); 44 | TEST_ASSERT(fstat(4, &stat) == 0); 45 | 46 | execve(argv[0], av, ep); 47 | } 48 | 49 | TEST_FAIL(); 50 | return 1; 51 | } 52 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/cyanurus.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | require 'coop/serial' 20 | require 'coop/message_parser' 21 | 22 | class Coop::Cyanurus 23 | def initialize(resource) 24 | @buffer = "" 25 | @serial = Coop::Serial.new(resource.sock) 26 | end 27 | 28 | def run 29 | @serial.run 30 | end 31 | 32 | def recv 33 | while true 34 | if response = parse(@buffer) 35 | return response 36 | end 37 | 38 | @buffer += @serial.pop_output 39 | end 40 | end 41 | 42 | def send(message) 43 | @serial.add_input(message + "\n") 44 | end 45 | 46 | def add_input(str) 47 | @serial.add_input(str) 48 | end 49 | 50 | def unprocessed_data 51 | @buffer 52 | end 53 | 54 | private 55 | 56 | def parse(str) 57 | Coop::MessageParser.parse(str, eol: "\r\n") 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /src/kernel/lib/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_STRING_H_ 18 | #define _CYANURUS_LIB_STRING_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | size_t strlen(const char *str); 23 | size_t strnlen(const char *str, size_t maxlen); 24 | char *strcpy(char *dest, const char *src); 25 | char *strncpy(char *dest, const char *src, size_t size); 26 | int strcmp(const char *s1, const char *s2); 27 | int strncmp(const char *s1, const char *s2, size_t size); 28 | void *memcpy(void *dest, const void *src, size_t size); 29 | void *memset(void *buf, int c, size_t size); 30 | int memcmp(const void *buf1, const void *buf2, size_t n); 31 | char *strcat(char *dest, const char *src); 32 | char *strncat(char *dest, const char *src, size_t size); 33 | char *strchr(const char *s, int c); 34 | char *strrchr(const char *s, int c); 35 | char *strchrnul(const char *s, int c); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/test-user/unistd_pipe_EPIPE.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | void trap_sigpipe(int sig) { 25 | TEST_ASSERT(sig == SIGPIPE); 26 | } 27 | 28 | void set_signal_handler(void) { 29 | struct sigaction sa; 30 | memset(&sa, 0, sizeof(struct sigaction)); 31 | 32 | sigemptyset(&sa.sa_mask); 33 | sa.sa_handler = trap_sigpipe; 34 | TEST_ASSERT(sigaction(SIGPIPE, &sa, NULL) == 0); 35 | } 36 | 37 | int main(void) { 38 | int pipefd[2]; 39 | char data[1024 * 8]; 40 | 41 | TEST_START(); 42 | 43 | set_signal_handler(); 44 | TEST_ASSERT(pipe(pipefd) == 0); 45 | 46 | close(pipefd[0]); 47 | TEST_ASSERT(write(pipefd[1], data, sizeof(data)) == -1); 48 | TEST_ASSERT(errno == EPIPE); 49 | 50 | TEST_SUCCEED(); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /src/test-kernel/superblock.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "superblock.t" 21 | 22 | #include "page.h" 23 | #include "logger.h" 24 | 25 | static void setup(void) { 26 | page_init(); 27 | block_init(); 28 | superblock_init(); 29 | } 30 | 31 | TEST(test_superblock_init) { 32 | setup(); 33 | 34 | TEST_ASSERT(superblock.s_ninodes > 0); 35 | TEST_ASSERT(superblock.s_imap_blocks > 0); 36 | TEST_ASSERT(superblock.s_zmap_blocks > 0); 37 | TEST_ASSERT(superblock.s_firstdatazone > 0); 38 | TEST_ASSERT(superblock.s_log_zone_size == 0); 39 | TEST_ASSERT(superblock.s_max_size > 0); 40 | TEST_ASSERT(superblock.s_zones > 0); 41 | TEST_ASSERT(superblock.s_magic == SUPER_MAGIC_V3); 42 | TEST_ASSERT(superblock.s_blocksize == 4096); 43 | TEST_ASSERT(superblock.s_disk_version == 0); 44 | } 45 | -------------------------------------------------------------------------------- /src/test-user/signal_sigaction.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | void trap_sigint(int sig) { 24 | sigset_t set; 25 | 26 | sigprocmask(0, NULL, &set); 27 | TEST_ASSERT(sigismember(&set, sig)); 28 | 29 | _exit(97); 30 | } 31 | 32 | int main(void) { 33 | int st; 34 | pid_t pid; 35 | struct sigaction sa; 36 | 37 | TEST_START(); 38 | 39 | pid = fork(); 40 | TEST_ASSERT(pid >= 0); 41 | 42 | if (!pid) { 43 | memset(&sa, 0, sizeof(struct sigaction)); 44 | sigemptyset(&sa.sa_mask); 45 | sa.sa_handler = trap_sigint; 46 | 47 | TEST_ASSERT(sigaction(SIGINT, &sa, NULL) == 0); 48 | kill(getpid(), SIGINT); 49 | 50 | while(1); 51 | } 52 | wait(&st); 53 | 54 | TEST_ASSERT(WEXITSTATUS(st) == 97); 55 | TEST_SUCCEED(); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tool/mount: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 Akira Midorikawa 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eu 18 | 19 | # FUSE isn't mounted immediately in Mac OS X. 20 | # So polling is performed to ensure whether FUSE is mounted or not. 21 | osx-fuse-mfs() { 22 | if [ "$#" -ne 2 ]; then 23 | echo "USAGE: $0 device mount_point" >&2 24 | exit 1 25 | fi 26 | 27 | local device=$1 28 | local mount_point=$2 29 | local check_file=${mount_point}/.fuse-mfs 30 | 31 | touch ${check_file} 32 | fuse-mfs -osync ${device} ${mount_point} 33 | 34 | local retry=0 35 | 36 | while [ -f "${check_file}" ]; do 37 | sleep 0.01 38 | 39 | if [ "$retry" -eq 100 ]; then 40 | echo "couldn't mount device" >&2 41 | exit 1 42 | fi 43 | 44 | retry=$((retry+1)) 45 | done 46 | } 47 | 48 | case "$(uname)" in 49 | Darwin) 50 | osx-fuse-mfs "$@" 51 | ;; 52 | *) 53 | exec fuse-mfs "$@" 54 | ;; 55 | esac 56 | -------------------------------------------------------------------------------- /src/kernel/lib/libgen.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "lib/libgen.h" 18 | #include "lib/string.h" 19 | 20 | char *dirname(char *path) { 21 | size_t i; 22 | 23 | if (!path || !(*path)) { 24 | return "."; 25 | } 26 | 27 | i = strlen(path) - 1; 28 | while (path[i] == '/') { 29 | if (!i--) { 30 | return "/"; 31 | } 32 | } 33 | 34 | while (path[i] != '/') { 35 | if (!i--) { 36 | return "."; 37 | } 38 | } 39 | 40 | while (path[i] == '/') { 41 | if (!i--) { 42 | return "/"; 43 | } 44 | } 45 | 46 | path[i+1] = '\0'; 47 | return path; 48 | } 49 | 50 | char *basename(char *path) { 51 | size_t i; 52 | 53 | if (!path || !(*path)) { 54 | return "."; 55 | } 56 | 57 | i = strlen(path) - 1; 58 | while (i && path[i] == '/') { 59 | path[i--] = '\0'; 60 | } 61 | 62 | while (i && path[i-1] != '/') { 63 | i--; 64 | } 65 | 66 | return path + i; 67 | } 68 | -------------------------------------------------------------------------------- /src/test-user/unistd_fork.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | char data[] = "??: data"; 25 | 26 | int main(void) { 27 | int st; 28 | pid_t pid; 29 | char stack[] = "??: stack"; 30 | char *heap = NULL; 31 | 32 | TEST_START(); 33 | 34 | heap = malloc(1024); 35 | TEST_ASSERT(heap != NULL); 36 | 37 | strcpy(heap, "??: heap"); 38 | 39 | pid = fork(); 40 | TEST_ASSERT(pid >= 0); 41 | 42 | if (!pid) { 43 | data[0] = 'A'; 44 | heap[0] = 'A'; 45 | stack[0] = 'A'; 46 | 47 | puts(data); 48 | puts(heap); 49 | puts(stack); 50 | 51 | _exit(0); 52 | } 53 | wait(&st); 54 | 55 | data[1] = 'B'; 56 | heap[1] = 'B'; 57 | stack[1] = 'B'; 58 | 59 | puts(data); 60 | puts(heap); 61 | puts(stack); 62 | 63 | TEST_CHECK(); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /src/kernel/system.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_SYSTEM_H_ 18 | #define _CYANURUS_SYSTEM_H_ 19 | 20 | #include "lib/type.h" 21 | #include "lib/unix.h" 22 | #include "lib/extension.h" 23 | 24 | #define SYSTEM_BUG_ON(expr) \ 25 | if ((expr)) { \ 26 | system_bug_on(__FILE__, __LINE__, __func__); \ 27 | } 28 | 29 | void system_init(void); 30 | void system_irq_handler(void); 31 | void system_svc_handler(void); 32 | void system_data_abort_handler(void); 33 | noreturn void system_halt(void); 34 | noreturn void system_bug_on(const char *file, unsigned int line, const char *func); 35 | void system_sleep(void); 36 | void system_shutdown(void); 37 | int system_uname(struct utsname *uts); 38 | 39 | // implemented in asm/lib.S 40 | void system_dispatch(uint32_t context); 41 | void system_suspend(uint32_t context); 42 | void system_resume(uint32_t context); 43 | void system_idle(void); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/kernel/page.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_PAGE_H_ 18 | #define _CYANURUS_PAGE_H_ 19 | 20 | #include "lib/list.h" 21 | #include "lib/extension.h" 22 | 23 | #define PAGE_START ((char*)(0x65000000)) 24 | 25 | #define PAGE_SIZE 0x1000 26 | #define PAGE_NUM 0x4000 27 | 28 | #define PAGE_MAX_ORDER 10 29 | #define PAGE_MAX_DEPTH (PAGE_MAX_ORDER + 1) 30 | 31 | #define PF_FREE_LIST (1 << 0) 32 | #define PF_FIRST_PAGE (1 << 1) 33 | 34 | #define _page_cleanup_ _cleanup_(page_cleanup) 35 | 36 | typedef unsigned long page_index; 37 | 38 | struct page { 39 | page_index index; 40 | unsigned int flags; 41 | unsigned int order; 42 | struct page* next; 43 | }; 44 | 45 | extern struct page *pages; 46 | 47 | void page_init(void); 48 | void *page_address(const struct page *page); 49 | struct page *page_find_by_address(void *address); 50 | struct page *page_find_head(const struct page *page); 51 | void page_cleanup(struct page **page); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/kernel/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "timer.h" 18 | #include "gic.h" 19 | #include "lib/type.h" 20 | 21 | #define TIMER0 ((volatile uint32_t*)0x10011000) 22 | #define TIMER_VALUE 0x1 23 | #define TIMER_CONTROL 0x2 24 | #define TIMER_INTCLR 0x3 25 | #define TIMER_MIS 0x5 26 | 27 | #define TIMER_EN 0x80 28 | #define TIMER_PERIODIC 0x40 29 | #define TIMER_INTEN 0x20 30 | #define TIMER_32BIT 0x02 31 | #define TIMER_ONESHOT 0x01 32 | 33 | /* 1MHz timer */ 34 | #define TIMER_FREQUENCY 1000000 35 | 36 | void timer_enable(void) { 37 | gic_enable_irq(IRQ_TIMER01); 38 | 39 | /* interrupt every 10ms */ 40 | *TIMER0 = (uint32_t)(TIMER_FREQUENCY * 0.01); 41 | 42 | *(TIMER0 + TIMER_CONTROL) = 43 | TIMER_EN | TIMER_PERIODIC | TIMER_32BIT | TIMER_INTEN; 44 | } 45 | 46 | int timer_is_masked(void) { 47 | return *(TIMER0 + TIMER_MIS); 48 | } 49 | 50 | void timer_clear_interrupt(void) { 51 | *(TIMER0 + TIMER_INTCLR) = 1; 52 | } 53 | -------------------------------------------------------------------------------- /src/kernel/minix.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_FS_MINIX_H_ 18 | #define _CYANURUS_FS_MINIX_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | #define NAME_MAX 60 23 | #define SUPER_MAGIC_V3 0x4d5a 24 | 25 | struct minix3_superblock { 26 | uint32_t s_ninodes; 27 | uint16_t s_pad0; 28 | uint16_t s_imap_blocks; 29 | uint16_t s_zmap_blocks; 30 | uint16_t s_firstdatazone; 31 | uint16_t s_log_zone_size; 32 | uint16_t s_pad1; 33 | uint32_t s_max_size; 34 | uint32_t s_zones; 35 | uint16_t s_magic; 36 | uint16_t s_pad2; 37 | uint16_t s_blocksize; 38 | uint8_t s_disk_version; 39 | }; 40 | 41 | struct minix2_inode { 42 | uint16_t i_mode; 43 | uint16_t i_nlinks; 44 | uint16_t i_uid; 45 | uint16_t i_gid; 46 | uint32_t i_size; 47 | uint32_t i_atime; 48 | uint32_t i_mtime; 49 | uint32_t i_ctime; 50 | uint32_t i_zone[10]; 51 | }; 52 | 53 | struct minix3_dirent { 54 | uint32_t d_ino; 55 | char d_name[NAME_MAX]; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/test-user/unistd_fcntl_F_SETFD_new.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | extern char **environ; 26 | 27 | int main(int argc, char *argv[]) { 28 | int fd; 29 | char *fd0 = environ[0], *fd1 = environ[1]; 30 | 31 | (void)argc; 32 | (void)argv; 33 | 34 | { 35 | TEST_ASSERT(fd0 != NULL); 36 | TEST_ASSERT(strlen(fd0) > 0); 37 | 38 | fd = strtol(fd0, NULL, 10); 39 | TEST_ASSERT(errno != ERANGE && errno != EINVAL); 40 | 41 | TEST_ASSERT(fcntl(fd, F_GETFD) < 0); 42 | TEST_ASSERT(errno == EBADF); 43 | } 44 | 45 | { 46 | TEST_ASSERT(fd1 != NULL); 47 | TEST_ASSERT(strlen(fd1) > 0); 48 | 49 | fd = strtol(fd1, NULL, 10); 50 | TEST_ASSERT(errno != ERANGE && errno != EINVAL); 51 | 52 | TEST_ASSERT(fcntl(fd, F_GETFD) == 0); 53 | } 54 | 55 | TEST_SUCCEED(); 56 | } 57 | -------------------------------------------------------------------------------- /src/test-user/unistd_pipe_SIGPIPE.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | void trap_sigpipe(int sig) { 24 | TEST_ASSERT(sig == SIGPIPE); 25 | TEST_SUCCEED(); 26 | } 27 | 28 | void set_signal_handler(void) { 29 | struct sigaction sa; 30 | memset(&sa, 0, sizeof(struct sigaction)); 31 | 32 | sigemptyset(&sa.sa_mask); 33 | sa.sa_handler = trap_sigpipe; 34 | TEST_ASSERT(sigaction(SIGPIPE, &sa, NULL) == 0); 35 | } 36 | 37 | int main(void) { 38 | pid_t pid; 39 | int pipefd[2]; 40 | char data[1024 * 8]; 41 | 42 | TEST_START(); 43 | TEST_ASSERT(pipe(pipefd) == 0); 44 | 45 | pid = fork(); 46 | TEST_ASSERT(pid >= 0); 47 | 48 | if (!pid) { 49 | TEST_ASSERT(read(pipefd[0], data, 1) == 1); 50 | exit(0); 51 | } 52 | 53 | set_signal_handler(); 54 | close(pipefd[0]); 55 | write(pipefd[1], data, sizeof(data)); 56 | 57 | TEST_FAIL(); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /src/kernel/page.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "page.h" 18 | #include "buddy.h" 19 | #include "slab.h" 20 | 21 | struct page *pages; 22 | 23 | void page_init(void) { 24 | buddy_init(); 25 | slab_cache_init(); 26 | } 27 | 28 | void *page_address(const struct page *page) { 29 | return PAGE_START + (PAGE_SIZE * page->index); 30 | } 31 | 32 | struct page *page_find_by_address(void *address) { 33 | page_index index = (page_index)(((char*)address - PAGE_START) / PAGE_SIZE); 34 | 35 | if (index < PAGE_NUM) { 36 | return &pages[index]; 37 | } else { 38 | return NULL; 39 | } 40 | } 41 | 42 | struct page *page_find_head(const struct page *page) { 43 | page_index index = page->index; 44 | 45 | while (index < PAGE_NUM) { 46 | if (pages[index].flags & PF_FIRST_PAGE) { 47 | return &pages[index]; 48 | } 49 | 50 | index--; 51 | } 52 | 53 | return NULL; 54 | } 55 | 56 | void page_cleanup(struct page **page) { 57 | if (*page) { 58 | buddy_free(*page); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/kernel/asm/system.s: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | .text 18 | .code 32 19 | 20 | .global system_dispatch 21 | system_dispatch: 22 | MOV lr, r0 23 | 24 | LDMFD lr!, {r0} 25 | MSR spsr, r0 26 | 27 | LDMFD lr, {r0-lr}^ 28 | ADD lr, lr, #60 29 | 30 | LDMFD lr!, {pc}^ 31 | 32 | .global system_suspend 33 | system_suspend: 34 | ADD r0, r0, #68 35 | 36 | STMFD r0!, {lr} 37 | STMFD r0!, {r4-lr} 38 | SUB r0, r0, #16 39 | 40 | MRS r1, cpsr 41 | STMFD r0!, {r1} 42 | 43 | BL process_switch 44 | B . 45 | 46 | .global system_resume 47 | system_resume: 48 | LDMFD r0!, {r1} 49 | MSR cpsr, r1 50 | ADD r0, r0, #16 51 | LDMFD r0!, {r4-pc} 52 | 53 | .global system_idle 54 | system_idle: 55 | MRS r0, cpsr 56 | ORR r0, r0, #0x1f 57 | BIC r0, r0, #0x80 58 | MSR cpsr, r0 59 | WFI 60 | -------------------------------------------------------------------------------- /src/test-user/unistd_pipe.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | void seq(int fd, int last) { 24 | int i; 25 | char buf[1024]; 26 | 27 | for (i = 1; i <= last; ++i) { 28 | snprintf(buf, sizeof(buf), "%d\n", i); 29 | TEST_ASSERT(write(fd, buf, strlen(buf)) > 0); 30 | } 31 | } 32 | 33 | void output(int fd) { 34 | int r; 35 | char buf[1024]; 36 | 37 | while ((r = read(fd, buf, sizeof(buf) - 1))) { 38 | TEST_ASSERT(r > 0); 39 | buf[r] = '\0'; 40 | printf("%s", buf); 41 | } 42 | } 43 | 44 | int main(void) { 45 | pid_t pid; 46 | int pipefd[2]; 47 | 48 | TEST_START(); 49 | TEST_ASSERT(pipe(pipefd) == 0); 50 | 51 | pid = fork(); 52 | TEST_ASSERT(pid >= 0); 53 | 54 | if (!pid) { 55 | close(pipefd[0]); 56 | seq(pipefd[1], 4000); 57 | exit(0); 58 | } 59 | 60 | close(pipefd[1]); 61 | output(pipefd[0]); 62 | 63 | TEST_CHECK(); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /src/test-user/unistd_fcntl_F_SETFD.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | int main(int argc, char *argv[]) { 26 | int fd; 27 | char fd0[1024], fd1[1024]; 28 | 29 | char *av[] = { 30 | argv[0], 31 | NULL, 32 | }; 33 | 34 | char *ep[] = { 35 | fd0, 36 | fd1, 37 | NULL, 38 | }; 39 | 40 | (void)argc; 41 | 42 | TEST_START(); 43 | 44 | { 45 | fd = open(argv[0], O_RDONLY); 46 | TEST_ASSERT(fd >= 0); 47 | snprintf(fd0, sizeof(fd0), "%d", fd); 48 | 49 | TEST_ASSERT(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 50 | TEST_ASSERT(fcntl(fd, F_GETFD) == FD_CLOEXEC); 51 | } 52 | 53 | { 54 | fd = open(argv[0], O_RDONLY); 55 | TEST_ASSERT(fd >= 0); 56 | snprintf(fd1, sizeof(fd1), "%d", fd); 57 | 58 | TEST_ASSERT(fcntl(fd, F_GETFD) == 0); 59 | } 60 | 61 | execve("/sbin/unistd_fcntl_F_SETFD_new", av, ep); 62 | 63 | TEST_FAIL(); 64 | } 65 | -------------------------------------------------------------------------------- /src/test-user/unistd_open_O_APPEND.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define DATA_FILE "/tmp/data.txt" 25 | 26 | static void append(const char *str) { 27 | int fd; 28 | 29 | fd = open(DATA_FILE, O_APPEND | O_WRONLY | O_CREAT, 0644); 30 | TEST_ASSERT(fd >= 0); 31 | 32 | TEST_ASSERT(write(fd, str, strlen(str)) > 0); 33 | close(fd); 34 | } 35 | 36 | static void check(void) { 37 | int fd; 38 | ssize_t r; 39 | char buf[1024]; 40 | 41 | fd = open(DATA_FILE, O_RDONLY); 42 | TEST_ASSERT(fd >= 0); 43 | 44 | r = read(fd, buf, sizeof(buf)); 45 | 46 | TEST_ASSERT(r > 0); 47 | buf[r] = '\0'; 48 | 49 | TEST_ASSERT(strcmp(buf, "'Cos I'm guilty\n") == 0); 50 | } 51 | 52 | int main(void) { 53 | TEST_START(); 54 | 55 | append("'Cos"); 56 | append(" "); 57 | append("I'm"); 58 | append(" "); 59 | append("guilty"); 60 | append("\n"); 61 | 62 | check(); 63 | 64 | TEST_SUCCEED(); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /src/test-user/termios_tcgetattr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define OFLAG (OPOST|ONLCR) 27 | #define IFLAG (ICRNL|IXON|IXANY|IMAXBEL) 28 | #define CFLAG (CREAD|CS8|B9600) 29 | #define LFLAG (ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOCTL|ECHOKE) 30 | 31 | int main(void) { 32 | struct termios tio; 33 | int fd; 34 | TEST_START(); 35 | memset(&tio, 0, sizeof(struct termios)); 36 | 37 | fd = open("/a.txt", O_CREAT|O_WRONLY|O_TRUNC, 0644); 38 | TEST_ASSERT(tcgetattr(fd, &tio) == -1); 39 | TEST_ASSERT(errno == ENOTTY); 40 | 41 | TEST_ASSERT(tcgetattr(100, &tio) == -1); 42 | TEST_ASSERT(errno == EBADF); 43 | 44 | TEST_ASSERT(tcgetattr(0, &tio) == 0); 45 | TEST_ASSERT(tio.c_oflag == OFLAG); 46 | TEST_ASSERT(tio.c_iflag == IFLAG); 47 | TEST_ASSERT(tio.c_cflag == CFLAG); 48 | TEST_ASSERT(tio.c_lflag == LFLAG); 49 | TEST_ASSERT(tio.c_cc[VTIME] == 0); 50 | TEST_ASSERT(tio.c_cc[VMIN] == 1); 51 | 52 | TEST_SUCCEED(); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /src/test-kernel/fs.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "fs.t" 21 | 22 | #include "page.h" 23 | #include "mmu.h" 24 | 25 | static void generate_path(char *str, size_t size) { 26 | memset(str, 'a', size); 27 | str[0] = '/'; 28 | str[size - 1] = '\0'; 29 | } 30 | 31 | static void setup(void) { 32 | page_init(); 33 | fs_init(); 34 | 35 | mmu_init(); 36 | mmu_enable(); 37 | } 38 | 39 | TEST(test_fs_check_path) { 40 | char path[PATH_MAX + 100]; 41 | setup(); 42 | 43 | generate_path(path, sizeof(path)); 44 | 45 | TEST_ASSERT(fs_create(path, O_WRONLY|O_CREAT, 0644) == -ENAMETOOLONG); 46 | TEST_ASSERT(fs_unlink(path) == -ENAMETOOLONG); 47 | TEST_ASSERT(fs_mkdir(path, 0755) == -ENAMETOOLONG); 48 | TEST_ASSERT(fs_rmdir(path) == -ENAMETOOLONG); 49 | } 50 | 51 | TEST(test_fs_lstat64) { 52 | struct stat64 st; 53 | setup(); 54 | 55 | TEST_ASSERT(!fs_lstat64("/sbin", &st)); 56 | TEST_ASSERT(S_ISDIR(st.st_mode)); 57 | 58 | TEST_ASSERT(!fs_lstat64("/sbin/init", &st)); 59 | TEST_ASSERT(S_ISREG(st.st_mode)); 60 | 61 | TEST_ASSERT(fs_lstat64("/sbin/command_not_found", &st) == -ENOENT); 62 | } 63 | -------------------------------------------------------------------------------- /src/kernel/superblock.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "superblock.h" 18 | #include "lib/string.h" 19 | #include "block.h" 20 | #include "logger.h" 21 | #include "system.h" 22 | #include "buddy.h" 23 | 24 | #define SUPERBLOCK_ADDRESS 0x400 25 | 26 | struct minix3_superblock superblock; 27 | 28 | void superblock_init(void) { 29 | _page_cleanup_ struct page *page = buddy_alloc(BLOCK_SIZE); 30 | char *buf = page_address(page); 31 | 32 | SYSTEM_BUG_ON((SUPERBLOCK_ADDRESS + sizeof(struct minix3_superblock)) > BLOCK_SIZE); 33 | 34 | block_read(0, buf); 35 | memcpy(&superblock, buf + SUPERBLOCK_ADDRESS, sizeof(struct minix3_superblock)); 36 | 37 | if (superblock.s_magic != SUPER_MAGIC_V3) { 38 | logger_fatal("invalid magic bytes: 0x%x", (uint32_t)superblock.s_magic); 39 | system_halt(); 40 | } 41 | 42 | if (superblock.s_log_zone_size) { 43 | logger_fatal("blocks per zone must be zero: 0x%x", (uint32_t)superblock.s_log_zone_size); 44 | system_halt(); 45 | } 46 | 47 | if (superblock.s_blocksize != BLOCK_SIZE) { 48 | logger_fatal("block size must be 4096: 0x%x", (uint32_t)superblock.s_blocksize); 49 | system_halt(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/message/check.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | require 'open3' 20 | 21 | class Coop::Message::Check 22 | def initialize(app, session) 23 | @root_path = app.root_path 24 | @source_path = app.source_path 25 | @resource = session.resource 26 | @stats = app.stats 27 | end 28 | 29 | def dispatch(test, name, response) 30 | unless /\A[A-Za-z0-9_]+\z/ =~ name 31 | raise ArgumentError, "Invalid name: #{name}" 32 | end 33 | 34 | output = response.output 35 | 36 | env = { 37 | 'TEST_NAME' => test, 38 | 'BUILD_PATH' => Dir.getwd, 39 | 'ROOT_PATH' => @root_path, 40 | 'SOURCE_PATH' => @source_path, 41 | } 42 | 43 | command = File.join(@source_path, 'check', name) 44 | 45 | Dir.chdir(@resource.dir) do 46 | stdin_data = output.body.gsub(/\r?\n/, "\n") 47 | out, err, status = Open3.capture3(env, command, stdin_data: stdin_data) 48 | 49 | if status.success? 50 | @stats.succeed(test) 51 | else 52 | @stats.fail(test, '(on check)') 53 | end 54 | 55 | print(out) 56 | print(err) 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /src/kernel/lib/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "lib/type.h" 18 | #include "list.h" 19 | 20 | void list_init(struct list *list) { 21 | list->next = list; 22 | list->prev = list; 23 | } 24 | 25 | void list_add(struct list *list, struct list *item) { 26 | item->prev = list; 27 | item->next = list->next; 28 | list->next = item; 29 | item->next->prev = item; 30 | } 31 | 32 | void list_concat(struct list *list, struct list *other) { 33 | if (list_empty(other)) { 34 | return; 35 | } 36 | 37 | other->next->prev = list; 38 | other->prev->next = list->next; 39 | list->next->prev = other->prev; 40 | list->next = other->next; 41 | 42 | list_init(other); 43 | } 44 | 45 | void list_remove(struct list *item) { 46 | item->prev->next = item->next; 47 | item->next->prev = item->prev; 48 | item->next = NULL; 49 | item->prev = NULL; 50 | } 51 | 52 | int list_empty(const struct list *list) { 53 | return list->next == list; 54 | } 55 | 56 | int list_length(const struct list *list) { 57 | struct list *item; 58 | int count = 0; 59 | 60 | item = list->next; 61 | while (item != list) { 62 | item = item->next; 63 | count++; 64 | } 65 | return count; 66 | } 67 | -------------------------------------------------------------------------------- /src/test-user/dirent_readdir.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | struct entry { 22 | char *name; 23 | size_t count; 24 | }; 25 | 26 | void test_entries(const char *path, struct entry *entries, size_t len) { 27 | size_t i; 28 | DIR *dirp; 29 | struct dirent *dirent; 30 | 31 | TEST_ASSERT((dirp = opendir(path)) != NULL); 32 | 33 | while ((dirent = readdir(dirp))) { 34 | for (i = 0; i < len; ++i) { 35 | if (!strcmp(dirent->d_name, entries[i].name)) { 36 | entries[i].count++; 37 | break; 38 | } 39 | } 40 | 41 | if (i == len) { 42 | TEST_FAIL(); 43 | return; 44 | } 45 | } 46 | 47 | for (i = 0; i < len; ++i) { 48 | TEST_ASSERT(entries[i].count == 1); 49 | } 50 | 51 | closedir(dirp); 52 | } 53 | 54 | int main(void) { 55 | struct entry root_entries[] = { 56 | {".", 0}, {"..", 0}, {"sbin", 0} 57 | }; 58 | 59 | struct entry sbin_entries[] = { 60 | {".", 0}, {"..", 0}, {"dirent_readdir", 0} 61 | }; 62 | 63 | TEST_START(); 64 | 65 | test_entries("/", root_entries, 3); 66 | test_entries("/sbin", sbin_entries, 3); 67 | 68 | TEST_SUCCEED(); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /src/test-kernel/kernel.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "test.h" 18 | #include "uart.h" 19 | #include "logger.h" 20 | #include "lib/string.h" 21 | 22 | #include "entries.h" 23 | 24 | static void command_run(char *name) { 25 | struct test_entry *entry = test_entries; 26 | 27 | while (entry->name) { 28 | if (!strcmp(entry->name, name)) { 29 | test_run(entry->func); 30 | break; 31 | } 32 | entry++; 33 | } 34 | } 35 | 36 | static char *parse_command(char *cmd) { 37 | size_t len = strlen(cmd), i; 38 | char *arg = NULL; 39 | 40 | if (len && cmd[len-1] == '\n') { 41 | cmd[len-1] = '\0'; 42 | } 43 | 44 | if (cmd[0] != '$' && cmd[0] != ':') { 45 | return NULL; 46 | } 47 | 48 | for (i = 0; i < len; ++i) { 49 | if (cmd[i] == ' ') { 50 | cmd[i] = '\0'; 51 | arg = &cmd[i+1]; 52 | break; 53 | } 54 | } 55 | 56 | return arg; 57 | } 58 | 59 | void kernel_main(void) { 60 | char cmd[64], *arg; 61 | 62 | while (1) { 63 | logger_info("$please"); 64 | 65 | memset(cmd, 0, sizeof(cmd)); 66 | uart_read(cmd, sizeof(cmd) - 1); 67 | 68 | arg = parse_command(cmd); 69 | 70 | if (!strcmp(cmd, "$run") && arg) { 71 | command_run(arg); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test-user/kernel.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "system.h" 18 | #include "process.h" 19 | #include "logger.h" 20 | #include "uart.h" 21 | #include "lib/string.h" 22 | #include "lib/stdarg.h" 23 | 24 | static void command_run(char *name) { 25 | char path[64]; 26 | 27 | system_init(); 28 | 29 | snprintf(path, sizeof(path), "/sbin/%s", name); 30 | if (process_create(path) < 0) { 31 | logger_fatal("could not create process"); 32 | system_halt(); 33 | } 34 | 35 | process_switch(); 36 | } 37 | 38 | static char *parse_command(char *cmd) { 39 | size_t len = strlen(cmd), i; 40 | char *arg = NULL; 41 | 42 | if (len && cmd[len-1] == '\n') { 43 | cmd[len-1] = '\0'; 44 | } 45 | 46 | if (cmd[0] != '$' && cmd[0] != ':') { 47 | return NULL; 48 | } 49 | 50 | for (i = 0; i < len; ++i) { 51 | if (cmd[i] == ' ') { 52 | cmd[i] = '\0'; 53 | arg = &cmd[i+1]; 54 | break; 55 | } 56 | } 57 | 58 | return arg; 59 | } 60 | 61 | void kernel_main(void) { 62 | char cmd[64], *arg; 63 | 64 | logger_info("$please"); 65 | 66 | memset(cmd, 0, sizeof(cmd)); 67 | uart_read(cmd, sizeof(cmd) - 1); 68 | 69 | arg = parse_command(cmd); 70 | 71 | if (!strcmp(cmd, "$run") && arg) { 72 | command_run(arg); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test-user/unistd_read.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "alice_text.h" 26 | 27 | static void check_read_directory(void) { 28 | int fd; 29 | char buf[32]; 30 | 31 | fd = open("/usr/share", O_RDONLY); 32 | TEST_ASSERT(fd >= 0); 33 | 34 | TEST_ASSERT(read(fd, buf, sizeof(buf)) == -1); 35 | TEST_ASSERT(errno == EISDIR); 36 | 37 | TEST_ASSERT(!close(fd)); 38 | } 39 | 40 | static void check_read_file(void) { 41 | int fd; 42 | ssize_t size, total = 0; 43 | char buf[32], text[4096] = ""; 44 | 45 | fd = open("/usr/share/alice.txt", O_RDONLY); 46 | TEST_ASSERT(fd >= 0); 47 | 48 | while (1) { 49 | size = read(fd, buf, sizeof(buf) - 1); 50 | TEST_ASSERT(size >= 0); 51 | 52 | if (!size) { 53 | break; 54 | } 55 | buf[size] = '\0'; 56 | total += size; 57 | 58 | TEST_ASSERT((total + 1) <= (ssize_t)sizeof(text)); 59 | strcat(text, buf); 60 | } 61 | 62 | TEST_ASSERT(!strcmp(ALICE_TEXT, text)); 63 | TEST_ASSERT(!close(fd)); 64 | } 65 | 66 | int main(void) { 67 | TEST_START(); 68 | 69 | check_read_directory(); 70 | check_read_file(); 71 | 72 | TEST_SUCCEED(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /src/kernel/lib/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_LIST_H_ 18 | #define _CYANURUS_LIB_LIST_H_ 19 | 20 | #define container_of(ptr, type, member) \ 21 | ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 22 | 23 | #define list_foreach(item, head, member) \ 24 | for (item = container_of((head)->next, typeof(*item), member); \ 25 | &item->member != (head); \ 26 | item = container_of(item->member.next, typeof(*item), member)) 27 | 28 | #define list_foreach_safe(item, temp, head, member) \ 29 | for (item = container_of((head)->next, typeof(*item), member), \ 30 | temp = container_of(item->member.next, typeof(*temp), member); \ 31 | &item->member != (head); \ 32 | item = temp, \ 33 | temp = container_of(item->member.next, typeof(*temp), member)) 34 | 35 | struct list { 36 | struct list *prev; 37 | struct list *next; 38 | }; 39 | 40 | void list_init(struct list *list); 41 | void list_add(struct list *list, struct list *item); 42 | void list_concat(struct list *list, struct list *other); 43 | void list_remove(struct list *item); 44 | int list_empty(const struct list *list); 45 | int list_length(const struct list *list); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/test-user/test.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_TEST_USER_TEST_H_ 18 | #define _CYANURUS_TEST_USER_TEST_H_ 19 | 20 | #include 21 | 22 | #define TEST_MESSAGE_SIGNATURE "--a94e2gfwdd--" 23 | 24 | #define TEST_START() \ 25 | puts(":echo " TEST_MESSAGE_SIGNATURE); 26 | 27 | #define TEST_FAIL() \ 28 | do { \ 29 | char message[1024]; \ 30 | snprintf(message, sizeof(message), \ 31 | "$failure @%s() (%s:%u)", \ 32 | __func__, __FILE__, __LINE__ \ 33 | ); \ 34 | \ 35 | puts("\n" TEST_MESSAGE_SIGNATURE); \ 36 | puts(message); \ 37 | puts("$shudown"); \ 38 | while(1); \ 39 | } while(0); 40 | 41 | #define TEST_ASSERT(expr) \ 42 | if (!(expr)) { \ 43 | TEST_FAIL(); \ 44 | } 45 | 46 | #define TEST_SUCCEED() \ 47 | puts("\n" TEST_MESSAGE_SIGNATURE); \ 48 | puts("$success"); \ 49 | puts("$shudown"); \ 50 | while(1); 51 | 52 | #define TEST_CHECK() \ 53 | puts("\n" TEST_MESSAGE_SIGNATURE); \ 54 | puts("$check"); \ 55 | puts("$shudown"); \ 56 | while(1); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/test-kernel/lib/libgen.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "lib/libgen.t" 21 | 22 | TEST(test_dirname) { 23 | char path[16]; 24 | 25 | strcpy(path, "/usr/local"); 26 | TEST_ASSERT(!strcmp(dirname(path), "/usr")); 27 | 28 | strcpy(path, "/usr/"); 29 | TEST_ASSERT(!strcmp(dirname(path), "/")); 30 | 31 | strcpy(path, "usr"); 32 | TEST_ASSERT(!strcmp(dirname(path), ".")); 33 | 34 | strcpy(path, "/"); 35 | TEST_ASSERT(!strcmp(dirname(path), "/")); 36 | 37 | strcpy(path, "."); 38 | TEST_ASSERT(!strcmp(dirname(path), ".")); 39 | 40 | strcpy(path, ".."); 41 | TEST_ASSERT(!strcmp(dirname(path), ".")); 42 | 43 | strcpy(path, ""); 44 | TEST_ASSERT(!strcmp(dirname(path), ".")); 45 | } 46 | 47 | TEST(test_basename) { 48 | char path[16]; 49 | 50 | strcpy(path, "/usr/local"); 51 | TEST_ASSERT(!strcmp(basename(path), "local")); 52 | 53 | strcpy(path, "/usr/"); 54 | TEST_ASSERT(!strcmp(basename(path), "usr")); 55 | 56 | strcpy(path, "usr"); 57 | TEST_ASSERT(!strcmp(basename(path), "usr")); 58 | 59 | strcpy(path, "/"); 60 | TEST_ASSERT(!strcmp(basename(path), "/")); 61 | 62 | strcpy(path, "."); 63 | TEST_ASSERT(!strcmp(basename(path), ".")); 64 | 65 | strcpy(path, ".."); 66 | TEST_ASSERT(!strcmp(basename(path), "..")); 67 | 68 | strcpy(path, ""); 69 | TEST_ASSERT(!strcmp(basename(path), ".")); 70 | } 71 | -------------------------------------------------------------------------------- /src/test-kernel/block.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "block.t" 21 | 22 | static void setup(void) { 23 | page_init(); 24 | block_init(); 25 | } 26 | 27 | static void assert_pattern(int pat, char *start, char *end) { 28 | char *current; 29 | 30 | TEST_ASSERT(start < end); 31 | 32 | for (current = start; current < end; ++current) { 33 | TEST_ASSERT(*current == pat); 34 | } 35 | } 36 | 37 | TEST(test_block_read) { 38 | int i; 39 | char buf[BLOCK_SIZE]; 40 | setup(); 41 | 42 | TEST_ASSERT(list_length(&used_blocks) == 0); 43 | 44 | for (i = 1; i < 8; ++i) { 45 | block_read(i, buf); 46 | TEST_ASSERT(list_length(&used_blocks) == i); 47 | 48 | block_read(i, buf); 49 | TEST_ASSERT(list_length(&used_blocks) == i); 50 | } 51 | } 52 | 53 | TEST(test_block_write) { 54 | int i; 55 | char buf[BLOCK_SIZE]; 56 | setup(); 57 | 58 | TEST_ASSERT(list_length(&used_blocks) == 0); 59 | 60 | for (i = 1; i < 8; ++i) { 61 | if (i & 0x1) { 62 | block_read(i, buf); 63 | TEST_ASSERT(list_length(&used_blocks) == i); 64 | } 65 | 66 | memset(buf, 0xff, BLOCK_SIZE); 67 | block_write(i, buf); 68 | 69 | TEST_ASSERT(list_length(&used_blocks) == i); 70 | 71 | memset(buf, 0, BLOCK_SIZE); 72 | block_read(i, buf); 73 | 74 | TEST_ASSERT(list_length(&used_blocks) == i); 75 | assert_pattern(0xff, buf, buf + BLOCK_SIZE); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/test-user/unistd_syscall_EFAULT.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | static void check_stat(void) { 25 | struct stat st; 26 | 27 | TEST_ASSERT(stat((const char *)0xffffffffUL, &st) == -1); 28 | TEST_ASSERT(errno == EFAULT); 29 | 30 | TEST_ASSERT(stat("/", (struct stat*)0xffffffffUL) == -1); 31 | TEST_ASSERT(errno == EFAULT); 32 | } 33 | 34 | static void check_execve(void) { 35 | char *argv[] = { 36 | "ONE", 37 | (char*)0xffffffffUL, 38 | "THREE", 39 | NULL, 40 | }; 41 | 42 | char *envp[] = { 43 | "PATH=/bin", 44 | "TERM=vt100", 45 | NULL, 46 | }; 47 | 48 | TEST_ASSERT(execve("/sbin/command_not_found", argv, envp) == -1); 49 | TEST_ASSERT(errno == EFAULT); 50 | 51 | TEST_ASSERT(execve("/sbin/command_not_found", (char**)0xffffffffUL, envp) == -1); 52 | TEST_ASSERT(errno == EFAULT); 53 | } 54 | 55 | static void check_writev(void) { 56 | struct iovec iov[] = { 57 | { "aiueo", 5 }, 58 | { (void*)0xffffffffUL, 5 }, 59 | }; 60 | 61 | TEST_ASSERT(writev(1, iov, 2) == -1); 62 | TEST_ASSERT(errno == EFAULT); 63 | 64 | TEST_ASSERT(writev(1, (struct iovec*)0xffffffffUL, 2) == -1); 65 | TEST_ASSERT(errno == EFAULT); 66 | } 67 | 68 | int main(void) { 69 | TEST_START(); 70 | 71 | check_stat(); 72 | check_execve(); 73 | check_writev(); 74 | 75 | TEST_SUCCEED(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /src/kernel/gic.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "lib/type.h" 18 | #include "gic.h" 19 | #include "io.h" 20 | 21 | #define GIC_DIST_BASE ((volatile uint8_t*)0x1e001000) 22 | #define GIC_CPU_BASE ((volatile uint8_t*)0x1e000100) 23 | 24 | #define GICC_CTLR 0x0000 25 | #define GICC_PMR 0x0004 26 | #define GICC_IAR 0x000c 27 | #define GICC_EOIR 0x0010 28 | 29 | #define GICD_CTLR 0x0000 30 | #define GICD_ISENABLER(n) (GIC_DIST_BASE + 0x100 + (n / 32) * 4) 31 | #define GICD_ITARGETSR(n) (GIC_DIST_BASE + 0x800 + (n / 4) * 4) 32 | #define GICD_ICFGR(n) (GIC_DIST_BASE + 0xc00 + (n / 16) * 4) 33 | 34 | void gic_init(void) { 35 | // GICC_PMR: 36 | io_write32(GIC_CPU_BASE + GICC_PMR, 0xff); 37 | 38 | // GICC_CTLR: 39 | io_write32(GIC_CPU_BASE + GICC_CTLR, 0x1); 40 | 41 | // GICD_CTLR: 42 | io_write32(GIC_DIST_BASE + GICD_CTLR, 0x1); 43 | } 44 | 45 | void gic_enable_irq(int id) { 46 | // GICD_ISENABLERn: 47 | io_write32(GICD_ISENABLER(id), io_read32(GICD_ISENABLER(id)) | (0x1 << (id & 0x1f))); 48 | 49 | // GICD_ITARGETSRn: 50 | io_write32(GICD_ITARGETSR(id), io_read32(GICD_ITARGETSR(id)) | (0x1 << ((id & 0x3) * 8))); 51 | 52 | // GICD_ICFGRn: 53 | io_write32(GICD_ICFGR(id), io_read32(GICD_ICFGR(id)) & ~(0x3 << ((id & 0xf) * 2))); 54 | } 55 | 56 | uint32_t gic_interrupt_acknowledge(void) { 57 | // GICC_IAR 58 | return io_read32(GIC_CPU_BASE + GICC_IAR) & 0x3ff; 59 | } 60 | 61 | void gic_end_of_interrupt(uint32_t irq) { 62 | // GICC_EOIR 63 | io_write32(GIC_CPU_BASE + GICC_EOIR, irq & 0x3ff); 64 | } 65 | -------------------------------------------------------------------------------- /src/test-kernel/lib/arithmetic.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "lib/arithmetic.t" 21 | 22 | TEST(test_add_overflow_unsigned_long) { 23 | TEST_ASSERT(!add_overflow_unsigned_long(0x00000000UL, 0x00000000UL)); 24 | TEST_ASSERT(!add_overflow_unsigned_long(0xffff0000UL, 0x0000ffffUL)); 25 | TEST_ASSERT(!add_overflow_unsigned_long(0xfffffffeUL, 0x00000001UL)); 26 | 27 | TEST_ASSERT(add_overflow_unsigned_long(0xffffffffUL, 0x00000001UL)); 28 | TEST_ASSERT(add_overflow_unsigned_long(0xffff0000UL, 0x0001ffffUL)); 29 | TEST_ASSERT(add_overflow_unsigned_long(0xffffffffUL, 0xffffffffUL)); 30 | } 31 | 32 | TEST(test_add_overflow_long_long) { 33 | TEST_ASSERT(add_overflow_long_long(LLONG_MAX, 1)); 34 | TEST_ASSERT(!add_overflow_long_long(LLONG_MAX, 0)); 35 | 36 | TEST_ASSERT(add_overflow_long_long(1, LLONG_MAX)); 37 | TEST_ASSERT(!add_overflow_long_long(0, LLONG_MAX)); 38 | 39 | TEST_ASSERT(add_overflow_long_long(LLONG_MIN, -1)); 40 | TEST_ASSERT(!add_overflow_long_long(LLONG_MIN, 0)); 41 | 42 | TEST_ASSERT(add_overflow_long_long(-1, LLONG_MIN)); 43 | TEST_ASSERT(!add_overflow_long_long(0, LLONG_MIN)); 44 | 45 | TEST_ASSERT(add_overflow_long_long(LLONG_MAX, LLONG_MAX)); 46 | TEST_ASSERT(add_overflow_long_long(LLONG_MIN, LLONG_MIN)); 47 | TEST_ASSERT(!add_overflow_long_long(LLONG_MAX, LLONG_MIN)); 48 | 49 | TEST_ASSERT(!add_overflow_long_long(1, 1)); 50 | TEST_ASSERT(!add_overflow_long_long(1, -1)); 51 | TEST_ASSERT(!add_overflow_long_long(-1, -1)); 52 | } 53 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/entry_parser.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | require 'coop/message_parser' 20 | 21 | class Coop::EntryParser 22 | STATE_FUNCTION = :function 23 | STATE_COMMENT = :comment 24 | 25 | def self.parse(data) 26 | new(data).parse 27 | end 28 | 29 | def initialize(data) 30 | @data = data 31 | @state = STATE_FUNCTION 32 | 33 | @comment = '' 34 | @messages = [] 35 | 36 | @entries = {} 37 | end 38 | 39 | def parse 40 | @data.each_line do |line| 41 | line.chomp! 42 | 43 | case @state 44 | when STATE_FUNCTION 45 | on_function(line) 46 | when STATE_COMMENT 47 | on_comment(line) 48 | end 49 | end 50 | 51 | @entries 52 | end 53 | 54 | private 55 | 56 | def on_function(line) 57 | case line 58 | when /^TEST\(([a-zA-Z0-9_]+)\);$/ 59 | @entries[$1] = @messages.dup 60 | @messages.clear 61 | when '/*' 62 | @state = STATE_COMMENT 63 | when '' 64 | else 65 | raise Coop::InvalidFormat, line.inspect 66 | end 67 | end 68 | 69 | def on_comment(line) 70 | case line 71 | when '*/' 72 | if /^copyright/i =~ @comment 73 | @comment = "" 74 | end 75 | 76 | while message = Coop::MessageParser.parse(@comment) 77 | @messages << message 78 | end 79 | 80 | raise Coop::InvalidFormat, @comment.inspect if @comment != "" 81 | @state = STATE_FUNCTION 82 | else 83 | @comment += (line + "\n") 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /src/test-user/alice_text.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_TEST_USER_ALICE_TEXT_H_ 18 | #define _CYANURUS_TEST_USER_ALICE_TEXT_H_ 19 | 20 | #define ALICE_TEXT \ 21 | "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, \"and what is the use of a book,\" thought Alice, \"without pictures or conversations?\"\n" \ 22 | "So she was considering in her own mind, (as well as she could, for the hot day made her feel very sleepy and stupid,) whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a white rabbit with pink eyes ran close by her.\n" \ 23 | "There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, \"Oh dear! Oh dear! I shall be too late!\" (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural;) but when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and, burning with curiosity, she ran across the field after it, and was just in time to see it pop down a large rabbit-hole under the hedge.\n" \ 24 | "In another moment down went Alice after it, never once considering how in the world she was to get out again.\n" 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/test-kernel/test.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "test.h" 18 | #include "logger.h" 19 | #include "lib/setjmp.h" 20 | 21 | #define MESSAGE_SIGNATURE "--a94e2gfwdd--" 22 | 23 | enum test_flag { 24 | TEST_SUCCESS = 0, 25 | TEST_FAILURE 26 | }; 27 | 28 | struct test_state { 29 | enum test_flag flag; 30 | 31 | struct { 32 | const char *file; 33 | unsigned int line; 34 | const char *func; 35 | } failure; 36 | }; 37 | 38 | static struct test_state current_state; 39 | static jmp_buf env; 40 | 41 | static void report_each(void) { 42 | switch (current_state.flag) { 43 | case TEST_SUCCESS: 44 | logger_info("$success"); 45 | break; 46 | 47 | case TEST_FAILURE: 48 | logger_info( 49 | "$failure @%s() (%s:%u)", 50 | current_state.failure.func, 51 | current_state.failure.file, 52 | current_state.failure.line 53 | ); 54 | break; 55 | } 56 | } 57 | 58 | void test_run(void (*func)(void)) { 59 | current_state.flag = TEST_SUCCESS; 60 | 61 | test_message_start("echo"); 62 | if (!setjmp(env)) { 63 | func(); 64 | } 65 | test_message_stop(); 66 | 67 | report_each(); 68 | } 69 | 70 | void test_fail(const char *file, unsigned int line, const char *func) { 71 | current_state.flag = TEST_FAILURE; 72 | 73 | current_state.failure.file = file; 74 | current_state.failure.line = line; 75 | current_state.failure.func = func; 76 | 77 | longjmp(env, 1); 78 | } 79 | 80 | void test_message_start(const char *name) { 81 | logger_info(":%s %s", name, MESSAGE_SIGNATURE); 82 | } 83 | 84 | void test_message_stop(void) { 85 | logger_info("\n" MESSAGE_SIGNATURE); 86 | } 87 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/serial.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | require 'socket' 20 | 21 | class Coop::Serial 22 | def initialize(endpoint) 23 | @thread = nil 24 | 25 | @input = Queue.new 26 | @output = Queue.new 27 | @endpoint = endpoint 28 | end 29 | 30 | def run 31 | @thread = Thread.new do 32 | Thread.handle_interrupt(Coop::AbortSelect => :never) { dispatch } 33 | end 34 | end 35 | 36 | def add_input(str) 37 | @input << str 38 | @thread.raise Coop::AbortSelect 39 | end 40 | 41 | def pop_output 42 | @output.pop 43 | end 44 | 45 | private 46 | 47 | def add_output(str) 48 | @output << str 49 | end 50 | 51 | def pop_input 52 | @input.pop(true) rescue nil 53 | end 54 | 55 | def input_empty? 56 | @input.empty? 57 | end 58 | 59 | def dispatch 60 | Socket.unix_server_loop(@endpoint) do |sock, addr| 61 | start_loop(sock) 62 | break 63 | end 64 | rescue EOFError, Errno::EIO, Errno::ECONNRESET 65 | end 66 | 67 | def start_loop(sock) 68 | rs = nil 69 | ws = nil 70 | 71 | loop do 72 | Thread.handle_interrupt(Coop::AbortSelect => :immediate) do 73 | begin 74 | rs, ws, = IO.select([sock], (input_empty? ? [] : [sock])) 75 | rescue Coop::AbortSelect 76 | retry 77 | end 78 | end 79 | 80 | unless rs.empty? 81 | add_output(sock.read_nonblock(4096)) 82 | end 83 | 84 | unless ws.empty? 85 | if input = pop_input 86 | sock.write_nonblock(input) 87 | end 88 | end 89 | 90 | Thread.pass 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /src/test-kernel/lib/stdarg.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "lib/stdarg.t" 21 | 22 | #include "lib/string.h" 23 | #include "logger.h" 24 | 25 | TEST(test_stdarg_snprintf_0) { 26 | char buf[1024]; 27 | 28 | TEST_ASSERT(snprintf(buf, sizeof(buf), "aiueo%%") > 0); 29 | TEST_ASSERT(strcmp(buf, "aiueo%") == 0); 30 | 31 | TEST_ASSERT(snprintf(buf, sizeof(buf), "char: '%c' '%1c' '%4c'", 'a', 'b', 'c') > 0); 32 | TEST_ASSERT(strcmp(buf, "char: 'a' 'b' ' c'") == 0); 33 | 34 | TEST_ASSERT(snprintf(buf, sizeof(buf), "str: '%s' '%1s' '%4s'", "ka", "ki", "ku") > 0); 35 | TEST_ASSERT(strcmp(buf, "str: 'ka' 'ki' ' ku'") == 0); 36 | 37 | TEST_ASSERT(snprintf(buf, sizeof(buf), "hex: '%x' '%6x' '%06x'", 0xffffffff, 0xb2, 0xc3) > 0); 38 | TEST_ASSERT(strcmp(buf, "hex: 'ffffffff' ' b2' '0000c3'") == 0); 39 | 40 | TEST_ASSERT(snprintf(buf, sizeof(buf), "signed dec: '%d' '%4d' '%04d'", 10, -1, -2) > 0); 41 | TEST_ASSERT(strcmp(buf, "signed dec: '10' ' -1' '-002'") == 0); 42 | 43 | TEST_ASSERT(snprintf(buf, sizeof(buf), "unsigned dec: '%u' '%4u' '%04u'", 0xffffffff, 1, 2) > 0); 44 | TEST_ASSERT(strcmp(buf, "unsigned dec: '4294967295' ' 1' '0002'") == 0); 45 | } 46 | 47 | TEST(test_stdarg_snprintf_1) { 48 | size_t i; 49 | char buf[1024]; 50 | 51 | TEST_ASSERT(snprintf(buf, (size_t)INT_MAX + 1, "aiueo") == EOF); 52 | 53 | TEST_ASSERT(snprintf(buf, sizeof(buf), "aiueo") == 5); 54 | TEST_ASSERT(strlen(buf) == 5); 55 | 56 | for (i = 6; i > 0; --i) { 57 | TEST_ASSERT(snprintf(buf, i, "aiueo") == 5); 58 | TEST_ASSERT(strlen(buf) == (i - 1)); 59 | } 60 | 61 | TEST_ASSERT(snprintf(buf, 0, "aiueo") == 5); 62 | } 63 | -------------------------------------------------------------------------------- /src/kernel/inode.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_FS_INODE_H_ 18 | #define _CYANURUS_FS_INODE_H_ 19 | 20 | #include "lib/type.h" 21 | #include "lib/list.h" 22 | #include "block.h" 23 | 24 | #define S_ISREG(m) (m & S_IFREG) 25 | #define S_ISDIR(m) (m & S_IFDIR) 26 | #define S_ISCHR(m) (m & S_IFCHR) 27 | #define S_ISBLK(m) (m & S_IFBLK) 28 | #define S_ISFIFO(m) (m & S_IFIFO) 29 | #define S_ISLNK(m) (m & S_IFLNK) 30 | #define S_ISSOCK(m) (m & S_IFSOCK) 31 | 32 | #define S_IFMT 0170000 33 | #define S_IFSOCK 0140000 34 | #define S_IFLNK 0120000 35 | #define S_IFREG 0100000 36 | #define S_IFBLK 0060000 37 | #define S_IFDIR 0040000 38 | #define S_IFCHR 0020000 39 | #define S_IFIFO 0010000 40 | #define S_ISUID 0004000 41 | #define S_ISGID 0002000 42 | #define S_ISVTX 0001000 43 | #define S_IRWXU 00700 44 | #define S_IRUSR 00400 45 | #define S_IWUSR 00200 46 | #define S_IXUSR 00100 47 | #define S_IRWXG 00070 48 | #define S_IRGRP 00040 49 | #define S_IWGRP 00020 50 | #define S_IXGRP 00010 51 | #define S_IRWXO 00007 52 | #define S_IROTH 00004 53 | #define S_IWOTH 00002 54 | #define S_IXOTH 00001 55 | 56 | typedef uint32_t inode_index; 57 | 58 | struct inode { 59 | inode_index index; 60 | struct list next; 61 | uint32_t mode; 62 | uint32_t nlinks; 63 | size_t size; 64 | }; 65 | 66 | void inode_init(void); 67 | struct inode *inode_create(uint32_t mode); 68 | int inode_destroy(struct inode *inode); 69 | int inode_truncate(struct inode *inode, size_t size); 70 | struct inode *inode_get(inode_index index); 71 | void inode_set(struct inode *inode); 72 | ssize_t inode_write(struct inode *inode, size_t size, size_t start, const void *data); 73 | ssize_t inode_read(struct inode *inode, size_t size, size_t start, void *data); 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/kernel/logger.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "logger.h" 18 | #include "lib/string.h" 19 | #include "lib/stdarg.h" 20 | #include "uart.h" 21 | #include "config.h" 22 | 23 | /* In order to disable gcc warnings (-Wtype-limits) */ 24 | static const enum logger_level logger_level = CYANURUS_LOGGER_LEVEL; 25 | 26 | static int logger_write(enum logger_level level, const char *format, va_list ap) { 27 | char str[128]; 28 | 29 | if (level < logger_level) { 30 | return 0; 31 | } 32 | 33 | if (vsnprintf(str, sizeof(str) - 1, format, ap) == EOF) { 34 | return -1; 35 | } 36 | strcat(str, "\n"); 37 | 38 | return uart_write(str, strlen(str)); 39 | } 40 | 41 | int logger_debug(const char *format, ...) { 42 | int ret; 43 | va_list ap; 44 | 45 | va_start(ap, format); 46 | ret = logger_write(LOGGER_LEVEL_DEBUG, format, ap); 47 | va_end(ap); 48 | 49 | return ret; 50 | } 51 | 52 | int logger_info(const char *format, ...) { 53 | int ret; 54 | va_list ap; 55 | 56 | va_start(ap, format); 57 | ret = logger_write(LOGGER_LEVEL_INFO, format, ap); 58 | va_end(ap); 59 | 60 | return ret; 61 | } 62 | 63 | int logger_warn(const char *format, ...) { 64 | int ret; 65 | va_list ap; 66 | 67 | va_start(ap, format); 68 | ret = logger_write(LOGGER_LEVEL_WARN, format, ap); 69 | va_end(ap); 70 | 71 | return ret; 72 | } 73 | 74 | int logger_error(const char *format, ...) { 75 | int ret; 76 | va_list ap; 77 | 78 | va_start(ap, format); 79 | ret = logger_write(LOGGER_LEVEL_ERROR, format, ap); 80 | va_end(ap); 81 | 82 | return ret; 83 | } 84 | 85 | int logger_fatal(const char *format, ...) { 86 | int ret; 87 | va_list ap; 88 | 89 | va_start(ap, format); 90 | ret = logger_write(LOGGER_LEVEL_FATAL, format, ap); 91 | va_end(ap); 92 | 93 | return ret; 94 | } 95 | -------------------------------------------------------------------------------- /src/test-user/termios_tcsetattr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define OFLAG (OPOST|ONLCR) 27 | #define IFLAG (ICRNL|IXON|IXANY|IMAXBEL) 28 | #define CFLAG (CREAD|CS8|B9600) 29 | #define LFLAG (ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOCTL|ECHOKE) 30 | 31 | int main(void) { 32 | struct termios tio, saved_tio; 33 | int i, fd, action; 34 | int optional_actions[] = { 35 | TCSANOW, TCSADRAIN, TCSAFLUSH 36 | }; 37 | TEST_START(); 38 | 39 | TEST_ASSERT(tcgetattr(0, &saved_tio) == 0); 40 | 41 | for (i = 0; i < 3; ++i) { 42 | action = optional_actions[i]; 43 | memset(&tio, 0, sizeof(struct termios)); 44 | 45 | fd = open("/a.txt", O_CREAT|O_WRONLY|O_TRUNC, 0644); 46 | TEST_ASSERT(tcsetattr(fd, action, &tio) == -1); 47 | TEST_ASSERT(errno == ENOTTY); 48 | 49 | TEST_ASSERT(tcsetattr(100, action, &tio) == -1); 50 | TEST_ASSERT(errno == EBADF); 51 | 52 | TEST_ASSERT(tcsetattr(0, action, &tio) == 0); 53 | TEST_ASSERT(tcgetattr(0, &tio) == 0); 54 | TEST_ASSERT(tio.c_oflag == 0); 55 | TEST_ASSERT(tio.c_iflag == 0); 56 | TEST_ASSERT(tio.c_cflag == 0); 57 | TEST_ASSERT(tio.c_lflag == 0); 58 | TEST_ASSERT(tio.c_cc[VTIME] == 0); 59 | TEST_ASSERT(tio.c_cc[VMIN] == 0); 60 | 61 | TEST_ASSERT(tcsetattr(0, action, &saved_tio) == 0); 62 | TEST_ASSERT(tcgetattr(0, &tio) == 0); 63 | TEST_ASSERT(tio.c_oflag == OFLAG); 64 | TEST_ASSERT(tio.c_iflag == IFLAG); 65 | TEST_ASSERT(tio.c_cflag == CFLAG); 66 | TEST_ASSERT(tio.c_lflag == LFLAG); 67 | TEST_ASSERT(tio.c_cc[VTIME] == 0); 68 | TEST_ASSERT(tio.c_cc[VMIN] == 1); 69 | } 70 | 71 | TEST_SUCCEED(); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /src/kernel/lib/signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _CYANURUS_LIB_SIGNAL_H_ 18 | #define _CYANURUS_LIB_SIGNAL_H_ 19 | 20 | #include "lib/type.h" 21 | 22 | #define NSIG 65 23 | 24 | #define SIG_ERR ((void (*)(int))-1) 25 | #define SIG_DFL ((void (*)(int)) 0) 26 | #define SIG_IGN ((void (*)(int)) 1) 27 | 28 | #define SIG_BLOCK 0 29 | #define SIG_UNBLOCK 1 30 | #define SIG_SETMASK 2 31 | 32 | #define SIGHUP 1 33 | #define SIGINT 2 34 | #define SIGQUIT 3 35 | #define SIGILL 4 36 | #define SIGTRAP 5 37 | #define SIGABRT 6 38 | #define SIGIOT 6 39 | #define SIGBUS 7 40 | #define SIGFPE 8 41 | #define SIGKILL 9 42 | #define SIGUSR1 10 43 | #define SIGSEGV 11 44 | #define SIGUSR2 12 45 | #define SIGPIPE 13 46 | #define SIGALRM 14 47 | #define SIGTERM 15 48 | #define SIGSTKFLT 16 49 | #define SIGCHLD 17 50 | #define SIGCONT 18 51 | #define SIGSTOP 19 52 | #define SIGTSTP 20 53 | #define SIGTTIN 21 54 | #define SIGTTOU 22 55 | #define SIGURG 23 56 | #define SIGXCPU 24 57 | #define SIGXFSZ 25 58 | #define SIGVTALRM 26 59 | #define SIGPROF 27 60 | #define SIGWINCH 28 61 | #define SIGIO 29 62 | #define SIGPOLL 29 63 | #define SIGPWR 30 64 | #define SIGSYS 31 65 | #define SIGUNUSED 31 66 | 67 | typedef struct { 68 | uint32_t __fields[2]; 69 | } sigset_t; 70 | 71 | int sigemptyset(sigset_t *set); 72 | int sigfillset(sigset_t *set); 73 | int sigaddset(sigset_t *set, int signum); 74 | int sigdelset(sigset_t *set, int signum); 75 | int sigismember(const sigset_t *set, int signum); 76 | int sigisemptyset(const sigset_t *set); 77 | int signotset(sigset_t *dest, const sigset_t *src); 78 | int sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right); 79 | int sigandset(sigset_t *dest, const sigset_t *left, const sigset_t *right); 80 | int sigpeekset(sigset_t *set); 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/kernel/tty.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "tty.h" 18 | #include "uart.h" 19 | #include "gic.h" 20 | #include "process.h" 21 | 22 | static struct process_waitq tty_read_waitq, tty_write_waitq; 23 | 24 | static int tty_getc(void) { 25 | while (1) { 26 | if (!uart_can_recv()) { 27 | uart_set_interrupt(O_RDONLY); 28 | process_sleep(&tty_read_waitq); 29 | uart_clear_interrupt(O_RDONLY); 30 | continue; 31 | } 32 | return uart_getc(); 33 | } 34 | } 35 | 36 | static int tty_putc(int c) { 37 | while (1) { 38 | if (!uart_can_send()) { 39 | uart_set_interrupt(O_WRONLY); 40 | process_sleep(&tty_write_waitq); 41 | uart_clear_interrupt(O_WRONLY); 42 | continue; 43 | } 44 | return uart_putc(c); 45 | } 46 | } 47 | 48 | static void wake_next(void) { 49 | process_wake(&tty_read_waitq); 50 | process_wake(&tty_write_waitq); 51 | } 52 | 53 | void tty_init(void) { 54 | gic_enable_irq(IRQ_UART0); 55 | 56 | process_waitq_init(&tty_read_waitq); 57 | process_waitq_init(&tty_write_waitq); 58 | } 59 | 60 | void tty_resume(void) { 61 | if (uart_can_recv()) { 62 | process_wake(&tty_read_waitq); 63 | } 64 | 65 | if (uart_can_send()) { 66 | process_wake(&tty_write_waitq); 67 | } 68 | } 69 | 70 | ssize_t tty_read(void *data, size_t size) { 71 | size_t i; 72 | char ch; 73 | char *buf = data; 74 | 75 | for (i = 0; i < size; ++i) { 76 | ch = tty_getc(); 77 | 78 | tty_putc(ch); 79 | buf[i] = ch; 80 | 81 | if (ch == '\n') { 82 | size = i + 1; 83 | goto done; 84 | } 85 | } 86 | 87 | done: 88 | wake_next(); 89 | return size; 90 | } 91 | 92 | ssize_t tty_write(const void *data, size_t size) { 93 | size_t i; 94 | const char *buf = data; 95 | 96 | for (i = 0; i < size; ++i) { 97 | tty_putc(buf[i]); 98 | } 99 | 100 | wake_next(); 101 | return size; 102 | } 103 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/session.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | require 'coop/resource' 20 | 21 | class Coop::Session 22 | TIMEOUT = 4.0 23 | 24 | Response = Struct.new(:result, :output) 25 | 26 | attr_reader :resource 27 | 28 | def self.respawn(kernel, session) 29 | session.close 30 | 31 | session = new(kernel) 32 | session.run 33 | 34 | session 35 | end 36 | 37 | def initialize(kernel) 38 | unless FileTest.exists?(kernel) 39 | raise ArgumentError, "kernel doesn't exist: #{kernel}" 40 | end 41 | 42 | @resource = Coop::Resource.create 43 | @cyanurus = Coop::Cyanurus.new(@resource) 44 | @qemu = Coop::Qemu.new(kernel, @resource) 45 | 46 | @threads = [] 47 | @ready = false 48 | end 49 | 50 | def run 51 | @threads << @cyanurus.run 52 | @threads << @qemu.run 53 | 54 | check_is_ready 55 | end 56 | 57 | def exec_run(name, stdin_data:) 58 | @cyanurus.send("$run #{name}") 59 | 60 | if stdin_data 61 | @cyanurus.add_input(stdin_data) 62 | end 63 | 64 | t = Thread.new do 65 | output = @cyanurus.recv 66 | result = @cyanurus.recv 67 | 68 | Response.new(result, output) 69 | end 70 | 71 | if t.join(TIMEOUT) 72 | check_is_ready 73 | t.value 74 | else 75 | t.kill 76 | @ready = false 77 | 78 | result = Coop::Message.new('failure', '(unresponsive)') 79 | output = Coop::Message.new('echo', @cyanurus.unprocessed_data) 80 | 81 | Response.new(result, output) 82 | end 83 | end 84 | 85 | def close 86 | @qemu.add_command("quit") 87 | 88 | @threads.each do |t| 89 | t.join 90 | end 91 | 92 | @resource.release 93 | end 94 | 95 | def ready? 96 | @ready 97 | end 98 | 99 | private 100 | 101 | def check_is_ready 102 | message = @cyanurus.recv 103 | @ready = (message.name == "please") 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /src/test-kernel/lib/bitset.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "lib/bitset.t" 21 | 22 | #include "lib/string.h" 23 | 24 | #define BITSET_NBITS 32 25 | 26 | TEST(test_bitset_sizeof) { 27 | TEST_ASSERT((sizeof(bitset) * 8) == BITSET_NBITS); 28 | } 29 | 30 | TEST(test_bitset_mask) { 31 | int i; 32 | 33 | for (i = 0; i < BITSET_NBITS; ++i) { 34 | TEST_ASSERT(bitset_mask(i) == (1U << i)); 35 | } 36 | 37 | for (i = 0; i < BITSET_NBITS; ++i) { 38 | TEST_ASSERT(bitset_mask(BITSET_NBITS + i) == (1U << i)); 39 | } 40 | } 41 | 42 | TEST(test_bitset_slot) { 43 | int i; 44 | 45 | for (i = 0; i < BITSET_NBITS; ++i) { 46 | TEST_ASSERT(bitset_slot(i) == 0); 47 | } 48 | 49 | for (i = 0; i < BITSET_NBITS; ++i) { 50 | TEST_ASSERT(bitset_slot(BITSET_NBITS + i) == 1); 51 | } 52 | } 53 | 54 | TEST(test_bitset_nslots) { 55 | int i; 56 | TEST_ASSERT(bitset_nslots(0) == 0); 57 | 58 | for (i = 0; i < 32; ++i) { 59 | TEST_ASSERT(bitset_nslots(i+1) == 1); 60 | } 61 | 62 | for (i = 0; i < 32; ++i) { 63 | TEST_ASSERT(bitset_nslots(i+BITSET_NBITS+1) == 2); 64 | } 65 | } 66 | 67 | TEST(test_bitset_add) { 68 | bitset s[2]; 69 | memset(s, 0, sizeof(s)); 70 | 71 | bitset_add(s, 0); 72 | bitset_add(s, 31); 73 | bitset_add(s, 32); 74 | bitset_add(s, 63); 75 | 76 | TEST_ASSERT(s[0] == 0x80000001); 77 | TEST_ASSERT(s[1] == 0x80000001); 78 | } 79 | 80 | TEST(test_bitset_remove) { 81 | bitset s[2]; 82 | memset(s, 0xff, sizeof(s)); 83 | 84 | bitset_remove(s, 0); 85 | bitset_remove(s, 31); 86 | bitset_remove(s, 32); 87 | bitset_remove(s, 63); 88 | 89 | TEST_ASSERT(s[0] == 0x7ffffffe); 90 | TEST_ASSERT(s[1] == 0x7ffffffe); 91 | } 92 | 93 | TEST(test_bitset_test) { 94 | bitset s[2] = {0x00000001, 0x00000001}; 95 | 96 | TEST_ASSERT(bitset_test(s, 0)); 97 | TEST_ASSERT(bitset_test(s, 32)); 98 | 99 | TEST_ASSERT(!bitset_test(s, 1)); 100 | TEST_ASSERT(!bitset_test(s, 33)); 101 | } 102 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/qemu.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | require 'pty' 20 | 21 | class Coop::Qemu 22 | COMMAND = %w( 23 | qemu-system-arm 24 | -M vexpress-a9 25 | -m 1G 26 | -nographic 27 | -kernel %{kernel} 28 | -serial %{serial} 29 | -drive if=sd,file=%{disk},format=raw 30 | 2>/dev/null 31 | ).join(' ') 32 | 33 | def initialize(kernel, resource) 34 | @thread = nil 35 | @commands = Queue.new 36 | @kernel = kernel 37 | @resource = resource 38 | end 39 | 40 | def run 41 | @thread = Thread.new do 42 | Thread.handle_interrupt(Coop::AbortSelect => :never) { dispatch } 43 | end 44 | end 45 | 46 | def add_command(command) 47 | @commands << command 48 | @thread.raise Coop::AbortSelect 49 | end 50 | 51 | private 52 | 53 | def pop_command 54 | @commands.pop(true) rescue nil 55 | end 56 | 57 | def command_empty? 58 | @commands.empty? 59 | end 60 | 61 | def dispatch 62 | sock = @resource.sock 63 | disk = @resource.disk 64 | 65 | Thread.pass until FileTest.socket?(sock) 66 | command = (COMMAND % {kernel: @kernel, serial: 'unix:' + sock, disk: disk}) 67 | 68 | PTY.getpty(command) do |read, write, pid| 69 | start_loop(read, write) 70 | end 71 | rescue EOFError, Errno::EIO 72 | end 73 | 74 | def start_loop(read, write) 75 | rs = nil 76 | ws = nil 77 | 78 | loop do 79 | Thread.handle_interrupt(Coop::AbortSelect => :immediate) do 80 | begin 81 | rs, ws, = IO.select([read], (command_empty? ? [] : [write])) 82 | rescue Coop::AbortSelect 83 | retry 84 | end 85 | end 86 | 87 | unless rs.empty? 88 | read.read_nonblock(4096) 89 | end 90 | 91 | unless ws.empty? 92 | if command = pop_command 93 | write.write_nonblock(command + "\n") 94 | end 95 | end 96 | 97 | Thread.pass 98 | end 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /tool/coop/lib/coop/test.rb: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | =begin 4 | Copyright 2014 Akira Midorikawa 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | =end 18 | 19 | class Coop::Test 20 | def initialize(name, messages, app, session) 21 | @name = name 22 | @messages = messages 23 | @app = app 24 | @session = session 25 | end 26 | 27 | def run 28 | prepare_fixture 29 | response = @session.exec_run(@name, stdin_data: stdin_data) 30 | handle_response(response) 31 | end 32 | 33 | def shutdown_required? 34 | @messages.any?{|m| m.name == 'shutdown'} 35 | end 36 | 37 | private 38 | 39 | def stats 40 | @app.stats 41 | end 42 | 43 | def disabled_echo_on_check? 44 | @messages.any?{|m| m.name == 'disable_echo_on_check'} 45 | end 46 | 47 | def prepare_fixture 48 | fixture = Coop::Message::Fixture.new(@app, @session) 49 | 50 | @messages.each do |message| 51 | fixture.dispatch(@name, message.body) if message.name == 'fixture' 52 | end 53 | end 54 | 55 | def stdin_data 56 | @messages.each do |message| 57 | return message.body if message.name == 'stdin' 58 | end 59 | 60 | nil 61 | end 62 | 63 | def check_evidence(response) 64 | check = Coop::Message::Check.new(@app, @session) 65 | messages = @messages.select{|message| message.name == 'check' } 66 | 67 | if messages.empty? 68 | stats.fail(@name, '($check not found)') 69 | return 70 | end 71 | 72 | messages.each do |message| 73 | check.dispatch(@name, message.body, response) 74 | end 75 | end 76 | 77 | def handle_response(response) 78 | result = response.result 79 | output = response.output 80 | 81 | if output.name != 'echo' 82 | STDERR.puts "unknown message: #{output.name}" 83 | return 84 | end 85 | 86 | case result.name 87 | when 'success' 88 | stats.succeed(@name) 89 | when 'failure' 90 | stats.fail(@name, result.body) 91 | when 'check' 92 | check_evidence(response) 93 | return if disabled_echo_on_check? 94 | else 95 | STDERR.puts "unknown message: #{result.name}" 96 | end 97 | 98 | print(output.body) 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /src/test-kernel/elf.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "test.h" 20 | #include "elf.t" 21 | 22 | #include "mmu.h" 23 | 24 | #define INIT_PID 1 25 | #define INIT_PATH "/sbin/init" 26 | 27 | static void setup(void) { 28 | page_init(); 29 | fs_init(); 30 | 31 | mmu_init(); 32 | mmu_enable(); 33 | } 34 | 35 | static void assert_pattern(int pat, uint8_t *start, uint8_t *end) { 36 | uint8_t *current; 37 | 38 | TEST_ASSERT(start < end); 39 | 40 | for (current = start; current < end; ++current) { 41 | TEST_ASSERT(*current == pat); 42 | } 43 | } 44 | 45 | TEST(test_elf) { 46 | struct elf_executable executable; 47 | 48 | uint8_t *text, *data; 49 | uint32_t text_start, text_end; 50 | uint32_t data_start, data_end; 51 | uint32_t fill_start, fill_end; 52 | 53 | setup(); 54 | elf_load(INIT_PATH, &executable); 55 | 56 | text = page_address(executable.text.page); 57 | data = page_address(executable.data.page); 58 | 59 | text_start = executable.text.addr; 60 | text_end = executable.text.addr + executable.text.memory_size; 61 | data_start = executable.data.addr; 62 | data_end = executable.data.addr + executable.data.memory_size; 63 | TEST_ASSERT(text_start <= text_end); 64 | TEST_ASSERT(text_end <= data_start); 65 | TEST_ASSERT(data_start <= data_end); 66 | 67 | fill_start = text_start - 0x1000; 68 | fill_end = data_end + 0x1000; 69 | TEST_ASSERT(fill_start < fill_end); 70 | 71 | mmu_alloc(INIT_PID, fill_start, fill_end - fill_start); 72 | mmu_set_ttb(INIT_PID); 73 | 74 | memset((char*)fill_start, 0xff, fill_end - fill_start); 75 | elf_copy(&executable); 76 | 77 | TEST_ASSERT(!memcmp(text, (void*)executable.text.addr, executable.text.memory_size)); 78 | TEST_ASSERT(!memcmp(data, (void*)executable.data.addr, executable.data.file_size)); 79 | 80 | assert_pattern( 81 | 0x00, 82 | (uint8_t*)executable.data.addr + executable.data.file_size, 83 | (uint8_t*)executable.data.addr + executable.data.memory_size 84 | ); 85 | 86 | assert_pattern(0xff, (uint8_t*)fill_start, (uint8_t*)text_start); 87 | assert_pattern(0xff, (uint8_t*)text_end, (uint8_t*)data_start); 88 | assert_pattern(0xff, (uint8_t*)data_end, (uint8_t*)fill_end); 89 | 90 | elf_release(&executable); 91 | TEST_ASSERT(!executable.text.page); 92 | TEST_ASSERT(!executable.data.page); 93 | } 94 | -------------------------------------------------------------------------------- /src/kernel/lib/signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "lib/signal.h" 18 | 19 | int sigemptyset(sigset_t *set) { 20 | set->__fields[0] = 0; 21 | set->__fields[1] = 0; 22 | return 0; 23 | } 24 | 25 | int sigfillset(sigset_t *set) { 26 | set->__fields[0] = 0xffffffff; 27 | set->__fields[1] = 0xffffffff; 28 | return 0; 29 | } 30 | 31 | int sigaddset(sigset_t *set, int signum) { 32 | if (signum < 1 || signum >= NSIG) { 33 | return -1; 34 | } 35 | 36 | if (signum > 32) { 37 | set->__fields[1] |= (1 << (signum - 33)); 38 | } else { 39 | set->__fields[0] |= (1 << (signum - 1)); 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | int sigdelset(sigset_t *set, int signum) { 46 | if (signum < 1 || signum >= NSIG) { 47 | return -1; 48 | } 49 | 50 | if (signum > 32) { 51 | set->__fields[1] &= ~(1 << (signum - 33)); 52 | } else { 53 | set->__fields[0] &= ~(1 << (signum - 1)); 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | int sigismember(const sigset_t *set, int signum) { 60 | if (signum < 1 || signum >= NSIG) { 61 | return -1; 62 | } 63 | 64 | if (signum > 32) { 65 | return (set->__fields[1] & (1 << (signum - 33))) ? 1 : 0; 66 | } else { 67 | return (set->__fields[0] & (1 << (signum - 1))) ? 1 : 0; 68 | } 69 | } 70 | 71 | int sigisemptyset(const sigset_t *set) { 72 | return (!set->__fields[0] && !set->__fields[1]) ? 1 : 0; 73 | } 74 | 75 | int signotset(sigset_t *dest, const sigset_t *src) { 76 | dest->__fields[0] = ~src->__fields[0]; 77 | dest->__fields[1] = ~src->__fields[1]; 78 | return 0; 79 | } 80 | 81 | int sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right) { 82 | dest->__fields[0] = left->__fields[0] | right->__fields[0]; 83 | dest->__fields[1] = left->__fields[1] | right->__fields[1]; 84 | return 0; 85 | } 86 | 87 | int sigandset(sigset_t *dest, const sigset_t *left, const sigset_t *right) { 88 | dest->__fields[0] = left->__fields[0] & right->__fields[0]; 89 | dest->__fields[1] = left->__fields[1] & right->__fields[1]; 90 | return 0; 91 | } 92 | 93 | int sigpeekset(sigset_t *set) { 94 | int sig; 95 | 96 | if ((sig = __builtin_ffs(set->__fields[0])) > 0) { 97 | return sig; 98 | } 99 | 100 | if ((sig = __builtin_ffs(set->__fields[1])) > 0) { 101 | return sig + 32; 102 | } 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /src/kernel/block.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Akira Midorikawa 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "block.h" 18 | #include "lib/string.h" 19 | #include "lib/list.h" 20 | #include "buddy.h" 21 | #include "page.h" 22 | #include "slab.h" 23 | #include "system.h" 24 | #include "logger.h" 25 | #include "mmc.h" 26 | 27 | #define BLOCKS_PER_PAGE (PAGE_SIZE/BLOCK_SIZE) 28 | 29 | struct block { 30 | block_index index; 31 | struct list next; 32 | struct page *page; 33 | void *data; 34 | }; 35 | 36 | static struct slab_cache* block_cache; 37 | 38 | static struct list used_blocks; 39 | static struct list free_blocks; 40 | 41 | static void prepare_blocks(void) { 42 | int i; 43 | char *address; 44 | struct page *page; 45 | struct block *block; 46 | 47 | page = buddy_alloc(PAGE_SIZE); 48 | address = page_address(page); 49 | 50 | for (i = 0; i < BLOCKS_PER_PAGE; ++i) { 51 | block = slab_cache_alloc(block_cache); 52 | memset(block, 0, sizeof(struct block)); 53 | 54 | block->page = page; 55 | block->data = address + (i * BLOCK_SIZE); 56 | 57 | list_add(&free_blocks, &block->next); 58 | } 59 | } 60 | 61 | static struct block *get_block(block_index index) { 62 | struct block *block; 63 | 64 | list_foreach(block, &used_blocks, next) { 65 | if (block->index == index) { 66 | return block; 67 | } 68 | } 69 | 70 | if (list_empty(&free_blocks)) { 71 | prepare_blocks(); 72 | } 73 | 74 | block = NULL; 75 | list_foreach(block, &free_blocks, next) { 76 | list_remove(&block->next); 77 | break; 78 | } 79 | 80 | if (!block) { 81 | logger_fatal("broken block cache"); 82 | system_halt(); 83 | } 84 | 85 | block->index = index; 86 | list_add(&used_blocks, &block->next); 87 | 88 | mmc_read(index * BLOCK_SIZE, BLOCK_SIZE, block->data); 89 | return block; 90 | } 91 | 92 | void block_init(void) { 93 | mmc_init(); 94 | 95 | block_cache = slab_cache_create("block", sizeof(struct block)); 96 | 97 | list_init(&used_blocks); 98 | list_init(&free_blocks); 99 | } 100 | 101 | void block_read(block_index index, void *data) { 102 | struct block *block = get_block(index); 103 | memcpy(data, block->data, BLOCK_SIZE); 104 | } 105 | 106 | void block_write(block_index index, const void *data) { 107 | struct block *block = get_block(index); 108 | memcpy(block->data, data, BLOCK_SIZE); 109 | mmc_write(index * BLOCK_SIZE, BLOCK_SIZE, block->data); 110 | } 111 | --------------------------------------------------------------------------------