├── .gdbinit.tmpl ├── .gitignore ├── GNUmakefile ├── Readme.md ├── boot ├── Makefrag ├── boot.S ├── main.c └── sign.pl ├── conf └── env.mk ├── documents ├── MOS系统设计.pdf ├── [finish](lab1)Boot.md ├── [finish](lab2)内存管理.md ├── [finish](lab3)进程管理.md ├── [finish](lab4)多核任务调度.md ├── [finish](lab5)文件系统.md ├── [finish]macOS编译运行配置.md ├── [finish]内存管理进阶.md ├── [finish]图形化界面.md ├── [finish]图形库.md ├── [finish]工作路径&用户空间工具.md ├── [finish]被动读写锁&核间中断&原子操作.md ├── [planning]文件内存映射mmap.md └── img │ ├── 1.jpg │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── GUI1.png │ ├── GUI2.png │ ├── GUI3.png │ ├── GUI4.png │ ├── cga.png │ ├── disk.png │ ├── fd.png │ ├── file.png │ ├── graph.png │ ├── ioapic.gif │ ├── ps1.png │ └── ps2.png ├── fs ├── Makefrag ├── bc.c ├── fs.c ├── fs.h ├── fsformat.c ├── ide.c ├── lorem ├── motd ├── newmotd ├── script ├── serv.c ├── test.c ├── testshell.key └── testshell.sh ├── image ├── Makefile ├── Readme.md ├── fs.img └── kernel.img ├── inc ├── COPYRIGHT ├── args.h ├── assert.h ├── atomic.h ├── bitmap.h ├── bprintf.h ├── canvas.h ├── elf.h ├── env.h ├── error.h ├── fd.h ├── file.h ├── font.h ├── fs.h ├── interface.h ├── kbdreg.h ├── lib.h ├── memlayout.h ├── mmu.h ├── partition.h ├── spinlock.h ├── stab.h ├── stdarg.h ├── stdio.h ├── string.h ├── syscall.h ├── sysinfo.h ├── time.h ├── trap.h ├── types.h ├── usyscall.h └── x86.h ├── kern ├── COPYRIGHT ├── Makefrag ├── console.c ├── console.h ├── cpu.h ├── entry.S ├── entrypgdir.c ├── env.c ├── env.h ├── graph.c ├── graph.h ├── init.c ├── kclock.c ├── kclock.h ├── kdebug.c ├── kdebug.h ├── kernel.ld ├── lapic.c ├── monitor.c ├── monitor.h ├── mpconfig.c ├── mpentry.S ├── picirq.c ├── picirq.h ├── pmap.c ├── pmap.h ├── printf.c ├── prwlock.c ├── prwlock.h ├── rwlock.c ├── rwlock.h ├── sched.c ├── sched.h ├── spinlock.c ├── spinlock.h ├── syscall.c ├── syscall.h ├── time.c ├── time.h ├── trap.c ├── trap.h └── trapentry.S ├── lib ├── Makefrag ├── args.c ├── bitmap.c ├── bprintf.c ├── canvas.c ├── console.c ├── dir.c ├── entry.S ├── exit.c ├── fd.c ├── file.c ├── font_ascii.c ├── font_cn.c ├── fork.c ├── fprintf.c ├── interface.c ├── ipc.c ├── libmain.c ├── pageref.c ├── panic.c ├── pfentry.S ├── pgfault.c ├── pipe.c ├── printf.c ├── printfmt.c ├── readline.c ├── screen.c ├── spawn.c ├── spinlock.c ├── string.c ├── syscall.c └── wait.c ├── mergedep.pl └── user ├── Makefrag ├── applauncher.c ├── bmpviewer.c ├── calendar.c ├── cat.c ├── echo.c ├── hello.c ├── icons ├── cal.bmp ├── calsel.bmp ├── clock.bmp ├── clock.plt ├── drive.bmp ├── drivesel.bmp ├── launcher.plt ├── rocket.bmp ├── setting.bmp ├── settingsel.bmp ├── sysinfo.bmp ├── sysinfo.plt ├── term.bmp ├── term.plt ├── termbg.bmp ├── termsel.bmp └── title.bmp ├── ls.c ├── lsfd.c ├── mkdir.c ├── msh.c ├── pwd.c ├── sh.c ├── sys_func_test ├── badsegment.c ├── breakpoint.c ├── buggyhello.c ├── buggyhello2.c ├── divzero.c ├── dumbfork.c ├── evilhello.c ├── fairness.c ├── faultalloc.c ├── faultallocbad.c ├── faultbadhandler.c ├── faultdie.c ├── faultevilhandler.c ├── faultio.c ├── faultnostack.c ├── faultread.c ├── faultreadkernel.c ├── faultregs.c ├── faultwrite.c ├── faultwritekernel.c ├── forktree.c ├── icode.c ├── idle.c ├── init.c ├── initsh.c ├── num.c ├── pingpong.c ├── pingpongs.c ├── primes.c ├── primespipe.c ├── rwlocktest.c ├── sendpage.c ├── softint.c ├── spawnfaultio.c ├── spawnhello.c ├── spawninit.c ├── spin.c ├── stresssched.c ├── testbss.c ├── testfdsharing.c ├── testfile.c ├── testkbd.c ├── testmalloc.c ├── testpipe.c ├── testpiperace.c ├── testpiperace2.c ├── testptelibrary.c ├── testpteshare.c ├── testshell.c ├── writemotd.c └── yield.c ├── sysinfo.c ├── system.c ├── term.c ├── touch.c └── user.ld /.gdbinit.tmpl: -------------------------------------------------------------------------------- 1 | set $lastcs = -1 2 | 3 | define hook-stop 4 | # There doesn't seem to be a good way to detect if we're in 16- or 5 | # 32-bit mode, but we always run with CS == 8 in 32-bit mode. 6 | if $cs == 8 || $cs == 27 7 | if $lastcs != 8 && $lastcs != 27 8 | set architecture i386 9 | end 10 | x/i $pc 11 | else 12 | if $lastcs == -1 || $lastcs == 8 || $lastcs == 27 13 | set architecture i8086 14 | end 15 | # Translate the segment:offset into a physical address 16 | printf "[%4x:%4x] ", $cs, $eip 17 | x/i $cs*16+$eip 18 | end 19 | set $lastcs = $cs 20 | end 21 | 22 | echo + target remote localhost:1234\n 23 | target remote localhost:1234 24 | 25 | # If this fails, it's probably because your GDB doesn't support ELF. 26 | echo + symbol-file obj/kern/kernel\n 27 | symbol-file obj/kern/kernel 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /obj 2 | /jos.in 3 | /jos.log 4 | /jos.out 5 | /jos.out.* 6 | /jos.cmd 7 | /.gdbinit 8 | /wget.log 9 | /qemu.pcap 10 | /qemu.pcap.* 11 | /qemu.out 12 | /qemu.log 13 | /gradelib.pyc 14 | /lab*-handin.tar.gz 15 | /lab?/ 16 | /sol?/ 17 | /myapi.key 18 | /.suf 19 | **/.DS_Store 20 | settings.json 21 | .vscode/ 22 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Micro homemade OS 2 | 3 | `MOS`是一个基于`MIT 6.828 JOS`的自制操作系统。在完成`JOS`实验的基础上添加了很多新特性,并提供了基础的图形界面与应用程序接口。关于此操作系统的详细设计与实现文档见`./documents`。 4 | 5 | 6 | 7 | ## CGA 显示界面 8 | 9 | ![](./documents/img/cga.png) 10 | 11 | ## 图像显示界面 12 | 13 | 在启动后`msh`中输入`$ applauncher`启动图形化界面应用启动器 14 | 15 | ```shell 16 | ====Graph mode on==== 17 | scrnx = 1024 18 | scrny = 768 19 | MMIO VRAM = 0xef800000 20 | ===================== 21 | SMP: CPU 0 found 1 CPU(s) 22 | enabled interrupts: 1 2 4 23 | FS is running 24 | FS can do I/O 25 | Device 1 presence: 1 26 | block cache is good 27 | superblock is good 28 | bitmap is good 29 | 30 | # msh in / [10:02:07] 31 | $ applauncher 32 | ``` 33 | 34 | 35 | 36 | ![](./documents/img/GUI1.png) 37 | 38 | ![](./documents/img/GUI2.png) 39 | 40 | ![](./documents/img/GUI4.png) 41 | 42 | ![](./documents/img/GUI3.png) 43 | 44 | ## 运行环境 45 | 46 | 运行需要安装`QEMU`,请到`image`文件夹下查看。 47 | 48 | ## 编译环境 49 | 50 | 需要配置`/conf/env.mk`下的`qemu`所在路径 51 | 52 | ```shell 53 | $ i386-elf-gcc -v 54 | 使用内建 specs。 55 | COLLECT_GCC=i386-elf-gcc 56 | COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/i386-elf/4.7.2/lto-wrapper 57 | 目标:i386-elf 58 | 配置为:/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_cross_i386-elf-gcc/i386-elf-gcc/work/gcc-4.7.2/configure --prefix=/opt/local --target=i386-elf --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/i386-elf-gcc --with-system-zlib --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --enable-stage1-checking --enable-multilib --with-newlib --enable-languages=c,c++ 59 | 线程模型:single 60 | gcc 版本 4.7.2 (GCC) 61 | ``` 62 | 63 | `MIT`课程中使用`linux`的环境,这里配置了`macOS`下的开发环境。 64 | 65 | 具体配置方法见`./documents/[finish] macOS编译运行配置.md` 66 | 67 | 68 | 69 | ## MIT6.828 JOS lab 完成列表 70 | 71 | - [x] lab1 Booting a PC 72 | - [x] lab1 challenge: VGA GUI 73 | - [x] lab2 Memory Management 74 | - [x] lab2 challenge 75 | - [x] lab3 User Environments 76 | - [x] lab3 challenge: single step debug 77 | - [x] lab4 Preemptive Multitasking 78 | - [ ] lab4 challenge 79 | - [x] Lab 5: File system, Spawn and Shell 80 | - [ ] lab5 challenge 81 | 82 | 83 | 84 | 85 | ## 实验中已支持的特性 86 | 87 | - 段页式内存管理 (详见`\lab_record\lab2.md`) 88 | - 支持进程(`Environments`) 89 | - 进程切换 90 | - 进程间通讯,通过`syscall`实现 91 | - 进程单独地址空间 92 | - `spawn`创建进程,`fork`使用`Read Copy Update`策略 93 | - 支持抢断式任务调度 94 | - 支持多核`CPU` 95 | - 支持`IPI`,提供`IPI`接口 96 | - 支持大内核锁(基于自旋锁) 97 | - 系统服务`syscall` 98 | - 打印字符 99 | - 获取字符 100 | - 获取进程编号 101 | - 回收进程 102 | - 主动调度 103 | - `fork` 104 | - 设置进程状态 105 | - 申请页,映射页,取消映射 106 | - **用户空间页错误处理入口设置** 107 | - `IPC`进程间通讯 108 | - 用户空间异常处理栈设置 109 | - 支持页错误用户空间处理 110 | - 支持简易文件系统 (CS结构) 111 | - 支持文件描述符 112 | - 支持`pipe` 113 | - 用户空间工具 114 | - `sh`简易`shell` 115 | 116 | 117 | 118 | ## 新特性 119 | 120 | - 支持原子操作 121 | - 支持读写锁 122 | - 支持针对单一核心`IPI` 123 | - 支持`PRWLock` 124 | - 支持基本图形显示 125 | - 支持中英文显示(中英文点阵字库) 126 | - 支持进程工作目录 提供`getcwd`与`chdir` 127 | - 新的`syscall` 128 | - `SYS_env_set_workpath` 修改工作路径 129 | - 新的用户程序 130 | - `ls` 功能完善 131 | - `pwd` 输出当前工作目录 132 | - `cat` 接入工作目录 133 | - `touch` 由于文件属性没啥可改的,用于创建文件 134 | - `mkdir` 创建目录文件 135 | - `msh` 更高级的`shell` 还未完全完工 支持`cd` 支持默认二进制路径为 `bin` 136 | - 调整目标磁盘生成工具 137 | - 支持从RTC读取时间 138 | - 支持`kmalloc/kfree`,支持分配连续空间 139 | - 提供`RW/RW`用户内核共享`framebuffer/palette` 140 | - 提供用户`GUI`接口 141 | - 提供调色板预设 142 | - 提供`Applauncher` 143 | - 日历应用 144 | - 系统信息应用 145 | - 模拟`CGA`显示模式的终端程序(基于`pipe`) 146 | 147 | ​ 148 | 149 | ## 计划完成的特性 150 | 151 | - `mmap` -------------------------------------------------------------------------------- /boot/Makefrag: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile fragment for the JOS kernel. 3 | # This is NOT a complete makefile; 4 | # you must run GNU make in the top-level directory 5 | # where the GNUmakefile is located. 6 | # 7 | 8 | OBJDIRS += boot 9 | 10 | BOOT_OBJS := $(OBJDIR)/boot/boot.o $(OBJDIR)/boot/main.o 11 | 12 | $(OBJDIR)/boot/%.o: boot/%.c 13 | @echo + cc -Os $< 14 | @mkdir -p $(@D) 15 | $(V)$(CC) -nostdinc $(KERN_CFLAGS) -Os -c -o $@ $< 16 | 17 | $(OBJDIR)/boot/%.o: boot/%.S 18 | @echo + as $< 19 | @mkdir -p $(@D) 20 | $(V)$(CC) -nostdinc $(KERN_CFLAGS) -c -o $@ $< 21 | 22 | $(OBJDIR)/boot/main.o: boot/main.c 23 | @echo + cc -Os $< 24 | $(V)$(CC) -nostdinc $(KERN_CFLAGS) -Os -c -o $(OBJDIR)/boot/main.o boot/main.c 25 | 26 | $(OBJDIR)/boot/boot: $(BOOT_OBJS) 27 | @echo + ld boot/boot 28 | $(V)$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o $@.out $^ 29 | $(V)$(OBJDUMP) -S $@.out >$@.asm 30 | $(V)$(OBJCOPY) -S -O binary -j .text $@.out $@ 31 | $(V)perl boot/sign.pl $(OBJDIR)/boot/boot 32 | 33 | -------------------------------------------------------------------------------- /boot/sign.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(BB, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | binmode BB; 6 | my $buf; 7 | read(BB, $buf, 1000); 8 | $n = length($buf); 9 | 10 | if($n > 510){ 11 | print STDERR "boot block too large: $n bytes (max 510)\n"; 12 | exit 1; 13 | } 14 | 15 | print STDERR "boot block is $n bytes (max 510)\n"; 16 | 17 | $buf .= "\0" x (510-$n); 18 | $buf .= "\x55\xAA"; 19 | 20 | open(BB, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 21 | binmode BB; 22 | print BB $buf; 23 | close BB; 24 | -------------------------------------------------------------------------------- /conf/env.mk: -------------------------------------------------------------------------------- 1 | # env.mk - configuration variables for the JOS lab 2 | 3 | # '$(V)' controls whether the lab makefiles print verbose commands (the 4 | # actual shell commands run by Make), as well as the "overview" commands 5 | # (such as '+ cc lib/readline.c'). 6 | # 7 | # For overview commands only, the line should read 'V = @'. 8 | # For overview and verbose commands, the line should read 'V ='. 9 | V = @ 10 | 11 | # If your system-standard GNU toolchain is ELF-compatible, then comment 12 | # out the following line to use those tools (as opposed to the i386-jos-elf 13 | # tools that the 6.828 make system looks for by default). 14 | # 15 | # GCCPREFIX='' 16 | 17 | # If the makefile cannot find your QEMU binary, uncomment the 18 | # following line and set it to the full path to QEMU. 19 | # 20 | QEMU=/usr/local/Cellar/qemu/2.10.0/bin/qemu-system-i386 21 | # QEMU=/usr/local/bin/qemu-system-i386 -------------------------------------------------------------------------------- /documents/MOS系统设计.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/MOS系统设计.pdf -------------------------------------------------------------------------------- /documents/[finish]macOS编译运行配置.md: -------------------------------------------------------------------------------- 1 | # 在macOS上搭建JOS编译运行环境 2 | 3 | ## Tools we need 4 | 5 | 在搭建环境之前,首先macOS上需要有以下两个工具: 6 | 7 | - `Homebrew` [*Homebrew — The missing package manager for macOS*](https://brew.sh/) 8 | - `MacPorts` [The *MacPorts* Project -- Home](http://www.baidu.com/link?url=81LcppTMUWAiK3PYa9pVTKx0TW2NrOFMGisnjCJ_IechHtiRzN0kbC0ydOtP5C7q) 9 | 10 | 11 | 12 | ## 运行`JOS` 13 | 14 | - `QEMU` 15 | 16 | 有了`Homebrew`,直接利用`brew`安装即可安装(自动安装依赖库) 17 | 18 | ``` 19 | $brew install qemu 20 | ``` 21 | 22 | - 将`kernel.img`与`fs.img`放在目标目录下 (也可以在其他位置,为了下面的`Makefile`好写) 23 | 24 | ``` 25 | . 26 | ├── Makefile 27 | ├── fs.img 28 | └── kernel.img 29 | ``` 30 | 31 | - 书写`Makefile` 32 | 33 | ```makefile 34 | QEMU=/usr/local/Cellar/qemu/2.10.0/bin/qemu-system-i386 # path to qemu 35 | run: 36 | $(QEMU) -drive file=./kernel.img,index=0,media=disk,format=raw -serial mon:stdio -vga std -smp 1 -drive file=./fs.img,index=1,media=disk,format=raw 37 | ``` 38 | 39 | ## 编译`JOS` 40 | 41 | - `i386-elf-gcc` 42 | 43 | 利用`Macports`来安装`i386-elf-gcc` 44 | 45 | ``` 46 | $ sudo port -v selfupdate 47 | $ sudo port install i386-elf-gcc 48 | ``` 49 | 50 | `Macports`会帮你下载源码,编译(非常漫长) 51 | 52 | - 修改`Makefile`中的一些内容 53 | 54 | ```shell 55 | diff --git a/GNUmakefile b/GNUmakefile 56 | index adc693e..60fe010 100644 57 | --- a/GNUmakefile 58 | +++ b/GNUmakefile 59 | @@ -33,15 +33,15 @@ TOP = . 60 | 61 | # try to infer the correct GCCPREFIX 62 | ifndef GCCPREFIX 63 | -GCCPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \ 64 | - then echo 'i386-jos-elf-'; \ 65 | +GCCPREFIX := $(shell if i386-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \ 66 | + then echo 'i386-elf-'; \ 67 | elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \ 68 | then echo ''; \ 69 | else echo "***" 1>&2; \ 70 | echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \ 71 | - echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \ 72 | + echo "*** Is the directory with i386-elf-gcc in your PATH?" 1>&2; \ 73 | echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \ 74 | - echo "*** prefix other than 'i386-jos-elf-', set your GCCPREFIX" 1>&2; \ 75 | + echo "*** prefix other than 'i386-elf-', set your GCCPREFIX" 1>&2; \ 76 | echo "*** environment variable to that prefix and run 'make' again." 1>&2; \ 77 | echo "*** To turn off this error, run 'gmake GCCPREFIX= ...'." 1>&2; \ 78 | echo "***" 1>&2; exit 1; fi) 79 | ``` 80 | 81 | - 修改`.deps`中一些内容 82 | 83 | 删除`fsformat`的依赖检查 84 | 85 | ```shell 86 | obj/fs/: fs/fsformat.c 87 | ``` 88 | 89 | - 修改配置文件中的`qemu`参数 90 | 91 | ``` 92 | QEMU=/usr/local/Cellar/qemu/2.10.0/bin/qemu-system-i386 93 | ``` -------------------------------------------------------------------------------- /documents/[planning]文件内存映射mmap.md: -------------------------------------------------------------------------------- 1 | # 文件映射到内存 mmap的实现 (lab5 challenge) 2 | 3 | 4 | 5 | ## 关于`mmap` 6 | 7 | ### 实现目标 8 | 9 | > `mmap`是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。 10 | > 11 | > http://www.cnblogs.com/huxiao-tee/p/4660352.html 12 | 13 | ### 实现原理 14 | 15 | - 当进程调用`mmap`,其需要在当前的虚拟地址空间中找到一段空闲的满足要求的连续虚拟地址。 16 | - 获取文件描述符,找到文件结构体。 17 | 18 | -------------------------------------------------------------------------------- /documents/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/1.jpg -------------------------------------------------------------------------------- /documents/img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/2.png -------------------------------------------------------------------------------- /documents/img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/3.png -------------------------------------------------------------------------------- /documents/img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/4.png -------------------------------------------------------------------------------- /documents/img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/5.png -------------------------------------------------------------------------------- /documents/img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/6.png -------------------------------------------------------------------------------- /documents/img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/7.png -------------------------------------------------------------------------------- /documents/img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/8.png -------------------------------------------------------------------------------- /documents/img/GUI1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/GUI1.png -------------------------------------------------------------------------------- /documents/img/GUI2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/GUI2.png -------------------------------------------------------------------------------- /documents/img/GUI3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/GUI3.png -------------------------------------------------------------------------------- /documents/img/GUI4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/GUI4.png -------------------------------------------------------------------------------- /documents/img/cga.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/cga.png -------------------------------------------------------------------------------- /documents/img/disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/disk.png -------------------------------------------------------------------------------- /documents/img/fd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/fd.png -------------------------------------------------------------------------------- /documents/img/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/file.png -------------------------------------------------------------------------------- /documents/img/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/graph.png -------------------------------------------------------------------------------- /documents/img/ioapic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/ioapic.gif -------------------------------------------------------------------------------- /documents/img/ps1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/ps1.png -------------------------------------------------------------------------------- /documents/img/ps2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He11oLiu/MOS/2865d6d6ddb9e5f08d73ea7cc70a24daf9085639/documents/img/ps2.png -------------------------------------------------------------------------------- /fs/Makefrag: -------------------------------------------------------------------------------- 1 | 2 | OBJDIRS += fs 3 | 4 | FSOFILES := $(OBJDIR)/fs/ide.o \ 5 | $(OBJDIR)/fs/bc.o \ 6 | $(OBJDIR)/fs/fs.o \ 7 | $(OBJDIR)/fs/serv.o \ 8 | $(OBJDIR)/fs/test.o \ 9 | 10 | FSIMGTXTFILES := fs/newmotd \ 11 | fs/motd 12 | 13 | 14 | USERAPPS := $(USERAPPS) \ 15 | $(OBJDIR)/user/cat \ 16 | $(OBJDIR)/user/echo \ 17 | $(OBJDIR)/user/ls \ 18 | $(OBJDIR)/user/lsfd \ 19 | $(OBJDIR)/user/sh \ 20 | $(OBJDIR)/user/hello \ 21 | $(OBJDIR)/user/pwd \ 22 | $(OBJDIR)/user/mkdir \ 23 | $(OBJDIR)/user/touch \ 24 | $(OBJDIR)/user/msh \ 25 | $(OBJDIR)/user/sysinfo \ 26 | $(OBJDIR)/user/applauncher \ 27 | $(OBJDIR)/user/bmpviewer \ 28 | $(OBJDIR)/user/calendar \ 29 | $(OBJDIR)/user/system \ 30 | $(OBJDIR)/user/term 31 | 32 | 33 | FSIMGTXTFILES := $(FSIMGTXTFILES) \ 34 | fs/lorem \ 35 | fs/script \ 36 | fs/testshell.key \ 37 | fs/testshell.sh 38 | 39 | FSIMGBITMAPFILES := user/icons/*.bmp \ 40 | user/icons/*.plt 41 | 42 | 43 | FSIMGFILES := $(FSIMGBITMAPFILES) $(FSIMGTXTFILES) $(USERAPPS) 44 | 45 | $(OBJDIR)/fs/%.o: fs/%.c fs/fs.h inc/lib.h $(OBJDIR)/.vars.USER_CFLAGS 46 | @echo + cc[USER] $< 47 | @mkdir -p $(@D) 48 | $(V)$(CC) -nostdinc $(USER_CFLAGS) -c -o $@ $< 49 | 50 | $(OBJDIR)/fs/fs: $(FSOFILES) $(OBJDIR)/lib/entry.o $(OBJDIR)/lib/libjos.a user/user.ld 51 | @echo + ld $@ 52 | $(V)mkdir -p $(@D) 53 | $(V)$(LD) -o $@ $(ULDFLAGS) $(LDFLAGS) -nostdlib \ 54 | $(OBJDIR)/lib/entry.o $(FSOFILES) \ 55 | -L$(OBJDIR)/lib -ljos $(GCC_LIB) 56 | $(V)$(OBJDUMP) -S $@ >$@.asm 57 | 58 | # How to build the file system image 59 | $(OBJDIR)/fs/fsformat: fs/fsformat.c 60 | @echo + mk $(OBJDIR)/fs/fsformat 61 | $(V)mkdir -p $(@D) 62 | $(V)$(NCC) $(NATIVE_CFLAGS) -o $(OBJDIR)/fs/fsformat fs/fsformat.c 63 | 64 | $(OBJDIR)/fs/clean-fs.img: $(OBJDIR)/fs/fsformat $(FSIMGFILES) 65 | @echo + mk $(OBJDIR)/fs/clean-fs.img 66 | $(V)mkdir -p $(@D) 67 | $(V)$(OBJDIR)/fs/fsformat $(OBJDIR)/fs/clean-fs.img 2048 $(FSIMGFILES) 68 | 69 | $(OBJDIR)/fs/fs.img: $(OBJDIR)/fs/clean-fs.img 70 | @echo + cp $(OBJDIR)/fs/clean-fs.img $@ 71 | $(V)cp $(OBJDIR)/fs/clean-fs.img $@ 72 | 73 | all: $(OBJDIR)/fs/fs.img 74 | 75 | #all: $(addsuffix .sym, $(USERAPPS)) 76 | 77 | #all: $(addsuffix .asm, $(USERAPPS)) 78 | 79 | -------------------------------------------------------------------------------- /fs/fs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SECTSIZE 512 // bytes per disk sector 5 | #define BLKSECTS (BLKSIZE / SECTSIZE) // sectors per block 6 | 7 | /* Disk block n, when in memory, is mapped into the file system 8 | * server's address space at DISKMAP + (n*BLKSIZE). */ 9 | #define DISKMAP 0x10000000 10 | 11 | /* Maximum disk size we can handle (3GB) */ 12 | #define DISKSIZE 0xC0000000 13 | 14 | struct Super *super; // superblock 15 | uint32_t *bitmap; // bitmap blocks mapped in memory 16 | 17 | /* ide.c */ 18 | bool ide_probe_disk1(void); 19 | void ide_set_disk(int diskno); 20 | void ide_set_partition(uint32_t first_sect, uint32_t nsect); 21 | int ide_read(uint32_t secno, void *dst, size_t nsecs); 22 | int ide_write(uint32_t secno, const void *src, size_t nsecs); 23 | 24 | /* bc.c */ 25 | void *diskaddr(uint32_t blockno); 26 | bool va_is_mapped(void *va); 27 | bool va_is_dirty(void *va); 28 | void flush_block(void *addr); 29 | void bc_init(void); 30 | 31 | /* fs.c */ 32 | void fs_init(void); 33 | int file_get_block(struct File *f, uint32_t file_blockno, char **pblk); 34 | int file_create(const char *path, struct File **f); 35 | int dir_create(const char *path, struct File **f); 36 | int file_open(const char *path, struct File **f); 37 | ssize_t file_read(struct File *f, void *buf, size_t count, off_t offset); 38 | int file_write(struct File *f, const void *buf, size_t count, off_t offset); 39 | int file_set_size(struct File *f, off_t newsize); 40 | void file_flush(struct File *f); 41 | int file_remove(const char *path); 42 | void fs_sync(void); 43 | 44 | /* int map_block(uint32_t); */ 45 | bool block_is_free(uint32_t blockno); 46 | int alloc_block(void); 47 | 48 | /* test.c */ 49 | void fs_test(void); 50 | -------------------------------------------------------------------------------- /fs/ide.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Minimal PIO-based (non-interrupt-driven) IDE driver code. 3 | * For information about what all this IDE/ATA magic means, 4 | * see the materials available on the class references page. 5 | */ 6 | 7 | #include "fs.h" 8 | #include 9 | 10 | #define IDE_BSY 0x80 11 | #define IDE_DRDY 0x40 12 | #define IDE_DF 0x20 13 | #define IDE_ERR 0x01 14 | 15 | static int diskno = 1; 16 | 17 | static int 18 | ide_wait_ready(bool check_error) 19 | { 20 | int r; 21 | 22 | while (((r = inb(0x1F7)) & (IDE_BSY | IDE_DRDY)) != IDE_DRDY) 23 | /* do nothing */; 24 | 25 | if (check_error && (r & (IDE_DF | IDE_ERR)) != 0) 26 | return -1; 27 | return 0; 28 | } 29 | 30 | bool ide_probe_disk1(void) 31 | { 32 | int r, x; 33 | 34 | // wait for Device 0 to be ready 35 | ide_wait_ready(0); 36 | 37 | // switch to Device 1 38 | outb(0x1F6, 0xE0 | (1 << 4)); 39 | 40 | // check for Device 1 to be ready for a while 41 | for (x = 0; 42 | x < 1000 && ((r = inb(0x1F7)) & (IDE_BSY | IDE_DF | IDE_ERR)) != 0; 43 | x++) 44 | /* do nothing */; 45 | 46 | // switch back to Device 0 47 | outb(0x1F6, 0xE0 | (0 << 4)); 48 | 49 | cprintf("Device 1 presence: %d\n", (x < 1000)); 50 | return (x < 1000); 51 | } 52 | 53 | void ide_set_disk(int d) 54 | { 55 | if (d != 0 && d != 1) 56 | panic("bad disk number"); 57 | diskno = d; 58 | } 59 | 60 | int ide_read(uint32_t secno, void *dst, size_t nsecs) 61 | { 62 | int r; 63 | 64 | assert(nsecs <= 256); 65 | 66 | ide_wait_ready(0); 67 | 68 | outb(0x1F2, nsecs); 69 | outb(0x1F3, secno & 0xFF); 70 | outb(0x1F4, (secno >> 8) & 0xFF); 71 | outb(0x1F5, (secno >> 16) & 0xFF); 72 | outb(0x1F6, 0xE0 | ((diskno & 1) << 4) | ((secno >> 24) & 0x0F)); 73 | outb(0x1F7, 0x20); // CMD 0x20 means read sector 74 | 75 | for (; nsecs > 0; nsecs--, dst += SECTSIZE) 76 | { 77 | if ((r = ide_wait_ready(1)) < 0) 78 | return r; 79 | insl(0x1F0, dst, SECTSIZE / 4); 80 | } 81 | 82 | return 0; 83 | } 84 | 85 | int ide_write(uint32_t secno, const void *src, size_t nsecs) 86 | { 87 | int r; 88 | 89 | assert(nsecs <= 256); 90 | 91 | ide_wait_ready(0); 92 | 93 | outb(0x1F2, nsecs); 94 | outb(0x1F3, secno & 0xFF); 95 | outb(0x1F4, (secno >> 8) & 0xFF); 96 | outb(0x1F5, (secno >> 16) & 0xFF); 97 | outb(0x1F6, 0xE0 | ((diskno & 1) << 4) | ((secno >> 24) & 0x0F)); 98 | outb(0x1F7, 0x30); // CMD 0x30 means write sector 99 | 100 | for (; nsecs > 0; nsecs--, src += SECTSIZE) 101 | { 102 | if ((r = ide_wait_ready(1)) < 0) 103 | return r; 104 | outsl(0x1F0, src, SECTSIZE / 4); 105 | } 106 | 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /fs/lorem: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur 2 | adipisicing elit, sed do eiusmod tempor 3 | incididunt ut labore et dolore magna 4 | aliqua. Ut enim ad minim veniam, quis 5 | nostrud exercitation ullamco laboris 6 | nisi ut aliquip ex ea commodo consequat. 7 | Duis aute irure dolor in reprehenderit 8 | in voluptate velit esse cillum dolore eu 9 | fugiat nulla pariatur. Excepteur sint 10 | occaecat cupidatat non proident, sunt in 11 | culpa qui officia deserunt mollit anim 12 | id est laborum. 13 | -------------------------------------------------------------------------------- /fs/motd: -------------------------------------------------------------------------------- 1 | This is /motd, the message of the day. 2 | 3 | Welcome to the JOS kernel, now with a file system! 4 | 5 | -------------------------------------------------------------------------------- /fs/newmotd: -------------------------------------------------------------------------------- 1 | This is the NEW message of the day! 2 | 3 | -------------------------------------------------------------------------------- /fs/script: -------------------------------------------------------------------------------- 1 | echo This is from the script. 2 | cat lorem | num | cat 3 | echo These are my file descriptors. 4 | lsfd -1 5 | echo This is the end of the script. 6 | -------------------------------------------------------------------------------- /fs/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "fs.h" 5 | 6 | static char *msg = "This is the NEW message of the day!\n\n"; 7 | 8 | void 9 | fs_test(void) 10 | { 11 | struct File *f; 12 | int r; 13 | char *blk; 14 | uint32_t *bits; 15 | 16 | // back up bitmap 17 | if ((r = sys_page_alloc(0, (void*) PGSIZE, PTE_P|PTE_U|PTE_W)) < 0) 18 | panic("sys_page_alloc: %e", r); 19 | bits = (uint32_t*) PGSIZE; 20 | memmove(bits, bitmap, PGSIZE); 21 | // allocate block 22 | if ((r = alloc_block()) < 0) 23 | panic("alloc_block: %e", r); 24 | // check that block was free 25 | assert(bits[r/32] & (1 << (r%32))); 26 | // and is not free any more 27 | assert(!(bitmap[r/32] & (1 << (r%32)))); 28 | cprintf("alloc_block is good\n"); 29 | 30 | if ((r = file_open("/not-found", &f)) < 0 && r != -E_NOT_FOUND) 31 | panic("file_open /not-found: %e", r); 32 | else if (r == 0) 33 | panic("file_open /not-found succeeded!"); 34 | if ((r = file_open("/newmotd", &f)) < 0) 35 | panic("file_open /newmotd: %e", r); 36 | cprintf("file_open is good\n"); 37 | 38 | if ((r = file_get_block(f, 0, &blk)) < 0) 39 | panic("file_get_block: %e", r); 40 | if (strcmp(blk, msg) != 0) 41 | panic("file_get_block returned wrong data"); 42 | cprintf("file_get_block is good\n"); 43 | 44 | *(volatile char*)blk = *(volatile char*)blk; 45 | assert((uvpt[PGNUM(blk)] & PTE_D)); 46 | file_flush(f); 47 | assert(!(uvpt[PGNUM(blk)] & PTE_D)); 48 | cprintf("file_flush is good\n"); 49 | 50 | if ((r = file_set_size(f, 0)) < 0) 51 | panic("file_set_size: %e", r); 52 | assert(f->f_direct[0] == 0); 53 | assert(!(uvpt[PGNUM(f)] & PTE_D)); 54 | cprintf("file_truncate is good\n"); 55 | 56 | if ((r = file_set_size(f, strlen(msg))) < 0) 57 | panic("file_set_size 2: %e", r); 58 | assert(!(uvpt[PGNUM(f)] & PTE_D)); 59 | if ((r = file_get_block(f, 0, &blk)) < 0) 60 | panic("file_get_block 2: %e", r); 61 | strcpy(blk, msg); 62 | assert((uvpt[PGNUM(blk)] & PTE_D)); 63 | file_flush(f); 64 | assert(!(uvpt[PGNUM(blk)] & PTE_D)); 65 | assert(!(uvpt[PGNUM(f)] & PTE_D)); 66 | cprintf("file rewrite is good\n"); 67 | } 68 | -------------------------------------------------------------------------------- /fs/testshell.key: -------------------------------------------------------------------------------- 1 | # echo hello world | cat 2 | hello world 3 | # cat lorem 4 | Lorem ipsum dolor sit amet, consectetur 5 | adipisicing elit, sed do eiusmod tempor 6 | incididunt ut labore et dolore magna 7 | aliqua. Ut enim ad minim veniam, quis 8 | nostrud exercitation ullamco laboris 9 | nisi ut aliquip ex ea commodo consequat. 10 | Duis aute irure dolor in reprehenderit 11 | in voluptate velit esse cillum dolore eu 12 | fugiat nulla pariatur. Excepteur sint 13 | occaecat cupidatat non proident, sunt in 14 | culpa qui officia deserunt mollit anim 15 | id est laborum. 16 | # cat lorem |num 17 | 1 Lorem ipsum dolor sit amet, consectetur 18 | 2 adipisicing elit, sed do eiusmod tempor 19 | 3 incididunt ut labore et dolore magna 20 | 4 aliqua. Ut enim ad minim veniam, quis 21 | 5 nostrud exercitation ullamco laboris 22 | 6 nisi ut aliquip ex ea commodo consequat. 23 | 7 Duis aute irure dolor in reprehenderit 24 | 8 in voluptate velit esse cillum dolore eu 25 | 9 fugiat nulla pariatur. Excepteur sint 26 | 10 occaecat cupidatat non proident, sunt in 27 | 11 culpa qui officia deserunt mollit anim 28 | 12 id est laborum. 29 | # cat lorem |num |num |num |num |num 30 | 1 1 1 1 1 Lorem ipsum dolor sit amet, consectetur 31 | 2 2 2 2 2 adipisicing elit, sed do eiusmod tempor 32 | 3 3 3 3 3 incididunt ut labore et dolore magna 33 | 4 4 4 4 4 aliqua. Ut enim ad minim veniam, quis 34 | 5 5 5 5 5 nostrud exercitation ullamco laboris 35 | 6 6 6 6 6 nisi ut aliquip ex ea commodo consequat. 36 | 7 7 7 7 7 Duis aute irure dolor in reprehenderit 37 | 8 8 8 8 8 in voluptate velit esse cillum dolore eu 38 | 9 9 9 9 9 fugiat nulla pariatur. Excepteur sint 39 | 10 10 10 10 10 occaecat cupidatat non proident, sunt in 40 | 11 11 11 11 11 culpa qui officia deserunt mollit anim 41 | 12 12 12 12 12 id est laborum. 42 | # lsfd -1 43 | fd 0: name testshell.sh isdir 0 size 113 dev file 44 | fd 1: name isdir 0 size 32 dev pipe 45 | fd 3: name isdir 0 size 32 dev pipe 46 | # cat script 47 | echo This is from the script. 48 | cat lorem | num | cat 49 | echo These are my file descriptors. 50 | lsfd -1 51 | echo This is the end of the script. 52 | # sh