├── .dir-locals.el ├── .gdbinit.tmpl ├── .gitignore ├── CODING ├── GNUmakefile ├── README.md ├── boot ├── Makefrag ├── boot.S ├── main.c └── sign.pl ├── conf ├── env.mk └── lab.mk ├── fs ├── Makefrag ├── bc.c ├── fs.c ├── fs.h ├── fsformat.c ├── ide.c ├── index.html ├── lorem ├── motd ├── newmotd ├── script ├── serv.c ├── test.c ├── testshell.key └── testshell.sh ├── grade-lab1 ├── grade-lab2 ├── grade-lab3 ├── grade-lab4 ├── grade-lab5 ├── grade-lab6 ├── gradelib.py ├── inc ├── COPYRIGHT ├── args.h ├── assert.h ├── elf.h ├── env.h ├── error.h ├── fd.h ├── fs.h ├── kbdreg.h ├── lib.h ├── malloc.h ├── memlayout.h ├── mmu.h ├── ns.h ├── partition.h ├── stab.h ├── stdarg.h ├── stdio.h ├── string.h ├── syscall.h ├── trap.h ├── types.h └── x86.h ├── kern ├── COPYRIGHT ├── Makefrag ├── console.c ├── console.h ├── cpu.h ├── e1000.c ├── e1000.h ├── entry.S ├── entrypgdir.c ├── env.c ├── env.h ├── init.c ├── kclock.c ├── kclock.h ├── kdebug.c ├── kdebug.h ├── kernel.ld ├── lapic.c ├── monitor.c ├── monitor.h ├── mpconfig.c ├── mpentry.S ├── pci.c ├── pci.h ├── pcireg.h ├── picirq.c ├── picirq.h ├── pmap.c ├── pmap.h ├── printf.c ├── 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 ├── console.c ├── entry.S ├── exit.c ├── fd.c ├── file.c ├── fork.c ├── fprintf.c ├── ipc.c ├── libmain.c ├── malloc.c ├── nsipc.c ├── pageref.c ├── panic.c ├── pfentry.S ├── pgfault.c ├── pipe.c ├── printf.c ├── printfmt.c ├── readline.c ├── sockets.c ├── spawn.c ├── string.c ├── syscall.c └── wait.c ├── mergedep.pl ├── net ├── Makefrag ├── input.c ├── lwip │ ├── FILES │ ├── Makefrag │ ├── api │ │ ├── api_lib.c │ │ ├── api_msg.c │ │ ├── err.c │ │ ├── netbuf.c │ │ ├── netdb.c │ │ ├── netifapi.c │ │ ├── sockets.c │ │ └── tcpip.c │ ├── core │ │ ├── dhcp.c │ │ ├── dns.c │ │ ├── init.c │ │ ├── ipv4 │ │ │ ├── autoip.c │ │ │ ├── icmp.c │ │ │ ├── igmp.c │ │ │ ├── inet.c │ │ │ ├── inet_chksum.c │ │ │ ├── ip.c │ │ │ ├── ip_addr.c │ │ │ └── ip_frag.c │ │ ├── ipv6 │ │ │ ├── README │ │ │ ├── icmp6.c │ │ │ ├── inet6.c │ │ │ ├── ip6.c │ │ │ └── ip6_addr.c │ │ ├── mem.c │ │ ├── memp.c │ │ ├── netif.c │ │ ├── pbuf.c │ │ ├── raw.c │ │ ├── snmp │ │ │ ├── asn1_dec.c │ │ │ ├── asn1_enc.c │ │ │ ├── mib2.c │ │ │ ├── mib_structs.c │ │ │ ├── msg_in.c │ │ │ └── msg_out.c │ │ ├── stats.c │ │ ├── sys.c │ │ ├── tcp.c │ │ ├── tcp_in.c │ │ ├── tcp_out.c │ │ └── udp.c │ ├── include │ │ ├── ipv4 │ │ │ └── lwip │ │ │ │ ├── autoip.h │ │ │ │ ├── icmp.h │ │ │ │ ├── igmp.h │ │ │ │ ├── inet.h │ │ │ │ ├── inet_chksum.h │ │ │ │ ├── ip.h │ │ │ │ ├── ip_addr.h │ │ │ │ └── ip_frag.h │ │ ├── ipv6 │ │ │ └── lwip │ │ │ │ ├── icmp.h │ │ │ │ ├── inet.h │ │ │ │ ├── ip.h │ │ │ │ └── ip_addr.h │ │ ├── lwip │ │ │ ├── api.h │ │ │ ├── api_msg.h │ │ │ ├── arch.h │ │ │ ├── debug.h │ │ │ ├── def.h │ │ │ ├── dhcp.h │ │ │ ├── dns.h │ │ │ ├── err.h │ │ │ ├── init.h │ │ │ ├── mem.h │ │ │ ├── memp.h │ │ │ ├── memp_std.h │ │ │ ├── netbuf.h │ │ │ ├── netdb.h │ │ │ ├── netif.h │ │ │ ├── netifapi.h │ │ │ ├── opt.h │ │ │ ├── pbuf.h │ │ │ ├── raw.h │ │ │ ├── sio.h │ │ │ ├── snmp.h │ │ │ ├── snmp_asn1.h │ │ │ ├── snmp_msg.h │ │ │ ├── snmp_structs.h │ │ │ ├── sockets.h │ │ │ ├── stats.h │ │ │ ├── sys.h │ │ │ ├── tcp.h │ │ │ ├── tcpip.h │ │ │ └── udp.h │ │ └── netif │ │ │ ├── etharp.h │ │ │ ├── loopif.h │ │ │ ├── ppp_oe.h │ │ │ └── slipif.h │ ├── jos │ │ ├── arch │ │ │ ├── cc.h │ │ │ ├── i386 │ │ │ │ └── setjmp.h │ │ │ ├── longjmp.S │ │ │ ├── perf.h │ │ │ ├── perror.c │ │ │ ├── perror.h │ │ │ ├── queue.h │ │ │ ├── setjmp.h │ │ │ ├── sys_arch.c │ │ │ ├── sys_arch.h │ │ │ ├── thread.c │ │ │ ├── thread.h │ │ │ └── threadq.h │ │ ├── jif │ │ │ ├── jif.c │ │ │ └── jif.h │ │ └── lwipopts.h │ └── netif │ │ ├── FILES │ │ ├── etharp.c │ │ ├── ethernetif.c │ │ ├── loopif.c │ │ ├── ppp │ │ ├── auth.c │ │ ├── auth.h │ │ ├── chap.c │ │ ├── chap.h │ │ ├── chpms.c │ │ ├── chpms.h │ │ ├── fsm.c │ │ ├── fsm.h │ │ ├── ipcp.c │ │ ├── ipcp.h │ │ ├── lcp.c │ │ ├── lcp.h │ │ ├── magic.c │ │ ├── magic.h │ │ ├── md5.c │ │ ├── md5.h │ │ ├── pap.c │ │ ├── pap.h │ │ ├── ppp.c │ │ ├── ppp.h │ │ ├── ppp_oe.c │ │ ├── pppdebug.h │ │ ├── randm.c │ │ ├── randm.h │ │ ├── vj.c │ │ ├── vj.h │ │ └── vjbsdhdr.h │ │ └── slipif.c ├── ns.h ├── output.c ├── serv.c ├── testinput.c ├── testoutput.c └── timer.c └── user ├── Makefrag ├── badsegment.c ├── breakpoint.c ├── buggyhello.c ├── buggyhello2.c ├── cat.c ├── divzero.c ├── dumbfork.c ├── echo.c ├── echosrv.c ├── echotest.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 ├── hello.c ├── httpd.c ├── icode.c ├── idle.c ├── init.c ├── initsh.c ├── ls.c ├── lsfd.c ├── num.c ├── pingpong.c ├── pingpongs.c ├── primes.c ├── primespipe.c ├── sendpage.c ├── sh.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 ├── testtime.c ├── user.ld ├── writemotd.c └── yield.c /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((nil 2 | (indent-tabs-mode . t) 3 | (tab-width . 8)) 4 | (c-mode 5 | (c-file-style . "bsd") 6 | (c-basic-offset . 8)) 7 | (shell-mode 8 | (sh-basic-offset . 8) 9 | (sh-indentation . 8)) 10 | (python-mode 11 | (indent-tabs-mode . nil)) 12 | ) 13 | -------------------------------------------------------------------------------- /.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 | # Look at the tools page at 27 | # http://pdos.csail.mit.edu/6.828/2009/tools.html 28 | # for instructions on building GDB with ELF support. 29 | echo + symbol-file obj/kern/kernel\n 30 | symbol-file obj/kern/kernel 31 | -------------------------------------------------------------------------------- /.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 | *.swp 20 | *.swo 21 | -------------------------------------------------------------------------------- /CODING: -------------------------------------------------------------------------------- 1 | JOS CODING STANDARDS 2 | 3 | It's easier on everyone if all authors working on a shared 4 | code base are consistent in the way they write their programs. 5 | We have the following conventions in our code: 6 | 7 | * No space after the name of a function in a call 8 | For example, printf("hello") not printf ("hello"). 9 | 10 | * One space after keywords "if", "for", "while", "switch". 11 | For example, if (x) not if(x). 12 | 13 | * Space before braces. 14 | For example, if (x) { not if (x){. 15 | 16 | * Function names are all lower-case separated by underscores. 17 | 18 | * Beginning-of-line indentation via tabs, not spaces. 19 | 20 | * Preprocessor macros are always UPPERCASE. 21 | There are a few grandfathered exceptions: assert, panic, 22 | static_assert, offsetof. 23 | 24 | * Pointer types have spaces: (uint16_t *) not (uint16_t*). 25 | 26 | * Multi-word names are lower_case_with_underscores. 27 | 28 | * Comments in imported code are usually C /* ... */ comments. 29 | Comments in new code are C++ style //. 30 | 31 | * In a function definition, the function name starts a new line. 32 | Then you can grep -n '^foo' */*.c to find the definition of foo. 33 | 34 | * Functions that take no arguments are declared f(void) not f(). 35 | 36 | The included .dir-locals.el file will automatically set up the basic 37 | indentation style in Emacs. 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mit 6.828 2018 2 | 3 | --- 4 | 本仓库是mit 6.828 2018年秋季操作系统课程的全部实现,课程主页:[https://pdos.csail.mit.edu/6.828/2018/schedule.html][1]。本实验总共分为6个lab,每个lab的解析和总结记录在blog中。上完这门课大概花了280多个番茄时,收获很大,希望更多的人能接触这类优秀的课程。 5 | 6 | 7 | 1. [lab1:C, Assembly, Tools, and Bootstrapping][2] 8 | 2. [lab2:Memory management][3] 9 | 3. [lab3:User Environments][4] 10 | 4. [lab4:Preemptive Multitasking][5] 11 | 5. [lab5:File system, Spawn and Shell][6] 12 | 6. [lab6:Network Driver][7] 13 | 14 | Enjoy it~ 15 | 16 | 17 | [1]: https://pdos.csail.mit.edu/6.828/2018/schedule.html 18 | [2]: https://www.cnblogs.com/gatsby123/p/9759153.html 19 | [3]: https://www.cnblogs.com/gatsby123/p/9832223.html 20 | [4]: https://www.cnblogs.com/gatsby123/p/9838304.html 21 | [5]: https://www.cnblogs.com/gatsby123/p/9930630.html 22 | [6]: https://www.cnblogs.com/gatsby123/p/9950705.html 23 | [7]: https://www.cnblogs.com/gatsby123/p/10080311.html -------------------------------------------------------------------------------- /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/boot.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | # Start the CPU: switch to 32-bit protected mode, jump into C. 4 | # The BIOS loads this code from the first sector of the hard disk into 5 | # memory at physical address 0x7c00 and starts executing in real mode 6 | # with %cs=0 %ip=7c00. 7 | 8 | .set PROT_MODE_CSEG, 0x8 # kernel code segment selector 9 | .set PROT_MODE_DSEG, 0x10 # kernel data segment selector 10 | .set CR0_PE_ON, 0x1 # protected mode enable flag 11 | 12 | .globl start 13 | start: 14 | .code16 # Assemble for 16-bit mode 15 | cli # Disable interrupts 16 | cld # String operations increment 17 | 18 | # Set up the important data segment registers (DS, ES, SS). 19 | xorw %ax,%ax # Segment number zero 20 | movw %ax,%ds # -> Data Segment 21 | movw %ax,%es # -> Extra Segment 22 | movw %ax,%ss # -> Stack Segment 23 | 24 | # Enable A20: 25 | # For backwards compatibility with the earliest PCs, physical 26 | # address line 20 is tied low, so that addresses higher than 27 | # 1MB wrap around to zero by default. This code undoes this. 28 | seta20.1: 29 | inb $0x64,%al # Wait for not busy 30 | testb $0x2,%al 31 | jnz seta20.1 32 | 33 | movb $0xd1,%al # 0xd1 -> port 0x64 34 | outb %al,$0x64 35 | 36 | seta20.2: 37 | inb $0x64,%al # Wait for not busy 38 | testb $0x2,%al 39 | jnz seta20.2 40 | 41 | movb $0xdf,%al # 0xdf -> port 0x60 42 | outb %al,$0x60 43 | 44 | # Switch from real to protected mode, using a bootstrap GDT 45 | # and segment translation that makes virtual addresses 46 | # identical to their physical addresses, so that the 47 | # effective memory map does not change during the switch. 48 | lgdt gdtdesc 49 | movl %cr0, %eax 50 | orl $CR0_PE_ON, %eax 51 | movl %eax, %cr0 52 | 53 | # Jump to next instruction, but in 32-bit code segment. 54 | # Switches processor into 32-bit mode. 55 | ljmp $PROT_MODE_CSEG, $protcseg 56 | 57 | .code32 # Assemble for 32-bit mode 58 | protcseg: 59 | # Set up the protected-mode data segment registers 60 | movw $PROT_MODE_DSEG, %ax # Our data segment selector 61 | movw %ax, %ds # -> DS: Data Segment 62 | movw %ax, %es # -> ES: Extra Segment 63 | movw %ax, %fs # -> FS 64 | movw %ax, %gs # -> GS 65 | movw %ax, %ss # -> SS: Stack Segment 66 | 67 | # Set up the stack pointer and call into C. 68 | movl $start, %esp 69 | call bootmain 70 | 71 | # If bootmain returns (it shouldn't), loop. 72 | spin: 73 | jmp spin 74 | 75 | # Bootstrap GDT 76 | .p2align 2 # force 4 byte alignment 77 | gdt: 78 | SEG_NULL # null seg 79 | SEG(STA_X|STA_R, 0x0, 0xffffffff) # code seg 80 | SEG(STA_W, 0x0, 0xffffffff) # data seg 81 | 82 | gdtdesc: 83 | .word 0x17 # sizeof(gdt) - 1 84 | .long gdt # address gdt 85 | 86 | -------------------------------------------------------------------------------- /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= 21 | -------------------------------------------------------------------------------- /conf/lab.mk: -------------------------------------------------------------------------------- 1 | LAB=6 2 | PACKAGEDATE=Wed Oct 24 20:46:05 EDT 2018 3 | -------------------------------------------------------------------------------- /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 | USERAPPS := $(OBJDIR)/user/init 11 | 12 | FSIMGTXTFILES := fs/newmotd \ 13 | fs/motd 14 | 15 | FSIMGTXTFILES := $(FSIMGTXTFILES) \ 16 | fs/index.html 17 | 18 | USERAPPS := $(USERAPPS) \ 19 | $(OBJDIR)/user/cat \ 20 | $(OBJDIR)/user/echo \ 21 | $(OBJDIR)/user/init \ 22 | $(OBJDIR)/user/ls \ 23 | $(OBJDIR)/user/lsfd \ 24 | $(OBJDIR)/user/num \ 25 | $(OBJDIR)/user/forktree \ 26 | $(OBJDIR)/user/primes \ 27 | $(OBJDIR)/user/primespipe \ 28 | $(OBJDIR)/user/sh \ 29 | $(OBJDIR)/user/testfdsharing \ 30 | $(OBJDIR)/user/testkbd \ 31 | $(OBJDIR)/user/testpipe \ 32 | $(OBJDIR)/user/testpteshare \ 33 | $(OBJDIR)/user/testshell \ 34 | $(OBJDIR)/user/hello \ 35 | $(OBJDIR)/user/faultio \ 36 | 37 | FSIMGTXTFILES := $(FSIMGTXTFILES) \ 38 | fs/lorem \ 39 | fs/script \ 40 | fs/testshell.key \ 41 | fs/testshell.sh 42 | 43 | 44 | FSIMGFILES := $(FSIMGTXTFILES) $(USERAPPS) 45 | 46 | $(OBJDIR)/fs/%.o: fs/%.c fs/fs.h inc/lib.h $(OBJDIR)/.vars.USER_CFLAGS 47 | @echo + cc[USER] $< 48 | @mkdir -p $(@D) 49 | $(V)$(CC) -nostdinc $(USER_CFLAGS) -c -o $@ $< 50 | 51 | $(OBJDIR)/fs/fs: $(FSOFILES) $(OBJDIR)/lib/entry.o $(OBJDIR)/lib/libjos.a user/user.ld 52 | @echo + ld $@ 53 | $(V)mkdir -p $(@D) 54 | $(V)$(LD) -o $@ $(ULDFLAGS) $(LDFLAGS) -nostdlib \ 55 | $(OBJDIR)/lib/entry.o $(FSOFILES) \ 56 | -L$(OBJDIR)/lib -ljos $(GCC_LIB) 57 | $(V)$(OBJDUMP) -S $@ >$@.asm 58 | 59 | # How to build the file system image 60 | $(OBJDIR)/fs/fsformat: fs/fsformat.c 61 | @echo + mk $(OBJDIR)/fs/fsformat 62 | $(V)mkdir -p $(@D) 63 | $(V)$(NCC) $(NATIVE_CFLAGS) -o $(OBJDIR)/fs/fsformat fs/fsformat.c 64 | 65 | $(OBJDIR)/fs/clean-fs.img: $(OBJDIR)/fs/fsformat $(FSIMGFILES) 66 | @echo + mk $(OBJDIR)/fs/clean-fs.img 67 | $(V)mkdir -p $(@D) 68 | $(V)$(OBJDIR)/fs/fsformat $(OBJDIR)/fs/clean-fs.img 1024 $(FSIMGFILES) 69 | 70 | $(OBJDIR)/fs/fs.img: $(OBJDIR)/fs/clean-fs.img 71 | @echo + cp $(OBJDIR)/fs/clean-fs.img $@ 72 | $(V)cp $(OBJDIR)/fs/clean-fs.img $@ 73 | 74 | all: $(OBJDIR)/fs/fs.img 75 | 76 | #all: $(addsuffix .sym, $(USERAPPS)) 77 | 78 | #all: $(addsuffix .asm, $(USERAPPS)) 79 | 80 | -------------------------------------------------------------------------------- /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 file_open(const char *path, struct File **f); 36 | ssize_t file_read(struct File *f, void *buf, size_t count, off_t offset); 37 | int file_write(struct File *f, const void *buf, size_t count, off_t offset); 38 | int file_set_size(struct File *f, off_t newsize); 39 | void file_flush(struct File *f); 40 | int file_remove(const char *path); 41 | void fs_sync(void); 42 | 43 | /* int map_block(uint32_t); */ 44 | bool block_is_free(uint32_t blockno); 45 | int alloc_block(void); 46 | 47 | /* test.c */ 48 | void fs_test(void); 49 | 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 31 | ide_probe_disk1(void) 32 | { 33 | int r, x; 34 | 35 | // wait for Device 0 to be ready 36 | ide_wait_ready(0); 37 | 38 | // switch to Device 1 39 | outb(0x1F6, 0xE0 | (1<<4)); 40 | 41 | // check for Device 1 to be ready for a while 42 | for (x = 0; 43 | x < 1000 && ((r = inb(0x1F7)) & (IDE_BSY|IDE_DF|IDE_ERR)) != 0; 44 | x++) 45 | /* do nothing */; 46 | 47 | // switch back to Device 0 48 | outb(0x1F6, 0xE0 | (0<<4)); 49 | 50 | cprintf("Device 1 presence: %d\n", (x < 1000)); 51 | return (x < 1000); 52 | } 53 | 54 | void 55 | ide_set_disk(int d) 56 | { 57 | if (d != 0 && d != 1) 58 | panic("bad disk number"); 59 | diskno = d; 60 | } 61 | 62 | 63 | int 64 | ide_read(uint32_t secno, void *dst, size_t nsecs) 65 | { 66 | int r; 67 | 68 | assert(nsecs <= 256); 69 | 70 | ide_wait_ready(0); 71 | 72 | outb(0x1F2, nsecs); 73 | outb(0x1F3, secno & 0xFF); 74 | outb(0x1F4, (secno >> 8) & 0xFF); 75 | outb(0x1F5, (secno >> 16) & 0xFF); 76 | outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F)); 77 | outb(0x1F7, 0x20); // CMD 0x20 means read sector 78 | 79 | for (; nsecs > 0; nsecs--, dst += SECTSIZE) { 80 | if ((r = ide_wait_ready(1)) < 0) 81 | return r; 82 | insl(0x1F0, dst, SECTSIZE/4); 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | int 89 | ide_write(uint32_t secno, const void *src, size_t nsecs) 90 | { 91 | int r; 92 | 93 | assert(nsecs <= 256); 94 | 95 | ide_wait_ready(0); 96 | 97 | outb(0x1F2, nsecs); 98 | outb(0x1F3, secno & 0xFF); 99 | outb(0x1F4, (secno >> 8) & 0xFF); 100 | outb(0x1F5, (secno >> 16) & 0xFF); 101 | outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F)); 102 | outb(0x1F7, 0x30); // CMD 0x30 means write sector 103 | 104 | for (; nsecs > 0; nsecs--, src += SECTSIZE) { 105 | if ((r = ide_wait_ready(1)) < 0) 106 | return r; 107 | outsl(0x1F0, src, SECTSIZE/4); 108 | } 109 | 110 | return 0; 111 | } 112 | 113 | -------------------------------------------------------------------------------- /fs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | jhttpd on JOS 4 | 5 | 6 |
7 |

This file came from JOS.

8 | Cheesy web page! 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /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