├── .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 ├── handin-prep ├── 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 ├── 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 ├── 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 | -------------------------------------------------------------------------------- /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 | This is Jackie Yang's repo for Peking University OS Lab course. 2 | ========== 3 | The course material is adapted from 2014 MIT 6.828. 4 | ---------- 5 | 6 | ### Introduction 7 | 8 | This is my repo for Peking University OS Labs course. Peking University OS Lab (Honor Track) course. This course adapted contents from 2014 MIT 6.828, so this should also be helpful for other students studing any MIT 6.828 like courses. 9 | 10 | I post it here to as a reference for future attendents of this course. During my own experence of completing those labs, I found other's repo extremely helpful. I hope that my homework can also be helpful to others, especially in the following aspects: 11 | 12 | * A insight of what completed code should looks like. 13 | * A correct version to be compare to when debugging an extremely concealed bug. 14 | * A reference of programming style. (I tried to program a clean and decent code throughtout every lab. Hope you can do it better.) 15 | 16 | In the meanwhile, I disapprove the following way of using this repo: 17 | 18 | * Source for plagiarize homework 19 | 20 | Hope you have a good experence in completing those labs. Don't forget to star me if you find this helpful. 21 | 22 | ### Status 23 | 24 | All the labs (including lab 6) are finished. According to course requirement, I have also finished at least one challenge for each lab. 25 | 26 | ### Usage 27 | 28 | If you would like to find code for a specific lab, please look at the corresponding branch. 29 | 30 | If you would like to find code for a specific exercise, please find the corresponding commit and look at code diff. 31 | 32 | For example, lab 4's code can be found at [lab4](https://github.com/valkjsaaa/PKU-OS-Labs/tree/lab4). Exercise 10's code change can be found at [Exercise 10](https://github.com/valkjsaaa/PKU-OS-Labs/commit/b05c386ff814dfdc3a5f4040bbfd5f12ce59d8e8). 33 | 34 | ### Notice 35 | 36 | Some commits(exercises) might have bug that are fixed in latter commit(exercise). One way to deal with this problem is to look at the relevent lines in master repository. This repository can pass all the grade script in all labs, and thus less bug. You can alos look at line blame in this repo to find out if there is a bug fix later commit. 37 | 38 | ### Pull requests are welcome 39 | 40 | If you finished another challenge or find a bug in my code and willing to share with others, feel free to send a pull request :) -------------------------------------------------------------------------------- /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=Mon Nov 17 18:30:59 EST 2014 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 | 36 | FSIMGTXTFILES := $(FSIMGTXTFILES) \ 37 | fs/lorem \ 38 | fs/script \ 39 | fs/testshell.key \ 40 | fs/testshell.sh 41 | 42 | 43 | FSIMGFILES := $(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 1024 $(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 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