├── genboot.pl ├── lab1-181860013 └── lab1 │ ├── Makefile │ ├── app │ ├── Makefile │ └── app.s │ ├── bootloader │ ├── Makefile │ ├── boot.c │ ├── boot.h │ ├── start.s │ └── start.s.bak │ └── utils │ └── genboot.pl ├── lab2-181860013 └── lab2 │ ├── Makefile │ ├── app │ ├── Makefile │ └── main.c │ ├── bootloader │ ├── Makefile │ ├── boot.c │ ├── boot.h │ └── start.S │ ├── kernel │ ├── Makefile │ ├── include │ │ ├── common.h │ │ ├── common │ │ │ ├── assert.h │ │ │ ├── const.h │ │ │ ├── types.h │ │ │ └── utils.h │ │ ├── device.h │ │ ├── device │ │ │ ├── disk.h │ │ │ ├── keyboard.h │ │ │ ├── serial.h │ │ │ ├── timer.h │ │ │ └── vga.h │ │ ├── fs.h │ │ ├── fs │ │ │ └── minix.h │ │ ├── x86.h │ │ └── x86 │ │ │ ├── cpu.h │ │ │ ├── io.h │ │ │ ├── irq.h │ │ │ └── memory.h │ ├── kernel │ │ ├── disk.c │ │ ├── doIrq.S │ │ ├── fs.c │ │ ├── i8259.c │ │ ├── idt.c │ │ ├── irqHandle.c │ │ ├── keyboard.c │ │ ├── kvm.c │ │ ├── serial.c │ │ ├── timer.c │ │ └── vga.c │ ├── lib │ │ ├── abort.c │ │ └── utils.c │ └── main.c │ ├── lib │ ├── lib.h │ ├── syscall.c │ └── types.h │ └── utils │ ├── genBoot.pl │ ├── genFS │ ├── Makefile │ ├── data.h │ ├── func.c │ ├── func.h │ ├── main.c │ ├── types.h │ ├── utils.c │ └── utils.h │ └── genKernel.pl ├── lab3-181860013 └── lab3 │ ├── Makefile │ ├── app │ ├── Makefile │ └── main.c │ ├── app_print │ ├── Makefile │ └── main.c │ ├── bootloader │ ├── Makefile │ ├── boot.c │ ├── boot.h │ └── start.S │ ├── kernel │ ├── Makefile │ ├── include │ │ ├── common.h │ │ ├── common │ │ │ ├── assert.h │ │ │ ├── const.h │ │ │ ├── types.h │ │ │ └── utils.h │ │ ├── device.h │ │ ├── device │ │ │ ├── disk.h │ │ │ ├── keyboard.h │ │ │ ├── serial.h │ │ │ ├── timer.h │ │ │ └── vga.h │ │ ├── fs.h │ │ ├── fs │ │ │ └── minix.h │ │ ├── x86.h │ │ └── x86 │ │ │ ├── cpu.h │ │ │ ├── io.h │ │ │ ├── irq.h │ │ │ └── memory.h │ ├── kernel │ │ ├── disk.c │ │ ├── doIrq.S │ │ ├── fs.c │ │ ├── i8259.c │ │ ├── idt.c │ │ ├── irqHandle.c │ │ ├── keyboard.c │ │ ├── kvm.c │ │ ├── serial.c │ │ ├── timer.c │ │ └── vga.c │ ├── lib │ │ ├── abort.c │ │ └── utils.c │ └── main.c │ ├── lib │ ├── lib.h │ ├── syscall.c │ └── types.h │ └── utils │ ├── genBoot.pl │ ├── genFS │ ├── Makefile │ ├── data.h │ ├── func.c │ ├── func.h │ ├── main.c │ ├── types.h │ ├── utils.c │ └── utils.h │ └── genKernel.pl ├── lab4-181860013 └── lab4 │ ├── Makefile │ ├── app │ ├── Makefile │ └── main.c │ ├── app_print │ ├── Makefile │ └── main.c │ ├── bootloader │ ├── Makefile │ ├── boot.c │ ├── boot.h │ └── start.S │ ├── bounded_buffer │ ├── Makefile │ └── main.c │ ├── kernel │ ├── Makefile │ ├── include │ │ ├── common.h │ │ ├── common │ │ │ ├── assert.h │ │ │ ├── const.h │ │ │ ├── types.h │ │ │ └── utils.h │ │ ├── device.h │ │ ├── device │ │ │ ├── disk.h │ │ │ ├── keyboard.h │ │ │ ├── serial.h │ │ │ ├── timer.h │ │ │ └── vga.h │ │ ├── fs.h │ │ ├── fs │ │ │ └── minix.h │ │ ├── x86.h │ │ └── x86 │ │ │ ├── cpu.h │ │ │ ├── io.h │ │ │ ├── irq.h │ │ │ └── memory.h │ ├── kernel │ │ ├── disk.c │ │ ├── doIrq.S │ │ ├── fs.c │ │ ├── i8259.c │ │ ├── idt.c │ │ ├── irqHandle.c │ │ ├── keyboard.c │ │ ├── kvm.c │ │ ├── serial.c │ │ ├── timer.c │ │ └── vga.c │ ├── lib │ │ ├── abort.c │ │ └── utils.c │ └── main.c │ ├── lib │ ├── lib.h │ ├── syscall.c │ └── types.h │ ├── philosopher │ ├── Makefile │ └── main.c │ ├── reader_writer │ ├── Makefile │ └── main.c │ └── utils │ ├── genBoot.pl │ ├── genFS │ ├── Makefile │ ├── data.h │ ├── func.c │ ├── func.h │ ├── main.c │ ├── types.h │ ├── utils.c │ └── utils.h │ └── genKernel.pl ├── lab5-181860013 └── lab5 │ ├── Makefile │ ├── app │ ├── Makefile │ └── main.c │ ├── app_print │ ├── Makefile │ └── main.c │ ├── bootloader │ ├── Makefile │ ├── boot.c │ ├── boot.h │ └── start.S │ ├── bounded_buffer │ ├── Makefile │ └── main.c │ ├── kernel │ ├── Makefile │ ├── include │ │ ├── common.h │ │ ├── common │ │ │ ├── assert.h │ │ │ ├── const.h │ │ │ ├── types.h │ │ │ └── utils.h │ │ ├── device.h │ │ ├── device │ │ │ ├── disk.h │ │ │ ├── keyboard.h │ │ │ ├── serial.h │ │ │ ├── timer.h │ │ │ └── vga.h │ │ ├── fs.h │ │ ├── fs │ │ │ └── minix.h │ │ ├── x86.h │ │ └── x86 │ │ │ ├── cpu.h │ │ │ ├── io.h │ │ │ ├── irq.h │ │ │ └── memory.h │ ├── kernel │ │ ├── disk.c │ │ ├── doIrq.S │ │ ├── fs.c │ │ ├── i8259.c │ │ ├── idt.c │ │ ├── irqHandle.c │ │ ├── keyboard.c │ │ ├── kvm.c │ │ ├── serial.c │ │ ├── timer.c │ │ └── vga.c │ ├── lib │ │ ├── abort.c │ │ └── utils.c │ └── main.c │ ├── lib │ ├── lib.h │ ├── syscall.c │ └── types.h │ ├── philosopher │ ├── Makefile │ └── main.c │ ├── reader_writer │ ├── Makefile │ └── main.c │ └── utils │ ├── genBoot.pl │ ├── genFS │ ├── Makefile │ ├── data.h │ ├── func.c │ ├── func.h │ ├── main.c │ ├── types.h │ ├── utils.c │ └── utils.h │ └── genKernel.pl └── mbr.s /genboot.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 3 | $n = sysread(SIG, $buf, 1000); 4 | if($n > 510){ 5 | print STDERR "ERROR: boot block too large: $n bytes (max 510)\n"; 6 | exit 1; 7 | } 8 | print STDERR "OK: boot block is $n bytes (max 510)\n"; 9 | $buf .= "\0" x (510-$n); 10 | $buf .= "\x55\xAA"; 11 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 12 | print SIG $buf; 13 | close SIG; 14 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/Makefile: -------------------------------------------------------------------------------- 1 | os.img: 2 | cd bootloader; make bootloader.bin 3 | cd app; make app.bin 4 | cat bootloader/bootloader.bin app/app.bin > os.img 5 | 6 | clean: 7 | cd bootloader; make clean 8 | cd app; make clean 9 | rm -f os.img 10 | 11 | play: 12 | qemu-system-i386 os.img 13 | 14 | debug: 15 | qemu-system-i386 -s -S os.img 16 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/app/Makefile: -------------------------------------------------------------------------------- 1 | app.bin: app.s 2 | gcc -c -m32 app.s -o app.o 3 | ld -m elf_i386 -e start -Ttext 0x8c00 app.o -o app.elf 4 | objcopy -S -j .text -O binary app.elf app.bin 5 | 6 | clean: 7 | rm -rf *.o *.elf *.bin 8 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/app/app.s: -------------------------------------------------------------------------------- 1 | .code32 2 | 3 | .global start 4 | start: 5 | pushl $2004 6 | pushl $ascpic 7 | calll displayStr 8 | loop: 9 | jmp loop 10 | 11 | ascpic: 12 | .string "t;i1t;;,;;itL;;ii.:.:;;fLC888800000000000008000000008C800888C0000000000000000000ff1ff:tt;:;t1i;it;LGGCCC880000000000888000000800000000000000000008000000000000::tfLGtfi i;;ii1tLLCG8888888880888080000008888LL800000000000000008000000000001::;;1fLff111,:1fLGC8888C80C088800800808888L808f1i;::;;;;i800800800080080000001;;:;itt;,fttff1fG0C80G8GGGC8888880088CCGC808ti1t;;;:;;;;;;i;;;;i8808000000000:::;iti1111ttittG800808LLCC8C8888CGC8CC880tL8L1ff1i;;;:::;iiiiii1i;;;;G0000080;:;;1ttfL:;:ittfL8000CCL8CCGC888C8G1G8888Li1L808Gtt1ii;;;;;i11ttff11i;;;;;;f000;;;1tfG::;;;:i1L8C00GGCGfCCCGGGffCCL1iif88CLLf800Cff11ii;iiitft1ii;i1i;;;;;;;;:::;;;;;;iiii11tfC08CC8LGG88CLGCLGGif1LfttLGLffLLG8Gftii;:::;i;::;;;;;tiiii;;iii:;iiii;1ii1111if8088C8G888CC88LGt1fft1itt11t11ttttt1i;;;;;;;;:::;;i1;;1fii11iii111ftf111111fCC;C08C8888888G8LtfLfftfft111iiiiiiii;;;;;;;;;;::::;ii1tt1;1i11tt11tttftGCCC8CCG01t00080C880CCfLGGLLLft111iiiiiiiiiii;;;;;iiii11tttt1tffGt1LtffffffffffffCGC8CCC88fC800888CCCCGGLLftt11iiiiiiiiii11t11ttttftttfffffttffGGGLGLGfffffffffffLLGti1tCLG808088CCCCCGLftt1111iiiiiiii1ttffffLLLffffffffLf11tfGGGLGGffffttfttttfGCC1i;;itL888G8CCGCGLftt1111i1iiiiii1tLLffffffLftttttttttLGLLGLGLLGLftttt11111tLG8CC0ii1ttfLC0CCC8CLft11111111iiii11tGCGffi18CL1111iiiiii111LGGGLLGLfttt11111tLGC00000000;,;C8GGGGGfft11111111111it1fCCLti1C100ttt1iiiiiiiii11tffffftttt1111fLGG000000000 .1GCCCCGGLffttttttt11111ttCCft1t8080ttt1iiiiiii1i11ttttttt111111GGGG0000000000 ., iGLCCC8CGGGLLftttftttttt88ftttG8LLfft1iiiiii1111tttt1t111111C8CC000000000000 ., LCC8888888CCCCGLLffffttGCfttttG8Cft11ii11ii111111111111iiG00000000000000000.:, LC8808880888888CGGLLfLLCft1ttttttt11111iiiiiiii111iiii00000000000000000000ii,,;i:CCCC80088880008888888CCCLi1111t11t1i;;;;;iii11iiiG00000000000000000000880tt: :;;G880GLGCCG8C8888888888CCCCCGtiiii1;:;i1iif8800000000800000000000000008001itfLfLLfL8C88088C88CGC88CCCCGGCC888888C8880800000000000008088888088000000000000LLLLLLLLLGCGLCCCC800888C8CGGCCCCCCCG88880800000000808888888800000000000000000000\n\0" 13 | 14 | message: 15 | .string "Hello, World!\n\0" 16 | 17 | displayStr: 18 | movl 4(%esp), %ebx 19 | movl 8(%esp), %ecx 20 | movl $0, %edi 21 | movb $0xf0, %ah 22 | nextChar: 23 | movb (%ebx), %al 24 | movw %ax, %gs:(%edi) 25 | addl $2, %edi 26 | incl %ebx 27 | loopnz nextChar # loopnz decrease ecx by 1 28 | ret 29 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/bootloader/Makefile: -------------------------------------------------------------------------------- 1 | bootloader.bin: start.s boot.c boot.h 2 | gcc -c -m32 start.s -o start.o 3 | gcc -c -m32 -O1 -fno-stack-protector boot.c -o boot.o 4 | ld -m elf_i386 -e start -Ttext 0x7c00 start.o boot.o -o bootloader.elf 5 | objcopy -S -j .text -O binary bootloader.elf bootloader.bin 6 | ../utils/genboot.pl bootloader.bin 7 | 8 | clean: 9 | rm -rf *.o *.elf *.bin 10 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/bootloader/boot.c: -------------------------------------------------------------------------------- 1 | #include "boot.h" 2 | 3 | #define SECTSIZE 512 4 | 5 | void bootMain(void) { 6 | int i = 0; 7 | void (*elf)(void); 8 | elf = (void(*)(void))0x8c00; 9 | for (i = 0; i < 200; i++) { 10 | readSect((void*)(elf + i*512), 1+i); 11 | } 12 | readSect((void*)elf, 1); // loading sector 1 to 0x8c00 13 | // TODO jumping to the loaded program 14 | elf(); 15 | } 16 | 17 | void waitDisk(void) { // waiting for disk 18 | while((inByte(0x1F7) & 0xC0) != 0x40); 19 | } 20 | 21 | void readSect(void *dst, int offset) { // reading a sector of disk 22 | int i; 23 | waitDisk(); 24 | outByte(0x1F2, 1); 25 | outByte(0x1F3, offset); 26 | outByte(0x1F4, offset >> 8); 27 | outByte(0x1F5, offset >> 16); 28 | outByte(0x1F6, (offset >> 24) | 0xE0); 29 | outByte(0x1F7, 0x20); 30 | 31 | waitDisk(); 32 | for (i = 0; i < SECTSIZE / 4; i ++) { 33 | ((int *)dst)[i] = inLong(0x1F0); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/bootloader/boot.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOT_H 2 | #define BOOT_H 3 | 4 | void waitDisk(void); 5 | 6 | void readSect(void *dst, int offset); 7 | 8 | /* I/O functions */ 9 | static inline char inByte(short port) { 10 | char data; 11 | asm volatile("in %1,%0" : "=a" (data) : "d" (port)); 12 | return data; 13 | } 14 | 15 | static inline int inLong(short port) { 16 | int data; 17 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 18 | return data; 19 | } 20 | 21 | static inline void outByte(short port, char data) { 22 | asm volatile("out %0,%1" : : "a" (data), "d" (port)); 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/bootloader/start.s: -------------------------------------------------------------------------------- 1 | .code16 2 | start: 3 | cli # 关闭中断 4 | inb $0x92, %al # 启动A20总线 5 | orb $0x02, %al 6 | outb %al, $0x92 7 | data32 addr32 lgdt gdtDesc # 加载GDTR 8 | movl %cr0, %eax # 启动保护模式 9 | orb $0x01, %al 10 | movl %eax, %cr0 # 设置CR0的PE位(第0位)为1 11 | data32 ljmp $0x08, $start32 # ⻓跳转切换⾄保护模式 12 | 13 | .code32 14 | start32: 15 | # 初始化DS ES FS GS SS 初始化栈顶指针ESP 16 | movw $0x10, %ax 17 | movw %ax, %ds 18 | movw %ax, %es 19 | movw %ax, %ss 20 | movw %ax, %fs 21 | movw $0x18, %ax 22 | movw %ax, %gs 23 | movl $(128 << 20), %esp 24 | jmp bootMain # 跳转⾄bootMain函数 定义于boot.c 25 | 26 | gdt: 27 | .word 0,0 # GDT第⼀个表项必须为空 28 | .byte 0,0,0,0 29 | 30 | .word 0xffff,0 # 代码段描述符 31 | .byte 0,0x9a,0xcf,0 32 | 33 | .word 0xffff,0 # 数据段描述符 34 | .byte 0,0x92,0xcf,0 35 | 36 | .word 0xffff,0x8000 # 视频段描述符 37 | .byte 0x0b,0x92,0xcf,0 38 | 39 | 40 | gdtDesc: 41 | .word (gdtDesc - gdt -1) 42 | .long gdt 43 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/bootloader/start.s.bak: -------------------------------------------------------------------------------- 1 | /* Real Mode Hello World */ 2 | .code16 3 | 4 | .global start 5 | start: 6 | movw %cs, %ax 7 | movw %ax, %ds 8 | movw %ax, %es 9 | movw %ax, %ss 10 | movw $0x7d00, %ax 11 | movw %ax, %sp # setting stack pointer to 0x7d00 12 | pushw $13 # pushing the size to print into stack 13 | pushw $message # pushing the address of message into stack 14 | callw displayStr # calling the display function 15 | loop: 16 | jmp loop 17 | 18 | message: 19 | .string "Hello, World!\n\0" 20 | 21 | displayStr: 22 | pushw %bp 23 | movw 4(%esp), %ax 24 | movw %ax, %bp 25 | movw 6(%esp), %cx 26 | movw $0x1301, %ax 27 | movw $0x000c, %bx 28 | movw $0x0000, %dx 29 | int $0x10 30 | popw %bp 31 | ret 32 | -------------------------------------------------------------------------------- /lab1-181860013/lab1/utils/genboot.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 1000); 6 | 7 | if($n > 510){ 8 | print STDERR "ERROR: boot block too large: $n bytes (max 510)\n"; 9 | exit 1; 10 | } 11 | 12 | print STDERR "OK: boot block is $n bytes (max 510)\n"; 13 | 14 | $buf .= "\0" x (510-$n); 15 | $buf .= "\x55\xAA"; 16 | 17 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 18 | print SIG $buf; 19 | close SIG; 20 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/Makefile: -------------------------------------------------------------------------------- 1 | QEMU = qemu-system-i386 2 | 3 | os.img: 4 | @cd utils/genFS; make 5 | @cd bootloader; make 6 | @cd kernel; make 7 | @cd app; make 8 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.bin > os.img 9 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.elf > os.img 10 | @#cat bootloader/bootloader.bin kernel/kMain.elf app/uMain.elf > os.img 11 | cat bootloader/bootloader.bin kernel/kMain.elf app/fs.bin > os.img 12 | 13 | play: os.img 14 | $(QEMU) -serial stdio os.img 15 | 16 | debug: os.img 17 | $(QEMU) -serial stdio -s -S os.img 18 | 19 | clean: 20 | @cd utils/genFS; make clean 21 | @cd bootloader; make clean 22 | @cd kernel; make clean 23 | @cd app; make clean 24 | rm -f os.img 25 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/app/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | #UOBJS = $(LCFILES:.c=.o) $(UCFILES:.c=.o) 13 | 14 | umain.bin: $(UOBJS) 15 | @#$(LD) $(LDFLAGS) -e uEntry -Ttext 0x00200000 -o uMain.elf $(UOBJS) 16 | $(LD) $(LDFLAGS) -e uEntry -Ttext 0x00000000 -o uMain.elf $(UOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary uMain.elf uMain.bin 18 | @#objcopy -O binary uMain.elf uMain.bin 19 | @../utils/genFS/genFS uMain.elf 20 | 21 | clean: 22 | @#rm -rf $(UOBJS) uMain.elf uMain.bin 23 | rm -rf $(UOBJS) uMain.elf fs.bin 24 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/app/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | //int data = 0; 5 | 6 | int uEntry(void) { 7 | 8 | //asm volatile("cli"); //XXX test for CPL, will cause a #GP 9 | //asm volatile("int $0xe"); //XXX test for SWInterrupt/exception:fault, current instruction address is pushed into kernel stack, if idt[0xe].dpl>=cpl, o.w., cause #GP 10 | //asm volatile("int $0x80");//XXX test for SWInterrupt, next instruction address is pushed into kernel stack, if idt[0x80].dpl>=cpl, o.w., cause #GP 11 | //asm volatile("int 3 ...");//XXX equivalent to int 0x3? 12 | //asm volatile("into ...");//XXX equivalent to int 0x4? 13 | //asm volatile("bound ...");//XXX equivalent to int 0x5? 14 | //printf("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n"); 15 | //printf("Scroll Screen Test.\n"); 16 | //char data = 'H'; 17 | //printf("%c\n", data); 18 | 19 | printf("printf test begin...\n"); 20 | printf("the answer should be:\n"); 21 | printf("#######################################################\n"); 22 | printf("Hello, welcome to OSlab! I'm the body of the game. "); 23 | printf("Bootblock loads me to the memory position of 0x100000, and Makefile also tells me that I'm at the location of 0x100000. "); 24 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 25 | printf("Now I will test your printf: "); 26 | printf("1 + 1 = 2, 123 * 456 = 56088\n0, -1, -2147483648, -1412567295, -32768, 102030\n0, ffffffff, 80000000, abcdef01, ffff8000, 18e8e\n"); 27 | printf("#######################################################\n"); 28 | printf("your answer:\n"); 29 | printf("=======================================================\n"); 30 | printf("%s %s%scome %co%s", "Hello,", "", "wel", 't', " "); 31 | printf("%c%c%c%c%c! ", 'O', 'S', 'l', 'a', 'b'); 32 | printf("I'm the %s of %s. %s 0x%x, %s 0x%x. ", "body", "the game", "Bootblock loads me to the memory position of", 0x100000, "and Makefile also tells me that I'm at the location of", 0x100000); 33 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 34 | printf("Now I will test your printf: "); 35 | printf("%d + %d = %d, %d * %d = %d\n", 1, 1, 1 + 1, 123, 456, 123 * 456); 36 | printf("%d, %d, %d, %d, %d, %d\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 37 | printf("%x, %x, %x, %x, %x, %x\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 38 | printf("=======================================================\n"); 39 | printf("Test end!!! Good luck!!!\n"); 40 | 41 | while(1); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/bootloader/Makefile: -------------------------------------------------------------------------------- 1 | #bootloader.bin: start.S boot.c boot.h 2 | # gcc -c -m32 start.S -o start.o 3 | # gcc -c -m32 -O1 -fno-stack-protector boot.c -o boot.o 4 | # ld -m elf_i386 -e start -Ttext 0x7c00 start.o boot.o -o bootloader.elf 5 | # @#ld -m elf_i386 -e start -Ttext 0x7c00 boot.o start.o -o bootloader.elf 6 | # @#objcopy -S -j .text -O binary bootloader.elf bootloader.bin 7 | # objcopy -O binary bootloader.elf bootloader.bin 8 | # ../utils/genBoot.pl bootloader.bin 9 | # 10 | #clean: 11 | # rm -rf *.o *.elf *.bin 12 | 13 | # take care of link order of object files 14 | # -Ttext set the address of the first byte of the text segment 15 | # -e set the entry address in elf-header 16 | # i.e., the entry address may not be the address of the first byte of the text segment 17 | 18 | CC = gcc 19 | LD = ld 20 | 21 | CFLAGS = -m32 -march=i386 -static \ 22 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 23 | -Wall -Werror -O2 24 | ASFLAGS = -m32 25 | LDFLAGS = -m elf_i386 26 | 27 | BSFILES = $(shell find ./ -name "*.S") 28 | BCFILES = $(shell find ./ -name "*.c") 29 | BOBJS = $(BSFILES:.S=.o) $(BCFILES:.c=.o) 30 | 31 | bootloader.bin: $(BOBJS) 32 | $(LD) $(LDFLAGS) -e start -Ttext 0x7c00 -o bootloader.elf $(BOBJS) 33 | objcopy -S -j .text -O binary bootloader.elf bootloader.bin 34 | @../utils/genBoot.pl bootloader.bin 35 | 36 | clean: 37 | rm -rf $(BOBJS) bootloader.elf bootloader.bin 38 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/bootloader/boot.c: -------------------------------------------------------------------------------- 1 | #include "boot.h" 2 | 3 | #define SECTSIZE 512 4 | 5 | /* 6 | void bootMain(void) { 7 | int i = 0; 8 | void (*elf)(void); 9 | elf = (void(*)(void))0x100000; // kernel is loaded to location 0x100000 10 | for (i = 0; i < 200; i ++) { 11 | //readSect((void*)elf + i*512, i+1); 12 | readSect((void*)elf + i*512, i+9); 13 | } 14 | elf(); // jumping to the loaded program 15 | } 16 | */ 17 | 18 | void bootMain(void) { 19 | int i = 0; 20 | int phoff = 0x34; 21 | int offset = 0x1000; 22 | unsigned int elf = 0x100000; 23 | void (*kMainEntry)(void); 24 | kMainEntry = (void(*)(void))0x100000; 25 | 26 | for (i = 0; i < 200; i++) { 27 | readSect((void*)(elf + i*512), 1+i); 28 | } 29 | 30 | kMainEntry = (void(*)(void))((struct ELFHeader *)elf)->entry; 31 | phoff = ((struct ELFHeader *)elf)->phoff; 32 | offset = ((struct ProgramHeader *)(elf + phoff))->off; 33 | 34 | for (i = 0; i < 200 * 512; i++) { 35 | *(unsigned char *)(elf + i) = *(unsigned char *)(elf + i + offset); 36 | } 37 | 38 | kMainEntry(); 39 | } 40 | 41 | void waitDisk(void) { // waiting for disk 42 | while((inByte(0x1F7) & 0xC0) != 0x40); 43 | } 44 | 45 | void readSect(void *dst, int offset) { // reading a sector of disk 46 | int i; 47 | waitDisk(); 48 | outByte(0x1F2, 1); 49 | outByte(0x1F3, offset); 50 | outByte(0x1F4, offset >> 8); 51 | outByte(0x1F5, offset >> 16); 52 | outByte(0x1F6, (offset >> 24) | 0xE0); 53 | outByte(0x1F7, 0x20); 54 | 55 | waitDisk(); 56 | for (i = 0; i < SECTSIZE / 4; i ++) { 57 | ((int *)dst)[i] = inLong(0x1F0); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/bootloader/boot.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOT_H 2 | #define BOOT_H 3 | 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | void waitDisk(void); 35 | 36 | void readSect(void *dst, int offset); 37 | 38 | /* I/O functions */ 39 | static inline char inByte(short port) { 40 | char data; 41 | asm volatile("in %1,%0" : "=a" (data) : "d" (port)); 42 | return data; 43 | } 44 | 45 | static inline int inLong(short port) { 46 | int data; 47 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 48 | return data; 49 | } 50 | 51 | static inline void outByte(short port, char data) { 52 | asm volatile("out %0,%1" : : "a" (data), "d" (port)); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O0 -I./include 7 | ASFLAGS = -m32 8 | LDFLAGS = -m elf_i386 9 | 10 | KCFILES = $(shell find ./ -name "*.c") 11 | KSFILES = $(shell find ./ -name "*.S") 12 | KOBJS = $(KCFILES:.c=.o) $(KSFILES:.S=.o) 13 | #KOBJS = $(KSFILES:.S=.o) $(KCFILES:.c=.o) 14 | 15 | kmain.bin: $(KOBJS) 16 | $(LD) $(LDFLAGS) -e kEntry -Ttext 0x00100000 -o kMain.elf $(KOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary kMain.elf kMain.bin 18 | @#objcopy -O binary kMain.elf kMain.bin 19 | @../utils/genKernel.pl kMain.elf 20 | @#../utils/genKernel.pl kMain.bin 21 | 22 | 23 | clean: 24 | @#rm -rf $(KOBJS) kMain.elf kMain.bin 25 | rm -rf $(KOBJS) kMain.elf kMain.bin 26 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include "common/types.h" 5 | #include "common/const.h" 6 | #include "common/assert.h" 7 | #include "common/utils.h" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/common/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASSERT_H__ 2 | #define __ASSERT_H__ 3 | 4 | int abort(const char *, int); 5 | 6 | /* assert: 断言条件为真,若为假则蓝屏退出 */ 7 | #define assert(cond) \ 8 | ((cond) ? (0) : (abort(__FILE__, __LINE__))) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/common/const.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONST_H__ 2 | #define __CONST_H__ 3 | 4 | #define TRUE 1 5 | #define FALSE 0 6 | 7 | #define NULL ((void*)0) 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/common/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | /* 定义数据类型 */ 5 | typedef unsigned int uint32_t; 6 | typedef int int32_t; 7 | typedef unsigned short uint16_t; 8 | typedef short int16_t; 9 | typedef unsigned char uint8_t; 10 | typedef char int8_t; 11 | typedef unsigned int size_t; 12 | #endif 13 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/common/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | int stringChr(const char *string, char token, int *size); 5 | 6 | int stringChrR (const char *string, char token, int *size); 7 | 8 | int stringLen(const char *string); 9 | 10 | int stringCmp(const char *srcString, const char *destString, int size); 11 | 12 | int stringCpy (const char *srcString, char *destString, int size); 13 | 14 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 15 | 16 | #endif -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/device.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVICE_H__ 2 | #define __DEVICE_H__ 3 | 4 | #include "device/serial.h" 5 | #include "device/disk.h" 6 | #include "device/vga.h" 7 | #include "device/timer.h" 8 | #include "device/keyboard.h" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/device/disk.h: -------------------------------------------------------------------------------- 1 | #ifndef __DISK_H__ 2 | #define __DISK_H__ 3 | 4 | #define SECTOR_NUM 8192 5 | #define SECTOR_SIZE 512 6 | 7 | void waitDisk(void); 8 | void readSect(void *dst, int offset); 9 | void writeSect(void *src, int offset); 10 | 11 | void diskRead(void *destBuffer, int size, int num, int offset); 12 | void diskWrite(void *destBuffer, int size, int num, int offset); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/device/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYBOARD_H__ 2 | #define __KEYBOARD_H__ 3 | 4 | #define MAX_KEYBUFFER_SIZE 256 5 | 6 | void initKeyTable(); 7 | 8 | uint32_t getKeyCode(); 9 | 10 | char getChar(uint32_t code); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/device/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERIAL_H__ 2 | #define __SERIAL_H__ 3 | 4 | void initSerial(void); 5 | void putChar(char); 6 | void putString(const char *); 7 | void putInt(int); 8 | 9 | #define SERIAL_PORT 0x3F8 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/device/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_H__ 2 | #define __TIMER_H__ 3 | 4 | void initTimer(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/device/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef __VGA_H__ 2 | #define __VGA_H__ 3 | 4 | void initVga(); 5 | void clearScreen(); 6 | void updateCursor(int row, int col); 7 | void scrollScreen(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef __FS_H__ 2 | #define __FS_H__ 3 | 4 | #include "fs/minix.h" 5 | 6 | int readSuperBlock (SuperBlock *superBlock); 7 | 8 | int allocInode (SuperBlock *superBlock, 9 | Inode *fatherInode, 10 | int fatherInodeOffset, 11 | Inode *destInode, 12 | int *destInodeOffset, 13 | const char *destFilename, 14 | int destFiletype); 15 | 16 | int freeInode (SuperBlock *superBlock, 17 | Inode *fatherInode, 18 | int fatherInodeOffset, 19 | Inode *destInode, 20 | int *destInodeOffset, 21 | const char *destFilename, 22 | int destFiletype); 23 | 24 | int readInode (SuperBlock *superBlock, 25 | Inode *destInode, 26 | int *inodeOffset, 27 | const char *destFilePath); 28 | 29 | int allocBlock (SuperBlock *superBlock, 30 | Inode *inode, 31 | int inodeOffset); 32 | 33 | int readBlock (SuperBlock *superBlock, 34 | Inode *inode, 35 | int blockIndex, 36 | uint8_t *buffer); 37 | 38 | int writeBlock (SuperBlock *superBlock, 39 | Inode *inode, 40 | int blockIndex, 41 | uint8_t *buffer); 42 | 43 | int getDirEntry (SuperBlock *superBlock, 44 | Inode *inode, 45 | int dirIndex, 46 | DirEntry *destDirEntry); 47 | 48 | void initFS (void); 49 | 50 | void initFile (void); 51 | 52 | #endif /* __FS_H__ */ 53 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/fs/minix.h: -------------------------------------------------------------------------------- 1 | #ifndef __MINIX_H__ 2 | #define __MINIX_H__ 3 | 4 | /* 5 | * minix like filesystem 6 | */ 7 | 8 | /* 9 | * Layout of file system 10 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 11 | *| SuperBlock | InodeBitmap | BlockBitmap | InodeTable | DataBlocks | 12 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 13 | * 1024 Bytes 1 Block 1 Block 128 Blocks Many More Blocks 14 | * 15 | */ 16 | 17 | #define SECTORS_PER_BLOCK 2 18 | #define POINTER_NUM 14 19 | #define NAME_LENGTH 64 20 | 21 | #define BLOCK_SIZE (SECTOR_SIZE * SECTORS_PER_BLOCK) 22 | #define SUPER_BLOCK_SIZE BLOCK_SIZE 23 | #define INODE_BITMAP_SIZE BLOCK_SIZE 24 | #define BLOCK_BITMAP_SIZE BLOCK_SIZE 25 | #define INODE_SIZE 128 26 | #define DIRENTRY_SIZE 128 27 | #define INODE_BLOCKS (SECTOR_NUM / SECTORS_PER_BLOCK / 32) 28 | 29 | #define UNKNOWN_TYPE 0 30 | #define REGULAR_TYPE 1 31 | #define DIRECTORY_TYPE 2 32 | #define CHARACTER_TYPE 3 33 | #define BLOCK_TYPE 4 34 | #define FIFO_TYPE 5 35 | #define SOCKET_TYPE 6 36 | #define SYMBOLIC_TYPE 7 37 | 38 | union SuperBlock { 39 | uint8_t byte[SUPER_BLOCK_SIZE]; 40 | struct { 41 | int32_t sectorNum; // total number of sectors 42 | int32_t inodeNum; // total number of inodes 43 | int32_t blockNum; // total number of data blocks 44 | int32_t availInodeNum; // total number of available inodes 45 | int32_t availBlockNum; // total number of available data blocks 46 | int32_t blockSize; // number of bytes in each block 47 | int32_t inodeBitmap; // XXX sector as unit 48 | int32_t blockBitmap; // XXX sector as unit 49 | int32_t inodeTable; // XXX sector as unit 50 | int32_t blocks; // XXX sector as unit 51 | }; 52 | }; 53 | typedef union SuperBlock SuperBlock; 54 | 55 | struct InodeBitmap { 56 | uint8_t byte[INODE_BITMAP_SIZE]; 57 | }; 58 | typedef struct InodeBitmap InodeBitmap; 59 | 60 | struct BlockBitmap { 61 | uint8_t byte[BLOCK_BITMAP_SIZE]; 62 | }; 63 | typedef struct BlockBitmap BlockBitmap; 64 | 65 | union Inode { 66 | uint8_t byte[INODE_SIZE]; 67 | struct { 68 | int16_t type; 69 | int16_t linkCount; 70 | int32_t blockCount; 71 | int32_t size; 72 | int32_t pointer[POINTER_NUM]; // XXX sector as unit 73 | int32_t singlyPointer; // XXX sector as unit 74 | }; 75 | }; 76 | typedef union Inode Inode; 77 | 78 | union DirEntry { 79 | uint8_t byte[DIRENTRY_SIZE]; 80 | struct { 81 | int32_t inode; // index in inode table, started from 1, 0 for unused. 82 | char name[NAME_LENGTH]; 83 | }; 84 | }; 85 | typedef union DirEntry DirEntry; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/x86.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_H__ 2 | #define __X86_H__ 3 | 4 | #include "x86/cpu.h" 5 | #include "x86/memory.h" 6 | #include "x86/io.h" 7 | #include "x86/irq.h" 8 | 9 | void initSeg(void); 10 | void loadUMain(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/x86/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_CPU_H__ 2 | #define __X86_CPU_H__ 3 | 4 | #include "common.h" 5 | 6 | /* 将CPU置入休眠状态直到下次中断到来 */ 7 | static inline void waitForInterrupt() { 8 | asm volatile("hlt"); 9 | } 10 | 11 | /* 修改IDTR */ 12 | static inline void saveIdt(void *addr, uint32_t size) { 13 | static volatile uint16_t data[3]; 14 | data[0] = size - 1; 15 | data[1] = (uint32_t)addr; 16 | data[2] = ((uint32_t)addr) >> 16; 17 | asm volatile("lidt (%0)" : : "r"(data)); 18 | } 19 | 20 | /* 打开外部中断 */ 21 | static inline void enableInterrupt(void) { 22 | asm volatile("sti"); 23 | } 24 | 25 | /* 关闭外部中断 */ 26 | static inline void disableInterrupt(void) { 27 | asm volatile("cli"); 28 | } 29 | 30 | #define NR_IRQ 256 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/x86/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_IO_H__ 2 | #define __X86_IO_H__ 3 | /* ELF32二进制文件头 */ 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | 35 | static inline int inLong(short port) { 36 | int data; 37 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 38 | return data; 39 | } 40 | 41 | static inline void outLong(uint16_t port, uint32_t data) { 42 | asm volatile("out %0, %1" : : "a"(data), "d"(port)); 43 | } 44 | 45 | /* 读I/O端口 */ 46 | static inline uint8_t inByte(uint16_t port) { 47 | uint8_t data; 48 | asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 49 | return data; 50 | } 51 | 52 | /* 写I/O端口 */ 53 | static inline void outByte(uint16_t port, int8_t data) { 54 | asm volatile("out %%al, %%dx" : : "a"(data), "d"(port)); 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/include/x86/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __IRQ_H__ 2 | #define __IRQ_H__ 3 | 4 | /* 中断处理相关函数 */ 5 | void initIdt(void); 6 | void initIntr(void); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/kernel/disk.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define SECTSIZE 512 5 | 6 | void waitDisk(void) { 7 | while((inByte(0x1F7) & 0xC0) != 0x40); 8 | } 9 | 10 | void readSect(void *dst, int offset) { 11 | int i; 12 | waitDisk(); 13 | 14 | outByte(0x1F2, 1); 15 | outByte(0x1F3, offset); 16 | outByte(0x1F4, offset >> 8); 17 | outByte(0x1F5, offset >> 16); 18 | outByte(0x1F6, (offset >> 24) | 0xE0); 19 | outByte(0x1F7, 0x20); 20 | 21 | waitDisk(); 22 | for (i = 0; i < SECTSIZE / 4; i ++) { 23 | ((int *)dst)[i] = inLong(0x1F0); 24 | } 25 | } 26 | 27 | void writeSect(void *src, int offset) { 28 | int i; 29 | waitDisk(); 30 | 31 | outByte(0x1F2, 1); 32 | outByte(0x1F3, offset); 33 | outByte(0x1F4, offset >> 8); 34 | outByte(0x1F5, offset >> 16); 35 | outByte(0x1F6, (offset >> 24) | 0xE0); 36 | outByte(0x1F7, 0x30); 37 | 38 | waitDisk(); 39 | for (i = 0; i < SECTOR_SIZE / 4; i ++) { 40 | outLong(0x1F0, ((uint32_t *)src)[i]); 41 | } 42 | } 43 | 44 | void diskRead (void *destBuffer, int size, int num, int offset) { 45 | int i = 0; 46 | int j = 0; 47 | uint8_t buffer[SECTOR_SIZE]; 48 | int quotient = offset / SECTOR_SIZE; 49 | int remainder = offset % SECTOR_SIZE; 50 | 51 | readSect((void*)buffer, 201 + quotient + j); 52 | j ++; 53 | while (i < size * num) { 54 | ((uint8_t*)destBuffer)[i] = buffer[(remainder + i) % SECTOR_SIZE]; 55 | i ++; 56 | if ((remainder + i) % SECTOR_SIZE == 0) { 57 | readSect((void*)buffer, 201 + quotient + j); 58 | j ++; 59 | } 60 | } 61 | } 62 | 63 | void diskWrite (void *destBuffer, int size, int num, int offset) { 64 | int i = 0; 65 | int j = 0; 66 | uint8_t buffer[SECTOR_SIZE]; 67 | int quotient = offset / SECTOR_SIZE; 68 | int remainder = offset % SECTOR_SIZE; 69 | 70 | readSect((void*)buffer, 201 + quotient + j); 71 | while (i < size * num) { 72 | buffer[(remainder + i) % SECTOR_SIZE] = ((uint8_t*)destBuffer)[i]; 73 | i ++; 74 | if ((remainder + i) % SECTOR_SIZE == 0) { 75 | writeSect((void*)buffer, 201 + quotient + j); 76 | j ++; 77 | readSect((void*)buffer, 201 + quotient + j); 78 | } 79 | } 80 | writeSect((void*)buffer, 201 + quotient + j); 81 | } 82 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/kernel/doIrq.S: -------------------------------------------------------------------------------- 1 | /*TODO 2 | otherwise need to reassign esp0 of tss in task switching for each user process 3 | note that for conforming code OR same PRL, no need to switch task 4 | that is TSS doesn't work 5 | 1. Trap Gate, IF won't be set 6 | 2. Interrupt Gate, IF is set automatically 7 | 3. System Gate 8 | */ 9 | 10 | .code32 11 | 12 | .global irqEmpty 13 | irqEmpty: 14 | pushl $0 // push dummy error code 15 | pushl $-1 // push interruption number into kernel 16 | jmp asmDoIrq 17 | 18 | .global irqErrorCode 19 | irqErrorCode: 20 | pushl $-1 // push interruption number into kernel 21 | jmp asmDoIrq 22 | 23 | .global irqDoubleFault 24 | irqDoubleFault: 25 | pushl $-1 26 | jmp asmDoIrq 27 | 28 | .global irqInvalidTSS 29 | irqInvalidTSS: 30 | pushl $-1 31 | jmp asmDoIrq 32 | 33 | .global irqSegNotPresent 34 | irqSegNotPresent: 35 | pushl $-1 36 | jmp asmDoIrq 37 | 38 | .global irqStackSegFault 39 | irqStackSegFault: 40 | pushl $-1 41 | jmp asmDoIrq 42 | 43 | .global irqGProtectFault 44 | irqGProtectFault: 45 | pushl $0xd 46 | jmp asmDoIrq 47 | 48 | .global irqPageFault 49 | irqPageFault: 50 | pushl $-1 51 | jmp asmDoIrq 52 | 53 | .global irqAlignCheck 54 | irqAlignCheck: 55 | pushl $-1 56 | jmp asmDoIrq 57 | 58 | .global irqSecException 59 | irqSecException: 60 | pushl $-1 61 | jmp asmDoIrq 62 | 63 | .global irqTimer 64 | irqTimer: 65 | pushl $0 66 | pushl $0x20 67 | jmp asmDoIrq 68 | 69 | .global irqKeyboard 70 | irqKeyboard: 71 | pushl $0 72 | pushl $0x21 73 | jmp asmDoIrq 74 | 75 | .global irqSyscall 76 | irqSyscall: 77 | pushl $0 // push dummy error code 78 | pushl $0x80 // push interruption number into kernel stack 79 | jmp asmDoIrq 80 | 81 | //.extern irqHandle //defined in irq_handle.c 82 | 83 | .global asmDoIrq 84 | asmDoIrq: 85 | pushal // push process state into kernel stack 86 | pushl %ds 87 | pushl %es 88 | pushl %fs 89 | pushl %gs 90 | pushl %esp //esp is treated as a parameter 91 | call irqHandle 92 | addl $4, %esp //esp is on top of kernel stack 93 | popl %gs 94 | popl %fs 95 | popl %es 96 | popl %ds 97 | popal 98 | addl $4, %esp //interrupt number is on top of kernel stack 99 | addl $4, %esp //error code is on top of kernel stack 100 | iret 101 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/kernel/i8259.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | 3 | #define PORT_PIC_MASTER 0x20 4 | #define PORT_PIC_SLAVE 0xA0 5 | #define IRQ_SLAVE 2 6 | 7 | /* 初始化8259中断控制器: 8 | * 硬件中断IRQ从32号开始,自动发送EOI */ 9 | void 10 | initIntr(void) { 11 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 12 | //outByte(PORT_PIC_SLAVE + 1 , 0xFF); // OCW1, Disable Slave PIC all IRQs 13 | outByte(PORT_PIC_MASTER, 0x11); // ICW1, Initialization command 14 | outByte(PORT_PIC_SLAVE, 0x11); // ICW1, Initialization command 15 | outByte(PORT_PIC_MASTER + 1, 32); // ICW2, Interrupt Vector Offset 0x20 16 | outByte(PORT_PIC_SLAVE + 1, 32 + 8); // ICW2, Interrupt Vector Offset 0x28 17 | outByte(PORT_PIC_MASTER + 1, 1 << 2); // ICW3, Tell Master PIC that there is a slave 18 | outByte(PORT_PIC_SLAVE + 1, 2); // ICW3, Tell Slave PIC its cascade identity 19 | outByte(PORT_PIC_MASTER + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 20 | outByte(PORT_PIC_SLAVE + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 21 | 22 | //outByte(PORT_PIC_MASTER, 0x68); // OCW3, Enable Special Mask Mode 23 | //outByte(PORT_PIC_MASTER, 0x0A); // OCW3, Read ISR of Master on next CMD Read 24 | //outByte(PORT_PIC_SLAVE, 0x68); // OCW3, Enable Special Mask Mode 25 | //outByte(PORT_PIC_SLAVE, 0x0A); // OCW3, Read ISR of Slave on next CMD Read 26 | 27 | //outByte(PORT_PIC_MASTER + 1, 0xFE); // OCW1, Enable Timer IRQ 28 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 29 | //outByte(PORT_PIC_SLAVE + 1, 0xFF); // OCW1, Disable Slave PIC all IRQs 30 | } 31 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/kernel/serial.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | void initSerial(void) { 5 | outByte(SERIAL_PORT + 1, 0x00); 6 | outByte(SERIAL_PORT + 3, 0x80); 7 | outByte(SERIAL_PORT + 0, 0x01); 8 | outByte(SERIAL_PORT + 1, 0x00); 9 | outByte(SERIAL_PORT + 3, 0x03); 10 | outByte(SERIAL_PORT + 2, 0xC7); 11 | outByte(SERIAL_PORT + 4, 0x0B); 12 | } 13 | 14 | static inline int serialIdle(void) { 15 | return (inByte(SERIAL_PORT + 5) & 0x20) != 0; 16 | } 17 | 18 | void putChar(char ch) { 19 | while (serialIdle() != TRUE); 20 | outByte(SERIAL_PORT, ch); 21 | } 22 | 23 | void putString(const char *str) { 24 | int i = 0; 25 | if (str == NULL) { 26 | return; 27 | } 28 | while (str[i] != 0) { 29 | putChar(str[i++]); 30 | } 31 | } 32 | 33 | void putInt(int a) { 34 | char buf[32]; 35 | char *p = buf + sizeof(buf) - 1; 36 | *p = '\0'; 37 | *(--p) = '\n'; 38 | do { 39 | *--p = '0' + a % 10; 40 | } while (a /= 10); 41 | putString(p); 42 | } 43 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/kernel/timer.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define TIMER_PORT 0x40 5 | #define FREQ_8253 1193182 6 | #define HZ 100 7 | //#define HZ 1000 8 | 9 | void initTimer() { 10 | int counter = FREQ_8253 / HZ; 11 | //assert(TIMER_PORT < 65536); 12 | outByte(TIMER_PORT + 3, 0x34); 13 | outByte(TIMER_PORT + 0, counter % 256); 14 | outByte(TIMER_PORT + 0, counter / 256); 15 | } 16 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/kernel/vga.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | int displayRow = 0; //TODO futher extend, display position, in .bss section, not in .data section 5 | int displayCol = 0; 6 | uint16_t displayMem[80*25]; 7 | int displayClear = 0; 8 | 9 | void initVga() { 10 | displayRow = 0; 11 | displayCol = 0; 12 | displayClear = 0; 13 | clearScreen(); 14 | updateCursor(0, 0); 15 | } 16 | 17 | void clearScreen() { 18 | int i = 0; 19 | int pos = 0; 20 | uint16_t data = 0 | (0x0c << 8); 21 | for (i = 0; i < 80 * 25; i++) { 22 | pos = i * 2; 23 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 24 | } 25 | } 26 | 27 | void updateCursor(int row, int col){ 28 | int cursorPos = row * 80 + col; 29 | outByte(0x3d4, 0x0f); 30 | outByte(0x3d5, (unsigned char)(cursorPos & 0xff)); 31 | 32 | outByte(0x3d4, 0x0e); 33 | outByte(0x3d5, (unsigned char)((cursorPos>>8) & 0xff)); 34 | } 35 | 36 | void scrollScreen() { 37 | int i = 0; 38 | int pos = 0; 39 | uint16_t data = 0; 40 | for (i = 0; i < 80 * 25; i++) { 41 | pos = i * 2; 42 | asm volatile("movw (%1), %0":"=r"(data):"r"(pos+0xb8000)); 43 | displayMem[i] = data; 44 | } 45 | for (i = 0; i < 80 * 24; i++) { 46 | pos = i * 2; 47 | data = displayMem[i+80]; 48 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 49 | } 50 | data = 0 | (0x0c << 8); 51 | for (i = 80 * 24; i < 80 * 25; i++) { 52 | pos = i * 2; 53 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/lib/abort.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | 5 | static char *i2A(int a) { 6 | static char buf[30]; 7 | char *p = buf + sizeof(buf) - 1; 8 | do { 9 | *--p = '0' + a % 10; 10 | } while (a /= 10); 11 | return p; 12 | } 13 | 14 | static void append(char **p, const char *str) { 15 | while (*str) { 16 | *((*p) ++) = *str ++; 17 | } 18 | } 19 | 20 | /* 将文件名和assert fail的行号显示在屏幕上 */ 21 | #define BLUE_SCREEN_TEXT "Assertion failed: " 22 | static void displayMessage(const char *file, int line) { 23 | static char buf[256] = BLUE_SCREEN_TEXT; 24 | char *p = buf + sizeof(BLUE_SCREEN_TEXT) - 1; 25 | 26 | append(&p, file); 27 | append(&p, ":"); 28 | append(&p, i2A(line)); 29 | append(&p, "\n"); 30 | 31 | for (p = buf; *p; p ++) { 32 | putChar(*p); 33 | } 34 | } 35 | 36 | int abort(const char *fname, int line) { 37 | disableInterrupt(); 38 | displayMessage(fname, line); 39 | while (TRUE) { 40 | waitForInterrupt(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/lib/utils.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /* 4 | * find the first token in string 5 | * set *size as the number of bytes before token 6 | * if not found, set *size as the length of *string 7 | */ 8 | int stringChr (const char *string, char token, int *size) { 9 | int i = 0; 10 | if (string == NULL) { 11 | *size = 0; 12 | return -1; 13 | } 14 | while (string[i] != 0) { 15 | if (token == string[i]) { 16 | *size = i; 17 | return 0; 18 | } 19 | else 20 | i ++; 21 | } 22 | *size = i; 23 | return -1; 24 | } 25 | 26 | /* 27 | * find the last token in string 28 | * set *size as the number of bytes before token 29 | * if not found, set *size as the length of *string 30 | */ 31 | int stringChrR (const char *string, char token, int *size) { 32 | int i = 0; 33 | if (string == NULL) { 34 | *size = 0; 35 | return -1; 36 | } 37 | while (string[i] != 0) 38 | i ++; 39 | *size = i; 40 | while (i > -1) { 41 | if (token == string[i]) { 42 | *size = i; 43 | return 0; 44 | } 45 | else 46 | i --; 47 | } 48 | return -1; 49 | } 50 | 51 | int stringLen (const char *string) { 52 | int i = 0; 53 | if (string == NULL) 54 | return 0; 55 | while (string[i] != 0) 56 | i ++; 57 | return i; 58 | } 59 | 60 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 61 | int i = 0; 62 | if (srcString == NULL || destString == NULL) 63 | return -1; 64 | while (i != size) { 65 | if (srcString[i] != destString[i]) 66 | return -1; 67 | else if (srcString[i] == 0) 68 | return 0; 69 | else 70 | i ++; 71 | } 72 | return 0; 73 | } 74 | 75 | int stringCpy (const char *srcString, char *destString, int size) { 76 | int i = 0; 77 | if (srcString == NULL || destString == NULL) 78 | return -1; 79 | while (i != size) { 80 | if (srcString[i] != 0) { 81 | destString[i] = srcString[i]; 82 | i++; 83 | } 84 | else 85 | break; 86 | } 87 | destString[i] = 0; 88 | return 0; 89 | } 90 | 91 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 92 | int i = 0; 93 | if (buffer == NULL) 94 | return -1; 95 | for (i = 0; i < size ; i ++) 96 | buffer[i] = value; 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/kernel/main.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | #include "fs.h" 5 | 6 | void kEntry(void) { 7 | 8 | // Interruption is disabled in bootloader 9 | 10 | initSerial();// initialize serial port 11 | initIdt(); // initialize idt 12 | initIntr(); // iniialize 8259a 13 | initSeg(); // initialize gdt, tss 14 | initVga(); // initialize vga device 15 | initTimer(); 16 | initKeyTable(); 17 | initFS(); 18 | loadUMain(); // load user program, enter user space 19 | 20 | while(1); 21 | assert(0); 22 | } 23 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/lib/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __lib_h__ 2 | #define __lib_h__ 3 | 4 | #define SYS_WRITE 0 5 | #define STD_OUT 0 6 | 7 | #define MAX_BUFFER_SIZE 256 8 | //#define MAX_BUFFER_SIZE 1 9 | 10 | void printf(const char *format,...); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/lib/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef int int32_t; 6 | typedef unsigned short uint16_t; 7 | typedef short int16_t; 8 | typedef unsigned char uint8_t; 9 | typedef char int8_t; 10 | typedef unsigned char boolean; 11 | 12 | typedef uint32_t size_t; 13 | typedef int32_t pid_t; 14 | 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genBoot.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 1000); 6 | 7 | if($n > 510){ 8 | print STDERR "ERROR: boot block too large: $n bytes (max 510)\n"; 9 | exit 1; 10 | } 11 | 12 | print STDERR "OK: boot block is $n bytes (max 510)\n"; 13 | 14 | $buf .= "\0" x (510-$n); 15 | $buf .= "\x55\xAA"; 16 | 17 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 18 | print SIG $buf; 19 | close SIG; 20 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genFS/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | 3 | CFLAGS = -g 4 | #CFLAGS = -m32 -g 5 | 6 | CFILES = $(shell find ./ -name "*.c") 7 | OBJS = $(CFILES:.c=.o) 8 | 9 | genFS: $(CFILES) 10 | $(CC) $(CFLAGS) -o genFS $(CFILES) 11 | 12 | clean: 13 | @#rm -rf $(OBJS) genFS fs.bin 14 | rm -rf $(OBJS) genFS 15 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genFS/func.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_H__ 2 | #define __FUNC_H__ 3 | 4 | int format (const char *driver, int sectorNum, int sectorsPerBlock); 5 | 6 | int mkdir (const char *driver, const char *destDirPath); 7 | 8 | int rmdir (const char *driver, const char *destDirPath); 9 | 10 | int cp (const char *driver, const char *srcFilePath, const char *destFilePath); 11 | 12 | int rm (const char *driver, const char *destFilePath); 13 | 14 | int ls (const char *driver, const char *destFilePath); 15 | 16 | int touch (const char *driver, const char *destFilePath); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genFS/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | #include "data.h" 4 | #include "func.h" 5 | 6 | int main(int argc, char *argv[]) { 7 | char driver[NAME_LENGTH]; 8 | char srcFilePath[NAME_LENGTH]; 9 | char destFilePath[NAME_LENGTH]; 10 | 11 | stringCpy("fs.bin", driver, NAME_LENGTH - 1); 12 | format(driver, SECTOR_NUM, SECTORS_PER_BLOCK); 13 | 14 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 15 | mkdir(driver, destFilePath); 16 | 17 | stringCpy(argv[1], srcFilePath, NAME_LENGTH - 1); 18 | stringCpy("/boot/initrd", destFilePath, NAME_LENGTH - 1); 19 | cp(driver, srcFilePath, destFilePath); 20 | 21 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 22 | mkdir(driver, destFilePath); 23 | 24 | stringCpy("/", destFilePath, NAME_LENGTH - 1); 25 | ls(driver, destFilePath); 26 | 27 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 28 | ls(driver, destFilePath); 29 | 30 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 31 | ls(driver, destFilePath); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genFS/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef unsigned short uint16_t; 6 | typedef unsigned char uint8_t; 7 | 8 | typedef int int32_t; 9 | typedef short int16_t; 10 | typedef char int8_t; 11 | 12 | // #define NULL ((void*)0) 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genFS/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | /* 5 | * find the first token in string 6 | * set *size as the number of bytes before token 7 | * if not found, set *size as the length of *string 8 | */ 9 | int stringChr (const char *string, char token, int *size) { 10 | int i = 0; 11 | if (string == NULL) { 12 | *size = 0; 13 | return -1; 14 | } 15 | while (string[i] != 0) { 16 | if (token == string[i]) { 17 | *size = i; 18 | return 0; 19 | } 20 | else 21 | i ++; 22 | } 23 | *size = i; 24 | return -1; 25 | } 26 | 27 | /* 28 | * find the last token in string 29 | * set *size as the number of bytes before token 30 | * if not found, set *size as the length of *string 31 | */ 32 | int stringChrR (const char *string, char token, int *size) { 33 | int i = 0; 34 | if (string == NULL) { 35 | *size = 0; 36 | return -1; 37 | } 38 | while (string[i] != 0) 39 | i ++; 40 | *size = i; 41 | while (i > -1) { 42 | if (token == string[i]) { 43 | *size = i; 44 | return 0; 45 | } 46 | else 47 | i --; 48 | } 49 | return -1; 50 | } 51 | 52 | int stringLen (const char *string) { 53 | int i = 0; 54 | if (string == NULL) 55 | return 0; 56 | while (string[i] != 0) 57 | i ++; 58 | return i; 59 | } 60 | 61 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 62 | int i = 0; 63 | if (srcString == NULL || destString == NULL) 64 | return -1; 65 | while (i != size) { 66 | if (srcString[i] != destString[i]) 67 | return -1; 68 | else if (srcString[i] == 0) 69 | return 0; 70 | else 71 | i ++; 72 | } 73 | return 0; 74 | } 75 | 76 | int stringCpy (const char *srcString, char *destString, int size) { 77 | int i = 0; 78 | if (srcString == NULL || destString == NULL) 79 | return -1; 80 | while (i != size) { 81 | if (srcString[i] != 0) { 82 | destString[i] = srcString[i]; 83 | i++; 84 | } 85 | else 86 | break; 87 | } 88 | destString[i] = 0; 89 | return 0; 90 | } 91 | 92 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 93 | int i = 0; 94 | if (buffer == NULL) 95 | return -1; 96 | for (i = 0; i < size ; i ++) 97 | buffer[i] = value; 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genFS/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | #include "types.h" 5 | 6 | int stringChr(const char *string, char token, int *size); 7 | 8 | int stringChrR (const char *string, char token, int *size); 9 | 10 | int stringLen(const char *string); 11 | 12 | int stringCmp(const char *srcString, const char *destString, int size); 13 | 14 | int stringCpy (const char *srcString, char *destString, int size); 15 | 16 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 17 | 18 | #endif -------------------------------------------------------------------------------- /lab2-181860013/lab2/utils/genKernel.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 100000); 6 | 7 | print STDERR "OK: Kernel is $n bytes - Extended to 200 sectors\n"; 8 | 9 | $buf .= "\0" x (102400-$n); 10 | 11 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 12 | print SIG $buf; 13 | close SIG; 14 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/Makefile: -------------------------------------------------------------------------------- 1 | QEMU = qemu-system-i386 2 | 3 | os.img: 4 | @cd utils/genFS; make 5 | @cd bootloader; make 6 | @cd kernel; make 7 | @cd app_print; make 8 | @cd app; make 9 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.bin > os.img 10 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.elf > os.img 11 | @#cat bootloader/bootloader.bin kernel/kMain.elf app/uMain.elf > os.img 12 | cat bootloader/bootloader.bin kernel/kMain.elf app/fs.bin > os.img 13 | 14 | play: os.img 15 | $(QEMU) -serial stdio os.img 16 | 17 | debug: os.img 18 | $(QEMU) -serial stdio -s -S os.img 19 | 20 | clean: 21 | @cd utils/genFS; make clean 22 | @cd bootloader; make clean 23 | @cd kernel; make clean 24 | @cd app_print; make clean 25 | @cd app; make clean 26 | rm -f os.img 27 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/app/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | #UOBJS = $(LCFILES:.c=.o) $(UCFILES:.c=.o) 13 | 14 | umain.bin: $(UOBJS) 15 | @#$(LD) $(LDFLAGS) -e uEntry -Ttext 0x00200000 -o uMain.elf $(UOBJS) 16 | $(LD) $(LDFLAGS) -e uEntry -Ttext 0x00000000 -o uMain.elf $(UOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary uMain.elf uMain.bin 18 | @#objcopy -O binary uMain.elf uMain.bin 19 | @cp ../app_print/app_print.elf ./app_print.elf 20 | @../utils/genFS/genFS uMain.elf app_print.elf 21 | 22 | clean: 23 | @#rm -rf $(UOBJS) uMain.elf uMain.bin 24 | rm -rf $(UOBJS) uMain.elf app_print.elf fs.bin 25 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/app/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | int data = 0; 5 | 6 | int uEntry(void) { 7 | int ret = fork(); 8 | int i = 8; 9 | if (ret == 0) { 10 | data = 2; 11 | while(i != 0) { 12 | i --; 13 | printf("Child Process: Pong %d, %d;\n", data, i); 14 | sleep(128); 15 | } 16 | exit(); 17 | } 18 | else if (ret != -1) { 19 | data = 1; 20 | while(i != 0) { 21 | i --; 22 | printf("Father Process: Ping %d, %d;\n", data, i); 23 | sleep(128); 24 | } 25 | exec("/usr/print\0", 0); 26 | exit(); 27 | } 28 | while(1); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/app_print/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | #UOBJS = $(LCFILES:.c=.o) $(UCFILES:.c=.o) 13 | 14 | app_print.bin: $(UOBJS) 15 | @#$(LD) $(LDFLAGS) -e uEntry -Ttext 0x00200000 -o uMain.elf $(UOBJS) 16 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o app_print.elf $(UOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary uMain.elf uMain.bin 18 | @#objcopy -O binary uMain.elf uMain.bin 19 | 20 | clean: 21 | @#rm -rf $(UOBJS) uMain.elf uMain.bin 22 | rm -rf $(UOBJS) app_print.elf 23 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/app_print/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | int main(void) { 5 | printf("printf test begin...\n"); 6 | printf("the answer should be:\n"); 7 | printf("#######################################################\n"); 8 | printf("Hello, welcome to OSlab! I'm the body of the game. "); 9 | printf("Bootblock loads me to the memory position of 0x100000, and Makefile also tells me that I'm at the location of 0x100000. "); 10 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 11 | printf("Now I will test your printf: "); 12 | printf("1 + 1 = 2, 123 * 456 = 56088\n0, -1, -2147483648, -1412567295, -32768, 102030\n0, ffffffff, 80000000, abcdef01, ffff8000, 18e8e\n"); 13 | printf("#######################################################\n"); 14 | printf("your answer:\n"); 15 | printf("=======================================================\n"); 16 | printf("%s %s%scome %co%s", "Hello,", "", "wel", 't', " "); 17 | printf("%c%c%c%c%c! ", 'O', 'S', 'l', 'a', 'b'); 18 | printf("I'm the %s of %s. %s 0x%x, %s 0x%x. ", "body", "the game", "Bootblock loads me to the memory position of", 0x100000, "and Makefile also tells me that I'm at the location of", 0x100000); 19 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 20 | printf("Now I will test your printf: "); 21 | printf("%d + %d = %d, %d * %d = %d\n", 1, 1, 1 + 1, 123, 456, 123 * 456); 22 | printf("%d, %d, %d, %d, %d, %d\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 23 | printf("%x, %x, %x, %x, %x, %x\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 24 | printf("=======================================================\n"); 25 | printf("Test end!!! Good luck!!!\n"); 26 | 27 | exit(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/bootloader/Makefile: -------------------------------------------------------------------------------- 1 | #bootloader.bin: start.S boot.c boot.h 2 | # gcc -c -m32 start.S -o start.o 3 | # gcc -c -m32 -O1 -fno-stack-protector boot.c -o boot.o 4 | # ld -m elf_i386 -e start -Ttext 0x7c00 start.o boot.o -o bootloader.elf 5 | # @#ld -m elf_i386 -e start -Ttext 0x7c00 boot.o start.o -o bootloader.elf 6 | # @#objcopy -S -j .text -O binary bootloader.elf bootloader.bin 7 | # objcopy -O binary bootloader.elf bootloader.bin 8 | # ../utils/genBoot.pl bootloader.bin 9 | # 10 | #clean: 11 | # rm -rf *.o *.elf *.bin 12 | 13 | # take care of link order of object files 14 | # -Ttext set the address of the first byte of the text segment 15 | # -e set the entry address in elf-header 16 | # i.e., the entry address may not be the address of the first byte of the text segment 17 | 18 | CC = gcc 19 | LD = ld 20 | 21 | CFLAGS = -m32 -march=i386 -static \ 22 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 23 | -Wall -Werror -O2 24 | ASFLAGS = -m32 25 | LDFLAGS = -m elf_i386 26 | 27 | BSFILES = $(shell find ./ -name "*.S") 28 | BCFILES = $(shell find ./ -name "*.c") 29 | BOBJS = $(BSFILES:.S=.o) $(BCFILES:.c=.o) 30 | 31 | bootloader.bin: $(BOBJS) 32 | $(LD) $(LDFLAGS) -e start -Ttext 0x7c00 -o bootloader.elf $(BOBJS) 33 | objcopy -S -j .text -O binary bootloader.elf bootloader.bin 34 | @../utils/genBoot.pl bootloader.bin 35 | 36 | clean: 37 | rm -rf $(BOBJS) bootloader.elf bootloader.bin 38 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/bootloader/boot.c: -------------------------------------------------------------------------------- 1 | #include "boot.h" 2 | 3 | #define SECTSIZE 512 4 | 5 | /* 6 | void bootMain(void) { 7 | int i = 0; 8 | void (*elf)(void); 9 | elf = (void(*)(void))0x100000; // kernel is loaded to location 0x100000 10 | for (i = 0; i < 200; i ++) { 11 | //readSect((void*)elf + i*512, i+1); 12 | readSect((void*)elf + i*512, i+9); 13 | } 14 | elf(); // jumping to the loaded program 15 | } 16 | */ 17 | 18 | void bootMain(void) { 19 | int i = 0; 20 | int phoff = 0x34; 21 | int offset = 0x1000; 22 | unsigned int elf = 0x100000; 23 | void (*kMainEntry)(void); 24 | kMainEntry = (void(*)(void))0x100000; 25 | 26 | for (i = 0; i < 200; i++) { 27 | readSect((void*)(elf + i*512), 1+i); 28 | } 29 | 30 | kMainEntry = (void(*)(void))((struct ELFHeader *)elf)->entry; 31 | phoff = ((struct ELFHeader *)elf)->phoff; 32 | offset = ((struct ProgramHeader *)(elf + phoff))->off; 33 | 34 | for (i = 0; i < 200 * 512; i++) { 35 | *(unsigned char *)(elf + i) = *(unsigned char *)(elf + i + offset); 36 | } 37 | 38 | kMainEntry(); 39 | } 40 | 41 | void waitDisk(void) { // waiting for disk 42 | while((inByte(0x1F7) & 0xC0) != 0x40); 43 | } 44 | 45 | void readSect(void *dst, int offset) { // reading a sector of disk 46 | int i; 47 | waitDisk(); 48 | outByte(0x1F2, 1); 49 | outByte(0x1F3, offset); 50 | outByte(0x1F4, offset >> 8); 51 | outByte(0x1F5, offset >> 16); 52 | outByte(0x1F6, (offset >> 24) | 0xE0); 53 | outByte(0x1F7, 0x20); 54 | 55 | waitDisk(); 56 | for (i = 0; i < SECTSIZE / 4; i ++) { 57 | ((int *)dst)[i] = inLong(0x1F0); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/bootloader/boot.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOT_H 2 | #define BOOT_H 3 | 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | void waitDisk(void); 35 | 36 | void readSect(void *dst, int offset); 37 | 38 | /* I/O functions */ 39 | static inline char inByte(short port) { 40 | char data; 41 | asm volatile("in %1,%0" : "=a" (data) : "d" (port)); 42 | return data; 43 | } 44 | 45 | static inline int inLong(short port) { 46 | int data; 47 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 48 | return data; 49 | } 50 | 51 | static inline void outByte(short port, char data) { 52 | asm volatile("out %0,%1" : : "a" (data), "d" (port)); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O0 -I./include 7 | ASFLAGS = -m32 8 | LDFLAGS = -m elf_i386 9 | 10 | KCFILES = $(shell find ./ -name "*.c") 11 | KSFILES = $(shell find ./ -name "*.S") 12 | KOBJS = $(KCFILES:.c=.o) $(KSFILES:.S=.o) 13 | #KOBJS = $(KSFILES:.S=.o) $(KCFILES:.c=.o) 14 | 15 | kmain.bin: $(KOBJS) 16 | $(LD) $(LDFLAGS) -e kEntry -Ttext 0x00100000 -o kMain.elf $(KOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary kMain.elf kMain.bin 18 | @#objcopy -O binary kMain.elf kMain.bin 19 | @../utils/genKernel.pl kMain.elf 20 | @#../utils/genKernel.pl kMain.bin 21 | 22 | 23 | clean: 24 | @#rm -rf $(KOBJS) kMain.elf kMain.bin 25 | rm -rf $(KOBJS) kMain.elf kMain.bin 26 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include "common/types.h" 5 | #include "common/const.h" 6 | #include "common/assert.h" 7 | #include "common/utils.h" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/common/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASSERT_H__ 2 | #define __ASSERT_H__ 3 | 4 | int abort(const char *, int); 5 | 6 | /* assert: 断言条件为真,若为假则蓝屏退出 */ 7 | #define assert(cond) \ 8 | ((cond) ? (0) : (abort(__FILE__, __LINE__))) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/common/const.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONST_H__ 2 | #define __CONST_H__ 3 | 4 | #define TRUE 1 5 | #define FALSE 0 6 | 7 | #define NULL ((void*)0) 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/common/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | /* 定义数据类型 */ 5 | typedef unsigned int uint32_t; 6 | typedef int int32_t; 7 | typedef unsigned short uint16_t; 8 | typedef short int16_t; 9 | typedef unsigned char uint8_t; 10 | typedef char int8_t; 11 | typedef unsigned int size_t; 12 | #endif 13 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/common/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | int stringChr(const char *string, char token, int *size); 5 | 6 | int stringChrR (const char *string, char token, int *size); 7 | 8 | int stringLen(const char *string); 9 | 10 | int stringCmp(const char *srcString, const char *destString, int size); 11 | 12 | int stringCpy (const char *srcString, char *destString, int size); 13 | 14 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 15 | 16 | #endif -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/device.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVICE_H__ 2 | #define __DEVICE_H__ 3 | 4 | #include "device/serial.h" 5 | #include "device/disk.h" 6 | #include "device/vga.h" 7 | #include "device/timer.h" 8 | #include "device/keyboard.h" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/device/disk.h: -------------------------------------------------------------------------------- 1 | #ifndef __DISK_H__ 2 | #define __DISK_H__ 3 | 4 | #define SECTOR_NUM 8192 5 | #define SECTOR_SIZE 512 6 | 7 | void waitDisk(void); 8 | void readSect(void *dst, int offset); 9 | void writeSect(void *src, int offset); 10 | 11 | void diskRead(void *destBuffer, int size, int num, int offset); 12 | void diskWrite(void *destBuffer, int size, int num, int offset); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/device/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYBOARD_H__ 2 | #define __KEYBOARD_H__ 3 | 4 | #define MAX_KEYBUFFER_SIZE 256 5 | 6 | void initKeyTable(); 7 | 8 | uint32_t getKeyCode(); 9 | 10 | char getChar(uint32_t code); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/device/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERIAL_H__ 2 | #define __SERIAL_H__ 3 | 4 | void initSerial(void); 5 | void putChar(char); 6 | void putString(const char *); 7 | void putInt(int); 8 | 9 | #define SERIAL_PORT 0x3F8 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/device/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_H__ 2 | #define __TIMER_H__ 3 | 4 | void initTimer(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/device/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef __VGA_H__ 2 | #define __VGA_H__ 3 | 4 | void initVga(); 5 | void clearScreen(); 6 | void updateCursor(int row, int col); 7 | void scrollScreen(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef __FS_H__ 2 | #define __FS_H__ 3 | 4 | #include "fs/minix.h" 5 | 6 | int readSuperBlock (SuperBlock *superBlock); 7 | 8 | int allocInode (SuperBlock *superBlock, 9 | Inode *fatherInode, 10 | int fatherInodeOffset, 11 | Inode *destInode, 12 | int *destInodeOffset, 13 | const char *destFilename, 14 | int destFiletype); 15 | 16 | int freeInode (SuperBlock *superBlock, 17 | Inode *fatherInode, 18 | int fatherInodeOffset, 19 | Inode *destInode, 20 | int *destInodeOffset, 21 | const char *destFilename, 22 | int destFiletype); 23 | 24 | int readInode (SuperBlock *superBlock, 25 | Inode *destInode, 26 | int *inodeOffset, 27 | const char *destFilePath); 28 | 29 | int allocBlock (SuperBlock *superBlock, 30 | Inode *inode, 31 | int inodeOffset); 32 | 33 | int readBlock (SuperBlock *superBlock, 34 | Inode *inode, 35 | int blockIndex, 36 | uint8_t *buffer); 37 | 38 | int writeBlock (SuperBlock *superBlock, 39 | Inode *inode, 40 | int blockIndex, 41 | uint8_t *buffer); 42 | 43 | int getDirEntry (SuperBlock *superBlock, 44 | Inode *inode, 45 | int dirIndex, 46 | DirEntry *destDirEntry); 47 | 48 | void initFS (void); 49 | 50 | void initFile (void); 51 | 52 | #endif /* __FS_H__ */ 53 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/fs/minix.h: -------------------------------------------------------------------------------- 1 | #ifndef __MINIX_H__ 2 | #define __MINIX_H__ 3 | 4 | /* 5 | * minix like filesystem 6 | */ 7 | 8 | /* 9 | * Layout of file system 10 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 11 | *| SuperBlock | InodeBitmap | BlockBitmap | InodeTable | DataBlocks | 12 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 13 | * 1024 Bytes 1 Block 1 Block 128 Blocks Many More Blocks 14 | * 15 | */ 16 | 17 | #define SECTORS_PER_BLOCK 2 18 | #define POINTER_NUM 14 19 | #define NAME_LENGTH 64 20 | 21 | #define BLOCK_SIZE (SECTOR_SIZE * SECTORS_PER_BLOCK) 22 | #define SUPER_BLOCK_SIZE BLOCK_SIZE 23 | #define INODE_BITMAP_SIZE BLOCK_SIZE 24 | #define BLOCK_BITMAP_SIZE BLOCK_SIZE 25 | #define INODE_SIZE 128 26 | #define DIRENTRY_SIZE 128 27 | #define INODE_BLOCKS (SECTOR_NUM / SECTORS_PER_BLOCK / 32) 28 | 29 | #define UNKNOWN_TYPE 0 30 | #define REGULAR_TYPE 1 31 | #define DIRECTORY_TYPE 2 32 | #define CHARACTER_TYPE 3 33 | #define BLOCK_TYPE 4 34 | #define FIFO_TYPE 5 35 | #define SOCKET_TYPE 6 36 | #define SYMBOLIC_TYPE 7 37 | 38 | union SuperBlock { 39 | uint8_t byte[SUPER_BLOCK_SIZE]; 40 | struct { 41 | int32_t sectorNum; // total number of sectors 42 | int32_t inodeNum; // total number of inodes 43 | int32_t blockNum; // total number of data blocks 44 | int32_t availInodeNum; // total number of available inodes 45 | int32_t availBlockNum; // total number of available data blocks 46 | int32_t blockSize; // number of bytes in each block 47 | int32_t inodeBitmap; // XXX sector as unit 48 | int32_t blockBitmap; // XXX sector as unit 49 | int32_t inodeTable; // XXX sector as unit 50 | int32_t blocks; // XXX sector as unit 51 | }; 52 | }; 53 | typedef union SuperBlock SuperBlock; 54 | 55 | struct InodeBitmap { 56 | uint8_t byte[INODE_BITMAP_SIZE]; 57 | }; 58 | typedef struct InodeBitmap InodeBitmap; 59 | 60 | struct BlockBitmap { 61 | uint8_t byte[BLOCK_BITMAP_SIZE]; 62 | }; 63 | typedef struct BlockBitmap BlockBitmap; 64 | 65 | union Inode { 66 | uint8_t byte[INODE_SIZE]; 67 | struct { 68 | int16_t type; 69 | int16_t linkCount; 70 | int32_t blockCount; 71 | int32_t size; 72 | int32_t pointer[POINTER_NUM]; // XXX sector as unit 73 | int32_t singlyPointer; // XXX sector as unit 74 | }; 75 | }; 76 | typedef union Inode Inode; 77 | 78 | union DirEntry { 79 | uint8_t byte[DIRENTRY_SIZE]; 80 | struct { 81 | int32_t inode; // index in inode table, started from 1, 0 for unused. 82 | char name[NAME_LENGTH]; 83 | }; 84 | }; 85 | typedef union DirEntry DirEntry; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/x86.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_H__ 2 | #define __X86_H__ 3 | 4 | #include "x86/cpu.h" 5 | #include "x86/memory.h" 6 | #include "x86/io.h" 7 | #include "x86/irq.h" 8 | 9 | void initSeg(void); 10 | void initProc(void); 11 | int loadElf(const char *filename, uint32_t physAddr, uint32_t *entry); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/x86/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_CPU_H__ 2 | #define __X86_CPU_H__ 3 | 4 | #include "common.h" 5 | 6 | /* 将CPU置入休眠状态直到下次中断到来 */ 7 | static inline void waitForInterrupt() { 8 | asm volatile("hlt"); 9 | } 10 | 11 | /* 修改IDTR */ 12 | static inline void saveIdt(void *addr, uint32_t size) { 13 | static volatile uint16_t data[3]; 14 | data[0] = size - 1; 15 | data[1] = (uint32_t)addr; 16 | data[2] = ((uint32_t)addr) >> 16; 17 | asm volatile("lidt (%0)" : : "r"(data)); 18 | } 19 | 20 | /* 打开外部中断 */ 21 | static inline void enableInterrupt(void) { 22 | asm volatile("sti"); 23 | } 24 | 25 | /* 关闭外部中断 */ 26 | static inline void disableInterrupt(void) { 27 | asm volatile("cli"); 28 | } 29 | 30 | #define NR_IRQ 256 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/x86/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_IO_H__ 2 | #define __X86_IO_H__ 3 | /* ELF32二进制文件头 */ 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | 35 | static inline int inLong(short port) { 36 | int data; 37 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 38 | return data; 39 | } 40 | 41 | static inline void outLong(uint16_t port, uint32_t data) { 42 | asm volatile("out %0, %1" : : "a"(data), "d"(port)); 43 | } 44 | 45 | /* 读I/O端口 */ 46 | static inline uint8_t inByte(uint16_t port) { 47 | uint8_t data; 48 | asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 49 | return data; 50 | } 51 | 52 | /* 写I/O端口 */ 53 | static inline void outByte(uint16_t port, int8_t data) { 54 | asm volatile("out %%al, %%dx" : : "a"(data), "d"(port)); 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/include/x86/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __IRQ_H__ 2 | #define __IRQ_H__ 3 | 4 | /* 中断处理相关函数 */ 5 | void initIdt(void); 6 | void initIntr(void); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/kernel/disk.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define SECTSIZE 512 5 | 6 | void waitDisk(void) { 7 | while((inByte(0x1F7) & 0xC0) != 0x40); 8 | } 9 | 10 | void readSect(void *dst, int offset) { 11 | int i; 12 | waitDisk(); 13 | 14 | outByte(0x1F2, 1); 15 | outByte(0x1F3, offset); 16 | outByte(0x1F4, offset >> 8); 17 | outByte(0x1F5, offset >> 16); 18 | outByte(0x1F6, (offset >> 24) | 0xE0); 19 | outByte(0x1F7, 0x20); 20 | 21 | waitDisk(); 22 | for (i = 0; i < SECTSIZE / 4; i ++) { 23 | ((int *)dst)[i] = inLong(0x1F0); 24 | } 25 | } 26 | 27 | void writeSect(void *src, int offset) { 28 | int i; 29 | waitDisk(); 30 | 31 | outByte(0x1F2, 1); 32 | outByte(0x1F3, offset); 33 | outByte(0x1F4, offset >> 8); 34 | outByte(0x1F5, offset >> 16); 35 | outByte(0x1F6, (offset >> 24) | 0xE0); 36 | outByte(0x1F7, 0x30); 37 | 38 | waitDisk(); 39 | for (i = 0; i < SECTOR_SIZE / 4; i ++) { 40 | outLong(0x1F0, ((uint32_t *)src)[i]); 41 | } 42 | } 43 | 44 | void diskRead (void *destBuffer, int size, int num, int offset) { 45 | int i = 0; 46 | int j = 0; 47 | uint8_t buffer[SECTOR_SIZE]; 48 | int quotient = offset / SECTOR_SIZE; 49 | int remainder = offset % SECTOR_SIZE; 50 | 51 | readSect((void*)buffer, 201 + quotient + j); 52 | j ++; 53 | while (i < size * num) { 54 | ((uint8_t*)destBuffer)[i] = buffer[(remainder + i) % SECTOR_SIZE]; 55 | i ++; 56 | if ((remainder + i) % SECTOR_SIZE == 0) { 57 | readSect((void*)buffer, 201 + quotient + j); 58 | j ++; 59 | } 60 | } 61 | } 62 | 63 | void diskWrite (void *destBuffer, int size, int num, int offset) { 64 | int i = 0; 65 | int j = 0; 66 | uint8_t buffer[SECTOR_SIZE]; 67 | int quotient = offset / SECTOR_SIZE; 68 | int remainder = offset % SECTOR_SIZE; 69 | 70 | readSect((void*)buffer, 201 + quotient + j); 71 | while (i < size * num) { 72 | buffer[(remainder + i) % SECTOR_SIZE] = ((uint8_t*)destBuffer)[i]; 73 | i ++; 74 | if ((remainder + i) % SECTOR_SIZE == 0) { 75 | writeSect((void*)buffer, 201 + quotient + j); 76 | j ++; 77 | readSect((void*)buffer, 201 + quotient + j); 78 | } 79 | } 80 | writeSect((void*)buffer, 201 + quotient + j); 81 | } 82 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/kernel/doIrq.S: -------------------------------------------------------------------------------- 1 | /*TODO 2 | otherwise need to reassign esp0 of tss in task switching for each user process 3 | note that for conforming code OR same PRL, no need to switch task 4 | that is TSS doesn't work 5 | 1. Trap Gate, IF won't be set 6 | 2. Interrupt Gate, IF is set automatically 7 | 3. System Gate 8 | */ 9 | 10 | .code32 11 | 12 | .global irqEmpty 13 | irqEmpty: 14 | pushl $0 // push dummy error code 15 | pushl $-1 // push interruption number into kernel 16 | jmp asmDoIrq 17 | 18 | .global irqErrorCode 19 | irqErrorCode: 20 | pushl $-1 // push interruption number into kernel 21 | jmp asmDoIrq 22 | 23 | .global irqDoubleFault 24 | irqDoubleFault: 25 | pushl $-1 26 | jmp asmDoIrq 27 | 28 | .global irqInvalidTSS 29 | irqInvalidTSS: 30 | pushl $-1 31 | jmp asmDoIrq 32 | 33 | .global irqSegNotPresent 34 | irqSegNotPresent: 35 | pushl $-1 36 | jmp asmDoIrq 37 | 38 | .global irqStackSegFault 39 | irqStackSegFault: 40 | pushl $-1 41 | jmp asmDoIrq 42 | 43 | .global irqGProtectFault 44 | irqGProtectFault: 45 | pushl $0xd 46 | jmp asmDoIrq 47 | 48 | .global irqPageFault 49 | irqPageFault: 50 | pushl $-1 51 | jmp asmDoIrq 52 | 53 | .global irqAlignCheck 54 | irqAlignCheck: 55 | pushl $-1 56 | jmp asmDoIrq 57 | 58 | .global irqSecException 59 | irqSecException: 60 | pushl $-1 61 | jmp asmDoIrq 62 | 63 | .global irqTimer 64 | irqTimer: 65 | pushl $0 66 | pushl $0x20 67 | jmp asmDoIrq 68 | 69 | .global irqKeyboard 70 | irqKeyboard: 71 | pushl $0 72 | pushl $0x21 73 | jmp asmDoIrq 74 | 75 | .global irqSyscall 76 | irqSyscall: 77 | pushl $0 // push dummy error code 78 | pushl $0x80 // push interruption number into kernel stack 79 | jmp asmDoIrq 80 | 81 | //.extern irqHandle //defined in irq_handle.c 82 | 83 | .global asmDoIrq 84 | asmDoIrq: 85 | pushal // push process state into kernel stack 86 | pushl %ds 87 | pushl %es 88 | pushl %fs 89 | pushl %gs 90 | pushl %esp //esp is treated as a parameter 91 | call irqHandle 92 | addl $4, %esp //esp is on top of kernel stack 93 | popl %gs 94 | popl %fs 95 | popl %es 96 | popl %ds 97 | popal 98 | addl $4, %esp //interrupt number is on top of kernel stack 99 | addl $4, %esp //error code is on top of kernel stack 100 | iret 101 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/kernel/i8259.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | 3 | #define PORT_PIC_MASTER 0x20 4 | #define PORT_PIC_SLAVE 0xA0 5 | #define IRQ_SLAVE 2 6 | 7 | /* 初始化8259中断控制器: 8 | * 硬件中断IRQ从32号开始,自动发送EOI */ 9 | void 10 | initIntr(void) { 11 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 12 | //outByte(PORT_PIC_SLAVE + 1 , 0xFF); // OCW1, Disable Slave PIC all IRQs 13 | outByte(PORT_PIC_MASTER, 0x11); // ICW1, Initialization command 14 | outByte(PORT_PIC_SLAVE, 0x11); // ICW1, Initialization command 15 | outByte(PORT_PIC_MASTER + 1, 32); // ICW2, Interrupt Vector Offset 0x20 16 | outByte(PORT_PIC_SLAVE + 1, 32 + 8); // ICW2, Interrupt Vector Offset 0x28 17 | outByte(PORT_PIC_MASTER + 1, 1 << 2); // ICW3, Tell Master PIC that there is a slave 18 | outByte(PORT_PIC_SLAVE + 1, 2); // ICW3, Tell Slave PIC its cascade identity 19 | outByte(PORT_PIC_MASTER + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 20 | outByte(PORT_PIC_SLAVE + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 21 | 22 | //outByte(PORT_PIC_MASTER, 0x68); // OCW3, Enable Special Mask Mode 23 | //outByte(PORT_PIC_MASTER, 0x0A); // OCW3, Read ISR of Master on next CMD Read 24 | //outByte(PORT_PIC_SLAVE, 0x68); // OCW3, Enable Special Mask Mode 25 | //outByte(PORT_PIC_SLAVE, 0x0A); // OCW3, Read ISR of Slave on next CMD Read 26 | 27 | //outByte(PORT_PIC_MASTER + 1, 0xFE); // OCW1, Enable Timer IRQ 28 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 29 | //outByte(PORT_PIC_SLAVE + 1, 0xFF); // OCW1, Disable Slave PIC all IRQs 30 | } 31 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/kernel/idt.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define INTERRUPT_GATE_32 0xE 5 | #define TRAP_GATE_32 0xF 6 | 7 | /* IDT表的内容 */ 8 | struct GateDescriptor idt[NR_IRQ]; // NR_IRQ=256, defined in x86/cpu.h 9 | 10 | /* 初始化一个中断门(interrupt gate) */ 11 | static void setIntr(struct GateDescriptor *ptr, uint32_t selector, uint32_t offset, uint32_t dpl) { 12 | ptr->offset_15_0 = offset & 0xFFFF; 13 | ptr->segment = selector << 3; 14 | ptr->pad0 = 0; 15 | ptr->type = INTERRUPT_GATE_32; 16 | ptr->system = FALSE; 17 | ptr->privilege_level = dpl; 18 | ptr->present = TRUE; 19 | ptr->offset_31_16 = (offset >> 16) & 0xFFFF; 20 | } 21 | 22 | /* 初始化一个陷阱门(trap gate) */ 23 | static void setTrap(struct GateDescriptor *ptr, uint32_t selector, uint32_t offset, uint32_t dpl) { 24 | ptr->offset_15_0 = offset & 0xFFFF; 25 | ptr->segment = selector << 3; 26 | ptr->pad0 = 0; 27 | ptr->type = TRAP_GATE_32; 28 | ptr->system = FALSE; 29 | ptr->privilege_level = dpl; 30 | ptr->present = TRUE; 31 | ptr->offset_31_16 = (offset >> 16) & 0xFFFF; 32 | } 33 | 34 | /* 声明函数,这些函数在汇编代码里定义 */ 35 | void irqEmpty(); 36 | void irqErrorCode(); 37 | 38 | void irqDoubleFault(); // 0x8 39 | void irqInvalidTSS(); // 0xa 40 | void irqSegNotPresent(); // 0xb 41 | void irqStackSegFault(); // 0xc 42 | void irqGProtectFault(); // 0xd 43 | void irqPageFault(); // 0xe 44 | void irqAlignCheck(); // 0x11 45 | void irqSecException(); // 0x1e 46 | 47 | void irqSyscall(); 48 | void irqTimer(); 49 | void irqKeyboard(); 50 | 51 | void initIdt() { 52 | int i; 53 | /* 为了防止系统异常终止,所有irq都有处理函数(irqEmpty)。 */ 54 | for (i = 0; i < NR_IRQ; i ++) { 55 | setTrap(idt + i, SEG_KCODE, (uint32_t)irqEmpty, DPL_KERN); 56 | } 57 | /* 58 | * init your idt here 59 | * 初始化 IDT 表, 为中断设置中断处理函数 60 | */ 61 | /* Exceptions with error code */ 62 | setTrap(idt + 0x8, SEG_KCODE, (uint32_t)irqDoubleFault, DPL_KERN); 63 | setTrap(idt + 0xa, SEG_KCODE, (uint32_t)irqInvalidTSS, DPL_KERN); 64 | setTrap(idt + 0xb, SEG_KCODE, (uint32_t)irqSegNotPresent, DPL_KERN); 65 | setTrap(idt + 0xc, SEG_KCODE, (uint32_t)irqStackSegFault, DPL_KERN); 66 | setTrap(idt + 0xd, SEG_KCODE, (uint32_t)irqGProtectFault, DPL_KERN); 67 | //setTrap(idt + 0xd, SEG_KCODE, (uint32_t)irqGProtectFault, DPL_USER); 68 | setTrap(idt + 0xe, SEG_KCODE, (uint32_t)irqPageFault, DPL_KERN); 69 | //setTrap(idt + 0xe, SEG_KCODE, (uint32_t)irqPageFault, DPL_USER); 70 | setTrap(idt + 0x11, SEG_KCODE, (uint32_t)irqAlignCheck, DPL_KERN); 71 | setTrap(idt + 0x1e, SEG_KCODE, (uint32_t)irqSecException, DPL_KERN); 72 | 73 | /* Exceptions with DPL = 3 */ 74 | //setIntr(idt + 0x3, SEG_KCODE, , DPL_USER); // for int 3, interrupt vector is 0x3, Interruption is disabled 75 | //setIntr(idt + 0x4, SEG_KCODE, , DPL_USER); // for into, interrupt vector is 0x4, Interruption is disabled 76 | //setIntr(idt + 0x5, SEG_KCODE, , DPL_USER); // for bound, interrupt vector is 0x5, Interruption is disabled 77 | setIntr(idt + 0x20, SEG_KCODE, (uint32_t)irqTimer, DPL_KERN); 78 | setIntr(idt + 0x21, SEG_KCODE, (uint32_t)irqKeyboard, DPL_KERN); 79 | setIntr(idt + 0x80, SEG_KCODE, (uint32_t)irqSyscall, DPL_USER); // for int 0x80, interrupt vector is 0x80, Interruption is disabled 80 | 81 | /* 写入IDT */ 82 | saveIdt(idt, sizeof(idt)); 83 | } 84 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/kernel/serial.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | void initSerial(void) { 5 | outByte(SERIAL_PORT + 1, 0x00); 6 | outByte(SERIAL_PORT + 3, 0x80); 7 | outByte(SERIAL_PORT + 0, 0x01); 8 | outByte(SERIAL_PORT + 1, 0x00); 9 | outByte(SERIAL_PORT + 3, 0x03); 10 | outByte(SERIAL_PORT + 2, 0xC7); 11 | outByte(SERIAL_PORT + 4, 0x0B); 12 | } 13 | 14 | static inline int serialIdle(void) { 15 | return (inByte(SERIAL_PORT + 5) & 0x20) != 0; 16 | } 17 | 18 | void putChar(char ch) { 19 | while (serialIdle() != TRUE); 20 | outByte(SERIAL_PORT, ch); 21 | } 22 | 23 | void putString(const char *str) { 24 | int i = 0; 25 | if (str == NULL) { 26 | return; 27 | } 28 | while (str[i] != 0) { 29 | putChar(str[i++]); 30 | } 31 | } 32 | 33 | void putInt(int a) { 34 | char buf[32]; 35 | char *p = buf + sizeof(buf) - 1; 36 | *p = '\0'; 37 | *(--p) = '\n'; 38 | do { 39 | *--p = '0' + a % 10; 40 | } while (a /= 10); 41 | putString(p); 42 | } 43 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/kernel/timer.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define TIMER_PORT 0x40 5 | #define FREQ_8253 1193182 6 | #define HZ 100 7 | //#define HZ 1000 8 | 9 | void initTimer() { 10 | int counter = FREQ_8253 / HZ; 11 | //assert(TIMER_PORT < 65536); 12 | outByte(TIMER_PORT + 3, 0x34); 13 | outByte(TIMER_PORT + 0, counter % 256); 14 | outByte(TIMER_PORT + 0, counter / 256); 15 | } 16 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/kernel/vga.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | int displayRow = 0; //TODO futher extend, display position, in .bss section, not in .data section 5 | int displayCol = 0; 6 | uint16_t displayMem[80*25]; 7 | int displayClear = 0; 8 | 9 | void initVga() { 10 | displayRow = 0; 11 | displayCol = 0; 12 | displayClear = 0; 13 | clearScreen(); 14 | updateCursor(0, 0); 15 | } 16 | 17 | void clearScreen() { 18 | int i = 0; 19 | int pos = 0; 20 | uint16_t data = 0 | (0x0c << 8); 21 | for (i = 0; i < 80 * 25; i++) { 22 | pos = i * 2; 23 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 24 | } 25 | } 26 | 27 | void updateCursor(int row, int col){ 28 | int cursorPos = row * 80 + col; 29 | outByte(0x3d4, 0x0f); 30 | outByte(0x3d5, (unsigned char)(cursorPos & 0xff)); 31 | 32 | outByte(0x3d4, 0x0e); 33 | outByte(0x3d5, (unsigned char)((cursorPos>>8) & 0xff)); 34 | } 35 | 36 | void scrollScreen() { 37 | int i = 0; 38 | int pos = 0; 39 | uint16_t data = 0; 40 | for (i = 0; i < 80 * 25; i++) { 41 | pos = i * 2; 42 | asm volatile("movw (%1), %0":"=r"(data):"r"(pos+0xb8000)); 43 | displayMem[i] = data; 44 | } 45 | for (i = 0; i < 80 * 24; i++) { 46 | pos = i * 2; 47 | data = displayMem[i+80]; 48 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 49 | } 50 | data = 0 | (0x0c << 8); 51 | for (i = 80 * 24; i < 80 * 25; i++) { 52 | pos = i * 2; 53 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/lib/abort.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | 5 | static char *i2A(int a) { 6 | static char buf[30]; 7 | char *p = buf + sizeof(buf) - 1; 8 | do { 9 | *--p = '0' + a % 10; 10 | } while (a /= 10); 11 | return p; 12 | } 13 | 14 | static void append(char **p, const char *str) { 15 | while (*str) { 16 | *((*p) ++) = *str ++; 17 | } 18 | } 19 | 20 | /* 将文件名和assert fail的行号显示在屏幕上 */ 21 | #define BLUE_SCREEN_TEXT "Assertion failed: " 22 | static void displayMessage(const char *file, int line) { 23 | static char buf[256] = BLUE_SCREEN_TEXT; 24 | char *p = buf + sizeof(BLUE_SCREEN_TEXT) - 1; 25 | 26 | append(&p, file); 27 | append(&p, ":"); 28 | append(&p, i2A(line)); 29 | append(&p, "\n"); 30 | 31 | for (p = buf; *p; p ++) { 32 | putChar(*p); 33 | } 34 | } 35 | 36 | int abort(const char *fname, int line) { 37 | disableInterrupt(); 38 | displayMessage(fname, line); 39 | while (TRUE) { 40 | waitForInterrupt(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/lib/utils.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /* 4 | * find the first token in string 5 | * set *size as the number of bytes before token 6 | * if not found, set *size as the length of *string 7 | */ 8 | int stringChr (const char *string, char token, int *size) { 9 | int i = 0; 10 | if (string == NULL) { 11 | *size = 0; 12 | return -1; 13 | } 14 | while (string[i] != 0) { 15 | if (token == string[i]) { 16 | *size = i; 17 | return 0; 18 | } 19 | else 20 | i ++; 21 | } 22 | *size = i; 23 | return -1; 24 | } 25 | 26 | /* 27 | * find the last token in string 28 | * set *size as the number of bytes before token 29 | * if not found, set *size as the length of *string 30 | */ 31 | int stringChrR (const char *string, char token, int *size) { 32 | int i = 0; 33 | if (string == NULL) { 34 | *size = 0; 35 | return -1; 36 | } 37 | while (string[i] != 0) 38 | i ++; 39 | *size = i; 40 | while (i > -1) { 41 | if (token == string[i]) { 42 | *size = i; 43 | return 0; 44 | } 45 | else 46 | i --; 47 | } 48 | return -1; 49 | } 50 | 51 | int stringLen (const char *string) { 52 | int i = 0; 53 | if (string == NULL) 54 | return 0; 55 | while (string[i] != 0) 56 | i ++; 57 | return i; 58 | } 59 | 60 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 61 | int i = 0; 62 | if (srcString == NULL || destString == NULL) 63 | return -1; 64 | while (i != size) { 65 | if (srcString[i] != destString[i]) 66 | return -1; 67 | else if (srcString[i] == 0) 68 | return 0; 69 | else 70 | i ++; 71 | } 72 | return 0; 73 | } 74 | 75 | int stringCpy (const char *srcString, char *destString, int size) { 76 | int i = 0; 77 | if (srcString == NULL || destString == NULL) 78 | return -1; 79 | while (i != size) { 80 | if (srcString[i] != 0) { 81 | destString[i] = srcString[i]; 82 | i++; 83 | } 84 | else 85 | break; 86 | } 87 | destString[i] = 0; 88 | return 0; 89 | } 90 | 91 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 92 | int i = 0; 93 | if (buffer == NULL) 94 | return -1; 95 | for (i = 0; i < size ; i ++) 96 | buffer[i] = value; 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/kernel/main.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | #include "fs.h" 5 | 6 | void kEntry(void) { 7 | 8 | // Interruption is disabled in bootloader 9 | 10 | initSerial();// initialize serial port 11 | initIdt(); // initialize idt 12 | initIntr(); // iniialize 8259a 13 | initSeg(); // initialize gdt, tss 14 | initVga(); // initialize vga device 15 | initTimer(); 16 | initKeyTable(); 17 | initFS(); 18 | initProc(); 19 | 20 | while(1); 21 | assert(0); 22 | } 23 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/lib/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __lib_h__ 2 | #define __lib_h__ 3 | 4 | #include "types.h" 5 | 6 | #define SYS_WRITE 0 7 | #define SYS_FORK 1 8 | #define SYS_EXEC 2 9 | #define SYS_SLEEP 3 10 | #define SYS_EXIT 4 11 | 12 | #define STD_OUT 0 13 | 14 | #define MAX_BUFFER_SIZE 256 15 | 16 | int printf(const char *format,...); 17 | 18 | pid_t fork(); 19 | 20 | int exec(const char *filename, char * const argv[]); 21 | 22 | int sleep(uint32_t time); 23 | 24 | int exit(); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/lib/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef int int32_t; 6 | typedef unsigned short uint16_t; 7 | typedef short int16_t; 8 | typedef unsigned char uint8_t; 9 | typedef char int8_t; 10 | typedef unsigned char boolean; 11 | 12 | typedef uint32_t size_t; 13 | typedef int32_t pid_t; 14 | 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genBoot.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 1000); 6 | 7 | if($n > 510){ 8 | print STDERR "ERROR: boot block too large: $n bytes (max 510)\n"; 9 | exit 1; 10 | } 11 | 12 | print STDERR "OK: boot block is $n bytes (max 510)\n"; 13 | 14 | $buf .= "\0" x (510-$n); 15 | $buf .= "\x55\xAA"; 16 | 17 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 18 | print SIG $buf; 19 | close SIG; 20 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genFS/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | 3 | CFLAGS = -g 4 | #CFLAGS = -m32 -g 5 | 6 | CFILES = $(shell find ./ -name "*.c") 7 | OBJS = $(CFILES:.c=.o) 8 | 9 | genFS: $(CFILES) 10 | $(CC) $(CFLAGS) -o genFS $(CFILES) 11 | 12 | clean: 13 | @#rm -rf $(OBJS) genFS fs.bin 14 | rm -rf $(OBJS) genFS -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genFS/func.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_H__ 2 | #define __FUNC_H__ 3 | 4 | int format (const char *driver, int sectorNum, int sectorsPerBlock); 5 | 6 | int mkdir (const char *driver, const char *destDirPath); 7 | 8 | int rmdir (const char *driver, const char *destDirPath); 9 | 10 | int cp (const char *driver, const char *srcFilePath, const char *destFilePath); 11 | 12 | int rm (const char *driver, const char *destFilePath); 13 | 14 | int ls (const char *driver, const char *destFilePath); 15 | 16 | int touch (const char *driver, const char *destFilePath); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genFS/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | #include "data.h" 4 | #include "func.h" 5 | 6 | int main(int argc, char *argv[]) { 7 | char driver[NAME_LENGTH]; 8 | char srcFilePath[NAME_LENGTH]; 9 | char destFilePath[NAME_LENGTH]; 10 | 11 | stringCpy("fs.bin", driver, NAME_LENGTH - 1); 12 | format(driver, SECTOR_NUM, SECTORS_PER_BLOCK); 13 | 14 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 15 | mkdir(driver, destFilePath); 16 | 17 | stringCpy(argv[1], srcFilePath, NAME_LENGTH - 1); 18 | stringCpy("/boot/initrd", destFilePath, NAME_LENGTH - 1); 19 | cp(driver, srcFilePath, destFilePath); 20 | 21 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 22 | mkdir(driver, destFilePath); 23 | 24 | stringCpy(argv[2], srcFilePath, NAME_LENGTH - 1); 25 | stringCpy("/usr/print", destFilePath, NAME_LENGTH - 1); 26 | cp(driver, srcFilePath, destFilePath); 27 | 28 | stringCpy("/", destFilePath, NAME_LENGTH - 1); 29 | ls(driver, destFilePath); 30 | 31 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 32 | ls(driver, destFilePath); 33 | 34 | stringCpy("/boot/initrd", destFilePath, NAME_LENGTH - 1); 35 | ls(driver, destFilePath); 36 | 37 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 38 | ls(driver, destFilePath); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genFS/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef unsigned short uint16_t; 6 | typedef unsigned char uint8_t; 7 | 8 | typedef int int32_t; 9 | typedef short int16_t; 10 | typedef char int8_t; 11 | 12 | // #define NULL ((void*)0) 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genFS/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | /* 5 | * find the first token in string 6 | * set *size as the number of bytes before token 7 | * if not found, set *size as the length of *string 8 | */ 9 | int stringChr (const char *string, char token, int *size) { 10 | int i = 0; 11 | if (string == NULL) { 12 | *size = 0; 13 | return -1; 14 | } 15 | while (string[i] != 0) { 16 | if (token == string[i]) { 17 | *size = i; 18 | return 0; 19 | } 20 | else 21 | i ++; 22 | } 23 | *size = i; 24 | return -1; 25 | } 26 | 27 | /* 28 | * find the last token in string 29 | * set *size as the number of bytes before token 30 | * if not found, set *size as the length of *string 31 | */ 32 | int stringChrR (const char *string, char token, int *size) { 33 | int i = 0; 34 | if (string == NULL) { 35 | *size = 0; 36 | return -1; 37 | } 38 | while (string[i] != 0) 39 | i ++; 40 | *size = i; 41 | while (i > -1) { 42 | if (token == string[i]) { 43 | *size = i; 44 | return 0; 45 | } 46 | else 47 | i --; 48 | } 49 | return -1; 50 | } 51 | 52 | int stringLen (const char *string) { 53 | int i = 0; 54 | if (string == NULL) 55 | return 0; 56 | while (string[i] != 0) 57 | i ++; 58 | return i; 59 | } 60 | 61 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 62 | int i = 0; 63 | if (srcString == NULL || destString == NULL) 64 | return -1; 65 | while (i != size) { 66 | if (srcString[i] != destString[i]) 67 | return -1; 68 | else if (srcString[i] == 0) 69 | return 0; 70 | else 71 | i ++; 72 | } 73 | return 0; 74 | } 75 | 76 | int stringCpy (const char *srcString, char *destString, int size) { 77 | int i = 0; 78 | if (srcString == NULL || destString == NULL) 79 | return -1; 80 | while (i != size) { 81 | if (srcString[i] != 0) { 82 | destString[i] = srcString[i]; 83 | i++; 84 | } 85 | else 86 | break; 87 | } 88 | destString[i] = 0; 89 | return 0; 90 | } 91 | 92 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 93 | int i = 0; 94 | if (buffer == NULL) 95 | return -1; 96 | for (i = 0; i < size ; i ++) 97 | buffer[i] = value; 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genFS/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | #include "types.h" 5 | 6 | int stringChr(const char *string, char token, int *size); 7 | 8 | int stringChrR (const char *string, char token, int *size); 9 | 10 | int stringLen(const char *string); 11 | 12 | int stringCmp(const char *srcString, const char *destString, int size); 13 | 14 | int stringCpy (const char *srcString, char *destString, int size); 15 | 16 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 17 | 18 | #endif -------------------------------------------------------------------------------- /lab3-181860013/lab3/utils/genKernel.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 100000); 6 | 7 | print STDERR "OK: Kernel is $n bytes - Extended to 200 sectors\n"; 8 | 9 | $buf .= "\0" x (102400-$n); 10 | 11 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 12 | print SIG $buf; 13 | close SIG; 14 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/Makefile: -------------------------------------------------------------------------------- 1 | QEMU = qemu-system-i386 2 | 3 | os.img: 4 | @cd utils/genFS; make 5 | @cd bootloader; make 6 | @cd kernel; make 7 | @cd bounded_buffer; make 8 | @cd philosopher; make 9 | @cd reader_writer; make 10 | @cd app_print; make 11 | @cd app; make 12 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.bin > os.img 13 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.elf > os.img 14 | @#cat bootloader/bootloader.bin kernel/kMain.elf app/uMain.elf > os.img 15 | @./utils/genFS/genFS app/uMain.elf app_print/app_print.elf bounded_buffer/bounded_buffer.elf philosopher/philosopher.elf reader_writer/reader_writer.elf 16 | cat bootloader/bootloader.bin kernel/kMain.elf fs.bin > os.img 17 | 18 | play: os.img 19 | $(QEMU) -serial stdio os.img 20 | 21 | debug: os.img 22 | $(QEMU) -serial stdio -s -S os.img 23 | 24 | clean: 25 | @cd utils/genFS; make clean 26 | @cd bootloader; make clean 27 | @cd kernel; make clean 28 | @cd bounded_buffer; make clean 29 | @cd philosopher; make clean 30 | @cd reader_writer; make clean 31 | @cd app_print; make clean 32 | @cd app; make clean 33 | rm -f fs.bin os.img 34 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/app/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | #UOBJS = $(LCFILES:.c=.o) $(UCFILES:.c=.o) 13 | 14 | umain.bin: $(UOBJS) 15 | @#$(LD) $(LDFLAGS) -e uEntry -Ttext 0x00200000 -o uMain.elf $(UOBJS) 16 | $(LD) $(LDFLAGS) -e uEntry -Ttext 0x00000000 -o uMain.elf $(UOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary uMain.elf uMain.bin 18 | @#objcopy -O binary uMain.elf uMain.bin 19 | 20 | clean: 21 | @#rm -rf $(UOBJS) uMain.elf uMain.bin 22 | rm -rf $(UOBJS) uMain.elf 23 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/app/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | int uEntry(void) 5 | { 6 | /* 7 | int dec = 0; 8 | int hex = 0; 9 | char str[6]; 10 | char cha = 0; 11 | int ret = 0; 12 | while (1) 13 | { 14 | printf("Input:\" Test %%c Test %%6s %%d %%x\"\n"); 15 | ret = scanf(" Test %c Test %6s %d %x", &cha, str, &dec, &hex); 16 | printf("Ret: %d; %c, %s, %d, %x.\n", ret, cha, str, dec, hex); 17 | if (ret == 4) 18 | break; 19 | } 20 | 21 | int data = 2020; 22 | int data1 = 1000; 23 | int i = 4; 24 | int ret = fork(); 25 | if (ret == 0) 26 | { 27 | while (i != 0) 28 | { 29 | i--; 30 | printf("Child Process: %d, %d\n", data, data1); 31 | write(SH_MEM, (uint8_t *)&data, 4, 0); // define SH_MEM 3 32 | data += data1; 33 | sleep(128); 34 | } 35 | exit(); 36 | } 37 | else if (ret != -1) 38 | { 39 | while (i != 0) 40 | { 41 | i--; 42 | read(SH_MEM, (uint8_t *)&data1, 4, 0); 43 | printf("Father Process: %d, %d\n", data, data1); 44 | sleep(128); 45 | } 46 | exit(); 47 | } 48 | 49 | int i = 4; 50 | int ret = 0; 51 | int value = 2; 52 | sem_t sem; 53 | printf("Father Process: Semaphore Initializing.\n"); 54 | ret = sem_init(&sem, value); 55 | if (ret == -1) 56 | { 57 | printf("Father Process: Semaphore Initializing Failed.\n"); 58 | exit(); 59 | } 60 | ret = fork(); 61 | if (ret == 0) 62 | { 63 | while (i != 0) 64 | { 65 | i--; 66 | printf("Child Process: Semaphore Waiting.\n"); 67 | sem_wait(&sem); 68 | printf("Child Process: In Critical Area.\n"); 69 | } 70 | printf("Child Process: Semaphore Destroying.\n"); 71 | sem_destroy(&sem); 72 | exit(); 73 | } 74 | else if (ret != -1) 75 | { 76 | while (i != 0) 77 | { 78 | i--; 79 | printf("Father Process: Sleeping.\n"); 80 | sleep(128); 81 | printf("Father Process: Semaphore Posting.\n"); 82 | sem_post(&sem); 83 | } 84 | printf("Father Process: Semaphore Destroying.\n"); 85 | sem_destroy(&sem); 86 | exit(); 87 | } 88 | */ 89 | char ch; 90 | printf("Input: 1 for bounded_buffer\n 2 for philosopher\n 3 for reader_writer\n"); 91 | scanf("%c", &ch); 92 | switch (ch) 93 | { 94 | case '1': 95 | exec("/usr/bounded_buffer", 0); 96 | break; 97 | case '2': 98 | exec("/usr/philosopher", 0); 99 | break; 100 | case '3': 101 | exec("/usr/reader_writer", 0); 102 | break; 103 | default: 104 | break; 105 | } 106 | exit(); 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/app_print/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | #UOBJS = $(LCFILES:.c=.o) $(UCFILES:.c=.o) 13 | 14 | app_print.bin: $(UOBJS) 15 | @#$(LD) $(LDFLAGS) -e uEntry -Ttext 0x00200000 -o uMain.elf $(UOBJS) 16 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o app_print.elf $(UOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary uMain.elf uMain.bin 18 | @#objcopy -O binary uMain.elf uMain.bin 19 | 20 | clean: 21 | @#rm -rf $(UOBJS) uMain.elf uMain.bin 22 | rm -rf $(UOBJS) app_print.elf 23 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/app_print/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | int main(void) { 5 | printf("printf test begin...\n"); 6 | printf("the answer should be:\n"); 7 | printf("#######################################################\n"); 8 | printf("Hello, welcome to OSlab! I'm the body of the game. "); 9 | printf("Bootblock loads me to the memory position of 0x100000, and Makefile also tells me that I'm at the location of 0x100000. "); 10 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 11 | printf("Now I will test your printf: "); 12 | printf("1 + 1 = 2, 123 * 456 = 56088\n0, -1, -2147483648, -1412567295, -32768, 102030\n0, ffffffff, 80000000, abcdef01, ffff8000, 18e8e\n"); 13 | printf("#######################################################\n"); 14 | printf("your answer:\n"); 15 | printf("=======================================================\n"); 16 | printf("%s %s%scome %co%s", "Hello,", "", "wel", 't', " "); 17 | printf("%c%c%c%c%c! ", 'O', 'S', 'l', 'a', 'b'); 18 | printf("I'm the %s of %s. %s 0x%x, %s 0x%x. ", "body", "the game", "Bootblock loads me to the memory position of", 0x100000, "and Makefile also tells me that I'm at the location of", 0x100000); 19 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 20 | printf("Now I will test your printf: "); 21 | printf("%d + %d = %d, %d * %d = %d\n", 1, 1, 1 + 1, 123, 456, 123 * 456); 22 | printf("%d, %d, %d, %d, %d, %d\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 23 | printf("%x, %x, %x, %x, %x, %x\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 24 | printf("=======================================================\n"); 25 | printf("Test end!!! Good luck!!!\n"); 26 | 27 | exit(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/bootloader/Makefile: -------------------------------------------------------------------------------- 1 | #bootloader.bin: start.S boot.c boot.h 2 | # gcc -c -m32 start.S -o start.o 3 | # gcc -c -m32 -O1 -fno-stack-protector boot.c -o boot.o 4 | # ld -m elf_i386 -e start -Ttext 0x7c00 start.o boot.o -o bootloader.elf 5 | # @#ld -m elf_i386 -e start -Ttext 0x7c00 boot.o start.o -o bootloader.elf 6 | # @#objcopy -S -j .text -O binary bootloader.elf bootloader.bin 7 | # objcopy -O binary bootloader.elf bootloader.bin 8 | # ../utils/genBoot.pl bootloader.bin 9 | # 10 | #clean: 11 | # rm -rf *.o *.elf *.bin 12 | 13 | # take care of link order of object files 14 | # -Ttext set the address of the first byte of the text segment 15 | # -e set the entry address in elf-header 16 | # i.e., the entry address may not be the address of the first byte of the text segment 17 | 18 | CC = gcc 19 | LD = ld 20 | 21 | CFLAGS = -m32 -march=i386 -static \ 22 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 23 | -Wall -Werror -O2 24 | ASFLAGS = -m32 25 | LDFLAGS = -m elf_i386 26 | 27 | BSFILES = $(shell find ./ -name "*.S") 28 | BCFILES = $(shell find ./ -name "*.c") 29 | BOBJS = $(BSFILES:.S=.o) $(BCFILES:.c=.o) 30 | 31 | bootloader.bin: $(BOBJS) 32 | $(LD) $(LDFLAGS) -e start -Ttext 0x7c00 -o bootloader.elf $(BOBJS) 33 | objcopy -S -j .text -O binary bootloader.elf bootloader.bin 34 | @../utils/genBoot.pl bootloader.bin 35 | 36 | clean: 37 | rm -rf $(BOBJS) bootloader.elf bootloader.bin 38 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/bootloader/boot.c: -------------------------------------------------------------------------------- 1 | #include "boot.h" 2 | 3 | #define SECTSIZE 512 4 | 5 | /* 6 | void bootMain(void) { 7 | int i = 0; 8 | void (*elf)(void); 9 | elf = (void(*)(void))0x100000; // kernel is loaded to location 0x100000 10 | for (i = 0; i < 200; i ++) { 11 | //readSect((void*)elf + i*512, i+1); 12 | readSect((void*)elf + i*512, i+9); 13 | } 14 | elf(); // jumping to the loaded program 15 | } 16 | */ 17 | 18 | void bootMain(void) { 19 | int i = 0; 20 | int phoff = 0x34; 21 | int offset = 0x1000; 22 | unsigned int elf = 0x100000; 23 | void (*kMainEntry)(void); 24 | kMainEntry = (void(*)(void))0x100000; 25 | 26 | for (i = 0; i < 200; i++) { 27 | readSect((void*)(elf + i*512), 1+i); 28 | } 29 | 30 | kMainEntry = (void(*)(void))((struct ELFHeader *)elf)->entry; 31 | phoff = ((struct ELFHeader *)elf)->phoff; 32 | offset = ((struct ProgramHeader *)(elf + phoff))->off; 33 | 34 | for (i = 0; i < 200 * 512; i++) { 35 | *(unsigned char *)(elf + i) = *(unsigned char *)(elf + i + offset); 36 | } 37 | 38 | kMainEntry(); 39 | } 40 | 41 | void waitDisk(void) { // waiting for disk 42 | while((inByte(0x1F7) & 0xC0) != 0x40); 43 | } 44 | 45 | void readSect(void *dst, int offset) { // reading a sector of disk 46 | int i; 47 | waitDisk(); 48 | outByte(0x1F2, 1); 49 | outByte(0x1F3, offset); 50 | outByte(0x1F4, offset >> 8); 51 | outByte(0x1F5, offset >> 16); 52 | outByte(0x1F6, (offset >> 24) | 0xE0); 53 | outByte(0x1F7, 0x20); 54 | 55 | waitDisk(); 56 | for (i = 0; i < SECTSIZE / 4; i ++) { 57 | ((int *)dst)[i] = inLong(0x1F0); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/bootloader/boot.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOT_H 2 | #define BOOT_H 3 | 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | void waitDisk(void); 35 | 36 | void readSect(void *dst, int offset); 37 | 38 | /* I/O functions */ 39 | static inline char inByte(short port) { 40 | char data; 41 | asm volatile("in %1,%0" : "=a" (data) : "d" (port)); 42 | return data; 43 | } 44 | 45 | static inline int inLong(short port) { 46 | int data; 47 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 48 | return data; 49 | } 50 | 51 | static inline void outByte(short port, char data) { 52 | asm volatile("out %0,%1" : : "a" (data), "d" (port)); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/bounded_buffer/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | 13 | app.bin: $(UOBJS) 14 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o bounded_buffer.elf $(UOBJS) 15 | 16 | clean: 17 | rm -rf $(UOBJS) bounded_buffer.elf 18 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/bounded_buffer/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | static unsigned long next = 61; 5 | 6 | int myrand() 7 | { 8 | read(SH_MEM, (uint8_t *)&next, 4, 24); 9 | next = next * 1103515245 + 12345; 10 | write(SH_MEM, (uint8_t *)&next, 4, 24); 11 | return ((unsigned)(next / 65536) % 211) + 53; 12 | } 13 | 14 | void producer(sem_t *mutex, sem_t *full, sem_t *empty) 15 | { 16 | int id = getpid() - 2; 17 | while (1) 18 | { 19 | sem_wait(empty); 20 | sleep(myrand()); 21 | sem_wait(mutex); 22 | sleep(myrand()); 23 | printf("Producer %d: produce\n", id); 24 | sleep(myrand()); 25 | sem_post(mutex); 26 | sleep(myrand()); 27 | sem_post(full); 28 | sleep(myrand()); 29 | } 30 | } 31 | 32 | void consumer(sem_t *mutex, sem_t *full, sem_t *empty) 33 | { 34 | while (1) 35 | { 36 | sem_wait(full); 37 | sleep(myrand()); 38 | sem_wait(mutex); 39 | sleep(myrand()); 40 | printf("Consumer : consume\n"); 41 | sleep(myrand()); 42 | sem_post(mutex); 43 | sleep(myrand()); 44 | sem_post(empty); 45 | sleep(myrand()); 46 | } 47 | } 48 | 49 | int main(void) 50 | { 51 | // TODO in lab4 52 | printf("bounded_buffer\n"); 53 | sem_t mutex, fullBuffers, emptyBuffers; 54 | sem_init(&mutex, 1); 55 | sem_init(&fullBuffers, 0); 56 | sem_init(&emptyBuffers, 5); 57 | write(SH_MEM, (uint8_t *)&next, 4, 24); 58 | int ret = 1; 59 | for (int i = 0; i < 5; i++) 60 | { 61 | if (ret > 0) 62 | ret = fork(); 63 | } 64 | int id = getpid(); 65 | if (id > 1 && id < 6) 66 | { 67 | sleep(myrand()); 68 | producer(&mutex, &fullBuffers, &emptyBuffers); 69 | } 70 | else if (id == 6) 71 | { 72 | consumer(&mutex, &fullBuffers, &emptyBuffers); 73 | } 74 | 75 | while (1); 76 | sem_destroy(&mutex); 77 | sem_destroy(&fullBuffers); 78 | sem_destroy(&emptyBuffers); 79 | exit(); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O0 -I./include 7 | ASFLAGS = -m32 8 | LDFLAGS = -m elf_i386 9 | 10 | KCFILES = $(shell find ./ -name "*.c") 11 | KSFILES = $(shell find ./ -name "*.S") 12 | KOBJS = $(KCFILES:.c=.o) $(KSFILES:.S=.o) 13 | #KOBJS = $(KSFILES:.S=.o) $(KCFILES:.c=.o) 14 | 15 | kmain.bin: $(KOBJS) 16 | $(LD) $(LDFLAGS) -e kEntry -Ttext 0x00100000 -o kMain.elf $(KOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary kMain.elf kMain.bin 18 | @#objcopy -O binary kMain.elf kMain.bin 19 | @../utils/genKernel.pl kMain.elf 20 | @#../utils/genKernel.pl kMain.bin 21 | 22 | 23 | clean: 24 | @#rm -rf $(KOBJS) kMain.elf kMain.bin 25 | rm -rf $(KOBJS) kMain.elf kMain.bin 26 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include "common/types.h" 5 | #include "common/const.h" 6 | #include "common/assert.h" 7 | #include "common/utils.h" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/common/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASSERT_H__ 2 | #define __ASSERT_H__ 3 | 4 | int abort(const char *, int); 5 | 6 | /* assert: 断言条件为真,若为假则蓝屏退出 */ 7 | #define assert(cond) \ 8 | ((cond) ? (0) : (abort(__FILE__, __LINE__))) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/common/const.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONST_H__ 2 | #define __CONST_H__ 3 | 4 | #define TRUE 1 5 | #define FALSE 0 6 | 7 | #define NULL ((void*)0) 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/common/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | /* 定义数据类型 */ 5 | typedef unsigned int uint32_t; 6 | typedef int int32_t; 7 | typedef unsigned short uint16_t; 8 | typedef short int16_t; 9 | typedef unsigned char uint8_t; 10 | typedef char int8_t; 11 | typedef unsigned int size_t; 12 | #endif 13 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/common/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | int stringChr(const char *string, char token, int *size); 5 | 6 | int stringChrR (const char *string, char token, int *size); 7 | 8 | int stringLen(const char *string); 9 | 10 | int stringCmp(const char *srcString, const char *destString, int size); 11 | 12 | int stringCpy (const char *srcString, char *destString, int size); 13 | 14 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 15 | 16 | #endif -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/device.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVICE_H__ 2 | #define __DEVICE_H__ 3 | 4 | #include "device/serial.h" 5 | #include "device/disk.h" 6 | #include "device/vga.h" 7 | #include "device/timer.h" 8 | #include "device/keyboard.h" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/device/disk.h: -------------------------------------------------------------------------------- 1 | #ifndef __DISK_H__ 2 | #define __DISK_H__ 3 | 4 | #define SECTOR_NUM 8192 5 | #define SECTOR_SIZE 512 6 | 7 | void waitDisk(void); 8 | void readSect(void *dst, int offset); 9 | void writeSect(void *src, int offset); 10 | 11 | void diskRead(void *destBuffer, int size, int num, int offset); 12 | void diskWrite(void *destBuffer, int size, int num, int offset); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/device/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYBOARD_H__ 2 | #define __KEYBOARD_H__ 3 | 4 | #define MAX_KEYBUFFER_SIZE 256 5 | 6 | void initKeyTable(); 7 | 8 | uint32_t getKeyCode(); 9 | 10 | char getChar(uint32_t code); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/device/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERIAL_H__ 2 | #define __SERIAL_H__ 3 | 4 | void initSerial(void); 5 | void putChar(char); 6 | void putString(const char *); 7 | void putInt(int); 8 | 9 | #define SERIAL_PORT 0x3F8 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/device/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_H__ 2 | #define __TIMER_H__ 3 | 4 | void initTimer(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/device/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef __VGA_H__ 2 | #define __VGA_H__ 3 | 4 | void initVga(); 5 | void clearScreen(); 6 | void updateCursor(int row, int col); 7 | void scrollScreen(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef __FS_H__ 2 | #define __FS_H__ 3 | 4 | #include "fs/minix.h" 5 | 6 | int readSuperBlock (SuperBlock *superBlock); 7 | 8 | int allocInode (SuperBlock *superBlock, 9 | Inode *fatherInode, 10 | int fatherInodeOffset, 11 | Inode *destInode, 12 | int *destInodeOffset, 13 | const char *destFilename, 14 | int destFiletype); 15 | 16 | int freeInode (SuperBlock *superBlock, 17 | Inode *fatherInode, 18 | int fatherInodeOffset, 19 | Inode *destInode, 20 | int *destInodeOffset, 21 | const char *destFilename, 22 | int destFiletype); 23 | 24 | int readInode (SuperBlock *superBlock, 25 | Inode *destInode, 26 | int *inodeOffset, 27 | const char *destFilePath); 28 | 29 | int allocBlock (SuperBlock *superBlock, 30 | Inode *inode, 31 | int inodeOffset); 32 | 33 | int readBlock (SuperBlock *superBlock, 34 | Inode *inode, 35 | int blockIndex, 36 | uint8_t *buffer); 37 | 38 | int writeBlock (SuperBlock *superBlock, 39 | Inode *inode, 40 | int blockIndex, 41 | uint8_t *buffer); 42 | 43 | int getDirEntry (SuperBlock *superBlock, 44 | Inode *inode, 45 | int dirIndex, 46 | DirEntry *destDirEntry); 47 | 48 | void initFS (void); 49 | 50 | void initFile (void); 51 | 52 | #endif /* __FS_H__ */ 53 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/fs/minix.h: -------------------------------------------------------------------------------- 1 | #ifndef __MINIX_H__ 2 | #define __MINIX_H__ 3 | 4 | /* 5 | * minix like filesystem 6 | */ 7 | 8 | /* 9 | * Layout of file system 10 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 11 | *| SuperBlock | InodeBitmap | BlockBitmap | InodeTable | DataBlocks | 12 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 13 | * 1024 Bytes 1 Block 1 Block 128 Blocks Many More Blocks 14 | * 15 | */ 16 | 17 | #define SECTORS_PER_BLOCK 2 18 | #define POINTER_NUM 14 19 | #define NAME_LENGTH 64 20 | 21 | #define BLOCK_SIZE (SECTOR_SIZE * SECTORS_PER_BLOCK) 22 | #define SUPER_BLOCK_SIZE BLOCK_SIZE 23 | #define INODE_BITMAP_SIZE BLOCK_SIZE 24 | #define BLOCK_BITMAP_SIZE BLOCK_SIZE 25 | #define INODE_SIZE 128 26 | #define DIRENTRY_SIZE 128 27 | #define INODE_BLOCKS (SECTOR_NUM / SECTORS_PER_BLOCK / 32) 28 | 29 | #define UNKNOWN_TYPE 0 30 | #define REGULAR_TYPE 1 31 | #define DIRECTORY_TYPE 2 32 | #define CHARACTER_TYPE 3 33 | #define BLOCK_TYPE 4 34 | #define FIFO_TYPE 5 35 | #define SOCKET_TYPE 6 36 | #define SYMBOLIC_TYPE 7 37 | 38 | union SuperBlock { 39 | uint8_t byte[SUPER_BLOCK_SIZE]; 40 | struct { 41 | int32_t sectorNum; // total number of sectors 42 | int32_t inodeNum; // total number of inodes 43 | int32_t blockNum; // total number of data blocks 44 | int32_t availInodeNum; // total number of available inodes 45 | int32_t availBlockNum; // total number of available data blocks 46 | int32_t blockSize; // number of bytes in each block 47 | int32_t inodeBitmap; // XXX sector as unit 48 | int32_t blockBitmap; // XXX sector as unit 49 | int32_t inodeTable; // XXX sector as unit 50 | int32_t blocks; // XXX sector as unit 51 | }; 52 | }; 53 | typedef union SuperBlock SuperBlock; 54 | 55 | struct InodeBitmap { 56 | uint8_t byte[INODE_BITMAP_SIZE]; 57 | }; 58 | typedef struct InodeBitmap InodeBitmap; 59 | 60 | struct BlockBitmap { 61 | uint8_t byte[BLOCK_BITMAP_SIZE]; 62 | }; 63 | typedef struct BlockBitmap BlockBitmap; 64 | 65 | union Inode { 66 | uint8_t byte[INODE_SIZE]; 67 | struct { 68 | int16_t type; 69 | int16_t linkCount; 70 | int32_t blockCount; 71 | int32_t size; 72 | int32_t pointer[POINTER_NUM]; // XXX sector as unit 73 | int32_t singlyPointer; // XXX sector as unit 74 | }; 75 | }; 76 | typedef union Inode Inode; 77 | 78 | union DirEntry { 79 | uint8_t byte[DIRENTRY_SIZE]; 80 | struct { 81 | int32_t inode; // index in inode table, started from 1, 0 for unused. 82 | char name[NAME_LENGTH]; 83 | }; 84 | }; 85 | typedef union DirEntry DirEntry; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/x86.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_H__ 2 | #define __X86_H__ 3 | 4 | #include "x86/cpu.h" 5 | #include "x86/memory.h" 6 | #include "x86/io.h" 7 | #include "x86/irq.h" 8 | 9 | void initSeg(void); 10 | void initSem(void); 11 | void initDev(void); 12 | void initProc(void); 13 | int loadElf(const char *filename, uint32_t physAddr, uint32_t *entry); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/x86/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_CPU_H__ 2 | #define __X86_CPU_H__ 3 | 4 | #include "common.h" 5 | 6 | /* 将CPU置入休眠状态直到下次中断到来 */ 7 | static inline void waitForInterrupt() { 8 | asm volatile("hlt"); 9 | } 10 | 11 | /* 修改IDTR */ 12 | static inline void saveIdt(void *addr, uint32_t size) { 13 | static volatile uint16_t data[3]; 14 | data[0] = size - 1; 15 | data[1] = (uint32_t)addr; 16 | data[2] = ((uint32_t)addr) >> 16; 17 | asm volatile("lidt (%0)" : : "r"(data)); 18 | } 19 | 20 | /* 打开外部中断 */ 21 | static inline void enableInterrupt(void) { 22 | asm volatile("sti"); 23 | } 24 | 25 | /* 关闭外部中断 */ 26 | static inline void disableInterrupt(void) { 27 | asm volatile("cli"); 28 | } 29 | 30 | #define NR_IRQ 256 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/x86/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_IO_H__ 2 | #define __X86_IO_H__ 3 | /* ELF32二进制文件头 */ 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | 35 | static inline int inLong(short port) { 36 | int data; 37 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 38 | return data; 39 | } 40 | 41 | static inline void outLong(uint16_t port, uint32_t data) { 42 | asm volatile("out %0, %1" : : "a"(data), "d"(port)); 43 | } 44 | 45 | /* 读I/O端口 */ 46 | static inline uint8_t inByte(uint16_t port) { 47 | uint8_t data; 48 | asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 49 | return data; 50 | } 51 | 52 | /* 写I/O端口 */ 53 | static inline void outByte(uint16_t port, int8_t data) { 54 | asm volatile("out %%al, %%dx" : : "a"(data), "d"(port)); 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/include/x86/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __IRQ_H__ 2 | #define __IRQ_H__ 3 | 4 | /* 中断处理相关函数 */ 5 | void initIdt(void); 6 | void initIntr(void); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/kernel/disk.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define SECTSIZE 512 5 | 6 | void waitDisk(void) { 7 | while((inByte(0x1F7) & 0xC0) != 0x40); 8 | } 9 | 10 | void readSect(void *dst, int offset) { 11 | int i; 12 | waitDisk(); 13 | 14 | outByte(0x1F2, 1); 15 | outByte(0x1F3, offset); 16 | outByte(0x1F4, offset >> 8); 17 | outByte(0x1F5, offset >> 16); 18 | outByte(0x1F6, (offset >> 24) | 0xE0); 19 | outByte(0x1F7, 0x20); 20 | 21 | waitDisk(); 22 | for (i = 0; i < SECTSIZE / 4; i ++) { 23 | ((int *)dst)[i] = inLong(0x1F0); 24 | } 25 | } 26 | 27 | void writeSect(void *src, int offset) { 28 | int i; 29 | waitDisk(); 30 | 31 | outByte(0x1F2, 1); 32 | outByte(0x1F3, offset); 33 | outByte(0x1F4, offset >> 8); 34 | outByte(0x1F5, offset >> 16); 35 | outByte(0x1F6, (offset >> 24) | 0xE0); 36 | outByte(0x1F7, 0x30); 37 | 38 | waitDisk(); 39 | for (i = 0; i < SECTOR_SIZE / 4; i ++) { 40 | outLong(0x1F0, ((uint32_t *)src)[i]); 41 | } 42 | } 43 | 44 | void diskRead (void *destBuffer, int size, int num, int offset) { 45 | int i = 0; 46 | int j = 0; 47 | uint8_t buffer[SECTOR_SIZE]; 48 | int quotient = offset / SECTOR_SIZE; 49 | int remainder = offset % SECTOR_SIZE; 50 | 51 | readSect((void*)buffer, 201 + quotient + j); 52 | j ++; 53 | while (i < size * num) { 54 | ((uint8_t*)destBuffer)[i] = buffer[(remainder + i) % SECTOR_SIZE]; 55 | i ++; 56 | if ((remainder + i) % SECTOR_SIZE == 0) { 57 | readSect((void*)buffer, 201 + quotient + j); 58 | j ++; 59 | } 60 | } 61 | } 62 | 63 | void diskWrite (void *destBuffer, int size, int num, int offset) { 64 | int i = 0; 65 | int j = 0; 66 | uint8_t buffer[SECTOR_SIZE]; 67 | int quotient = offset / SECTOR_SIZE; 68 | int remainder = offset % SECTOR_SIZE; 69 | 70 | readSect((void*)buffer, 201 + quotient + j); 71 | while (i < size * num) { 72 | buffer[(remainder + i) % SECTOR_SIZE] = ((uint8_t*)destBuffer)[i]; 73 | i ++; 74 | if ((remainder + i) % SECTOR_SIZE == 0) { 75 | writeSect((void*)buffer, 201 + quotient + j); 76 | j ++; 77 | readSect((void*)buffer, 201 + quotient + j); 78 | } 79 | } 80 | writeSect((void*)buffer, 201 + quotient + j); 81 | } 82 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/kernel/doIrq.S: -------------------------------------------------------------------------------- 1 | /*TODO 2 | otherwise need to reassign esp0 of tss in task switching for each user process 3 | note that for conforming code OR same PRL, no need to switch task 4 | that is TSS doesn't work 5 | 1. Trap Gate, IF won't be set 6 | 2. Interrupt Gate, IF is set automatically 7 | 3. System Gate 8 | */ 9 | 10 | .code32 11 | 12 | .global irqEmpty 13 | irqEmpty: 14 | pushl $0 // push dummy error code 15 | pushl $-1 // push interruption number into kernel 16 | jmp asmDoIrq 17 | 18 | .global irqErrorCode 19 | irqErrorCode: 20 | pushl $-1 // push interruption number into kernel 21 | jmp asmDoIrq 22 | 23 | .global irqDoubleFault 24 | irqDoubleFault: 25 | pushl $-1 26 | jmp asmDoIrq 27 | 28 | .global irqInvalidTSS 29 | irqInvalidTSS: 30 | pushl $-1 31 | jmp asmDoIrq 32 | 33 | .global irqSegNotPresent 34 | irqSegNotPresent: 35 | pushl $-1 36 | jmp asmDoIrq 37 | 38 | .global irqStackSegFault 39 | irqStackSegFault: 40 | pushl $-1 41 | jmp asmDoIrq 42 | 43 | .global irqGProtectFault 44 | irqGProtectFault: 45 | pushl $0xd 46 | jmp asmDoIrq 47 | 48 | .global irqPageFault 49 | irqPageFault: 50 | pushl $-1 51 | jmp asmDoIrq 52 | 53 | .global irqAlignCheck 54 | irqAlignCheck: 55 | pushl $-1 56 | jmp asmDoIrq 57 | 58 | .global irqSecException 59 | irqSecException: 60 | pushl $-1 61 | jmp asmDoIrq 62 | 63 | .global irqTimer 64 | irqTimer: 65 | pushl $0 66 | pushl $0x20 67 | jmp asmDoIrq 68 | 69 | .global irqKeyboard 70 | irqKeyboard: 71 | pushl $0 72 | pushl $0x21 73 | jmp asmDoIrq 74 | 75 | .global irqSyscall 76 | irqSyscall: 77 | pushl $0 // push dummy error code 78 | pushl $0x80 // push interruption number into kernel stack 79 | jmp asmDoIrq 80 | 81 | //.extern irqHandle //defined in irq_handle.c 82 | 83 | .global asmDoIrq 84 | asmDoIrq: 85 | pushal // push process state into kernel stack 86 | pushl %ds 87 | pushl %es 88 | pushl %fs 89 | pushl %gs 90 | pushl %esp //esp is treated as a parameter 91 | call irqHandle 92 | addl $4, %esp //esp is on top of kernel stack 93 | popl %gs 94 | popl %fs 95 | popl %es 96 | popl %ds 97 | popal 98 | addl $4, %esp //interrupt number is on top of kernel stack 99 | addl $4, %esp //error code is on top of kernel stack 100 | iret 101 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/kernel/i8259.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | 3 | #define PORT_PIC_MASTER 0x20 4 | #define PORT_PIC_SLAVE 0xA0 5 | #define IRQ_SLAVE 2 6 | 7 | /* 初始化8259中断控制器: 8 | * 硬件中断IRQ从32号开始,自动发送EOI */ 9 | void 10 | initIntr(void) { 11 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 12 | //outByte(PORT_PIC_SLAVE + 1 , 0xFF); // OCW1, Disable Slave PIC all IRQs 13 | outByte(PORT_PIC_MASTER, 0x11); // ICW1, Initialization command 14 | outByte(PORT_PIC_SLAVE, 0x11); // ICW1, Initialization command 15 | outByte(PORT_PIC_MASTER + 1, 32); // ICW2, Interrupt Vector Offset 0x20 16 | outByte(PORT_PIC_SLAVE + 1, 32 + 8); // ICW2, Interrupt Vector Offset 0x28 17 | outByte(PORT_PIC_MASTER + 1, 1 << 2); // ICW3, Tell Master PIC that there is a slave 18 | outByte(PORT_PIC_SLAVE + 1, 2); // ICW3, Tell Slave PIC its cascade identity 19 | outByte(PORT_PIC_MASTER + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 20 | outByte(PORT_PIC_SLAVE + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 21 | 22 | //outByte(PORT_PIC_MASTER, 0x68); // OCW3, Enable Special Mask Mode 23 | //outByte(PORT_PIC_MASTER, 0x0A); // OCW3, Read ISR of Master on next CMD Read 24 | //outByte(PORT_PIC_SLAVE, 0x68); // OCW3, Enable Special Mask Mode 25 | //outByte(PORT_PIC_SLAVE, 0x0A); // OCW3, Read ISR of Slave on next CMD Read 26 | 27 | //outByte(PORT_PIC_MASTER + 1, 0xFE); // OCW1, Enable Timer IRQ 28 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 29 | //outByte(PORT_PIC_SLAVE + 1, 0xFF); // OCW1, Disable Slave PIC all IRQs 30 | } 31 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/kernel/idt.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define INTERRUPT_GATE_32 0xE 5 | #define TRAP_GATE_32 0xF 6 | 7 | /* IDT表的内容 */ 8 | struct GateDescriptor idt[NR_IRQ]; // NR_IRQ=256, defined in x86/cpu.h 9 | 10 | /* 初始化一个中断门(interrupt gate) */ 11 | static void setIntr(struct GateDescriptor *ptr, uint32_t selector, uint32_t offset, uint32_t dpl) { 12 | ptr->offset_15_0 = offset & 0xFFFF; 13 | ptr->segment = selector << 3; 14 | ptr->pad0 = 0; 15 | ptr->type = INTERRUPT_GATE_32; 16 | ptr->system = FALSE; 17 | ptr->privilege_level = dpl; 18 | ptr->present = TRUE; 19 | ptr->offset_31_16 = (offset >> 16) & 0xFFFF; 20 | } 21 | 22 | /* 初始化一个陷阱门(trap gate) */ 23 | static void setTrap(struct GateDescriptor *ptr, uint32_t selector, uint32_t offset, uint32_t dpl) { 24 | ptr->offset_15_0 = offset & 0xFFFF; 25 | ptr->segment = selector << 3; 26 | ptr->pad0 = 0; 27 | ptr->type = TRAP_GATE_32; 28 | ptr->system = FALSE; 29 | ptr->privilege_level = dpl; 30 | ptr->present = TRUE; 31 | ptr->offset_31_16 = (offset >> 16) & 0xFFFF; 32 | } 33 | 34 | /* 声明函数,这些函数在汇编代码里定义 */ 35 | void irqEmpty(); 36 | void irqErrorCode(); 37 | 38 | void irqDoubleFault(); // 0x8 39 | void irqInvalidTSS(); // 0xa 40 | void irqSegNotPresent(); // 0xb 41 | void irqStackSegFault(); // 0xc 42 | void irqGProtectFault(); // 0xd 43 | void irqPageFault(); // 0xe 44 | void irqAlignCheck(); // 0x11 45 | void irqSecException(); // 0x1e 46 | 47 | void irqSyscall(); 48 | void irqTimer(); 49 | void irqKeyboard(); 50 | 51 | void initIdt() { 52 | int i; 53 | /* 为了防止系统异常终止,所有irq都有处理函数(irqEmpty)。 */ 54 | for (i = 0; i < NR_IRQ; i ++) { 55 | setTrap(idt + i, SEG_KCODE, (uint32_t)irqEmpty, DPL_KERN); 56 | } 57 | /* 58 | * init your idt here 59 | * 初始化 IDT 表, 为中断设置中断处理函数 60 | */ 61 | /* Exceptions with error code */ 62 | setTrap(idt + 0x8, SEG_KCODE, (uint32_t)irqDoubleFault, DPL_KERN); 63 | setTrap(idt + 0xa, SEG_KCODE, (uint32_t)irqInvalidTSS, DPL_KERN); 64 | setTrap(idt + 0xb, SEG_KCODE, (uint32_t)irqSegNotPresent, DPL_KERN); 65 | setTrap(idt + 0xc, SEG_KCODE, (uint32_t)irqStackSegFault, DPL_KERN); 66 | setTrap(idt + 0xd, SEG_KCODE, (uint32_t)irqGProtectFault, DPL_KERN); 67 | //setTrap(idt + 0xd, SEG_KCODE, (uint32_t)irqGProtectFault, DPL_USER); 68 | setTrap(idt + 0xe, SEG_KCODE, (uint32_t)irqPageFault, DPL_KERN); 69 | //setTrap(idt + 0xe, SEG_KCODE, (uint32_t)irqPageFault, DPL_USER); 70 | setTrap(idt + 0x11, SEG_KCODE, (uint32_t)irqAlignCheck, DPL_KERN); 71 | setTrap(idt + 0x1e, SEG_KCODE, (uint32_t)irqSecException, DPL_KERN); 72 | 73 | /* Exceptions with DPL = 3 */ 74 | //setIntr(idt + 0x3, SEG_KCODE, , DPL_USER); // for int 3, interrupt vector is 0x3, Interruption is disabled 75 | //setIntr(idt + 0x4, SEG_KCODE, , DPL_USER); // for into, interrupt vector is 0x4, Interruption is disabled 76 | //setIntr(idt + 0x5, SEG_KCODE, , DPL_USER); // for bound, interrupt vector is 0x5, Interruption is disabled 77 | setIntr(idt + 0x20, SEG_KCODE, (uint32_t)irqTimer, DPL_KERN); 78 | setIntr(idt + 0x21, SEG_KCODE, (uint32_t)irqKeyboard, DPL_KERN); 79 | setIntr(idt + 0x80, SEG_KCODE, (uint32_t)irqSyscall, DPL_USER); // for int 0x80, interrupt vector is 0x80, Interruption is disabled 80 | 81 | /* 写入IDT */ 82 | saveIdt(idt, sizeof(idt)); 83 | } 84 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/kernel/serial.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | void initSerial(void) { 5 | outByte(SERIAL_PORT + 1, 0x00); 6 | outByte(SERIAL_PORT + 3, 0x80); 7 | outByte(SERIAL_PORT + 0, 0x01); 8 | outByte(SERIAL_PORT + 1, 0x00); 9 | outByte(SERIAL_PORT + 3, 0x03); 10 | outByte(SERIAL_PORT + 2, 0xC7); 11 | outByte(SERIAL_PORT + 4, 0x0B); 12 | } 13 | 14 | static inline int serialIdle(void) { 15 | return (inByte(SERIAL_PORT + 5) & 0x20) != 0; 16 | } 17 | 18 | void putChar(char ch) { 19 | while (serialIdle() != TRUE); 20 | outByte(SERIAL_PORT, ch); 21 | } 22 | 23 | void putString(const char *str) { 24 | int i = 0; 25 | if (str == NULL) { 26 | return; 27 | } 28 | while (str[i] != 0) { 29 | putChar(str[i++]); 30 | } 31 | } 32 | 33 | void putInt(int a) { 34 | char buf[32]; 35 | char *p = buf + sizeof(buf) - 1; 36 | *p = '\0'; 37 | *(--p) = '\n'; 38 | do { 39 | *--p = '0' + a % 10; 40 | } while (a /= 10); 41 | putString(p); 42 | } 43 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/kernel/timer.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define TIMER_PORT 0x40 5 | #define FREQ_8253 1193182 6 | #define HZ 100 7 | //#define HZ 1000 8 | 9 | void initTimer() { 10 | int counter = FREQ_8253 / HZ; 11 | //assert(TIMER_PORT < 65536); 12 | outByte(TIMER_PORT + 3, 0x34); 13 | outByte(TIMER_PORT + 0, counter % 256); 14 | outByte(TIMER_PORT + 0, counter / 256); 15 | } 16 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/kernel/vga.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | int displayRow = 0; //TODO futher extend, display position, in .bss section, not in .data section 5 | int displayCol = 0; 6 | uint16_t displayMem[80*25]; 7 | int displayClear = 0; 8 | 9 | void initVga() { 10 | displayRow = 0; 11 | displayCol = 0; 12 | displayClear = 0; 13 | clearScreen(); 14 | updateCursor(0, 0); 15 | } 16 | 17 | void clearScreen() { 18 | int i = 0; 19 | int pos = 0; 20 | uint16_t data = 0 | (0x0c << 8); 21 | for (i = 0; i < 80 * 25; i++) { 22 | pos = i * 2; 23 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 24 | } 25 | } 26 | 27 | void updateCursor(int row, int col){ 28 | int cursorPos = row * 80 + col; 29 | outByte(0x3d4, 0x0f); 30 | outByte(0x3d5, (unsigned char)(cursorPos & 0xff)); 31 | 32 | outByte(0x3d4, 0x0e); 33 | outByte(0x3d5, (unsigned char)((cursorPos>>8) & 0xff)); 34 | } 35 | 36 | void scrollScreen() { 37 | int i = 0; 38 | int pos = 0; 39 | uint16_t data = 0; 40 | for (i = 0; i < 80 * 25; i++) { 41 | pos = i * 2; 42 | asm volatile("movw (%1), %0":"=r"(data):"r"(pos+0xb8000)); 43 | displayMem[i] = data; 44 | } 45 | for (i = 0; i < 80 * 24; i++) { 46 | pos = i * 2; 47 | data = displayMem[i+80]; 48 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 49 | } 50 | data = 0 | (0x0c << 8); 51 | for (i = 80 * 24; i < 80 * 25; i++) { 52 | pos = i * 2; 53 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/lib/abort.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | 5 | static char *i2A(int a) { 6 | static char buf[30]; 7 | char *p = buf + sizeof(buf) - 1; 8 | do { 9 | *--p = '0' + a % 10; 10 | } while (a /= 10); 11 | return p; 12 | } 13 | 14 | static void append(char **p, const char *str) { 15 | while (*str) { 16 | *((*p) ++) = *str ++; 17 | } 18 | } 19 | 20 | /* 将文件名和assert fail的行号显示在屏幕上 */ 21 | #define BLUE_SCREEN_TEXT "Assertion failed: " 22 | static void displayMessage(const char *file, int line) { 23 | static char buf[256] = BLUE_SCREEN_TEXT; 24 | char *p = buf + sizeof(BLUE_SCREEN_TEXT) - 1; 25 | 26 | append(&p, file); 27 | append(&p, ":"); 28 | append(&p, i2A(line)); 29 | append(&p, "\n"); 30 | 31 | for (p = buf; *p; p ++) { 32 | putChar(*p); 33 | } 34 | } 35 | 36 | int abort(const char *fname, int line) { 37 | disableInterrupt(); 38 | displayMessage(fname, line); 39 | while (TRUE) { 40 | waitForInterrupt(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/lib/utils.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /* 4 | * find the first token in string 5 | * set *size as the number of bytes before token 6 | * if not found, set *size as the length of *string 7 | */ 8 | int stringChr (const char *string, char token, int *size) { 9 | int i = 0; 10 | if (string == NULL) { 11 | *size = 0; 12 | return -1; 13 | } 14 | while (string[i] != 0) { 15 | if (token == string[i]) { 16 | *size = i; 17 | return 0; 18 | } 19 | else 20 | i ++; 21 | } 22 | *size = i; 23 | return -1; 24 | } 25 | 26 | /* 27 | * find the last token in string 28 | * set *size as the number of bytes before token 29 | * if not found, set *size as the length of *string 30 | */ 31 | int stringChrR (const char *string, char token, int *size) { 32 | int i = 0; 33 | if (string == NULL) { 34 | *size = 0; 35 | return -1; 36 | } 37 | while (string[i] != 0) 38 | i ++; 39 | *size = i; 40 | while (i > -1) { 41 | if (token == string[i]) { 42 | *size = i; 43 | return 0; 44 | } 45 | else 46 | i --; 47 | } 48 | return -1; 49 | } 50 | 51 | int stringLen (const char *string) { 52 | int i = 0; 53 | if (string == NULL) 54 | return 0; 55 | while (string[i] != 0) 56 | i ++; 57 | return i; 58 | } 59 | 60 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 61 | int i = 0; 62 | if (srcString == NULL || destString == NULL) 63 | return -1; 64 | while (i != size) { 65 | if (srcString[i] != destString[i]) 66 | return -1; 67 | else if (srcString[i] == 0) 68 | return 0; 69 | else 70 | i ++; 71 | } 72 | return 0; 73 | } 74 | 75 | int stringCpy (const char *srcString, char *destString, int size) { 76 | int i = 0; 77 | if (srcString == NULL || destString == NULL) 78 | return -1; 79 | while (i != size) { 80 | if (srcString[i] != 0) { 81 | destString[i] = srcString[i]; 82 | i++; 83 | } 84 | else 85 | break; 86 | } 87 | destString[i] = 0; 88 | return 0; 89 | } 90 | 91 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 92 | int i = 0; 93 | if (buffer == NULL) 94 | return -1; 95 | for (i = 0; i < size ; i ++) 96 | buffer[i] = value; 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/kernel/main.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | #include "fs.h" 5 | 6 | void kEntry(void) { 7 | 8 | // Interruption is disabled in bootloader 9 | 10 | initSerial(); // initialize serial port 11 | initIdt(); // initialize idt 12 | initIntr(); // iniialize 8259a 13 | initSeg(); // initialize gdt, tss 14 | initVga(); // initialize vga device 15 | initTimer(); // initialize timer device 16 | initKeyTable(); // initialize keyboard device 17 | initFS(); // initialize file system 18 | initSem(); // initialize semaphore list 19 | initDev(); // initialize device list 20 | initProc(); // initialize pcb & load user program 21 | } 22 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/lib/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __lib_h__ 2 | #define __lib_h__ 3 | 4 | #include "types.h" 5 | 6 | #define SYS_WRITE 0 7 | #define SYS_FORK 1 8 | #define SYS_EXEC 2 9 | #define SYS_SLEEP 3 10 | #define SYS_EXIT 4 11 | #define SYS_READ 5 12 | #define SYS_SEM 6 13 | #define SYS_GETPID 7 14 | 15 | #define STD_OUT 0 16 | #define STD_IN 1 17 | #define SH_MEM 3 18 | 19 | #define SEM_INIT 0 20 | #define SEM_WAIT 1 21 | #define SEM_POST 2 22 | #define SEM_DESTROY 3 23 | 24 | #define MAX_BUFFER_SIZE 256 25 | 26 | int printf(const char *format,...); 27 | 28 | int scanf(const char *format,...); 29 | 30 | pid_t fork(); 31 | 32 | int exec(const char *filename, char * const argv[]); 33 | 34 | int sleep(uint32_t time); 35 | 36 | int exit(); 37 | 38 | int write(int fd, uint8_t *buffer, int size, ...); 39 | 40 | int read(int fd, uint8_t *buffer, int size, ...); 41 | 42 | int sem_init(sem_t *sem, uint32_t value); 43 | 44 | int sem_wait(sem_t *sem); 45 | 46 | int sem_post(sem_t *sem); 47 | 48 | int sem_destroy(sem_t *sem); 49 | 50 | int getpid(); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/lib/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef int int32_t; 6 | typedef unsigned short uint16_t; 7 | typedef short int16_t; 8 | typedef unsigned char uint8_t; 9 | typedef char int8_t; 10 | typedef unsigned char boolean; 11 | 12 | typedef uint32_t size_t; 13 | typedef int32_t pid_t; 14 | typedef int32_t sem_t; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/philosopher/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | 13 | app.bin: $(UOBJS) 14 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o philosopher.elf $(UOBJS) 15 | 16 | clean: 17 | rm -rf $(UOBJS) philosopher.elf 18 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/philosopher/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | #define N 5 5 | 6 | sem_t forks[5]; 7 | 8 | static unsigned long next = 48; 9 | 10 | int myrand() 11 | { 12 | read(SH_MEM, (uint8_t *)&next, 4, 24); 13 | next = next * 1103515245 + 12345; 14 | write(SH_MEM, (uint8_t *)&next, 4, 24); 15 | return ((unsigned)(next / 65536) % 231) + 83; 16 | } 17 | 18 | void philosopher(int i) 19 | { 20 | int id = getpid() - 2; 21 | while (1) 22 | { 23 | printf("Philosopher %d: think\n", id); 24 | sleep(myrand()); 25 | if (i % 2 == 0) 26 | { 27 | sem_wait(forks + i); 28 | sleep(myrand()); 29 | sem_wait(forks + ((i + 1) % N)); 30 | sleep(myrand()); 31 | } 32 | else 33 | { 34 | sem_wait(forks + ((i + 1) % N)); 35 | sleep(myrand()); 36 | sem_wait(forks + i); 37 | sleep(myrand()); 38 | } 39 | printf("Philosopher %d: eat\n", id); 40 | sleep(myrand()); 41 | sem_post(forks + i); 42 | sleep(myrand()); 43 | sem_post(forks + ((i + 1) % N)); 44 | sleep(myrand()); 45 | } 46 | } 47 | 48 | int main(void) 49 | { 50 | // TODO in lab4 51 | printf("philosopher\n"); 52 | for (int i = 0; i < 5; i++) 53 | { 54 | sem_init(forks + i, 1); 55 | } 56 | write(SH_MEM, (uint8_t *)&next, 4, 24); 57 | int ret = 1; 58 | for (int i = 0; i < 5; i++) 59 | { 60 | if (ret > 0) 61 | ret = fork(); 62 | } 63 | if (getpid() > 1) 64 | { 65 | sleep(myrand()); 66 | philosopher(getpid() - 2); 67 | } 68 | 69 | while (1); 70 | for (int i = 0; i < 5; i++) 71 | { 72 | sem_destroy(forks + i); 73 | } 74 | exit(); 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/reader_writer/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | 13 | app.bin: $(UOBJS) 14 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o reader_writer.elf $(UOBJS) 15 | 16 | clean: 17 | rm -rf $(UOBJS) reader_writer.elf 18 | 19 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/reader_writer/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | static unsigned long next = 97; 5 | 6 | int myrand() 7 | { 8 | read(SH_MEM, (uint8_t *)&next, 4, 24); 9 | next = next * 1103515245 + 12345; 10 | write(SH_MEM, (uint8_t *)&next, 4, 24); 11 | return ((unsigned)(next / 65536) % 211) + 83; 12 | } 13 | 14 | void writer(sem_t *writemutex) 15 | { 16 | int id = getpid() - 3 - 2; 17 | while (1) 18 | { 19 | sem_wait(writemutex); 20 | sleep(myrand()); 21 | printf("Writer %d: write\n", id); 22 | sleep(myrand()); 23 | sem_post(writemutex); 24 | sleep(myrand()); 25 | } 26 | } 27 | 28 | void reader(sem_t *writemutex, sem_t *countmutex, int *rcount) 29 | { 30 | int id = getpid() - 2; 31 | while (1) 32 | { 33 | sem_wait(countmutex); 34 | sleep(myrand()); 35 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 36 | if (*rcount == 0) 37 | { 38 | sem_wait(writemutex); 39 | sleep(myrand()); 40 | } 41 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 42 | ++(*rcount); 43 | write(SH_MEM, (uint8_t *)rcount, 4, 12); 44 | sleep(myrand()); 45 | sem_post(countmutex); 46 | sleep(myrand()); 47 | printf("Reader %d: read, total %d reader\n", id, *rcount); 48 | sleep(myrand()); 49 | sem_wait(countmutex); 50 | sleep(myrand()); 51 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 52 | --(*rcount); 53 | write(SH_MEM, (uint8_t *)rcount, 4, 12); 54 | sleep(myrand()); 55 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 56 | if (*rcount == 0) 57 | { 58 | sem_post(writemutex); 59 | sleep(myrand()); 60 | } 61 | sem_post(countmutex); 62 | sleep(myrand()); 63 | } 64 | } 65 | 66 | int main(void) 67 | { 68 | // TODO in lab4 69 | printf("reader_writer\n"); 70 | sem_t writemutex, countmutex; 71 | sem_init(&writemutex, 1); 72 | sem_init(&countmutex, 1); 73 | int rcount = 0; 74 | write(SH_MEM, (uint8_t *)&rcount, 4, 12); 75 | write(SH_MEM, (uint8_t *)&next, 4, 24); 76 | int ret = 1; 77 | for (int i = 0; i < 6; i++) 78 | { 79 | if (ret > 0) 80 | ret = fork(); 81 | } 82 | int id = getpid(); 83 | if (id > 1 && id < 5) 84 | { 85 | sleep(myrand()); 86 | reader(&writemutex, &countmutex, &rcount); 87 | } 88 | else if (id > 4 && id < 8) 89 | { 90 | sleep(myrand()); 91 | writer(&writemutex); 92 | } 93 | 94 | while (1); 95 | sem_destroy(&writemutex); 96 | sem_destroy(&countmutex); 97 | exit(); 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genBoot.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 1000); 6 | 7 | if($n > 510){ 8 | print STDERR "ERROR: boot block too large: $n bytes (max 510)\n"; 9 | exit 1; 10 | } 11 | 12 | print STDERR "OK: boot block is $n bytes (max 510)\n"; 13 | 14 | $buf .= "\0" x (510-$n); 15 | $buf .= "\x55\xAA"; 16 | 17 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 18 | print SIG $buf; 19 | close SIG; 20 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genFS/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | 3 | CFLAGS = -g 4 | #CFLAGS = -m32 -g 5 | 6 | CFILES = $(shell find ./ -name "*.c") 7 | OBJS = $(CFILES:.c=.o) 8 | 9 | genFS: $(CFILES) 10 | $(CC) $(CFLAGS) -o genFS $(CFILES) 11 | 12 | clean: 13 | @#rm -rf $(OBJS) genFS fs.bin 14 | rm -rf $(OBJS) genFS -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genFS/func.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_H__ 2 | #define __FUNC_H__ 3 | 4 | int format (const char *driver, int sectorNum, int sectorsPerBlock); 5 | 6 | int mkdir (const char *driver, const char *destDirPath); 7 | 8 | int rmdir (const char *driver, const char *destDirPath); 9 | 10 | int cp (const char *driver, const char *srcFilePath, const char *destFilePath); 11 | 12 | int rm (const char *driver, const char *destFilePath); 13 | 14 | int ls (const char *driver, const char *destFilePath); 15 | 16 | int touch (const char *driver, const char *destFilePath); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genFS/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | #include "data.h" 4 | #include "func.h" 5 | 6 | int main(int argc, char *argv[]) { 7 | char driver[NAME_LENGTH]; 8 | char srcFilePath[NAME_LENGTH]; 9 | char destFilePath[NAME_LENGTH]; 10 | 11 | stringCpy("fs.bin", driver, NAME_LENGTH - 1); 12 | format(driver, SECTOR_NUM, SECTORS_PER_BLOCK); 13 | 14 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 15 | mkdir(driver, destFilePath); 16 | 17 | stringCpy(argv[1], srcFilePath, NAME_LENGTH - 1); 18 | stringCpy("/boot/initrd", destFilePath, NAME_LENGTH - 1); 19 | cp(driver, srcFilePath, destFilePath); 20 | 21 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 22 | mkdir(driver, destFilePath); 23 | 24 | stringCpy(argv[2], srcFilePath, NAME_LENGTH - 1); 25 | stringCpy("/usr/print", destFilePath, NAME_LENGTH - 1); 26 | cp(driver, srcFilePath, destFilePath); 27 | 28 | stringCpy(argv[3], srcFilePath, NAME_LENGTH - 1); 29 | stringCpy("/usr/bounded_buffer", destFilePath, NAME_LENGTH - 1); 30 | cp(driver, srcFilePath, destFilePath); 31 | 32 | stringCpy(argv[4], srcFilePath, NAME_LENGTH - 1); 33 | stringCpy("/usr/philosopher", destFilePath, NAME_LENGTH - 1); 34 | cp(driver, srcFilePath, destFilePath); 35 | 36 | stringCpy(argv[5], srcFilePath, NAME_LENGTH - 1); 37 | stringCpy("/usr/reader_writer", destFilePath, NAME_LENGTH - 1); 38 | cp(driver, srcFilePath, destFilePath); 39 | 40 | stringCpy("/", destFilePath, NAME_LENGTH - 1); 41 | ls(driver, destFilePath); 42 | 43 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 44 | ls(driver, destFilePath); 45 | 46 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 47 | ls(driver, destFilePath); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genFS/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef unsigned short uint16_t; 6 | typedef unsigned char uint8_t; 7 | 8 | typedef int int32_t; 9 | typedef short int16_t; 10 | typedef char int8_t; 11 | 12 | // #define NULL ((void*)0) 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genFS/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | /* 5 | * find the first token in string 6 | * set *size as the number of bytes before token 7 | * if not found, set *size as the length of *string 8 | */ 9 | int stringChr (const char *string, char token, int *size) { 10 | int i = 0; 11 | if (string == NULL) { 12 | *size = 0; 13 | return -1; 14 | } 15 | while (string[i] != 0) { 16 | if (token == string[i]) { 17 | *size = i; 18 | return 0; 19 | } 20 | else 21 | i ++; 22 | } 23 | *size = i; 24 | return -1; 25 | } 26 | 27 | /* 28 | * find the last token in string 29 | * set *size as the number of bytes before token 30 | * if not found, set *size as the length of *string 31 | */ 32 | int stringChrR (const char *string, char token, int *size) { 33 | int i = 0; 34 | if (string == NULL) { 35 | *size = 0; 36 | return -1; 37 | } 38 | while (string[i] != 0) 39 | i ++; 40 | *size = i; 41 | while (i > -1) { 42 | if (token == string[i]) { 43 | *size = i; 44 | return 0; 45 | } 46 | else 47 | i --; 48 | } 49 | return -1; 50 | } 51 | 52 | int stringLen (const char *string) { 53 | int i = 0; 54 | if (string == NULL) 55 | return 0; 56 | while (string[i] != 0) 57 | i ++; 58 | return i; 59 | } 60 | 61 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 62 | int i = 0; 63 | if (srcString == NULL || destString == NULL) 64 | return -1; 65 | while (i != size) { 66 | if (srcString[i] != destString[i]) 67 | return -1; 68 | else if (srcString[i] == 0) 69 | return 0; 70 | else 71 | i ++; 72 | } 73 | return 0; 74 | } 75 | 76 | int stringCpy (const char *srcString, char *destString, int size) { 77 | int i = 0; 78 | if (srcString == NULL || destString == NULL) 79 | return -1; 80 | while (i != size) { 81 | if (srcString[i] != 0) { 82 | destString[i] = srcString[i]; 83 | i++; 84 | } 85 | else 86 | break; 87 | } 88 | destString[i] = 0; 89 | return 0; 90 | } 91 | 92 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 93 | int i = 0; 94 | if (buffer == NULL) 95 | return -1; 96 | for (i = 0; i < size ; i ++) 97 | buffer[i] = value; 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genFS/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | #include "types.h" 5 | 6 | int stringChr(const char *string, char token, int *size); 7 | 8 | int stringChrR (const char *string, char token, int *size); 9 | 10 | int stringLen(const char *string); 11 | 12 | int stringCmp(const char *srcString, const char *destString, int size); 13 | 14 | int stringCpy (const char *srcString, char *destString, int size); 15 | 16 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 17 | 18 | #endif -------------------------------------------------------------------------------- /lab4-181860013/lab4/utils/genKernel.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 100000); 6 | 7 | print STDERR "OK: Kernel is $n bytes - Extended to 200 sectors\n"; 8 | 9 | $buf .= "\0" x (102400-$n); 10 | 11 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 12 | print SIG $buf; 13 | close SIG; 14 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/Makefile: -------------------------------------------------------------------------------- 1 | QEMU = qemu-system-i386 2 | 3 | os.img: 4 | @cd utils/genFS; make 5 | @cd bootloader; make 6 | @cd kernel; make 7 | @cd bounded_buffer; make 8 | @cd philosopher; make 9 | @cd reader_writer; make 10 | @cd app_print; make 11 | @cd app; make 12 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.bin > os.img 13 | @#cat bootloader/bootloader.bin kernel/kMain.bin app/uMain.elf > os.img 14 | @#cat bootloader/bootloader.bin kernel/kMain.elf app/uMain.elf > os.img 15 | @./utils/genFS/genFS app/uMain.elf app_print/app_print.elf bounded_buffer/bounded_buffer.elf philosopher/philosopher.elf reader_writer/reader_writer.elf 16 | cat bootloader/bootloader.bin kernel/kMain.elf fs.bin > os.img 17 | 18 | play: os.img 19 | $(QEMU) -serial stdio os.img 20 | 21 | debug: os.img 22 | $(QEMU) -serial stdio -s -S os.img 23 | 24 | clean: 25 | @cd utils/genFS; make clean 26 | @cd bootloader; make clean 27 | @cd kernel; make clean 28 | @cd bounded_buffer; make clean 29 | @cd philosopher; make clean 30 | @cd reader_writer; make clean 31 | @cd app_print; make clean 32 | @cd app; make clean 33 | rm -f fs.bin os.img 34 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/app/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | #UOBJS = $(LCFILES:.c=.o) $(UCFILES:.c=.o) 13 | 14 | umain.bin: $(UOBJS) 15 | @#$(LD) $(LDFLAGS) -e uEntry -Ttext 0x00200000 -o uMain.elf $(UOBJS) 16 | $(LD) $(LDFLAGS) -e uEntry -Ttext 0x00000000 -o uMain.elf $(UOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary uMain.elf uMain.bin 18 | @#objcopy -O binary uMain.elf uMain.bin 19 | 20 | clean: 21 | @#rm -rf $(UOBJS) uMain.elf uMain.bin 22 | rm -rf $(UOBJS) uMain.elf 23 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/app/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | int uEntry(void) 5 | { 6 | /* 7 | int dec = 0; 8 | int hex = 0; 9 | char str[6]; 10 | char cha = 0; 11 | int ret = 0; 12 | while (1) 13 | { 14 | printf("Input:\" Test %%c Test %%6s %%d %%x\"\n"); 15 | ret = scanf(" Test %c Test %6s %d %x", &cha, str, &dec, &hex); 16 | printf("Ret: %d; %c, %s, %d, %x.\n", ret, cha, str, dec, hex); 17 | if (ret == 4) 18 | break; 19 | } 20 | 21 | int data = 2020; 22 | int data1 = 1000; 23 | int i = 4; 24 | int ret = fork(); 25 | if (ret == 0) 26 | { 27 | while (i != 0) 28 | { 29 | i--; 30 | printf("Child Process: %d, %d\n", data, data1); 31 | write(SH_MEM, (uint8_t *)&data, 4, 0); // define SH_MEM 3 32 | data += data1; 33 | sleep(128); 34 | } 35 | exit(); 36 | } 37 | else if (ret != -1) 38 | { 39 | while (i != 0) 40 | { 41 | i--; 42 | read(SH_MEM, (uint8_t *)&data1, 4, 0); 43 | printf("Father Process: %d, %d\n", data, data1); 44 | sleep(128); 45 | } 46 | exit(); 47 | } 48 | 49 | int i = 4; 50 | int ret = 0; 51 | int value = 2; 52 | sem_t sem; 53 | printf("Father Process: Semaphore Initializing.\n"); 54 | ret = sem_init(&sem, value); 55 | if (ret == -1) 56 | { 57 | printf("Father Process: Semaphore Initializing Failed.\n"); 58 | exit(); 59 | } 60 | ret = fork(); 61 | if (ret == 0) 62 | { 63 | while (i != 0) 64 | { 65 | i--; 66 | printf("Child Process: Semaphore Waiting.\n"); 67 | sem_wait(&sem); 68 | printf("Child Process: In Critical Area.\n"); 69 | } 70 | printf("Child Process: Semaphore Destroying.\n"); 71 | sem_destroy(&sem); 72 | exit(); 73 | } 74 | else if (ret != -1) 75 | { 76 | while (i != 0) 77 | { 78 | i--; 79 | printf("Father Process: Sleeping.\n"); 80 | sleep(128); 81 | printf("Father Process: Semaphore Posting.\n"); 82 | sem_post(&sem); 83 | } 84 | printf("Father Process: Semaphore Destroying.\n"); 85 | sem_destroy(&sem); 86 | exit(); 87 | } 88 | */ 89 | char ch; 90 | printf("Input: 1 for bounded_buffer\n 2 for philosopher\n 3 for reader_writer\n"); 91 | scanf("%c", &ch); 92 | switch (ch) 93 | { 94 | case '1': 95 | exec("/usr/bounded_buffer", 0); 96 | break; 97 | case '2': 98 | exec("/usr/philosopher", 0); 99 | break; 100 | case '3': 101 | exec("/usr/reader_writer", 0); 102 | break; 103 | default: 104 | break; 105 | } 106 | exit(); 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/app_print/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | #UOBJS = $(LCFILES:.c=.o) $(UCFILES:.c=.o) 13 | 14 | app_print.bin: $(UOBJS) 15 | @#$(LD) $(LDFLAGS) -e uEntry -Ttext 0x00200000 -o uMain.elf $(UOBJS) 16 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o app_print.elf $(UOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary uMain.elf uMain.bin 18 | @#objcopy -O binary uMain.elf uMain.bin 19 | 20 | clean: 21 | @#rm -rf $(UOBJS) uMain.elf uMain.bin 22 | rm -rf $(UOBJS) app_print.elf 23 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/app_print/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | int main(void) { 5 | printf("printf test begin...\n"); 6 | printf("the answer should be:\n"); 7 | printf("#######################################################\n"); 8 | printf("Hello, welcome to OSlab! I'm the body of the game. "); 9 | printf("Bootblock loads me to the memory position of 0x100000, and Makefile also tells me that I'm at the location of 0x100000. "); 10 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 11 | printf("Now I will test your printf: "); 12 | printf("1 + 1 = 2, 123 * 456 = 56088\n0, -1, -2147483648, -1412567295, -32768, 102030\n0, ffffffff, 80000000, abcdef01, ffff8000, 18e8e\n"); 13 | printf("#######################################################\n"); 14 | printf("your answer:\n"); 15 | printf("=======================================================\n"); 16 | printf("%s %s%scome %co%s", "Hello,", "", "wel", 't', " "); 17 | printf("%c%c%c%c%c! ", 'O', 'S', 'l', 'a', 'b'); 18 | printf("I'm the %s of %s. %s 0x%x, %s 0x%x. ", "body", "the game", "Bootblock loads me to the memory position of", 0x100000, "and Makefile also tells me that I'm at the location of", 0x100000); 19 | printf("\\%%~!@#/(^&*()_+`1234567890-=...... "); 20 | printf("Now I will test your printf: "); 21 | printf("%d + %d = %d, %d * %d = %d\n", 1, 1, 1 + 1, 123, 456, 123 * 456); 22 | printf("%d, %d, %d, %d, %d, %d\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 23 | printf("%x, %x, %x, %x, %x, %x\n", 0, 0xffffffff, 0x80000000, 0xabcdef01, -32768, 102030); 24 | printf("=======================================================\n"); 25 | printf("Test end!!! Good luck!!!\n"); 26 | 27 | exit(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/bootloader/Makefile: -------------------------------------------------------------------------------- 1 | #bootloader.bin: start.S boot.c boot.h 2 | # gcc -c -m32 start.S -o start.o 3 | # gcc -c -m32 -O1 -fno-stack-protector boot.c -o boot.o 4 | # ld -m elf_i386 -e start -Ttext 0x7c00 start.o boot.o -o bootloader.elf 5 | # @#ld -m elf_i386 -e start -Ttext 0x7c00 boot.o start.o -o bootloader.elf 6 | # @#objcopy -S -j .text -O binary bootloader.elf bootloader.bin 7 | # objcopy -O binary bootloader.elf bootloader.bin 8 | # ../utils/genBoot.pl bootloader.bin 9 | # 10 | #clean: 11 | # rm -rf *.o *.elf *.bin 12 | 13 | # take care of link order of object files 14 | # -Ttext set the address of the first byte of the text segment 15 | # -e set the entry address in elf-header 16 | # i.e., the entry address may not be the address of the first byte of the text segment 17 | 18 | CC = gcc 19 | LD = ld 20 | 21 | CFLAGS = -m32 -march=i386 -static \ 22 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 23 | -Wall -Werror -O2 24 | ASFLAGS = -m32 25 | LDFLAGS = -m elf_i386 26 | 27 | BSFILES = $(shell find ./ -name "*.S") 28 | BCFILES = $(shell find ./ -name "*.c") 29 | BOBJS = $(BSFILES:.S=.o) $(BCFILES:.c=.o) 30 | 31 | bootloader.bin: $(BOBJS) 32 | $(LD) $(LDFLAGS) -e start -Ttext 0x7c00 -o bootloader.elf $(BOBJS) 33 | objcopy -S -j .text -O binary bootloader.elf bootloader.bin 34 | @../utils/genBoot.pl bootloader.bin 35 | 36 | clean: 37 | rm -rf $(BOBJS) bootloader.elf bootloader.bin 38 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/bootloader/boot.c: -------------------------------------------------------------------------------- 1 | #include "boot.h" 2 | 3 | #define SECTSIZE 512 4 | 5 | /* 6 | void bootMain(void) { 7 | int i = 0; 8 | void (*elf)(void); 9 | elf = (void(*)(void))0x100000; // kernel is loaded to location 0x100000 10 | for (i = 0; i < 200; i ++) { 11 | //readSect((void*)elf + i*512, i+1); 12 | readSect((void*)elf + i*512, i+9); 13 | } 14 | elf(); // jumping to the loaded program 15 | } 16 | */ 17 | 18 | void bootMain(void) { 19 | int i = 0; 20 | int phoff = 0x34; 21 | int offset = 0x1000; 22 | unsigned int elf = 0x100000; 23 | void (*kMainEntry)(void); 24 | kMainEntry = (void(*)(void))0x100000; 25 | 26 | for (i = 0; i < 200; i++) { 27 | readSect((void*)(elf + i*512), 1+i); 28 | } 29 | 30 | kMainEntry = (void(*)(void))((struct ELFHeader *)elf)->entry; 31 | phoff = ((struct ELFHeader *)elf)->phoff; 32 | offset = ((struct ProgramHeader *)(elf + phoff))->off; 33 | 34 | for (i = 0; i < 200 * 512; i++) { 35 | *(unsigned char *)(elf + i) = *(unsigned char *)(elf + i + offset); 36 | } 37 | 38 | kMainEntry(); 39 | } 40 | 41 | void waitDisk(void) { // waiting for disk 42 | while((inByte(0x1F7) & 0xC0) != 0x40); 43 | } 44 | 45 | void readSect(void *dst, int offset) { // reading a sector of disk 46 | int i; 47 | waitDisk(); 48 | outByte(0x1F2, 1); 49 | outByte(0x1F3, offset); 50 | outByte(0x1F4, offset >> 8); 51 | outByte(0x1F5, offset >> 16); 52 | outByte(0x1F6, (offset >> 24) | 0xE0); 53 | outByte(0x1F7, 0x20); 54 | 55 | waitDisk(); 56 | for (i = 0; i < SECTSIZE / 4; i ++) { 57 | ((int *)dst)[i] = inLong(0x1F0); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/bootloader/boot.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOT_H 2 | #define BOOT_H 3 | 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | void waitDisk(void); 35 | 36 | void readSect(void *dst, int offset); 37 | 38 | /* I/O functions */ 39 | static inline char inByte(short port) { 40 | char data; 41 | asm volatile("in %1,%0" : "=a" (data) : "d" (port)); 42 | return data; 43 | } 44 | 45 | static inline int inLong(short port) { 46 | int data; 47 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 48 | return data; 49 | } 50 | 51 | static inline void outByte(short port, char data) { 52 | asm volatile("out %0,%1" : : "a" (data), "d" (port)); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/bounded_buffer/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | 13 | app.bin: $(UOBJS) 14 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o bounded_buffer.elf $(UOBJS) 15 | 16 | clean: 17 | rm -rf $(UOBJS) bounded_buffer.elf 18 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/bounded_buffer/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | static unsigned long next = 61; 5 | 6 | int myrand() 7 | { 8 | read(SH_MEM, (uint8_t *)&next, 4, 24); 9 | next = next * 1103515245 + 12345; 10 | write(SH_MEM, (uint8_t *)&next, 4, 24); 11 | return ((unsigned)(next / 65536) % 211) + 53; 12 | } 13 | 14 | void producer(sem_t *mutex, sem_t *full, sem_t *empty) 15 | { 16 | int id = getpid() - 2; 17 | while (1) 18 | { 19 | sem_wait(empty); 20 | sleep(myrand()); 21 | sem_wait(mutex); 22 | sleep(myrand()); 23 | printf("Producer %d: produce\n", id); 24 | sleep(myrand()); 25 | sem_post(mutex); 26 | sleep(myrand()); 27 | sem_post(full); 28 | sleep(myrand()); 29 | } 30 | } 31 | 32 | void consumer(sem_t *mutex, sem_t *full, sem_t *empty) 33 | { 34 | while (1) 35 | { 36 | sem_wait(full); 37 | sleep(myrand()); 38 | sem_wait(mutex); 39 | sleep(myrand()); 40 | printf("Consumer : consume\n"); 41 | sleep(myrand()); 42 | sem_post(mutex); 43 | sleep(myrand()); 44 | sem_post(empty); 45 | sleep(myrand()); 46 | } 47 | } 48 | 49 | int main(void) 50 | { 51 | // TODO in lab4 52 | printf("bounded_buffer\n"); 53 | sem_t mutex, fullBuffers, emptyBuffers; 54 | sem_init(&mutex, 1); 55 | sem_init(&fullBuffers, 0); 56 | sem_init(&emptyBuffers, 5); 57 | write(SH_MEM, (uint8_t *)&next, 4, 24); 58 | int ret = 1; 59 | for (int i = 0; i < 5; i++) 60 | { 61 | if (ret > 0) 62 | ret = fork(); 63 | } 64 | int id = getpid(); 65 | if (id > 1 && id < 6) 66 | { 67 | sleep(myrand()); 68 | producer(&mutex, &fullBuffers, &emptyBuffers); 69 | } 70 | else if (id == 6) 71 | { 72 | consumer(&mutex, &fullBuffers, &emptyBuffers); 73 | } 74 | 75 | while (1); 76 | sem_destroy(&mutex); 77 | sem_destroy(&fullBuffers); 78 | sem_destroy(&emptyBuffers); 79 | exit(); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O0 -I./include 7 | ASFLAGS = -m32 8 | LDFLAGS = -m elf_i386 9 | 10 | KCFILES = $(shell find ./ -name "*.c") 11 | KSFILES = $(shell find ./ -name "*.S") 12 | KOBJS = $(KCFILES:.c=.o) $(KSFILES:.S=.o) 13 | #KOBJS = $(KSFILES:.S=.o) $(KCFILES:.c=.o) 14 | 15 | kmain.bin: $(KOBJS) 16 | $(LD) $(LDFLAGS) -e kEntry -Ttext 0x00100000 -o kMain.elf $(KOBJS) 17 | @#objcopy -S -j .text -j .rodata -j .eh_frame -j .data -j .bss -O binary kMain.elf kMain.bin 18 | @#objcopy -O binary kMain.elf kMain.bin 19 | @../utils/genKernel.pl kMain.elf 20 | @#../utils/genKernel.pl kMain.bin 21 | 22 | 23 | clean: 24 | @#rm -rf $(KOBJS) kMain.elf kMain.bin 25 | rm -rf $(KOBJS) kMain.elf kMain.bin 26 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include "common/types.h" 5 | #include "common/const.h" 6 | #include "common/assert.h" 7 | #include "common/utils.h" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/common/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASSERT_H__ 2 | #define __ASSERT_H__ 3 | 4 | int abort(const char *, int); 5 | 6 | /* assert: 断言条件为真,若为假则蓝屏退出 */ 7 | #define assert(cond) \ 8 | ((cond) ? (0) : (abort(__FILE__, __LINE__))) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/common/const.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONST_H__ 2 | #define __CONST_H__ 3 | 4 | #define TRUE 1 5 | #define FALSE 0 6 | 7 | #define NULL ((void*)0) 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/common/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | /* 定义数据类型 */ 5 | typedef unsigned int uint32_t; 6 | typedef int int32_t; 7 | typedef unsigned short uint16_t; 8 | typedef short int16_t; 9 | typedef unsigned char uint8_t; 10 | typedef char int8_t; 11 | typedef unsigned int size_t; 12 | #endif 13 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/common/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | int stringChr(const char *string, char token, int *size); 5 | 6 | int stringChrR (const char *string, char token, int *size); 7 | 8 | int stringLen(const char *string); 9 | 10 | int stringCmp(const char *srcString, const char *destString, int size); 11 | 12 | int stringCpy (const char *srcString, char *destString, int size); 13 | 14 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 15 | 16 | #endif -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/device.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVICE_H__ 2 | #define __DEVICE_H__ 3 | 4 | #include "device/serial.h" 5 | #include "device/disk.h" 6 | #include "device/vga.h" 7 | #include "device/timer.h" 8 | #include "device/keyboard.h" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/device/disk.h: -------------------------------------------------------------------------------- 1 | #ifndef __DISK_H__ 2 | #define __DISK_H__ 3 | 4 | #define SECTOR_NUM 8192 5 | #define SECTOR_SIZE 512 6 | 7 | void waitDisk(void); 8 | void readSect(void *dst, int offset); 9 | void writeSect(void *src, int offset); 10 | 11 | void diskRead(void *destBuffer, int size, int num, int offset); 12 | void diskWrite(void *destBuffer, int size, int num, int offset); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/device/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYBOARD_H__ 2 | #define __KEYBOARD_H__ 3 | 4 | #define MAX_KEYBUFFER_SIZE 256 5 | 6 | void initKeyTable(); 7 | 8 | uint32_t getKeyCode(); 9 | 10 | char getChar(uint32_t code); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/device/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERIAL_H__ 2 | #define __SERIAL_H__ 3 | 4 | void initSerial(void); 5 | void putChar(char); 6 | void putString(const char *); 7 | void putInt(int); 8 | 9 | #define SERIAL_PORT 0x3F8 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/device/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_H__ 2 | #define __TIMER_H__ 3 | 4 | void initTimer(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/device/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef __VGA_H__ 2 | #define __VGA_H__ 3 | 4 | void initVga(); 5 | void clearScreen(); 6 | void updateCursor(int row, int col); 7 | void scrollScreen(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef __FS_H__ 2 | #define __FS_H__ 3 | 4 | #include "fs/minix.h" 5 | 6 | int readSuperBlock (SuperBlock *superBlock); 7 | 8 | int allocInode (SuperBlock *superBlock, 9 | Inode *fatherInode, 10 | int fatherInodeOffset, 11 | Inode *destInode, 12 | int *destInodeOffset, 13 | const char *destFilename, 14 | int destFiletype); 15 | 16 | int freeInode (SuperBlock *superBlock, 17 | Inode *fatherInode, 18 | int fatherInodeOffset, 19 | Inode *destInode, 20 | int *destInodeOffset, 21 | const char *destFilename, 22 | int destFiletype); 23 | 24 | int readInode (SuperBlock *superBlock, 25 | Inode *destInode, 26 | int *inodeOffset, 27 | const char *destFilePath); 28 | 29 | int allocBlock (SuperBlock *superBlock, 30 | Inode *inode, 31 | int inodeOffset); 32 | 33 | int readBlock (SuperBlock *superBlock, 34 | Inode *inode, 35 | int blockIndex, 36 | uint8_t *buffer); 37 | 38 | int writeBlock (SuperBlock *superBlock, 39 | Inode *inode, 40 | int blockIndex, 41 | uint8_t *buffer); 42 | 43 | int getDirEntry (SuperBlock *superBlock, 44 | Inode *inode, 45 | int dirIndex, 46 | DirEntry *destDirEntry); 47 | 48 | void initFS (void); 49 | 50 | void initFile (void); 51 | 52 | #endif /* __FS_H__ */ 53 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/fs/minix.h: -------------------------------------------------------------------------------- 1 | #ifndef __MINIX_H__ 2 | #define __MINIX_H__ 3 | 4 | /* 5 | * minix like filesystem 6 | */ 7 | 8 | /* 9 | * Layout of file system 10 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 11 | *| SuperBlock | InodeBitmap | BlockBitmap | InodeTable | DataBlocks | 12 | *+--------------------+-------------------+--------------------+--------------------+--------------------+ 13 | * 1024 Bytes 1 Block 1 Block 128 Blocks Many More Blocks 14 | * 15 | */ 16 | 17 | #define SECTORS_PER_BLOCK 2 18 | #define POINTER_NUM 14 19 | #define NAME_LENGTH 64 20 | 21 | #define BLOCK_SIZE (SECTOR_SIZE * SECTORS_PER_BLOCK) 22 | #define SUPER_BLOCK_SIZE BLOCK_SIZE 23 | #define INODE_BITMAP_SIZE BLOCK_SIZE 24 | #define BLOCK_BITMAP_SIZE BLOCK_SIZE 25 | #define INODE_SIZE 128 26 | #define DIRENTRY_SIZE 128 27 | #define INODE_BLOCKS (SECTOR_NUM / SECTORS_PER_BLOCK / 32) 28 | 29 | #define UNKNOWN_TYPE 0 30 | #define REGULAR_TYPE 1 31 | #define DIRECTORY_TYPE 2 32 | #define CHARACTER_TYPE 3 33 | #define BLOCK_TYPE 4 34 | #define FIFO_TYPE 5 35 | #define SOCKET_TYPE 6 36 | #define SYMBOLIC_TYPE 7 37 | 38 | union SuperBlock { 39 | uint8_t byte[SUPER_BLOCK_SIZE]; 40 | struct { 41 | int32_t sectorNum; // total number of sectors 42 | int32_t inodeNum; // total number of inodes 43 | int32_t blockNum; // total number of data blocks 44 | int32_t availInodeNum; // total number of available inodes 45 | int32_t availBlockNum; // total number of available data blocks 46 | int32_t blockSize; // number of bytes in each block 47 | int32_t inodeBitmap; // XXX sector as unit 48 | int32_t blockBitmap; // XXX sector as unit 49 | int32_t inodeTable; // XXX sector as unit 50 | int32_t blocks; // XXX sector as unit 51 | }; 52 | }; 53 | typedef union SuperBlock SuperBlock; 54 | 55 | struct InodeBitmap { 56 | uint8_t byte[INODE_BITMAP_SIZE]; 57 | }; 58 | typedef struct InodeBitmap InodeBitmap; 59 | 60 | struct BlockBitmap { 61 | uint8_t byte[BLOCK_BITMAP_SIZE]; 62 | }; 63 | typedef struct BlockBitmap BlockBitmap; 64 | 65 | union Inode { 66 | uint8_t byte[INODE_SIZE]; 67 | struct { 68 | int16_t type; 69 | int16_t linkCount; 70 | int32_t blockCount; 71 | int32_t size; 72 | int32_t pointer[POINTER_NUM]; // XXX sector as unit 73 | int32_t singlyPointer; // XXX sector as unit 74 | }; 75 | }; 76 | typedef union Inode Inode; 77 | 78 | union DirEntry { 79 | uint8_t byte[DIRENTRY_SIZE]; 80 | struct { 81 | int32_t inode; // index in inode table, started from 1, 0 for unused. 82 | char name[NAME_LENGTH]; 83 | }; 84 | }; 85 | typedef union DirEntry DirEntry; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/x86.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_H__ 2 | #define __X86_H__ 3 | 4 | #include "x86/cpu.h" 5 | #include "x86/memory.h" 6 | #include "x86/io.h" 7 | #include "x86/irq.h" 8 | 9 | void initSeg(void); 10 | void initSem(void); 11 | void initDev(void); 12 | void initProc(void); 13 | int loadElf(const char *filename, uint32_t physAddr, uint32_t *entry); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/x86/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_CPU_H__ 2 | #define __X86_CPU_H__ 3 | 4 | #include "common.h" 5 | 6 | /* 将CPU置入休眠状态直到下次中断到来 */ 7 | static inline void waitForInterrupt() { 8 | asm volatile("hlt"); 9 | } 10 | 11 | /* 修改IDTR */ 12 | static inline void saveIdt(void *addr, uint32_t size) { 13 | static volatile uint16_t data[3]; 14 | data[0] = size - 1; 15 | data[1] = (uint32_t)addr; 16 | data[2] = ((uint32_t)addr) >> 16; 17 | asm volatile("lidt (%0)" : : "r"(data)); 18 | } 19 | 20 | /* 打开外部中断 */ 21 | static inline void enableInterrupt(void) { 22 | asm volatile("sti"); 23 | } 24 | 25 | /* 关闭外部中断 */ 26 | static inline void disableInterrupt(void) { 27 | asm volatile("cli"); 28 | } 29 | 30 | #define NR_IRQ 256 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/x86/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_IO_H__ 2 | #define __X86_IO_H__ 3 | /* ELF32二进制文件头 */ 4 | struct ELFHeader { 5 | unsigned int magic; 6 | unsigned char elf[12]; 7 | unsigned short type; 8 | unsigned short machine; 9 | unsigned int version; 10 | unsigned int entry; 11 | unsigned int phoff; 12 | unsigned int shoff; 13 | unsigned int flags; 14 | unsigned short ehsize; 15 | unsigned short phentsize; 16 | unsigned short phnum; 17 | unsigned short shentsize; 18 | unsigned short shnum; 19 | unsigned short shstrndx; 20 | }; 21 | 22 | /* ELF32 Program header */ 23 | struct ProgramHeader { 24 | unsigned int type; 25 | unsigned int off; 26 | unsigned int vaddr; 27 | unsigned int paddr; 28 | unsigned int filesz; 29 | unsigned int memsz; 30 | unsigned int flags; 31 | unsigned int align; 32 | }; 33 | 34 | 35 | static inline int inLong(short port) { 36 | int data; 37 | asm volatile("in %1, %0" : "=a" (data) : "d" (port)); 38 | return data; 39 | } 40 | 41 | static inline void outLong(uint16_t port, uint32_t data) { 42 | asm volatile("out %0, %1" : : "a"(data), "d"(port)); 43 | } 44 | 45 | /* 读I/O端口 */ 46 | static inline uint8_t inByte(uint16_t port) { 47 | uint8_t data; 48 | asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 49 | return data; 50 | } 51 | 52 | /* 写I/O端口 */ 53 | static inline void outByte(uint16_t port, int8_t data) { 54 | asm volatile("out %%al, %%dx" : : "a"(data), "d"(port)); 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/include/x86/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __IRQ_H__ 2 | #define __IRQ_H__ 3 | 4 | /* 中断处理相关函数 */ 5 | void initIdt(void); 6 | void initIntr(void); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/kernel/disk.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define SECTSIZE 512 5 | 6 | void waitDisk(void) { 7 | while((inByte(0x1F7) & 0xC0) != 0x40); 8 | } 9 | 10 | void readSect(void *dst, int offset) { 11 | int i; 12 | waitDisk(); 13 | 14 | outByte(0x1F2, 1); 15 | outByte(0x1F3, offset); 16 | outByte(0x1F4, offset >> 8); 17 | outByte(0x1F5, offset >> 16); 18 | outByte(0x1F6, (offset >> 24) | 0xE0); 19 | outByte(0x1F7, 0x20); 20 | 21 | waitDisk(); 22 | for (i = 0; i < SECTSIZE / 4; i ++) { 23 | ((int *)dst)[i] = inLong(0x1F0); 24 | } 25 | } 26 | 27 | void writeSect(void *src, int offset) { 28 | int i; 29 | waitDisk(); 30 | 31 | outByte(0x1F2, 1); 32 | outByte(0x1F3, offset); 33 | outByte(0x1F4, offset >> 8); 34 | outByte(0x1F5, offset >> 16); 35 | outByte(0x1F6, (offset >> 24) | 0xE0); 36 | outByte(0x1F7, 0x30); 37 | 38 | waitDisk(); 39 | for (i = 0; i < SECTOR_SIZE / 4; i ++) { 40 | outLong(0x1F0, ((uint32_t *)src)[i]); 41 | } 42 | } 43 | 44 | void diskRead (void *destBuffer, int size, int num, int offset) { 45 | int i = 0; 46 | int j = 0; 47 | uint8_t buffer[SECTOR_SIZE]; 48 | int quotient = offset / SECTOR_SIZE; 49 | int remainder = offset % SECTOR_SIZE; 50 | 51 | readSect((void*)buffer, 201 + quotient + j); 52 | j ++; 53 | while (i < size * num) { 54 | ((uint8_t*)destBuffer)[i] = buffer[(remainder + i) % SECTOR_SIZE]; 55 | i ++; 56 | if ((remainder + i) % SECTOR_SIZE == 0) { 57 | readSect((void*)buffer, 201 + quotient + j); 58 | j ++; 59 | } 60 | } 61 | } 62 | 63 | void diskWrite (void *destBuffer, int size, int num, int offset) { 64 | int i = 0; 65 | int j = 0; 66 | uint8_t buffer[SECTOR_SIZE]; 67 | int quotient = offset / SECTOR_SIZE; 68 | int remainder = offset % SECTOR_SIZE; 69 | 70 | readSect((void*)buffer, 201 + quotient + j); 71 | while (i < size * num) { 72 | buffer[(remainder + i) % SECTOR_SIZE] = ((uint8_t*)destBuffer)[i]; 73 | i ++; 74 | if ((remainder + i) % SECTOR_SIZE == 0) { 75 | writeSect((void*)buffer, 201 + quotient + j); 76 | j ++; 77 | readSect((void*)buffer, 201 + quotient + j); 78 | } 79 | } 80 | writeSect((void*)buffer, 201 + quotient + j); 81 | } 82 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/kernel/doIrq.S: -------------------------------------------------------------------------------- 1 | /*TODO 2 | otherwise need to reassign esp0 of tss in task switching for each user process 3 | note that for conforming code OR same PRL, no need to switch task 4 | that is TSS doesn't work 5 | 1. Trap Gate, IF won't be set 6 | 2. Interrupt Gate, IF is set automatically 7 | 3. System Gate 8 | */ 9 | 10 | .code32 11 | 12 | .global irqEmpty 13 | irqEmpty: 14 | pushl $0 // push dummy error code 15 | pushl $-1 // push interruption number into kernel 16 | jmp asmDoIrq 17 | 18 | .global irqErrorCode 19 | irqErrorCode: 20 | pushl $-1 // push interruption number into kernel 21 | jmp asmDoIrq 22 | 23 | .global irqDoubleFault 24 | irqDoubleFault: 25 | pushl $-1 26 | jmp asmDoIrq 27 | 28 | .global irqInvalidTSS 29 | irqInvalidTSS: 30 | pushl $-1 31 | jmp asmDoIrq 32 | 33 | .global irqSegNotPresent 34 | irqSegNotPresent: 35 | pushl $-1 36 | jmp asmDoIrq 37 | 38 | .global irqStackSegFault 39 | irqStackSegFault: 40 | pushl $-1 41 | jmp asmDoIrq 42 | 43 | .global irqGProtectFault 44 | irqGProtectFault: 45 | pushl $0xd 46 | jmp asmDoIrq 47 | 48 | .global irqPageFault 49 | irqPageFault: 50 | pushl $-1 51 | jmp asmDoIrq 52 | 53 | .global irqAlignCheck 54 | irqAlignCheck: 55 | pushl $-1 56 | jmp asmDoIrq 57 | 58 | .global irqSecException 59 | irqSecException: 60 | pushl $-1 61 | jmp asmDoIrq 62 | 63 | .global irqTimer 64 | irqTimer: 65 | pushl $0 66 | pushl $0x20 67 | jmp asmDoIrq 68 | 69 | .global irqKeyboard 70 | irqKeyboard: 71 | pushl $0 72 | pushl $0x21 73 | jmp asmDoIrq 74 | 75 | .global irqSyscall 76 | irqSyscall: 77 | pushl $0 // push dummy error code 78 | pushl $0x80 // push interruption number into kernel stack 79 | jmp asmDoIrq 80 | 81 | //.extern irqHandle //defined in irq_handle.c 82 | 83 | .global asmDoIrq 84 | asmDoIrq: 85 | pushal // push process state into kernel stack 86 | pushl %ds 87 | pushl %es 88 | pushl %fs 89 | pushl %gs 90 | pushl %esp //esp is treated as a parameter 91 | call irqHandle 92 | addl $4, %esp //esp is on top of kernel stack 93 | popl %gs 94 | popl %fs 95 | popl %es 96 | popl %ds 97 | popal 98 | addl $4, %esp //interrupt number is on top of kernel stack 99 | addl $4, %esp //error code is on top of kernel stack 100 | iret 101 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/kernel/i8259.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | 3 | #define PORT_PIC_MASTER 0x20 4 | #define PORT_PIC_SLAVE 0xA0 5 | #define IRQ_SLAVE 2 6 | 7 | /* 初始化8259中断控制器: 8 | * 硬件中断IRQ从32号开始,自动发送EOI */ 9 | void 10 | initIntr(void) { 11 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 12 | //outByte(PORT_PIC_SLAVE + 1 , 0xFF); // OCW1, Disable Slave PIC all IRQs 13 | outByte(PORT_PIC_MASTER, 0x11); // ICW1, Initialization command 14 | outByte(PORT_PIC_SLAVE, 0x11); // ICW1, Initialization command 15 | outByte(PORT_PIC_MASTER + 1, 32); // ICW2, Interrupt Vector Offset 0x20 16 | outByte(PORT_PIC_SLAVE + 1, 32 + 8); // ICW2, Interrupt Vector Offset 0x28 17 | outByte(PORT_PIC_MASTER + 1, 1 << 2); // ICW3, Tell Master PIC that there is a slave 18 | outByte(PORT_PIC_SLAVE + 1, 2); // ICW3, Tell Slave PIC its cascade identity 19 | outByte(PORT_PIC_MASTER + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 20 | outByte(PORT_PIC_SLAVE + 1, 0x3); // ICW4, Auto EOI in 8086/88 mode 21 | 22 | //outByte(PORT_PIC_MASTER, 0x68); // OCW3, Enable Special Mask Mode 23 | //outByte(PORT_PIC_MASTER, 0x0A); // OCW3, Read ISR of Master on next CMD Read 24 | //outByte(PORT_PIC_SLAVE, 0x68); // OCW3, Enable Special Mask Mode 25 | //outByte(PORT_PIC_SLAVE, 0x0A); // OCW3, Read ISR of Slave on next CMD Read 26 | 27 | //outByte(PORT_PIC_MASTER + 1, 0xFE); // OCW1, Enable Timer IRQ 28 | //outByte(PORT_PIC_MASTER + 1, 0xFF); // OCW1, Disable Master PIC all IRQs 29 | //outByte(PORT_PIC_SLAVE + 1, 0xFF); // OCW1, Disable Slave PIC all IRQs 30 | } 31 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/kernel/idt.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define INTERRUPT_GATE_32 0xE 5 | #define TRAP_GATE_32 0xF 6 | 7 | /* IDT表的内容 */ 8 | struct GateDescriptor idt[NR_IRQ]; // NR_IRQ=256, defined in x86/cpu.h 9 | 10 | /* 初始化一个中断门(interrupt gate) */ 11 | static void setIntr(struct GateDescriptor *ptr, uint32_t selector, uint32_t offset, uint32_t dpl) { 12 | ptr->offset_15_0 = offset & 0xFFFF; 13 | ptr->segment = selector << 3; 14 | ptr->pad0 = 0; 15 | ptr->type = INTERRUPT_GATE_32; 16 | ptr->system = FALSE; 17 | ptr->privilege_level = dpl; 18 | ptr->present = TRUE; 19 | ptr->offset_31_16 = (offset >> 16) & 0xFFFF; 20 | } 21 | 22 | /* 初始化一个陷阱门(trap gate) */ 23 | static void setTrap(struct GateDescriptor *ptr, uint32_t selector, uint32_t offset, uint32_t dpl) { 24 | ptr->offset_15_0 = offset & 0xFFFF; 25 | ptr->segment = selector << 3; 26 | ptr->pad0 = 0; 27 | ptr->type = TRAP_GATE_32; 28 | ptr->system = FALSE; 29 | ptr->privilege_level = dpl; 30 | ptr->present = TRUE; 31 | ptr->offset_31_16 = (offset >> 16) & 0xFFFF; 32 | } 33 | 34 | /* 声明函数,这些函数在汇编代码里定义 */ 35 | void irqEmpty(); 36 | void irqErrorCode(); 37 | 38 | void irqDoubleFault(); // 0x8 39 | void irqInvalidTSS(); // 0xa 40 | void irqSegNotPresent(); // 0xb 41 | void irqStackSegFault(); // 0xc 42 | void irqGProtectFault(); // 0xd 43 | void irqPageFault(); // 0xe 44 | void irqAlignCheck(); // 0x11 45 | void irqSecException(); // 0x1e 46 | 47 | void irqSyscall(); 48 | void irqTimer(); 49 | void irqKeyboard(); 50 | 51 | void initIdt() { 52 | int i; 53 | /* 为了防止系统异常终止,所有irq都有处理函数(irqEmpty)。 */ 54 | for (i = 0; i < NR_IRQ; i ++) { 55 | setTrap(idt + i, SEG_KCODE, (uint32_t)irqEmpty, DPL_KERN); 56 | } 57 | /* 58 | * init your idt here 59 | * 初始化 IDT 表, 为中断设置中断处理函数 60 | */ 61 | /* Exceptions with error code */ 62 | setTrap(idt + 0x8, SEG_KCODE, (uint32_t)irqDoubleFault, DPL_KERN); 63 | setTrap(idt + 0xa, SEG_KCODE, (uint32_t)irqInvalidTSS, DPL_KERN); 64 | setTrap(idt + 0xb, SEG_KCODE, (uint32_t)irqSegNotPresent, DPL_KERN); 65 | setTrap(idt + 0xc, SEG_KCODE, (uint32_t)irqStackSegFault, DPL_KERN); 66 | setTrap(idt + 0xd, SEG_KCODE, (uint32_t)irqGProtectFault, DPL_KERN); 67 | //setTrap(idt + 0xd, SEG_KCODE, (uint32_t)irqGProtectFault, DPL_USER); 68 | setTrap(idt + 0xe, SEG_KCODE, (uint32_t)irqPageFault, DPL_KERN); 69 | //setTrap(idt + 0xe, SEG_KCODE, (uint32_t)irqPageFault, DPL_USER); 70 | setTrap(idt + 0x11, SEG_KCODE, (uint32_t)irqAlignCheck, DPL_KERN); 71 | setTrap(idt + 0x1e, SEG_KCODE, (uint32_t)irqSecException, DPL_KERN); 72 | 73 | /* Exceptions with DPL = 3 */ 74 | //setIntr(idt + 0x3, SEG_KCODE, , DPL_USER); // for int 3, interrupt vector is 0x3, Interruption is disabled 75 | //setIntr(idt + 0x4, SEG_KCODE, , DPL_USER); // for into, interrupt vector is 0x4, Interruption is disabled 76 | //setIntr(idt + 0x5, SEG_KCODE, , DPL_USER); // for bound, interrupt vector is 0x5, Interruption is disabled 77 | setIntr(idt + 0x20, SEG_KCODE, (uint32_t)irqTimer, DPL_KERN); 78 | setIntr(idt + 0x21, SEG_KCODE, (uint32_t)irqKeyboard, DPL_KERN); 79 | setIntr(idt + 0x80, SEG_KCODE, (uint32_t)irqSyscall, DPL_USER); // for int 0x80, interrupt vector is 0x80, Interruption is disabled 80 | 81 | /* 写入IDT */ 82 | saveIdt(idt, sizeof(idt)); 83 | } 84 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/kernel/serial.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | void initSerial(void) { 5 | outByte(SERIAL_PORT + 1, 0x00); 6 | outByte(SERIAL_PORT + 3, 0x80); 7 | outByte(SERIAL_PORT + 0, 0x01); 8 | outByte(SERIAL_PORT + 1, 0x00); 9 | outByte(SERIAL_PORT + 3, 0x03); 10 | outByte(SERIAL_PORT + 2, 0xC7); 11 | outByte(SERIAL_PORT + 4, 0x0B); 12 | } 13 | 14 | static inline int serialIdle(void) { 15 | return (inByte(SERIAL_PORT + 5) & 0x20) != 0; 16 | } 17 | 18 | void putChar(char ch) { 19 | while (serialIdle() != TRUE); 20 | outByte(SERIAL_PORT, ch); 21 | } 22 | 23 | void putString(const char *str) { 24 | int i = 0; 25 | if (str == NULL) { 26 | return; 27 | } 28 | while (str[i] != 0) { 29 | putChar(str[i++]); 30 | } 31 | } 32 | 33 | void putInt(int a) { 34 | char buf[32]; 35 | char *p = buf + sizeof(buf) - 1; 36 | *p = '\0'; 37 | *(--p) = '\n'; 38 | do { 39 | *--p = '0' + a % 10; 40 | } while (a /= 10); 41 | putString(p); 42 | } 43 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/kernel/timer.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | #define TIMER_PORT 0x40 5 | #define FREQ_8253 1193182 6 | #define HZ 100 7 | //#define HZ 1000 8 | 9 | void initTimer() { 10 | int counter = FREQ_8253 / HZ; 11 | //assert(TIMER_PORT < 65536); 12 | outByte(TIMER_PORT + 3, 0x34); 13 | outByte(TIMER_PORT + 0, counter % 256); 14 | outByte(TIMER_PORT + 0, counter / 256); 15 | } 16 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/kernel/vga.c: -------------------------------------------------------------------------------- 1 | #include "x86.h" 2 | #include "device.h" 3 | 4 | int displayRow = 0; //TODO futher extend, display position, in .bss section, not in .data section 5 | int displayCol = 0; 6 | uint16_t displayMem[80*25]; 7 | int displayClear = 0; 8 | 9 | void initVga() { 10 | displayRow = 0; 11 | displayCol = 0; 12 | displayClear = 0; 13 | clearScreen(); 14 | updateCursor(0, 0); 15 | } 16 | 17 | void clearScreen() { 18 | int i = 0; 19 | int pos = 0; 20 | uint16_t data = 0 | (0x0c << 8); 21 | for (i = 0; i < 80 * 25; i++) { 22 | pos = i * 2; 23 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 24 | } 25 | } 26 | 27 | void updateCursor(int row, int col){ 28 | int cursorPos = row * 80 + col; 29 | outByte(0x3d4, 0x0f); 30 | outByte(0x3d5, (unsigned char)(cursorPos & 0xff)); 31 | 32 | outByte(0x3d4, 0x0e); 33 | outByte(0x3d5, (unsigned char)((cursorPos>>8) & 0xff)); 34 | } 35 | 36 | void scrollScreen() { 37 | int i = 0; 38 | int pos = 0; 39 | uint16_t data = 0; 40 | for (i = 0; i < 80 * 25; i++) { 41 | pos = i * 2; 42 | asm volatile("movw (%1), %0":"=r"(data):"r"(pos+0xb8000)); 43 | displayMem[i] = data; 44 | } 45 | for (i = 0; i < 80 * 24; i++) { 46 | pos = i * 2; 47 | data = displayMem[i+80]; 48 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 49 | } 50 | data = 0 | (0x0c << 8); 51 | for (i = 80 * 24; i < 80 * 25; i++) { 52 | pos = i * 2; 53 | asm volatile("movw %0, (%1)"::"r"(data),"r"(pos+0xb8000)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/lib/abort.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | 5 | static char *i2A(int a) { 6 | static char buf[30]; 7 | char *p = buf + sizeof(buf) - 1; 8 | do { 9 | *--p = '0' + a % 10; 10 | } while (a /= 10); 11 | return p; 12 | } 13 | 14 | static void append(char **p, const char *str) { 15 | while (*str) { 16 | *((*p) ++) = *str ++; 17 | } 18 | } 19 | 20 | /* 将文件名和assert fail的行号显示在屏幕上 */ 21 | #define BLUE_SCREEN_TEXT "Assertion failed: " 22 | static void displayMessage(const char *file, int line) { 23 | static char buf[256] = BLUE_SCREEN_TEXT; 24 | char *p = buf + sizeof(BLUE_SCREEN_TEXT) - 1; 25 | 26 | append(&p, file); 27 | append(&p, ":"); 28 | append(&p, i2A(line)); 29 | append(&p, "\n"); 30 | 31 | for (p = buf; *p; p ++) { 32 | putChar(*p); 33 | } 34 | } 35 | 36 | int abort(const char *fname, int line) { 37 | disableInterrupt(); 38 | displayMessage(fname, line); 39 | while (TRUE) { 40 | waitForInterrupt(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/lib/utils.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /* 4 | * find the first token in string 5 | * set *size as the number of bytes before token 6 | * if not found, set *size as the length of *string 7 | */ 8 | int stringChr (const char *string, char token, int *size) { 9 | int i = 0; 10 | if (string == NULL) { 11 | *size = 0; 12 | return -1; 13 | } 14 | while (string[i] != 0) { 15 | if (token == string[i]) { 16 | *size = i; 17 | return 0; 18 | } 19 | else 20 | i ++; 21 | } 22 | *size = i; 23 | return -1; 24 | } 25 | 26 | /* 27 | * find the last token in string 28 | * set *size as the number of bytes before token 29 | * if not found, set *size as the length of *string 30 | */ 31 | int stringChrR (const char *string, char token, int *size) { 32 | int i = 0; 33 | if (string == NULL) { 34 | *size = 0; 35 | return -1; 36 | } 37 | while (string[i] != 0) 38 | i ++; 39 | *size = i; 40 | while (i > -1) { 41 | if (token == string[i]) { 42 | *size = i; 43 | return 0; 44 | } 45 | else 46 | i --; 47 | } 48 | return -1; 49 | } 50 | 51 | int stringLen (const char *string) { 52 | int i = 0; 53 | if (string == NULL) 54 | return 0; 55 | while (string[i] != 0) 56 | i ++; 57 | return i; 58 | } 59 | 60 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 61 | int i = 0; 62 | if (srcString == NULL || destString == NULL) 63 | return -1; 64 | while (i != size) { 65 | if (srcString[i] != destString[i]) 66 | return -1; 67 | else if (srcString[i] == 0) 68 | return 0; 69 | else 70 | i ++; 71 | } 72 | return 0; 73 | } 74 | 75 | int stringCpy (const char *srcString, char *destString, int size) { 76 | int i = 0; 77 | if (srcString == NULL || destString == NULL) 78 | return -1; 79 | while (i != size) { 80 | if (srcString[i] != 0) { 81 | destString[i] = srcString[i]; 82 | i++; 83 | } 84 | else 85 | break; 86 | } 87 | destString[i] = 0; 88 | return 0; 89 | } 90 | 91 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 92 | int i = 0; 93 | if (buffer == NULL) 94 | return -1; 95 | for (i = 0; i < size ; i ++) 96 | buffer[i] = value; 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/kernel/main.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x86.h" 3 | #include "device.h" 4 | #include "fs.h" 5 | 6 | void kEntry(void) { 7 | 8 | // Interruption is disabled in bootloader 9 | 10 | initSerial(); // initialize serial port 11 | initIdt(); // initialize idt 12 | initIntr(); // iniialize 8259a 13 | initSeg(); // initialize gdt, tss 14 | initVga(); // initialize vga device 15 | initTimer(); // initialize timer device 16 | initKeyTable(); // initialize keyboard device 17 | initFS(); // initialize file system 18 | initSem(); // initialize semaphore list 19 | initDev(); // initialize device list 20 | initProc(); // initialize pcb & load user program 21 | } 22 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/lib/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __lib_h__ 2 | #define __lib_h__ 3 | 4 | #include "types.h" 5 | 6 | #define SYS_WRITE 0 7 | #define SYS_FORK 1 8 | #define SYS_EXEC 2 9 | #define SYS_SLEEP 3 10 | #define SYS_EXIT 4 11 | #define SYS_READ 5 12 | #define SYS_SEM 6 13 | #define SYS_GETPID 7 14 | 15 | #define STD_OUT 0 16 | #define STD_IN 1 17 | #define SH_MEM 3 18 | 19 | #define SEM_INIT 0 20 | #define SEM_WAIT 1 21 | #define SEM_POST 2 22 | #define SEM_DESTROY 3 23 | 24 | #define MAX_BUFFER_SIZE 256 25 | 26 | int printf(const char *format,...); 27 | 28 | int scanf(const char *format,...); 29 | 30 | pid_t fork(); 31 | 32 | int exec(const char *filename, char * const argv[]); 33 | 34 | int sleep(uint32_t time); 35 | 36 | int exit(); 37 | 38 | int write(int fd, uint8_t *buffer, int size, ...); 39 | 40 | int read(int fd, uint8_t *buffer, int size, ...); 41 | 42 | int sem_init(sem_t *sem, uint32_t value); 43 | 44 | int sem_wait(sem_t *sem); 45 | 46 | int sem_post(sem_t *sem); 47 | 48 | int sem_destroy(sem_t *sem); 49 | 50 | int getpid(); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/lib/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef int int32_t; 6 | typedef unsigned short uint16_t; 7 | typedef short int16_t; 8 | typedef unsigned char uint8_t; 9 | typedef char int8_t; 10 | typedef unsigned char boolean; 11 | 12 | typedef uint32_t size_t; 13 | typedef int32_t pid_t; 14 | typedef int32_t sem_t; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/philosopher/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | 13 | app.bin: $(UOBJS) 14 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o philosopher.elf $(UOBJS) 15 | 16 | clean: 17 | rm -rf $(UOBJS) philosopher.elf 18 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/philosopher/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | #define N 5 5 | 6 | sem_t forks[5]; 7 | 8 | static unsigned long next = 48; 9 | 10 | int myrand() 11 | { 12 | read(SH_MEM, (uint8_t *)&next, 4, 24); 13 | next = next * 1103515245 + 12345; 14 | write(SH_MEM, (uint8_t *)&next, 4, 24); 15 | return ((unsigned)(next / 65536) % 231) + 83; 16 | } 17 | 18 | void philosopher(int i) 19 | { 20 | int id = getpid() - 2; 21 | while (1) 22 | { 23 | printf("Philosopher %d: think\n", id); 24 | sleep(myrand()); 25 | if (i % 2 == 0) 26 | { 27 | sem_wait(forks + i); 28 | sleep(myrand()); 29 | sem_wait(forks + ((i + 1) % N)); 30 | sleep(myrand()); 31 | } 32 | else 33 | { 34 | sem_wait(forks + ((i + 1) % N)); 35 | sleep(myrand()); 36 | sem_wait(forks + i); 37 | sleep(myrand()); 38 | } 39 | printf("Philosopher %d: eat\n", id); 40 | sleep(myrand()); 41 | sem_post(forks + i); 42 | sleep(myrand()); 43 | sem_post(forks + ((i + 1) % N)); 44 | sleep(myrand()); 45 | } 46 | } 47 | 48 | int main(void) 49 | { 50 | // TODO in lab4 51 | printf("philosopher\n"); 52 | for (int i = 0; i < 5; i++) 53 | { 54 | sem_init(forks + i, 1); 55 | } 56 | write(SH_MEM, (uint8_t *)&next, 4, 24); 57 | int ret = 1; 58 | for (int i = 0; i < 5; i++) 59 | { 60 | if (ret > 0) 61 | ret = fork(); 62 | } 63 | if (getpid() > 1) 64 | { 65 | sleep(myrand()); 66 | philosopher(getpid() - 2); 67 | } 68 | 69 | while (1); 70 | for (int i = 0; i < 5; i++) 71 | { 72 | sem_destroy(forks + i); 73 | } 74 | exit(); 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/reader_writer/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | LD = ld 3 | 4 | CFLAGS = -m32 -march=i386 -static \ 5 | -fno-builtin -fno-stack-protector -fno-omit-frame-pointer \ 6 | -Wall -Werror -O2 -I../lib 7 | LDFLAGS = -m elf_i386 8 | 9 | UCFILES = $(shell find ./ -name "*.c") 10 | LCFILES = $(shell find ../lib -name "*.c") 11 | UOBJS = $(UCFILES:.c=.o) $(LCFILES:.c=.o) 12 | 13 | app.bin: $(UOBJS) 14 | $(LD) $(LDFLAGS) -e main -Ttext 0x00000000 -o reader_writer.elf $(UOBJS) 15 | 16 | clean: 17 | rm -rf $(UOBJS) reader_writer.elf 18 | 19 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/reader_writer/main.c: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "types.h" 3 | 4 | static unsigned long next = 97; 5 | 6 | int myrand() 7 | { 8 | read(SH_MEM, (uint8_t *)&next, 4, 24); 9 | next = next * 1103515245 + 12345; 10 | write(SH_MEM, (uint8_t *)&next, 4, 24); 11 | return ((unsigned)(next / 65536) % 211) + 83; 12 | } 13 | 14 | void writer(sem_t *writemutex) 15 | { 16 | int id = getpid() - 3 - 2; 17 | while (1) 18 | { 19 | sem_wait(writemutex); 20 | sleep(myrand()); 21 | printf("Writer %d: write\n", id); 22 | sleep(myrand()); 23 | sem_post(writemutex); 24 | sleep(myrand()); 25 | } 26 | } 27 | 28 | void reader(sem_t *writemutex, sem_t *countmutex, int *rcount) 29 | { 30 | int id = getpid() - 2; 31 | while (1) 32 | { 33 | sem_wait(countmutex); 34 | sleep(myrand()); 35 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 36 | if (*rcount == 0) 37 | { 38 | sem_wait(writemutex); 39 | sleep(myrand()); 40 | } 41 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 42 | ++(*rcount); 43 | write(SH_MEM, (uint8_t *)rcount, 4, 12); 44 | sleep(myrand()); 45 | sem_post(countmutex); 46 | sleep(myrand()); 47 | printf("Reader %d: read, total %d reader\n", id, *rcount); 48 | sleep(myrand()); 49 | sem_wait(countmutex); 50 | sleep(myrand()); 51 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 52 | --(*rcount); 53 | write(SH_MEM, (uint8_t *)rcount, 4, 12); 54 | sleep(myrand()); 55 | read(SH_MEM, (uint8_t *)rcount, 4, 12); 56 | if (*rcount == 0) 57 | { 58 | sem_post(writemutex); 59 | sleep(myrand()); 60 | } 61 | sem_post(countmutex); 62 | sleep(myrand()); 63 | } 64 | } 65 | 66 | int main(void) 67 | { 68 | // TODO in lab4 69 | printf("reader_writer\n"); 70 | sem_t writemutex, countmutex; 71 | sem_init(&writemutex, 1); 72 | sem_init(&countmutex, 1); 73 | int rcount = 0; 74 | write(SH_MEM, (uint8_t *)&rcount, 4, 12); 75 | write(SH_MEM, (uint8_t *)&next, 4, 24); 76 | int ret = 1; 77 | for (int i = 0; i < 6; i++) 78 | { 79 | if (ret > 0) 80 | ret = fork(); 81 | } 82 | int id = getpid(); 83 | if (id > 1 && id < 5) 84 | { 85 | sleep(myrand()); 86 | reader(&writemutex, &countmutex, &rcount); 87 | } 88 | else if (id > 4 && id < 8) 89 | { 90 | sleep(myrand()); 91 | writer(&writemutex); 92 | } 93 | 94 | while (1); 95 | sem_destroy(&writemutex); 96 | sem_destroy(&countmutex); 97 | exit(); 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genBoot.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 1000); 6 | 7 | if($n > 510){ 8 | print STDERR "ERROR: boot block too large: $n bytes (max 510)\n"; 9 | exit 1; 10 | } 11 | 12 | print STDERR "OK: boot block is $n bytes (max 510)\n"; 13 | 14 | $buf .= "\0" x (510-$n); 15 | $buf .= "\x55\xAA"; 16 | 17 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 18 | print SIG $buf; 19 | close SIG; 20 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genFS/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | 3 | CFLAGS = -g 4 | #CFLAGS = -m32 -g 5 | 6 | CFILES = $(shell find ./ -name "*.c") 7 | OBJS = $(CFILES:.c=.o) 8 | 9 | genFS: $(CFILES) 10 | $(CC) $(CFLAGS) -o genFS $(CFILES) 11 | 12 | clean: 13 | @#rm -rf $(OBJS) genFS fs.bin 14 | rm -rf $(OBJS) genFS -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genFS/func.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_H__ 2 | #define __FUNC_H__ 3 | 4 | int format (const char *driver, int sectorNum, int sectorsPerBlock); 5 | 6 | int mkdir (const char *driver, const char *destDirPath); 7 | 8 | int rmdir (const char *driver, const char *destDirPath); 9 | 10 | int cp (const char *driver, const char *srcFilePath, const char *destFilePath); 11 | 12 | int rm (const char *driver, const char *destFilePath); 13 | 14 | int ls (const char *driver, const char *destFilePath); 15 | 16 | int touch (const char *driver, const char *destFilePath); 17 | 18 | int recBlock(FILE *file, SuperBlock *superBlock, Inode *inode); 19 | 20 | int recInode(FILE *file, SuperBlock *superBlock, Inode *inode, int inodeOffset, Inode *fatherInode, const char *filename); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genFS/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | #include "data.h" 4 | #include "func.h" 5 | 6 | int main(int argc, char *argv[]) { 7 | char driver[NAME_LENGTH]; 8 | char srcFilePath[NAME_LENGTH]; 9 | char destFilePath[NAME_LENGTH]; 10 | 11 | stringCpy("fs.bin", driver, NAME_LENGTH - 1); 12 | format(driver, SECTOR_NUM, SECTORS_PER_BLOCK); 13 | 14 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 15 | mkdir(driver, destFilePath); 16 | 17 | stringCpy(argv[1], srcFilePath, NAME_LENGTH - 1); 18 | stringCpy("/boot/initrd", destFilePath, NAME_LENGTH - 1); 19 | cp(driver, srcFilePath, destFilePath); 20 | 21 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 22 | mkdir(driver, destFilePath); 23 | 24 | stringCpy(argv[2], srcFilePath, NAME_LENGTH - 1); 25 | stringCpy("/usr/print", destFilePath, NAME_LENGTH - 1); 26 | cp(driver, srcFilePath, destFilePath); 27 | 28 | stringCpy(argv[3], srcFilePath, NAME_LENGTH - 1); 29 | stringCpy("/usr/bounded_buffer", destFilePath, NAME_LENGTH - 1); 30 | cp(driver, srcFilePath, destFilePath); 31 | 32 | stringCpy(argv[4], srcFilePath, NAME_LENGTH - 1); 33 | stringCpy("/usr/philosopher", destFilePath, NAME_LENGTH - 1); 34 | cp(driver, srcFilePath, destFilePath); 35 | 36 | stringCpy(argv[5], srcFilePath, NAME_LENGTH - 1); 37 | stringCpy("/usr/reader_writer", destFilePath, NAME_LENGTH - 1); 38 | cp(driver, srcFilePath, destFilePath); 39 | 40 | stringCpy("/", destFilePath, NAME_LENGTH - 1); 41 | ls(driver, destFilePath); 42 | 43 | stringCpy("/boot", destFilePath, NAME_LENGTH - 1); 44 | ls(driver, destFilePath); 45 | 46 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 47 | ls(driver, destFilePath); 48 | 49 | stringCpy("/usr/philosopher", destFilePath, NAME_LENGTH - 1); 50 | rm(driver, destFilePath); 51 | 52 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 53 | ls(driver, destFilePath); 54 | 55 | stringCpy(argv[4], srcFilePath, NAME_LENGTH - 1); 56 | stringCpy("/usr/philosopher", destFilePath, NAME_LENGTH - 1); 57 | cp(driver, srcFilePath, destFilePath); 58 | 59 | stringCpy("/usr/test", destFilePath, NAME_LENGTH - 1); 60 | mkdir(driver, destFilePath); 61 | 62 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 63 | ls(driver, destFilePath); 64 | 65 | stringCpy("/usr", destFilePath, NAME_LENGTH - 1); 66 | rmdir(driver, destFilePath); 67 | 68 | stringCpy("/", destFilePath, NAME_LENGTH - 1); 69 | ls(driver, destFilePath); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genFS/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned int uint32_t; 5 | typedef unsigned short uint16_t; 6 | typedef unsigned char uint8_t; 7 | 8 | typedef int int32_t; 9 | typedef short int16_t; 10 | typedef char int8_t; 11 | 12 | // #define NULL ((void*)0) 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genFS/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utils.h" 3 | 4 | /* 5 | * find the first token in string 6 | * set *size as the number of bytes before token 7 | * if not found, set *size as the length of *string 8 | */ 9 | int stringChr (const char *string, char token, int *size) { 10 | int i = 0; 11 | if (string == NULL) { 12 | *size = 0; 13 | return -1; 14 | } 15 | while (string[i] != 0) { 16 | if (token == string[i]) { 17 | *size = i; 18 | return 0; 19 | } 20 | else 21 | i ++; 22 | } 23 | *size = i; 24 | return -1; 25 | } 26 | 27 | /* 28 | * find the last token in string 29 | * set *size as the number of bytes before token 30 | * if not found, set *size as the length of *string 31 | */ 32 | int stringChrR (const char *string, char token, int *size) { 33 | int i = 0; 34 | if (string == NULL) { 35 | *size = 0; 36 | return -1; 37 | } 38 | while (string[i] != 0) 39 | i ++; 40 | *size = i; 41 | while (i > -1) { 42 | if (token == string[i]) { 43 | *size = i; 44 | return 0; 45 | } 46 | else 47 | i --; 48 | } 49 | return -1; 50 | } 51 | 52 | int stringLen (const char *string) { 53 | int i = 0; 54 | if (string == NULL) 55 | return 0; 56 | while (string[i] != 0) 57 | i ++; 58 | return i; 59 | } 60 | 61 | int stringCmp (const char *srcString, const char *destString, int size) { // compre first 'size' bytes 62 | int i = 0; 63 | if (srcString == NULL || destString == NULL) 64 | return -1; 65 | while (i != size) { 66 | if (srcString[i] != destString[i]) 67 | return -1; 68 | else if (srcString[i] == 0) 69 | return 0; 70 | else 71 | i ++; 72 | } 73 | return 0; 74 | } 75 | 76 | int stringCpy (const char *srcString, char *destString, int size) { 77 | int i = 0; 78 | if (srcString == NULL || destString == NULL) 79 | return -1; 80 | while (i != size) { 81 | if (srcString[i] != 0) { 82 | destString[i] = srcString[i]; 83 | i++; 84 | } 85 | else 86 | break; 87 | } 88 | destString[i] = 0; 89 | return 0; 90 | } 91 | 92 | int setBuffer (uint8_t *buffer, int size, uint8_t value) { 93 | int i = 0; 94 | if (buffer == NULL) 95 | return -1; 96 | for (i = 0; i < size ; i ++) 97 | buffer[i] = value; 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genFS/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | #include "types.h" 5 | 6 | int stringChr(const char *string, char token, int *size); 7 | 8 | int stringChrR (const char *string, char token, int *size); 9 | 10 | int stringLen(const char *string); 11 | 12 | int stringCmp(const char *srcString, const char *destString, int size); 13 | 14 | int stringCpy (const char *srcString, char *destString, int size); 15 | 16 | int setBuffer (uint8_t *buffer, int size, uint8_t value); 17 | 18 | #endif -------------------------------------------------------------------------------- /lab5-181860013/lab5/utils/genKernel.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; 4 | 5 | $n = sysread(SIG, $buf, 100000); 6 | 7 | print STDERR "OK: Kernel is $n bytes - Extended to 200 sectors\n"; 8 | 9 | $buf .= "\0" x (102400-$n); 10 | 11 | open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; 12 | print SIG $buf; 13 | close SIG; 14 | -------------------------------------------------------------------------------- /mbr.s: -------------------------------------------------------------------------------- 1 | .code16 2 | .global start 3 | start: 4 | movw %cs, %ax 5 | movw %ax, %ds 6 | movw %ax, %es 7 | movw %ax, %ss 8 | movw $0x7d00, %ax 9 | movw %ax, %sp # setting stack pointer to 0x7d00 10 | pushw $13 # pushing the size to print into stack 11 | pushw $message # pushing the address of message into stack 12 | callw displayStr # calling the display function 13 | loop: 14 | jmp loop 15 | 16 | message: 17 | .string "Hello, World!\n\0" 18 | 19 | displayStr: 20 | pushw %bp 21 | movw 4(%esp), %ax 22 | movw %ax, %bp 23 | movw 6(%esp), %cx 24 | movw $0x1301, %ax 25 | movw $0x000c, %bx 26 | movw $0x0000, %dx 27 | int $0x10 28 | popw %bp 29 | ret 30 | --------------------------------------------------------------------------------