├── .gitignore ├── README.md ├── Resources ├── gcc-3.4-ubuntu.tar.gz ├── hit-oslab-linux-20110823.tar.gz ├── memtest ├── process.c ├── stat_log.py ├── testlab2.c └── testlab2.sh ├── lab1 ├── bootsect.s ├── build.c ├── report.txt └── setup.s ├── lab2 ├── iam.c ├── report.txt ├── sys.h ├── system_call.s ├── unistd.h ├── who.c └── whoami.c ├── lab3 ├── exit.c ├── fork.c ├── main.c ├── printk.c ├── process.c ├── report.txt └── sched.c ├── lab4 ├── pc.c ├── report.txt ├── sem.c ├── sys.h ├── system_call.s └── unistd.h ├── lab5 ├── consumer.c ├── memory.c ├── producer.c ├── report.txt ├── sem.c ├── shm.c ├── sys.h ├── system_call.s └── unistd.h ├── lab6 ├── console.c ├── file_dev.c ├── keyboard.S ├── read_write.c ├── report.txt └── tty_io.c ├── lab7 ├── main.c ├── namei.c ├── proc.c ├── read_write.c ├── report.txt └── stat.h └── lab8 ├── Image ├── Makefile ├── System.map ├── a.out ├── boot ├── bootsect ├── bootsect.o ├── bootsect.s ├── head.o ├── head.s ├── setup ├── setup.o └── setup.s ├── fs ├── Makefile ├── bitmap.c ├── bitmap.o ├── block_dev.c ├── block_dev.o ├── buffer.c ├── buffer.o ├── char_dev.c ├── char_dev.o ├── exec.c ├── exec.o ├── fcntl.c ├── fcntl.o ├── file_dev.c ├── file_dev.o ├── file_table.c ├── file_table.o ├── fs.o ├── inode.c ├── inode.o ├── ioctl.c ├── ioctl.o ├── namei.c ├── namei.o ├── open.c ├── open.o ├── pipe.c ├── pipe.o ├── read_write.c ├── read_write.o ├── stat.c ├── stat.o ├── super.c ├── super.o ├── truncate.c └── truncate.o ├── include ├── a.out.h ├── asm │ ├── io.h │ ├── memory.h │ ├── segment.h │ └── system.h ├── const.h ├── ctype.h ├── errno.h ├── fcntl.h ├── linux │ ├── config.h │ ├── fdreg.h │ ├── fs.h │ ├── hdreg.h │ ├── head.h │ ├── kernel.h │ ├── mm.h │ ├── sched.h │ ├── sched.h.cur1 │ ├── sched.h.old │ ├── sys.h │ └── tty.h ├── signal.h ├── stdarg.h ├── stddef.h ├── string.h ├── sys │ ├── stat.h │ ├── times.h │ ├── types.h │ ├── utsname.h │ └── wait.h ├── termios.h ├── time.h ├── unistd.h └── utime.h ├── init ├── main.c └── main.o ├── kernel ├── Makefile ├── asm.o ├── asm.s ├── blk_drv │ ├── Makefile │ ├── blk.h │ ├── blk_drv.a │ ├── floppy.c │ ├── floppy.o │ ├── hd.c │ ├── hd.o │ ├── ll_rw_blk.c │ ├── ll_rw_blk.o │ ├── ramdisk.c │ └── ramdisk.o ├── chr_drv │ ├── Makefile │ ├── chr_drv.a │ ├── console.c │ ├── console.o │ ├── keyboard.o │ ├── keyboard.s │ ├── rs_io.o │ ├── rs_io.s │ ├── serial.c │ ├── serial.o │ ├── tty_io.c │ ├── tty_io.o │ ├── tty_ioctl.c │ └── tty_ioctl.o ├── exit.c ├── exit.o ├── fork.c ├── fork.o ├── kernel.o ├── math │ ├── Makefile │ ├── math.a │ ├── math_emulate.c │ └── math_emulate.o ├── mktime.c ├── mktime.o ├── panic.c ├── panic.o ├── printk.c ├── printk.o ├── sched.c ├── sched.o ├── signal.c ├── signal.o ├── sys.c ├── sys.o ├── system_call.o ├── system_call.s ├── thread.c ├── thread.o ├── traps.c ├── traps.o ├── vsprintf.c └── vsprintf.o ├── lib ├── Makefile ├── _exit.c ├── _exit.o ├── close.c ├── close.o ├── ctype.c ├── ctype.o ├── dup.c ├── dup.o ├── errno.c ├── errno.o ├── execve.c ├── execve.o ├── lib.a ├── malloc.c ├── malloc.o ├── open.c ├── open.o ├── setsid.c ├── setsid.o ├── string.c ├── string.o ├── wait.c ├── wait.o ├── write.c └── write.o ├── memtest.c ├── mm ├── Makefile ├── memory.c ├── memory.o ├── mm.o ├── page.o └── page.s ├── pthread.c ├── pthread.h ├── tags ├── test.c └── tools ├── build ├── build.c └── system /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##HIT-OSLab 2 | 3 | 哈工大的操作系统课是本校CS课程中含金量最高的,尤其是实验课。这八个实验涉及到了操作系统的核心部分,虽然不是在本校待创的如 HITOS 上进行的,但 linux-0.11 确实是个好的选择。能让我们更加专注于实验,而不是纠结于各种奇怪问题,作为OS入门算是足够了。学完操作系统课只能算是OS入门了,这一点也是李治军老师一直强调的。 4 | 5 | 课程资源: 6 | 7 | - [操作系统之基础](http://mooc.study.163.com/course/HIT-1000002004#/info) 8 | - [操作系统之进程与线程](http://mooc.study.163.com/course/HIT-1000002008#/info) 9 | - [操作系统之内存管理](http://mooc.study.163.com/course/HIT-1000003007#/info) 10 | - [操作系统之外设与文件系统](http://mooc.study.163.com/course/HIT-1000002009#/info) 11 | 12 | 实验手册:[GitBook](https://traitorousfc.gitbooks.io/hit-oslab-manual/content/index.html) 13 | 14 | ##说明 15 | 16 | 本人荣升大四狗,有大把的空闲时间,准备写一个自己的OS,顺便将此仓库整理了一下。 17 | 18 | 作为本届唯一的操作系统实验满分(当然这门课也满分啦~oh~yeah~)的童鞋,在此分享一下本人当初的代码~仅供希望深入学习OS并对HIT-OSLab感兴趣的童鞋参考。 19 | 20 | 其中lab1-lab7只给出修改的部分。lab8给出了完整的修改后的linux-0.11代码。 21 | 22 | Resources目录存放相关资源。 23 | 24 | 最后送上一句话: 25 | 26 | Just coding system, it's fantastic ! -------------------------------------------------------------------------------- /Resources/gcc-3.4-ubuntu.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/Resources/gcc-3.4-ubuntu.tar.gz -------------------------------------------------------------------------------- /Resources/hit-oslab-linux-20110823.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/Resources/hit-oslab-linux-20110823.tar.gz -------------------------------------------------------------------------------- /Resources/memtest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/Resources/memtest -------------------------------------------------------------------------------- /Resources/process.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define HZ 100 7 | 8 | void cpuio_bound(int last, int cpu_time, int io_time); 9 | 10 | int main(int argc, char * argv[]) 11 | { 12 | return 0; 13 | } 14 | 15 | /* 16 | * 此函数按照参数占用CPU和I/O时间 17 | * last: 函数实际占用CPU和I/O的总时间,不含在就绪队列中的时间,>=0是必须的 18 | * cpu_time: 一次连续占用CPU的时间,>=0是必须的 19 | * io_time: 一次I/O消耗的时间,>=0是必须的 20 | * 如果last > cpu_time + io_time,则往复多次占用CPU和I/O 21 | * 所有时间的单位为秒 22 | */ 23 | void cpuio_bound(int last, int cpu_time, int io_time) 24 | { 25 | struct tms start_time, current_time; 26 | clock_t utime, stime; 27 | int sleep_time; 28 | 29 | while (last > 0) 30 | { 31 | /* CPU Burst */ 32 | times(&start_time); 33 | /* 其实只有t.tms_utime才是真正的CPU时间。但我们是在模拟一个 34 | * 只在用户状态运行的CPU大户,就像“for(;;);”。所以把t.tms_stime 35 | * 加上很合理。*/ 36 | do 37 | { 38 | times(¤t_time); 39 | utime = current_time.tms_utime - start_time.tms_utime; 40 | stime = current_time.tms_stime - start_time.tms_stime; 41 | } while ( ( (utime + stime) / HZ ) < cpu_time ); 42 | last -= cpu_time; 43 | 44 | if (last <= 0 ) 45 | break; 46 | 47 | /* IO Burst */ 48 | /* 用sleep(1)模拟1秒钟的I/O操作 */ 49 | sleep_time=0; 50 | while (sleep_time < io_time) 51 | { 52 | sleep(1); 53 | sleep_time++; 54 | } 55 | last -= sleep_time; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Resources/testlab2.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | string1="Sunner" 4 | string2="Richard Stallman" 5 | string3="This is a very very long string!" 6 | 7 | score1=10 8 | score2=10 9 | score3=10 10 | 11 | expected1="Sunner" 12 | expected2="Richard Stallman" 13 | expected3="Richard Stallman" 14 | 15 | echo Testing string:$string1 16 | ./iam "$string1" 17 | result=`./whoami` 18 | if [ "$result" = "$expected1" ]; then 19 | echo PASS. 20 | else 21 | score1=0 22 | echo FAILED. 23 | fi 24 | score=$score1 25 | 26 | echo Testing string:$string2 27 | ./iam "$string2" 28 | result=`./whoami` 29 | if [ "$result" = "$expected2" ]; then 30 | echo PASS. 31 | else 32 | score2=0 33 | echo FAILED. 34 | fi 35 | score=$score+$score2 36 | 37 | echo Testing string:$string3 38 | ./iam "$string3" 39 | result=`./whoami` 40 | if [ "$result" = "$expected3" ]; then 41 | echo PASS. 42 | else 43 | score3=0 44 | echo FAILED. 45 | fi 46 | score=$score+$score3 47 | 48 | let "totalscore=$score" 49 | echo Score: $score = $totalscore% 50 | -------------------------------------------------------------------------------- /lab1/bootsect.s: -------------------------------------------------------------------------------- 1 | .globl begtext, begdata, begbss, endtext, enddata, endbss 2 | .text 3 | begtext: 4 | .data 5 | begdata: 6 | .bss 7 | begbss: 8 | .text 9 | 10 | SETUPLEN = 4 ! setup程序代码占用扇区数 11 | BOOTSEG = 0x07c0 ! bootsect程序代码所在内存原始地址 12 | INITSEG = 0x9000 ! 将bootsect移动到0x9000处 13 | SETUPSEG = 0x9020 ! setup程序开始的地址 14 | 15 | entry _start 16 | _start: 17 | 18 | ! 下面这段代码将自身复制到0x9000处 19 | mov ax,#BOOTSEG 20 | mov ds,ax 21 | mov ax,#INITSEG 22 | mov es,ax 23 | mov cx,#256 24 | sub si,si 25 | sub di,di 26 | rep 27 | movw 28 | 29 | ! 复制完成从0x9000的go标号处开始执行 30 | jmpi go,INITSEG 31 | go: mov ax,cs 32 | mov ds,ax !设置ds=es=cs 33 | mov es,ax 34 | 35 | ! 加载setup.s程序 36 | load_setup: 37 | mov dx,#0x0000 ! drive 0, head 0 38 | mov cx,#0x0002 ! sector 2, track 0 39 | mov bx,#0x0200 ! address = 512, in INITSEG 40 | mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors 41 | int 0x13 ! read it 42 | jnc ok_load_setup ! ok - continue 43 | !加载错误 44 | mov dx,#0x0000 45 | mov ax,#0x0000 ! reset the diskette 46 | int 0x13 47 | j load_setup 48 | 49 | ok_load_setup: 50 | 51 | !输出一些信息 52 | 53 | mov ah,#0x03 ! read cursor pos 54 | xor bh,bh 55 | int 0x10 56 | 57 | mov cx,#27 58 | mov bx,#0x000c ! page 0, attribute c 59 | mov bp,#msg1 ! es:bp 指向待显示 字符串 60 | mov ax,#0x1301 ! write string, move cursor 61 | int 0x10 62 | !开始执行setup代码 63 | jmpi 0,SETUPSEG 64 | 65 | msg1: 66 | .byte 13,10 67 | .ascii "Tonatus is booting..." 68 | .byte 13,10,13,10 69 | 70 | .org 510 71 | boot_flag: 72 | .word 0xAA55 73 | .text 74 | endtext: 75 | .data 76 | enddata: 77 | .bss 78 | endbss: 79 | -------------------------------------------------------------------------------- /lab1/report.txt: -------------------------------------------------------------------------------- 1 | Answers: 2 | 1) 计算机上电,BIOS初始化中断向量表后,会将启动设备的第一个扇区(即引导扇区)读入内存地址0x7c00(31KB)处,并跳转到此处开始执行。而为了方便加载主模块,引导程序首先会将自己移动到内存相对靠后的位置,如linux0.11的bootsect程序先将自己移动到0x90000(576KB)处。这样先移动是多此一举的。 3 | 解决方案:在保证可靠性的前提下尽量扩大实地址模式下BIOS可访问的内存的范围,如引导扇区加载到0x90000等内存高地址处而不是0x7c00。 4 | 5 | 2) 计算机上电后,ROM BIOS会在物理内存0处初始化中断向量表,其中有256个中断向量,每个中断向量占用4字节,共1KB,在物理内存地址0x000 - ox3ff处,这些中断向量供BIOS中断使用。这就导致了一个问题,如果操作系统的引导程序在加载操作系统时使用了BIOS中断来获取或者显示一些信息时,这1KB地址不能被覆盖。然而操作系统的主模块为了让其中代码地址等于实际的物理地址,需要将其加载到内存0x0000处。所以操作系统在加载时需要先将主模块加载到内存中不与BIOS中断向量表冲突的地方,之后可以覆盖中断向量表时才将其移动到内存起始处,如Linux0.11的System模块就是在bootsect程序中先加载到0x10000,之后在setup程序中移到0x0000处。 这样先加载到另外地方之后再移动到内存起始位置是多此一举的。 6 | 解决方案:可以将BIOS中断向量表放到实模式下能寻址内存的其他地方,操作系统引导程序直接将操作系统的主模块读到内存的起始处。 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /lab1/setup.s: -------------------------------------------------------------------------------- 1 | .globl begtext, begdata, begbss, endtext, enddata, endbss 2 | .text 3 | begtext: 4 | .data 5 | begdata: 6 | .bss 7 | begbss: 8 | .text 9 | 10 | BOOTSEG = 0x07c0 ! original address of boot-sector 11 | INITSEG = 0x9000 ! we move boot here - out of the way 12 | SETUPSEG = 0x9020 ! setup starts here 13 | 14 | entry _start 15 | _start: 16 | 17 | !设置cs=ds=es 18 | mov ax,cs 19 | mov ds,ax 20 | mov es,ax 21 | 22 | mov ah,#0x03 ! read cursor pos 23 | xor bh,bh 24 | int 0x10 25 | 26 | mov cx,#28 27 | mov bx,#0x000c ! page 0, attribute c 28 | mov bp,#msg1 29 | mov ax,#0x1301 ! write string, move cursor 30 | int 0x10 31 | 32 | ! ok, the read went well so we get current cursor position and save it for 33 | ! posterity. 34 | ! 获取光标位置 => 0x9000:0 35 | mov ax,#INITSEG ! this is done in bootsect already, but... 36 | mov ds,ax 37 | mov ah,#0x03 ! read cursor pos 38 | xor bh,bh 39 | int 0x10 ! save it in known place, con_init fetches 40 | mov [0],dx ! it from 0x90000. 41 | 42 | ! Get memory size (extended mem, kB) 43 | ! 获取拓展内存大小 => 0x9000:2 44 | mov ah,#0x88 45 | int 0x15 46 | mov [2],ax 47 | 48 | ! Get hd0 data 49 | ! 获取硬盘参数 => 0x9000:80 大小:16B 50 | mov ax,#0x0000 51 | mov ds,ax 52 | lds si,[4*0x41] 53 | mov ax,#INITSEG 54 | mov es,ax 55 | mov di,#0x0080 56 | mov cx,#0x10 57 | rep 58 | movsb 59 | 60 | ! 前面修改了ds寄存器,这里将其设置为0x9000 61 | mov ax,#INITSEG 62 | mov ds,ax 63 | mov ax,#SETUPSEG 64 | mov es,ax 65 | 66 | !显示 Cursor POS: 字符串 67 | mov ah,#0x03 ! read cursor pos 68 | xor bh,bh 69 | int 0x10 70 | mov cx,#11 71 | mov bx,#0x0007 ! page 0, attribute c 72 | mov bp,#cur 73 | mov ax,#0x1301 ! write string, move cursor 74 | int 0x10 75 | 76 | !调用 print_hex 显示具体信息 77 | mov ax,[0] 78 | call print_hex 79 | call print_nl 80 | 81 | !显示 Memory SIZE: 字符串 82 | mov ah,#0x03 ! read cursor pos 83 | xor bh,bh 84 | int 0x10 85 | mov cx,#12 86 | mov bx,#0x0007 ! page 0, attribute c 87 | mov bp,#mem 88 | mov ax,#0x1301 ! write string, move cursor 89 | int 0x10 90 | 91 | !显示 具体信息 92 | mov ax,[2] 93 | call print_hex 94 | 95 | !显示相应 提示信息 96 | mov ah,#0x03 ! read cursor pos 97 | xor bh,bh 98 | int 0x10 99 | mov cx,#25 100 | mov bx,#0x0007 ! page 0, attribute c 101 | mov bp,#cyl 102 | mov ax,#0x1301 ! write string, move cursor 103 | int 0x10 104 | 105 | !显示具体信息 106 | mov ax,[0x80] 107 | call print_hex 108 | call print_nl 109 | 110 | !显示 提示信息 111 | mov ah,#0x03 ! read cursor pos 112 | xor bh,bh 113 | int 0x10 114 | mov cx,#8 115 | mov bx,#0x0007 ! page 0, attribute c 116 | mov bp,#head 117 | mov ax,#0x1301 ! write string, move cursor 118 | int 0x10 119 | 120 | !显示 具体信息 121 | mov ax,[0x80+0x02] 122 | call print_hex 123 | call print_nl 124 | 125 | !显示 提示信息 126 | mov ah,#0x03 ! read cursor pos 127 | xor bh,bh 128 | int 0x10 129 | mov cx,#8 130 | mov bx,#0x0007 ! page 0, attribute c 131 | mov bp,#sect 132 | mov ax,#0x1301 ! write string, move cursor 133 | int 0x10 134 | 135 | !显示 具体信息 136 | mov ax,[0x80+0x0e] 137 | call print_hex 138 | call print_nl 139 | 140 | !死循环 141 | l: jmp l 142 | 143 | !以16进制方式打印ax寄存器里的16位数 144 | print_hex: 145 | mov cx,#4 ! 4个十六进制数字 146 | mov dx,ax ! 将ax所指的值放入dx中,ax作为参数传递寄存器 147 | print_digit: 148 | rol dx,#4 ! 循环以使低4比特用上 !! 取dx的高4比特移到低4比特处。 149 | mov ax,#0xe0f ! ah = 请求的功能值,al = 半字节(4个比特)掩码。 150 | and al,dl ! 取dl的低4比特值。 151 | add al,#0x30 ! 给al数字加上十六进制0x30 152 | cmp al,#0x3a 153 | jl outp !是一个不大于十的数字 154 | add al,#0x07 !是a~f,要多加7 155 | outp: 156 | int 0x10 157 | loop print_digit 158 | ret 159 | 160 | !打印回车换行 161 | print_nl: 162 | mov ax,#0xe0d 163 | int 0x10 164 | mov al,#0xa 165 | int 0x10 166 | ret 167 | 168 | msg1: 169 | .byte 13,10 170 | .ascii "Now we are in setup..." 171 | .byte 13,10,13,10 172 | cur: 173 | .ascii "Cursor POS:" 174 | mem: 175 | .ascii "Memory SIZE:" 176 | cyl: 177 | .ascii "KB" 178 | .byte 13,10,13,10 179 | .ascii "HD Info" 180 | .byte 13,10 181 | .ascii "Cylinders:" 182 | head: 183 | .ascii "Headers:" 184 | sect: 185 | .ascii "Secotrs:" 186 | 187 | .text 188 | endtext: 189 | .data 190 | enddata: 191 | .bss 192 | endbss: 193 | -------------------------------------------------------------------------------- /lab2/iam.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define __LIBRARY__ 3 | #include 4 | #include 5 | 6 | _syscall1(int, iam, const char*, name); 7 | 8 | int main(int argc,char ** argv) 9 | { 10 | iam(argv[1]); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /lab2/report.txt: -------------------------------------------------------------------------------- 1 | Answers: 2 | 1) 从linux-0.11/include/unistd.h中可以知道_syscall宏展开的系统调用最多3个参数,使用ebx,ecx,edx三个寄存器传递参数。 3 | 解决限制的方法:将需要传递的多个参数保存在有特定结构的区间中,并将该用户态地址空间的这个区间的首地址作为一个参数传递给系统调用。最后通过寄存器间接寻址方式便可以访问所有参数。当然,这么做的话,参数合法性验证尤其必要。实际上,linux2.6内核废除了_syscall宏,而使用syscall函数,其接受一个可变参数,原理类似,参考《深入理解Linux内核(第三版)》 P409。 4 | 5 | 2) 6 | 首先,修改 include/linux/sys.h 在sys_call_table数组最后加入sys_foo,并仿照上面给出其他系统调用格式加上 7 | extern rettype sys_foo(); 8 | 9 | 其次,修改include/unistd.h 10 | #define __NR_foo num 11 | num为接下来使用的系统调用号 12 | 13 | 然后修改 kernel/system_call.s 14 | nr_system_calls = num 15 | num为在原值加1 即系统调用总数目加1 16 | 17 | 接着在kernel中添加 foo.c 18 | 若需要支持内核态与用户态数据交互 19 | 则包含include/asm/segment.h,其中有put_fs_XXX get_fs_XXX函数 20 | 在foo.c实现系统调用sys_foo() 21 | 22 | 最后修改kernel的Makefile,将foo.c与内核其它代码编译链接到一起 23 | 24 | 系统调用用户界面要 25 | #define __LIBRARY__ 26 | #include 27 | _syscallN宏展开系统调用,提供用户态的系统调用接口(参数数目确定具体宏) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /lab2/sys.h: -------------------------------------------------------------------------------- 1 | extern int sys_setup(); 2 | extern int sys_exit(); 3 | extern int sys_fork(); 4 | extern int sys_read(); 5 | extern int sys_write(); 6 | extern int sys_open(); 7 | extern int sys_close(); 8 | extern int sys_waitpid(); 9 | extern int sys_creat(); 10 | extern int sys_link(); 11 | extern int sys_unlink(); 12 | extern int sys_execve(); 13 | extern int sys_chdir(); 14 | extern int sys_time(); 15 | extern int sys_mknod(); 16 | extern int sys_chmod(); 17 | extern int sys_chown(); 18 | extern int sys_break(); 19 | extern int sys_stat(); 20 | extern int sys_lseek(); 21 | extern int sys_getpid(); 22 | extern int sys_mount(); 23 | extern int sys_umount(); 24 | extern int sys_setuid(); 25 | extern int sys_getuid(); 26 | extern int sys_stime(); 27 | extern int sys_ptrace(); 28 | extern int sys_alarm(); 29 | extern int sys_fstat(); 30 | extern int sys_pause(); 31 | extern int sys_utime(); 32 | extern int sys_stty(); 33 | extern int sys_gtty(); 34 | extern int sys_access(); 35 | extern int sys_nice(); 36 | extern int sys_ftime(); 37 | extern int sys_sync(); 38 | extern int sys_kill(); 39 | extern int sys_rename(); 40 | extern int sys_mkdir(); 41 | extern int sys_rmdir(); 42 | extern int sys_dup(); 43 | extern int sys_pipe(); 44 | extern int sys_times(); 45 | extern int sys_prof(); 46 | extern int sys_brk(); 47 | extern int sys_setgid(); 48 | extern int sys_getgid(); 49 | extern int sys_signal(); 50 | extern int sys_geteuid(); 51 | extern int sys_getegid(); 52 | extern int sys_acct(); 53 | extern int sys_phys(); 54 | extern int sys_lock(); 55 | extern int sys_ioctl(); 56 | extern int sys_fcntl(); 57 | extern int sys_mpx(); 58 | extern int sys_setpgid(); 59 | extern int sys_ulimit(); 60 | extern int sys_uname(); 61 | extern int sys_umask(); 62 | extern int sys_chroot(); 63 | extern int sys_ustat(); 64 | extern int sys_dup2(); 65 | extern int sys_getppid(); 66 | extern int sys_getpgrp(); 67 | extern int sys_setsid(); 68 | extern int sys_sigaction(); 69 | extern int sys_sgetmask(); 70 | extern int sys_ssetmask(); 71 | extern int sys_setreuid(); 72 | extern int sys_setregid(); 73 | extern int sys_iam(); 74 | extern int sys_whoami(); 75 | fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, 76 | sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, 77 | sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod, 78 | sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount, 79 | sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm, 80 | sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access, 81 | sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir, 82 | sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid, 83 | sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys, 84 | sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit, 85 | sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid, 86 | sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask, 87 | sys_setreuid,sys_setregid,sys_iam,sys_whoami }; 88 | -------------------------------------------------------------------------------- /lab2/who.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char msg[24]; //23个字符 +'\0' = 24 6 | 7 | int sys_iam(const char * name) 8 | /*** 9 | function:将name的内容拷贝到msg,name的长度不超过23个字符 10 | return:拷贝的字符数。如果name的字符个数超过了23,则返回“­-1”,并置errno为EINVAL。 11 | ****/ 12 | { 13 | int i; 14 | //临时存储 输入字符串 操作失败时不影响msg 15 | char tmp[30]; 16 | for(i=0; i<30; i++) 17 | { 18 | //从用户态内存取得数据 19 | tmp[i] = get_fs_byte(name+i); 20 | if(tmp[i] == '\0') break; //字符串结束 21 | } 22 | //printk(tmp); 23 | i=0; 24 | while(i<30&&tmp[i]!='\0') i++; 25 | int len = i; 26 | // int len = strlen(tmp); 27 | //字符长度大于23个 28 | if(len > 23) 29 | { 30 | // printk("String too long!\n"); 31 | return -(EINVAL); //置errno为EINVAL 返回“­-1” 具体见_syscalln宏展开 32 | } 33 | strcpy(msg,tmp); 34 | //printk(tmp); 35 | return i; 36 | } 37 | 38 | int sys_whoami(char* name, unsigned int size) 39 | /*** 40 | function:将msg拷贝到name指向的用户地址空间中,确保不会对name越界访存(name的大小由size说明) 41 | return: 拷贝的字符数。如果size小于需要的空间,则返回“­-1”,并置errno为EINVAL。 42 | ****/ 43 | { 44 | //msg的长度大于 size 45 | int len = 0; 46 | for(;msg[len]!='\0';len++); 47 | if(len > size) 48 | { 49 | return -(EINVAL); 50 | } 51 | int i = 0; 52 | //把msg 输出至 name 53 | for(i=0; i 2 | #define __LIBRARY__ 3 | #include 4 | 5 | _syscall2(int, whoami,char*,name,unsigned int,size); 6 | 7 | int main() 8 | { 9 | char s[30]; 10 | whoami(s,30); 11 | printf("%s",s); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /lab3/exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/exit.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int sys_pause(void); 17 | int sys_close(int fd); 18 | 19 | void release(struct task_struct * p) 20 | { 21 | int i; 22 | 23 | if (!p) 24 | return; 25 | for (i=1 ; i32) 38 | return -EINVAL; 39 | if (priv || (current->euid==p->euid) || suser()) 40 | p->signal |= (1<<(sig-1)); 41 | else 42 | return -EPERM; 43 | return 0; 44 | } 45 | 46 | static void kill_session(void) 47 | { 48 | struct task_struct **p = NR_TASKS + task; 49 | 50 | while (--p > &FIRST_TASK) { 51 | if (*p && (*p)->session == current->session) 52 | (*p)->signal |= 1<<(SIGHUP-1); 53 | } 54 | } 55 | 56 | /* 57 | * XXX need to check permissions needed to send signals to process 58 | * groups, etc. etc. kill() permissions semantics are tricky! 59 | */ 60 | int sys_kill(int pid,int sig) 61 | { 62 | struct task_struct **p = NR_TASKS + task; 63 | int err, retval = 0; 64 | 65 | if (!pid) while (--p > &FIRST_TASK) { 66 | if (*p && (*p)->pgrp == current->pid) 67 | if ((err=send_sig(sig,*p,1))) 68 | retval = err; 69 | } else if (pid>0) while (--p > &FIRST_TASK) { 70 | if (*p && (*p)->pid == pid) 71 | if ((err=send_sig(sig,*p,0))) 72 | retval = err; 73 | } else if (pid == -1) while (--p > &FIRST_TASK) { 74 | if ((err = send_sig(sig,*p,0))) 75 | retval = err; 76 | } else while (--p > &FIRST_TASK) 77 | if (*p && (*p)->pgrp == -pid) 78 | if ((err = send_sig(sig,*p,0))) 79 | retval = err; 80 | return retval; 81 | } 82 | 83 | static void tell_father(int pid) 84 | { 85 | int i; 86 | 87 | if (pid) 88 | for (i=0;ipid != pid) 92 | continue; 93 | task[i]->signal |= (1<<(SIGCHLD-1)); 94 | return; 95 | } 96 | /* if we don't find any fathers, we just release ourselves */ 97 | /* This is not really OK. Must change it to make father 1 */ 98 | printk("BAD BAD - no father found\n\r"); 99 | release(current); 100 | } 101 | 102 | int do_exit(long code) 103 | { 104 | int i; 105 | free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); 106 | free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); 107 | for (i=0 ; ifather == current->pid) { 109 | task[i]->father = 1; 110 | if (task[i]->state == TASK_ZOMBIE) 111 | {/* assumption task[1] is always init */ 112 | (void) send_sig(SIGCHLD, task[1], 1); 113 | } 114 | } 115 | for (i=0 ; ifilp[i]) 117 | sys_close(i); 118 | iput(current->pwd); 119 | current->pwd=NULL; 120 | iput(current->root); 121 | current->root=NULL; 122 | iput(current->executable); 123 | current->executable=NULL; 124 | if (current->leader && current->tty >= 0) 125 | tty_table[current->tty].pgrp = 0; 126 | if (last_task_used_math == current) 127 | last_task_used_math = NULL; 128 | if (current->leader) 129 | kill_session(); 130 | current->state = TASK_ZOMBIE; 131 | /* 132 | *退出一个进程 133 | */ 134 | fprintk(3,"%d\tE\t%d\n",current->pid,jiffies); 135 | current->exit_code = code; 136 | tell_father(current->father); 137 | schedule(); 138 | return (-1); /* just to suppress warnings */ 139 | } 140 | 141 | int sys_exit(int error_code) 142 | { 143 | return do_exit((error_code&0xff)<<8); 144 | } 145 | 146 | int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options) 147 | { 148 | int flag, code; 149 | struct task_struct ** p; 150 | 151 | verify_area(stat_addr,4); 152 | repeat: 153 | flag=0; 154 | for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) { 155 | if (!*p || *p == current) 156 | continue; 157 | if ((*p)->father != current->pid) 158 | continue; 159 | if (pid>0) { 160 | if ((*p)->pid != pid) 161 | continue; 162 | } else if (!pid) { 163 | if ((*p)->pgrp != current->pgrp) 164 | continue; 165 | } else if (pid != -1) { 166 | if ((*p)->pgrp != -pid) 167 | continue; 168 | } 169 | switch ((*p)->state) { 170 | case TASK_STOPPED: 171 | if (!(options & WUNTRACED)) 172 | continue; 173 | put_fs_long(0x7f,stat_addr); 174 | return (*p)->pid; 175 | case TASK_ZOMBIE: 176 | current->cutime += (*p)->utime; 177 | current->cstime += (*p)->stime; 178 | flag = (*p)->pid; 179 | code = (*p)->exit_code; 180 | release(*p); 181 | put_fs_long(code,stat_addr); 182 | return flag; 183 | default: 184 | flag=1; 185 | continue; 186 | } 187 | } 188 | if (flag) { 189 | if (options & WNOHANG) 190 | return 0; 191 | current->state=TASK_INTERRUPTIBLE; 192 | /* 193 | *当前进程 => 等待 194 | */ 195 | fprintk(3,"%d\tW\t%d\n",current->pid,jiffies); 196 | schedule(); 197 | if (!(current->signal &= ~(1<<(SIGCHLD-1)))) 198 | goto repeat; 199 | else 200 | return -EINTR; 201 | } 202 | return -ECHILD; 203 | } 204 | 205 | 206 | -------------------------------------------------------------------------------- /lab3/fork.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/fork.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * 'fork.c' contains the help-routines for the 'fork' system call 9 | * (see also system_call.s), and some misc functions ('verify_area'). 10 | * Fork is rather simple, once you get the hang of it, but the memory 11 | * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()' 12 | */ 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | extern void write_verify(unsigned long address); 21 | 22 | long last_pid=0; 23 | 24 | void verify_area(void * addr,int size) 25 | { 26 | unsigned long start; 27 | 28 | start = (unsigned long) addr; 29 | size += start & 0xfff; 30 | start &= 0xfffff000; 31 | start += get_base(current->ldt[2]); 32 | while (size>0) { 33 | size -= 4096; 34 | write_verify(start); 35 | start += 4096; 36 | } 37 | } 38 | 39 | int copy_mem(int nr,struct task_struct * p) 40 | { 41 | unsigned long old_data_base,new_data_base,data_limit; 42 | unsigned long old_code_base,new_code_base,code_limit; 43 | 44 | code_limit=get_limit(0x0f); 45 | data_limit=get_limit(0x17); 46 | old_code_base = get_base(current->ldt[1]); 47 | old_data_base = get_base(current->ldt[2]); 48 | if (old_data_base != old_code_base) 49 | panic("We don't support separate I&D"); 50 | if (data_limit < code_limit) 51 | panic("Bad data_limit"); 52 | new_data_base = new_code_base = nr * 0x4000000; 53 | p->start_code = new_code_base; 54 | set_base(p->ldt[1],new_code_base); 55 | set_base(p->ldt[2],new_data_base); 56 | if (copy_page_tables(old_data_base,new_data_base,data_limit)) { 57 | printk("free_page_tables: from copy_mem\n"); 58 | free_page_tables(new_data_base,data_limit); 59 | return -ENOMEM; 60 | } 61 | return 0; 62 | } 63 | 64 | /* 65 | * Ok, this is the main fork-routine. It copies the system process 66 | * information (task[nr]) and sets up the necessary registers. It 67 | * also copies the data segment in it's entirety. 68 | */ 69 | int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, 70 | long ebx,long ecx,long edx, 71 | long fs,long es,long ds, 72 | long eip,long cs,long eflags,long esp,long ss) 73 | { 74 | struct task_struct *p; 75 | int i; 76 | struct file *f; 77 | 78 | p = (struct task_struct *) get_free_page(); 79 | if (!p) 80 | return -EAGAIN; 81 | task[nr] = p; 82 | *p = *current; /* NOTE! this doesn't copy the supervisor stack */ 83 | p->state = TASK_UNINTERRUPTIBLE; 84 | p->pid = last_pid; 85 | p->father = current->pid; 86 | p->counter = p->priority; 87 | p->signal = 0; 88 | p->alarm = 0; 89 | p->leader = 0; /* process leadership doesn't inherit */ 90 | p->utime = p->stime = 0; 91 | p->cutime = p->cstime = 0; 92 | p->start_time = jiffies; 93 | /* 94 | *新建一个进程 95 | */ 96 | fprintk(3,"%d\tN\t%d\n",p->pid,jiffies); 97 | p->tss.back_link = 0; 98 | p->tss.esp0 = PAGE_SIZE + (long) p; 99 | p->tss.ss0 = 0x10; 100 | p->tss.eip = eip; 101 | p->tss.eflags = eflags; 102 | p->tss.eax = 0; 103 | p->tss.ecx = ecx; 104 | p->tss.edx = edx; 105 | p->tss.ebx = ebx; 106 | p->tss.esp = esp; 107 | p->tss.ebp = ebp; 108 | p->tss.esi = esi; 109 | p->tss.edi = edi; 110 | p->tss.es = es & 0xffff; 111 | p->tss.cs = cs & 0xffff; 112 | p->tss.ss = ss & 0xffff; 113 | p->tss.ds = ds & 0xffff; 114 | p->tss.fs = fs & 0xffff; 115 | p->tss.gs = gs & 0xffff; 116 | p->tss.ldt = _LDT(nr); 117 | p->tss.trace_bitmap = 0x80000000; 118 | if (last_task_used_math == current) 119 | __asm__("clts ; fnsave %0"::"m" (p->tss.i387)); 120 | if (copy_mem(nr,p)) { 121 | task[nr] = NULL; 122 | free_page((long) p); 123 | return -EAGAIN; 124 | } 125 | for (i=0; ifilp[i])) 127 | f->f_count++; 128 | if (current->pwd) 129 | current->pwd->i_count++; 130 | if (current->root) 131 | current->root->i_count++; 132 | if (current->executable) 133 | current->executable->i_count++; 134 | set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss)); 135 | set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt)); 136 | p->state = TASK_RUNNING; /* do this last, just in case */ 137 | /* 138 | *新建 => 就绪 139 | */ 140 | fprintk(3,"%d\tJ\t%d\n",p->pid,jiffies); 141 | return last_pid; 142 | } 143 | 144 | int find_empty_process(void) 145 | { 146 | int i; 147 | 148 | repeat: 149 | if ((++last_pid)<0) last_pid=1; 150 | for(i=0 ; ipid == last_pid) goto repeat; 152 | for(i=1 ; i 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | static char buf[1024]; 19 | 20 | extern int vsprintf(char * buf, const char * fmt, va_list args); 21 | 22 | int printk(const char *fmt, ...) 23 | { 24 | va_list args; 25 | int i; 26 | 27 | va_start(args, fmt); 28 | i=vsprintf(buf,fmt,args); 29 | va_end(args); 30 | __asm__("push %%fs\n\t" 31 | "push %%ds\n\t" 32 | "pop %%fs\n\t" 33 | "pushl %0\n\t" 34 | "pushl $buf\n\t" 35 | "pushl $0\n\t" 36 | "call tty_write\n\t" 37 | "addl $8,%%esp\n\t" 38 | "popl %0\n\t" 39 | "pop %%fs" 40 | ::"r" (i):"ax","cx","dx"); 41 | return i; 42 | } 43 | 44 | /* 45 | * write by sunner 46 | */ 47 | static char logbuf[1024]; 48 | int fprintk(int fd, const char *fmt, ...) 49 | { 50 | va_list args; 51 | int count; 52 | struct file * file; 53 | struct m_inode * inode; 54 | va_start(args, fmt); 55 | count=vsprintf(logbuf, fmt, args); 56 | va_end(args); 57 | if (fd < 3) 58 | /* 如果输出到stdout或stderr,直接调用sys_write即可 */ 59 | { 60 | __asm__("push %%fs\n\t" 61 | "push %%ds\n\t" 62 | "pop %%fs\n\t" 63 | "pushl %0\n\t" 64 | "pushl $logbuf\n\t" /* 注意对于Windows环境来说,是_logbuf,下同 */ 65 | "pushl %1\n\t" 66 | "call sys_write\n\t" /* 注意对于Windows环境来说,是_sys_write,下同 */ 67 | "addl $8,%%esp\n\t" 68 | "popl %0\n\t" 69 | "pop %%fs" 70 | ::"r" (count),"r" (fd):"ax","cx","dx"); 71 | } 72 | else 73 | /* 假定>=3的描述符都与文件关联。事实上,还存在很多其它情况,这里并没有考虑。*/ 74 | { 75 | if (!(file=task[0]->filp[fd])) /* 从进程0的文件描述符表中得到文件句柄 */ 76 | return 0; 77 | inode=file->f_inode; 78 | __asm__("push %%fs\n\t" 79 | "push %%ds\n\t" 80 | "pop %%fs\n\t" 81 | "pushl %0\n\t" 82 | "pushl $logbuf\n\t" 83 | "pushl %1\n\t" 84 | "pushl %2\n\t" 85 | "call file_write\n\t" 86 | "addl $12,%%esp\n\t" 87 | "popl %0\n\t" 88 | "pop %%fs" 89 | ::"r" (count),"r" (file),"r" (inode):"ax","cx","dx"); 90 | } 91 | return count; 92 | } -------------------------------------------------------------------------------- /lab3/process.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define HZ 100 8 | 9 | void cpuio_bound(int last, int cpu_time, int io_time); 10 | /* 11 | 1. 所有子进程都并行运行,每个子进程的实际运行时间一般不超过30秒; 12 | 2. 父进程向标准输出打印所有子进程的id,并在所有子进程都退出后才退出; 13 | */ 14 | int main(int argc, char * argv[]) 15 | { 16 | pid_t n_proc[10]; /*10个子进程 PID*/ 17 | int i; 18 | for(i=0;i<10;i++) 19 | { 20 | n_proc[i] = fork(); 21 | /*子进程*/ 22 | if(n_proc[i] == 0) 23 | { 24 | cpuio_bound(20,2*i,20-2*i); /*每个子进程都占用20s*/ 25 | return 0; /*执行完cpuio_bound 以后,结束该子进程*/ 26 | } 27 | /*fork 失败*/ 28 | else if(n_proc[i] < 0 ) 29 | { 30 | printf("Failed to fork child process %d!\n",i+1); 31 | return -1; 32 | } 33 | /*父进程继续fork*/ 34 | } 35 | /*打印所有子进程PID*/ 36 | for(i=0;i<10;i++) 37 | printf("Child PID: %d\n",n_proc[i]); 38 | /*等待所有子进程完成*/ 39 | wait(&i); /*Linux 0.11 上 gcc要求必须有一个参数, gcc3.4+则不需要*/ 40 | return 0; 41 | } 42 | 43 | /* 44 | * 此函数按照参数占用CPU和I/O时间 45 | * last: 函数实际占用CPU和I/O的总时间,不含在就绪队列中的时间,>=0是必须的 46 | * cpu_time: 一次连续占用CPU的时间,>=0是必须的 47 | * io_time: 一次I/O消耗的时间,>=0是必须的 48 | * 如果last > cpu_time + io_time,则往复多次占用CPU和I/O 49 | * 所有时间的单位为秒 50 | */ 51 | void cpuio_bound(int last, int cpu_time, int io_time) 52 | { 53 | struct tms start_time, current_time; 54 | clock_t utime, stime; 55 | int sleep_time; 56 | 57 | while (last > 0) 58 | { 59 | /* CPU Burst */ 60 | times(&start_time); 61 | /* 其实只有t.tms_utime才是真正的CPU时间。但我们是在模拟一个 62 | * 只在用户状态运行的CPU大户,就像“for(;;);”。所以把t.tms_stime 63 | * 加上很合理。*/ 64 | do 65 | { 66 | times(¤t_time); 67 | utime = current_time.tms_utime - start_time.tms_utime; 68 | stime = current_time.tms_stime - start_time.tms_stime; 69 | } while ( ( (utime + stime) / HZ ) < cpu_time ); 70 | last -= cpu_time; 71 | 72 | if (last <= 0 ) 73 | break; 74 | 75 | /* IO Burst */ 76 | /* 用sleep(1)模拟1秒钟的I/O操作 */ 77 | sleep_time=0; 78 | while (sleep_time < io_time) 79 | { 80 | sleep(1); 81 | sleep_time++; 82 | } 83 | last -= sleep_time; 84 | } 85 | } -------------------------------------------------------------------------------- /lab3/report.txt: -------------------------------------------------------------------------------- 1 | Answers: 2 | 1. 单进程编程所写的程序是顺序执行的,彼此之间有严格的执行逻辑;在没有其他程序的干扰下,数据是同步的,而多进程编程所写的程序是同时执行的,虽然共享文件等,但是由于多个进程之间执行顺序无法得知,故而要考虑进程之间的关系和影响,尤其是数据异步,程序员要做好进程之间同步,通信,互斥等。相比较而言,多进程编程比单进程编程复杂得多,但是用途广泛得多。 3 | 4 | 2. 在include/linux/sched.h中修改#define INIT_TASK宏定义中counter和priority数值 5 | 原始时间片为15,修改了两次时间片,分别为10和20,结果如下: 6 | 7 | 时间片10 8 | (Unit: tick) 9 | Process Turnaround Waiting CPU Burst I/O Burst 10 | 7 2298 97 0 2200 11 | 8 2319 1687 200 432 12 | 9 2368 2098 270 0 13 | 10 2358 2087 270 0 14 | 11 2347 2076 270 0 15 | 12 2336 2066 270 0 16 | 13 2326 2055 270 0 17 | 14 2315 2044 270 0 18 | 15 2304 2034 270 0 19 | 16 2292 2021 270 0 20 | Average: 2326.30 1826.50 21 | Throughout: 0.42/s 22 | 23 | 时间片15 24 | (Unit: tick) 25 | Process Turnaround Waiting CPU Burst I/O Burst 26 | 7 2247 142 0 2105 27 | 8 2202 1686 200 315 28 | 9 2246 1991 255 0 29 | 10 2230 1975 255 0 30 | 11 2215 1959 255 0 31 | 12 2199 1944 255 0 32 | 13 2183 1928 255 0 33 | 14 2168 1912 255 0 34 | 15 2152 1897 255 0 35 | 16 2137 1881 255 0 36 | Average: 2197.90 1731.50 37 | Throughout: 0.45/s 38 | 39 | 时间片20 40 | (Unit: tick) 41 | Process Turnaround Waiting CPU Burst I/O Burst 42 | 7 2587 187 0 2400 43 | 8 2567 1766 200 600 44 | 9 2608 2308 300 0 45 | 10 2585 2285 300 0 46 | 11 2565 2264 300 0 47 | 12 2544 2244 300 0 48 | 13 2523 2223 300 0 49 | 14 2503 2202 300 0 50 | 15 2482 2182 300 0 51 | 16 2461 2161 300 0 52 | Average: 2542.50 1982.20 53 | Throughout: 0.38/s 54 | 55 | 时间片变小,进程因时间片到时产生的进程调度次数变多,该进程等待时间越长。 56 | 然而随着时间片增大,进程因中断或者睡眠进入的进程调度次数也增多,等待时间随之变长。 57 | 故而需要设置合理的时间片,既不能过大,也不能过小。 58 | -------------------------------------------------------------------------------- /lab4/pc.c: -------------------------------------------------------------------------------- 1 | #define __LIBRARY__ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | _syscall2(sem_t*,sem_open,const char *,name,unsigned int,value); 9 | _syscall1(int,sem_wait,sem_t*,sem); 10 | _syscall1(int,sem_post,sem_t*,sem); 11 | _syscall1(int,sem_unlink,const char *,name); 12 | 13 | #define NUMBER 520 /*打出数字总数*/ 14 | #define CHILD 5 /*消费者进程数*/ 15 | #define BUFSIZE 10 /*缓冲区大小*/ 16 | 17 | sem_t *empty, *full, *mutex; 18 | int fno; /*文件描述符*/ 19 | 20 | int main() 21 | { 22 | int i,j,k; 23 | int data; 24 | pid_t p; 25 | int buf_out = 0; /*从缓冲区读取位置*/ 26 | int buf_in = 0; /*写入缓冲区位置*/ 27 | /*打开信号量*/ 28 | if((mutex = sem_open("carmutex",1)) == SEM_FAILED) 29 | { 30 | perror("sem_open() error!\n"); 31 | return -1; 32 | } 33 | if((empty = sem_open("carempty",10)) == SEM_FAILED) 34 | { 35 | perror("sem_open() error!\n"); 36 | return -1; 37 | } 38 | if((full = sem_open("carfull",0)) == SEM_FAILED) 39 | { 40 | perror("sem_open() error!\n"); 41 | return -1; 42 | } 43 | fno = open("buffer.dat",O_CREAT|O_RDWR|O_TRUNC,0666); 44 | /* 将待读取位置存入buffer后,以便 子进程 之间通信 */ 45 | lseek(fno,10*sizeof(int),SEEK_SET); 46 | write(fno,(char *)&buf_out,sizeof(int)); 47 | /*生产者进程*/ 48 | if((p=fork())==0) 49 | { 50 | for( i = 0 ; i < NUMBER; i++) 51 | { 52 | sem_wait(empty); 53 | sem_wait(mutex); 54 | /*写入一个字符*/ 55 | lseek(fno, buf_in*sizeof(int), SEEK_SET); 56 | write(fno,(char *)&i,sizeof(int)); 57 | buf_in = ( buf_in + 1)% BUFSIZE; 58 | 59 | sem_post(mutex); 60 | sem_post(full); 61 | } 62 | return 0; 63 | }else if(p < 0) 64 | { 65 | perror("Fail to fork!\n"); 66 | return -1; 67 | } 68 | 69 | for( j = 0; j < CHILD ; j++ ) 70 | { 71 | if((p=fork())==0) 72 | { 73 | for( k = 0; k < NUMBER/CHILD; k++ ) 74 | { 75 | sem_wait(full); 76 | sem_wait(mutex); 77 | /*获得读取位置*/ 78 | lseek(fno,10*sizeof(int),SEEK_SET); 79 | read(fno,(char *)&buf_out,sizeof(int)); 80 | /*读取数据*/ 81 | lseek(fno,buf_out*sizeof(int),SEEK_SET); 82 | read(fno,(char *)&data,sizeof(int)); 83 | /*写入读取位置*/ 84 | buf_out = (buf_out + 1) % BUFSIZE; 85 | lseek(fno,10*sizeof(int),SEEK_SET); 86 | write(fno,(char *)&buf_out,sizeof(int)); 87 | 88 | sem_post(mutex); 89 | sem_post(empty); 90 | /*消费资源*/ 91 | printf("%d: %d\n",getpid(),data); 92 | fflush(stdout); 93 | } 94 | return 0; 95 | }else if(p<0) 96 | { 97 | perror("Fail to fork!\n"); 98 | return -1; 99 | } 100 | } 101 | wait(NULL); 102 | /*释放信号量*/ 103 | sem_unlink("carfull"); 104 | sem_unlink("carempty"); 105 | sem_unlink("carmutex"); 106 | /*释放资源*/ 107 | close(fno); 108 | return 0; 109 | } -------------------------------------------------------------------------------- /lab4/report.txt: -------------------------------------------------------------------------------- 1 | Answers: 2 | 1. 有变化,输出没有顺序,甚至程序会崩溃。没有了信号量,进程之间无法同步或者协作,一种情况是缓冲区满了,生产者还在写入数据,会造覆盖掉部分数据。或者缓冲区为空,消费者尝试读取数据,读到的数据是已输出的数据。同时,由于多个进程对文件缓冲区同时访问,极容易造成程序奔溃。 3 | 4 | 2. 这样做不可行,只有当缓冲区可写或者可读时,才能锁定该临界资源,否则容易出现缓冲区未锁定(mutex=1),consumer锁定该缓冲区,却发现empty=10,full=0,等待缓冲区有字符信号量,这样程序会进入死锁状态。 5 | 6 | -------------------------------------------------------------------------------- /lab4/sem.c: -------------------------------------------------------------------------------- 1 | #define __LIBRARY__ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define SEM_COUNT 32 9 | sem_t semaphores[SEM_COUNT]; 10 | /*队列相关操作,rear始终是下一个待写入的位置,front始终是队列第一个元素*/ 11 | void init_queue(sem_queue* q) 12 | { 13 | q->front = q->rear = 0; 14 | } 15 | 16 | int is_empty(sem_queue* q) 17 | { 18 | return q->front == q->rear?1:0; 19 | } 20 | /*留下标QUE_LEN-1不用,判断是否慢*/ 21 | int is_full(sem_queue* q) 22 | { 23 | return (q->rear+1)%QUE_LEN == q->front?1:0; 24 | } 25 | /*获得队列头第一个任务*/ 26 | struct task_struct * get_task(sem_queue* q) 27 | { 28 | if(is_empty(q)) 29 | { 30 | printk("Queue is empty!\n"); 31 | return NULL; 32 | } 33 | struct task_struct *tmp = q->wait_tasks[q->front]; 34 | q->front = (q->front+1)%QUE_LEN; 35 | return tmp; 36 | } 37 | /*任务插入队列尾*/ 38 | int insert_task(struct task_struct *p,sem_queue* q) 39 | { 40 | // printk("Insert %d",p->pid); 41 | if(is_full(q)) 42 | { 43 | printk("Queue is full!\n"); 44 | return -1; 45 | } 46 | q->wait_tasks[q->rear] = p; 47 | q->rear = (q->rear+1)%QUE_LEN; 48 | return 1; 49 | } 50 | /*信号量是否已打开,是返回位置*/ 51 | int sem_location(const char* name) 52 | { 53 | int i; 54 | for(i = 0;i < SEM_COUNT; i++) 55 | { 56 | if(strcmp(name,semaphores[i].name) == 0 && semaphores[i].occupied == 1) 57 | { 58 | return i; 59 | } 60 | } 61 | return -1; 62 | } 63 | /*打开信号量*/ 64 | sem_t* sys_sem_open(const char* name,unsigned int value) 65 | { 66 | char tmp[16]; 67 | char c; 68 | int i; 69 | for( i = 0; i<16; i++) 70 | { 71 | c = get_fs_byte(name+i); 72 | tmp[i] = c; 73 | if(c =='\0') break; 74 | } 75 | if(c >= 16) 76 | { 77 | printk("Semaphore name is too long!"); 78 | return NULL; 79 | } 80 | if((i = sem_location(tmp)) != -1) 81 | { 82 | return &semaphores[i]; 83 | } 84 | for(i = 0;i< SEM_COUNT; i++) 85 | { 86 | if(!semaphores[i].occupied) 87 | { 88 | strcpy(semaphores[i].name,tmp); 89 | semaphores[i].occupied = 1; 90 | semaphores[i].value = value; 91 | init_queue(&(semaphores[i].wait_queue)); 92 | // printk("%d %d %d %s\n",semaphores[i].occupied,i,semaphores[i].value,semaphores[i].name); 93 | // printk("%p\n",&semaphores[i]); 94 | return &semaphores[i]; 95 | } 96 | } 97 | printk("Numbers of semaphores are limited!\n"); 98 | return NULL; 99 | } 100 | /*P原子操作*/ 101 | int sys_sem_wait(sem_t* sem) 102 | { 103 | cli(); 104 | sem->value--; 105 | if(sem->value < 0) 106 | { 107 | /*参见sleep_on*/ 108 | current->state = TASK_UNINTERRUPTIBLE; 109 | insert_task(current,&(sem->wait_queue)); 110 | schedule(); 111 | } 112 | sti(); 113 | return 0; 114 | } 115 | /*V原子操作*/ 116 | int sys_sem_post(sem_t* sem) 117 | { 118 | cli(); 119 | struct task_struct *p; 120 | sem->value++; 121 | if(sem->value <= 0) 122 | { 123 | p = get_task(&(sem->wait_queue)); 124 | if(p != NULL) 125 | { 126 | (*p).state = TASK_RUNNING; 127 | } 128 | } 129 | sti(); 130 | return 0; 131 | } 132 | /*释放信号量*/ 133 | int sys_sem_unlink(const char *name) 134 | { 135 | char tmp[16]; 136 | char c; 137 | int i; 138 | for( i = 0; i<16; i++) 139 | { 140 | c = get_fs_byte(name+i); 141 | tmp[i] = c; 142 | if(c =='\0') break; 143 | } 144 | if(c >= 16) 145 | { 146 | printk("Semphore name is too long!"); 147 | return -1; 148 | } 149 | int ret = sem_location(tmp); 150 | if(ret != -1) 151 | { 152 | semaphores[ret].value = 0; 153 | strcpy(semaphores[ret].name,"\0"); 154 | semaphores[ret].occupied = 0; 155 | return 0; 156 | } 157 | return -1; 158 | } 159 | -------------------------------------------------------------------------------- /lab4/sys.h: -------------------------------------------------------------------------------- 1 | extern int sys_setup(); 2 | extern int sys_exit(); 3 | extern int sys_fork(); 4 | extern int sys_read(); 5 | extern int sys_write(); 6 | extern int sys_open(); 7 | extern int sys_close(); 8 | extern int sys_waitpid(); 9 | extern int sys_creat(); 10 | extern int sys_link(); 11 | extern int sys_unlink(); 12 | extern int sys_execve(); 13 | extern int sys_chdir(); 14 | extern int sys_time(); 15 | extern int sys_mknod(); 16 | extern int sys_chmod(); 17 | extern int sys_chown(); 18 | extern int sys_break(); 19 | extern int sys_stat(); 20 | extern int sys_lseek(); 21 | extern int sys_getpid(); 22 | extern int sys_mount(); 23 | extern int sys_umount(); 24 | extern int sys_setuid(); 25 | extern int sys_getuid(); 26 | extern int sys_stime(); 27 | extern int sys_ptrace(); 28 | extern int sys_alarm(); 29 | extern int sys_fstat(); 30 | extern int sys_pause(); 31 | extern int sys_utime(); 32 | extern int sys_stty(); 33 | extern int sys_gtty(); 34 | extern int sys_access(); 35 | extern int sys_nice(); 36 | extern int sys_ftime(); 37 | extern int sys_sync(); 38 | extern int sys_kill(); 39 | extern int sys_rename(); 40 | extern int sys_mkdir(); 41 | extern int sys_rmdir(); 42 | extern int sys_dup(); 43 | extern int sys_pipe(); 44 | extern int sys_times(); 45 | extern int sys_prof(); 46 | extern int sys_brk(); 47 | extern int sys_setgid(); 48 | extern int sys_getgid(); 49 | extern int sys_signal(); 50 | extern int sys_geteuid(); 51 | extern int sys_getegid(); 52 | extern int sys_acct(); 53 | extern int sys_phys(); 54 | extern int sys_lock(); 55 | extern int sys_ioctl(); 56 | extern int sys_fcntl(); 57 | extern int sys_mpx(); 58 | extern int sys_setpgid(); 59 | extern int sys_ulimit(); 60 | extern int sys_uname(); 61 | extern int sys_umask(); 62 | extern int sys_chroot(); 63 | extern int sys_ustat(); 64 | extern int sys_dup2(); 65 | extern int sys_getppid(); 66 | extern int sys_getpgrp(); 67 | extern int sys_setsid(); 68 | extern int sys_sigaction(); 69 | extern int sys_sgetmask(); 70 | extern int sys_ssetmask(); 71 | extern int sys_setreuid(); 72 | extern int sys_setregid(); 73 | extern int sys_sem_open(); 74 | extern int sys_sem_wait(); 75 | extern int sys_sem_post(); 76 | extern int sys_sem_unlink(); 77 | 78 | fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, 79 | sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, 80 | sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod, 81 | sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount, 82 | sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm, 83 | sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access, 84 | sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir, 85 | sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid, 86 | sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys, 87 | sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit, 88 | sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid, 89 | sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask, 90 | sys_setreuid,sys_setregid,sys_sem_open,sys_sem_wait,sys_sem_post,sys_sem_unlink }; 91 | -------------------------------------------------------------------------------- /lab5/consumer.c: -------------------------------------------------------------------------------- 1 | #define __LIBRARY__ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | _syscall2(sem_t*,sem_open,const char *,name,unsigned int,value); 9 | _syscall1(int,sem_wait,sem_t*,sem); 10 | _syscall1(int,sem_post,sem_t*,sem); 11 | _syscall1(int,sem_unlink,const char *,name); 12 | _syscall1(void*,shmat,int,shmid); 13 | _syscall1(int,shmget,char*,name); 14 | 15 | #define NUMBER 520 /*打出数字总数*/ 16 | #define BUFSIZE 10 /*缓冲区大小*/ 17 | 18 | sem_t *empty, *full, *mutex; 19 | 20 | int main() 21 | { 22 | int i,shmid,data; 23 | int *p; 24 | int buf_out = 0; /*从缓冲区读取位置*/ 25 | /*打开信号量*/ 26 | if((mutex = sem_open("carpelamutex",1)) == SEM_FAILED) 27 | { 28 | perror("sem_open() error!\n"); 29 | return -1; 30 | } 31 | if((empty = sem_open("carpelaempty",10)) == SEM_FAILED) 32 | { 33 | perror("sem_open() error!\n"); 34 | return -1; 35 | } 36 | if((full = sem_open("carpelafull",0)) == SEM_FAILED) 37 | { 38 | perror("sem_open() error!\n"); 39 | return -1; 40 | } 41 | shmid = shmget("buffer"); 42 | if(shmid == -1) 43 | { 44 | return -1; 45 | } 46 | p = (int *)shmat(shmid); 47 | 48 | for( i = 0; i < NUMBER; i++ ) 49 | { 50 | sem_wait(full); 51 | sem_wait(mutex); 52 | 53 | data = p[buf_out]; 54 | buf_out = (buf_out + 1) % BUFSIZE; 55 | 56 | sem_post(mutex); 57 | sem_post(empty); 58 | /*消费资源*/ 59 | printf("%d: %d\n",getpid(),data); 60 | fflush(stdout); 61 | } 62 | 63 | /*释放信号量*/ 64 | sem_unlink("carpelafull"); 65 | sem_unlink("carpelaempty"); 66 | sem_unlink("carpelamutex"); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /lab5/producer.c: -------------------------------------------------------------------------------- 1 | #define __LIBRARY__ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | _syscall2(sem_t*,sem_open,const char *,name,unsigned int,value); 9 | _syscall1(int,sem_wait,sem_t*,sem); 10 | _syscall1(int,sem_post,sem_t*,sem); 11 | _syscall1(int,sem_unlink,const char *,name); 12 | _syscall1(void*,shmat,int,shmid); 13 | _syscall1(int,shmget,char*,name); 14 | 15 | #define NUMBER 520 /*打出数字总数*/ 16 | #define BUFSIZE 10 /*缓冲区大小*/ 17 | 18 | sem_t *empty, *full, *mutex; 19 | 20 | int main() 21 | { 22 | int i,shmid; 23 | int *p; 24 | int buf_in = 0; /*写入缓冲区位置*/ 25 | /*打开信号量*/ 26 | if((mutex = sem_open("carpelamutex",1)) == SEM_FAILED) 27 | { 28 | perror("sem_open() error!\n"); 29 | return -1; 30 | } 31 | if((empty = sem_open("carpelaempty",10)) == SEM_FAILED) 32 | { 33 | perror("sem_open() error!\n"); 34 | return -1; 35 | } 36 | if((full = sem_open("carpelafull",0)) == SEM_FAILED) 37 | { 38 | perror("sem_open() error!\n"); 39 | return -1; 40 | } 41 | shmid = shmget("buffer"); 42 | if(shmid == -1) 43 | { 44 | return -1; 45 | } 46 | p = (int*) shmat(shmid); 47 | /*生产者进程*/ 48 | for( i = 0 ; i < NUMBER; i++) 49 | { 50 | sem_wait(empty); 51 | sem_wait(mutex); 52 | p[buf_in] = i; 53 | buf_in = ( buf_in + 1)% BUFSIZE; 54 | sem_post(mutex); 55 | sem_post(full); 56 | } 57 | /*释放信号量*/ 58 | sem_unlink("carpelafull"); 59 | sem_unlink("carpelaempty"); 60 | sem_unlink("carpelamutex"); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /lab5/report.txt: -------------------------------------------------------------------------------- 1 | Answers: 2 | 1. 前提:知道段选择子(16位),段描述符(64位),页目录表及页表项(32位)的意义 3 | Step1:首先需要获得逻辑地址,LDT的地址: 4 | 逻辑地址 0x00003004 5 | 全局描述符表物理地址: gdtr:base=0x00005cb8, limit=0x7ff 6 | 而局部描述符选择子:ldtr:s=0x0068 二进制0000,0000,0110,1000b 1101即GDT表第14项 7 | bochs:4> xp /2w 0x5cb8 + 13*8 8 | [bochs]: 9 | 0x00005d20 : 0x52d40068 0x000082fd 10 | 即LDT的物理地址: 0x00fd52d4 11 | 12 | Step2:然后需要获得线性地址: 13 | DS段选择子 ds:s=0x0017 即LDT表中第3项 14 | xp /2w 0xfd52d4 + 2*8 15 | [bochs]: 16 | 0x00fd52e4 : 0x00003fff 0x10c0f300 17 | 即DS段基地址为 0x10000000 18 | 所以线性地址为:0x10003004 19 | 20 | Step3:其次获得页目录及页表地址计算得物理地址 21 | CR3内容: CR3=0x00000000 22 | 虚拟地址对应页目录第65项,页表第4项,页表内偏移0x004 23 | 查询页目录第65项: 24 | xp /w 64*4 25 | [bochs]: 26 | 0x00000100 : 0x00fa5027 27 | 页表物理地址为: 0x00fa5000, 查询第4项 28 | xp /w 0xfa5000 + 3*4 29 | [bochs]: 30 | 0x00fa500c : 0x00fa3067 31 | 页框物理地址:0x00fa3000 加上偏移0x004 32 | 计算得到物理地址: 0x00fa3004 33 | xp /w 0x00fa3004 34 | [bochs]: 35 | 0x00fa3004 : 0x12345678 36 | 37 | 2.逻辑地址和虚拟地址不变,页目录地址是操作系统放置的, 物理分页变了,所以物理地址也变了。原因是每次进程加载后都有64M的虚拟地址空间, 38 | 而且,逻辑地址没有变化。操作系统加载程序时,由于虚拟地址是按nr分配64M,两次运行nr一致,所以虚拟地址没变。 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /lab5/sem.c: -------------------------------------------------------------------------------- 1 | #define __LIBRARY__ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define SEM_COUNT 32 9 | sem_t semaphores[SEM_COUNT]; 10 | /*队列相关操作,rear始终是下一个待写入的位置,front始终是队列第一个元素*/ 11 | void init_queue(sem_queue* q) 12 | { 13 | q->front = q->rear = 0; 14 | } 15 | 16 | int is_empty(sem_queue* q) 17 | { 18 | return q->front == q->rear?1:0; 19 | } 20 | /*留下标QUE_LEN-1不用,判断是否慢*/ 21 | int is_full(sem_queue* q) 22 | { 23 | return (q->rear+1)%QUE_LEN == q->front?1:0; 24 | } 25 | /*获得队列头第一个任务*/ 26 | struct task_struct * get_task(sem_queue* q) 27 | { 28 | if(is_empty(q)) 29 | { 30 | printk("Queue is empty!\n"); 31 | return NULL; 32 | } 33 | struct task_struct *tmp = q->wait_tasks[q->front]; 34 | q->front = (q->front+1)%QUE_LEN; 35 | return tmp; 36 | } 37 | /*任务插入队列尾*/ 38 | int insert_task(struct task_struct *p,sem_queue* q) 39 | { 40 | // printk("Insert %d",p->pid); 41 | if(is_full(q)) 42 | { 43 | printk("Queue is full!\n"); 44 | return -1; 45 | } 46 | q->wait_tasks[q->rear] = p; 47 | q->rear = (q->rear+1)%QUE_LEN; 48 | return 1; 49 | } 50 | /*信号量是否已打开,是返回位置*/ 51 | int sem_location(const char* name) 52 | { 53 | int i; 54 | for(i = 0;i < SEM_COUNT; i++) 55 | { 56 | if(strcmp(name,semaphores[i].name) == 0 && semaphores[i].occupied == 1) 57 | { 58 | return i; 59 | } 60 | } 61 | return -1; 62 | } 63 | /*打开信号量*/ 64 | sem_t* sys_sem_open(const char* name,unsigned int value) 65 | { 66 | char tmp[16]; 67 | char c; 68 | int i; 69 | for( i = 0; i<16; i++) 70 | { 71 | c = get_fs_byte(name+i); 72 | tmp[i] = c; 73 | if(c =='\0') break; 74 | } 75 | if(c >= 16) 76 | { 77 | printk("Semaphore name is too long!"); 78 | return NULL; 79 | } 80 | if((i = sem_location(tmp)) != -1) 81 | { 82 | return &semaphores[i]; 83 | } 84 | for(i = 0;i< SEM_COUNT; i++) 85 | { 86 | if(!semaphores[i].occupied) 87 | { 88 | strcpy(semaphores[i].name,tmp); 89 | semaphores[i].occupied = 1; 90 | semaphores[i].value = value; 91 | init_queue(&(semaphores[i].wait_queue)); 92 | // printk("%d %d %d %s\n",semaphores[i].occupied,i,semaphores[i].value,semaphores[i].name); 93 | // printk("%p\n",&semaphores[i]); 94 | return &semaphores[i]; 95 | } 96 | } 97 | printk("Numbers of semaphores are limited!\n"); 98 | return NULL; 99 | } 100 | /*P原子操作*/ 101 | int sys_sem_wait(sem_t* sem) 102 | { 103 | cli(); 104 | sem->value--; 105 | if(sem->value < 0) 106 | { 107 | /*参见sleep_on*/ 108 | current->state = TASK_UNINTERRUPTIBLE; 109 | insert_task(current,&(sem->wait_queue)); 110 | schedule(); 111 | } 112 | sti(); 113 | return 0; 114 | } 115 | /*V原子操作*/ 116 | int sys_sem_post(sem_t* sem) 117 | { 118 | cli(); 119 | struct task_struct *p; 120 | sem->value++; 121 | if(sem->value <= 0) 122 | { 123 | p = get_task(&(sem->wait_queue)); 124 | if(p != NULL) 125 | { 126 | (*p).state = TASK_RUNNING; 127 | } 128 | } 129 | sti(); 130 | return 0; 131 | } 132 | /*释放信号量*/ 133 | int sys_sem_unlink(const char *name) 134 | { 135 | char tmp[16]; 136 | char c; 137 | int i; 138 | for( i = 0; i<16; i++) 139 | { 140 | c = get_fs_byte(name+i); 141 | tmp[i] = c; 142 | if(c =='\0') break; 143 | } 144 | if(c >= 16) 145 | { 146 | printk("Semphore name is too long!"); 147 | return -1; 148 | } 149 | int ret = sem_location(tmp); 150 | if(ret != -1) 151 | { 152 | semaphores[ret].value = 0; 153 | strcpy(semaphores[ret].name,"\0"); 154 | semaphores[ret].occupied = 0; 155 | return 0; 156 | } 157 | return -1; 158 | } 159 | -------------------------------------------------------------------------------- /lab5/shm.c: -------------------------------------------------------------------------------- 1 | // int shmget(char * name); 2 | // void * shmat(int shmid); 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define SHM_COUNT 20 10 | #define SHM_NAME_SIZE 20 11 | 12 | struct struct_shm_tables 13 | { 14 | int occupied; 15 | char name[SHM_NAME_SIZE]; 16 | long addr; 17 | } shm_tables[SHM_COUNT]; 18 | 19 | int find_shm_location(char *name) 20 | { 21 | int i; 22 | for(i=0; ibrk + current->start_code); 68 | return (void*)current->brk; 69 | } 70 | -------------------------------------------------------------------------------- /lab5/sys.h: -------------------------------------------------------------------------------- 1 | extern int sys_setup(); 2 | extern int sys_exit(); 3 | extern int sys_fork(); 4 | extern int sys_read(); 5 | extern int sys_write(); 6 | extern int sys_open(); 7 | extern int sys_close(); 8 | extern int sys_waitpid(); 9 | extern int sys_creat(); 10 | extern int sys_link(); 11 | extern int sys_unlink(); 12 | extern int sys_execve(); 13 | extern int sys_chdir(); 14 | extern int sys_time(); 15 | extern int sys_mknod(); 16 | extern int sys_chmod(); 17 | extern int sys_chown(); 18 | extern int sys_break(); 19 | extern int sys_stat(); 20 | extern int sys_lseek(); 21 | extern int sys_getpid(); 22 | extern int sys_mount(); 23 | extern int sys_umount(); 24 | extern int sys_setuid(); 25 | extern int sys_getuid(); 26 | extern int sys_stime(); 27 | extern int sys_ptrace(); 28 | extern int sys_alarm(); 29 | extern int sys_fstat(); 30 | extern int sys_pause(); 31 | extern int sys_utime(); 32 | extern int sys_stty(); 33 | extern int sys_gtty(); 34 | extern int sys_access(); 35 | extern int sys_nice(); 36 | extern int sys_ftime(); 37 | extern int sys_sync(); 38 | extern int sys_kill(); 39 | extern int sys_rename(); 40 | extern int sys_mkdir(); 41 | extern int sys_rmdir(); 42 | extern int sys_dup(); 43 | extern int sys_pipe(); 44 | extern int sys_times(); 45 | extern int sys_prof(); 46 | extern int sys_brk(); 47 | extern int sys_setgid(); 48 | extern int sys_getgid(); 49 | extern int sys_signal(); 50 | extern int sys_geteuid(); 51 | extern int sys_getegid(); 52 | extern int sys_acct(); 53 | extern int sys_phys(); 54 | extern int sys_lock(); 55 | extern int sys_ioctl(); 56 | extern int sys_fcntl(); 57 | extern int sys_mpx(); 58 | extern int sys_setpgid(); 59 | extern int sys_ulimit(); 60 | extern int sys_uname(); 61 | extern int sys_umask(); 62 | extern int sys_chroot(); 63 | extern int sys_ustat(); 64 | extern int sys_dup2(); 65 | extern int sys_getppid(); 66 | extern int sys_getpgrp(); 67 | extern int sys_setsid(); 68 | extern int sys_sigaction(); 69 | extern int sys_sgetmask(); 70 | extern int sys_ssetmask(); 71 | extern int sys_setreuid(); 72 | extern int sys_setregid(); 73 | extern int sys_sem_open(); 74 | extern int sys_sem_wait(); 75 | extern int sys_sem_post(); 76 | extern int sys_sem_unlink(); 77 | extern int sys_shmget(); 78 | extern void* sys_shmat(); 79 | 80 | fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, 81 | sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, 82 | sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod, 83 | sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount, 84 | sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm, 85 | sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access, 86 | sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir, 87 | sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid, 88 | sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys, 89 | sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit, 90 | sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid, 91 | sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask, 92 | sys_setreuid, sys_setregid, sys_sem_open, sys_sem_wait, sys_sem_post, 93 | sys_sem_unlink, sys_shmget, sys_shmat }; 94 | -------------------------------------------------------------------------------- /lab6/file_dev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/file_dev.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #define MIN(a,b) (((a)<(b))?(a):(b)) 15 | #define MAX(a,b) (((a)>(b))?(a):(b)) 16 | 17 | int file_read(struct m_inode * inode, struct file * filp, char * buf, int count) 18 | { 19 | int left,chars,nr; 20 | struct buffer_head * bh; 21 | 22 | if ((left=count)<=0) 23 | return 0; 24 | while (left) { 25 | if ((nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE))) { 26 | if (!(bh=bread(inode->i_dev,nr))) 27 | break; 28 | } else 29 | bh = NULL; 30 | nr = filp->f_pos % BLOCK_SIZE; 31 | chars = MIN( BLOCK_SIZE-nr , left ); 32 | filp->f_pos += chars; 33 | left -= chars; 34 | if (bh) { 35 | char * p = nr + bh->b_data; 36 | while (chars-->0) 37 | put_fs_byte(*(p++),buf++); 38 | brelse(bh); 39 | } else { 40 | while (chars-->0) 41 | put_fs_byte(0,buf++); 42 | } 43 | } 44 | inode->i_atime = CURRENT_TIME; 45 | return (count-left)?(count-left):-ERROR; 46 | } 47 | 48 | int file_write(struct m_inode * inode, struct file * filp, char * buf, int count) 49 | { 50 | off_t pos; 51 | int block,c; 52 | struct buffer_head * bh; 53 | char * p; 54 | int i=0; 55 | 56 | /* 57 | * ok, append may not work when many processes are writing at the same time 58 | * but so what. That way leads to madness anyway. 59 | */ 60 | if (filp->f_flags & O_APPEND) 61 | pos = inode->i_size; 62 | else 63 | pos = filp->f_pos; 64 | while (ii_dev,block))) 68 | break; 69 | c = pos % BLOCK_SIZE; 70 | p = c + bh->b_data; 71 | bh->b_dirt = 1; 72 | c = BLOCK_SIZE-c; 73 | if (c > count-i) c = count-i; 74 | pos += c; 75 | if (pos > inode->i_size) { 76 | inode->i_size = pos; 77 | inode->i_dirt = 1; 78 | } 79 | i += c; 80 | while (c-->0) 81 | *(p++) = get_fs_byte(buf++); 82 | brelse(bh); 83 | } 84 | inode->i_mtime = CURRENT_TIME; 85 | if (!(filp->f_flags & O_APPEND)) { 86 | filp->f_pos = pos; 87 | inode->i_ctime = CURRENT_TIME; 88 | } 89 | return (i?i:-1); 90 | } 91 | -------------------------------------------------------------------------------- /lab6/read_write.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/read_write.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos); 16 | extern int read_pipe(struct m_inode * inode, char * buf, int count); 17 | extern int write_pipe(struct m_inode * inode, char * buf, int count); 18 | extern int block_read(int dev, off_t * pos, char * buf, int count); 19 | extern int block_write(int dev, off_t * pos, char * buf, int count); 20 | extern int file_read(struct m_inode * inode, struct file * filp, 21 | char * buf, int count); 22 | extern int file_write(struct m_inode * inode, struct file * filp, 23 | char * buf, int count); 24 | 25 | int sys_lseek(unsigned int fd,off_t offset, int origin) 26 | { 27 | struct file * file; 28 | int tmp; 29 | 30 | if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode) 31 | || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev))) 32 | return -EBADF; 33 | if (file->f_inode->i_pipe) 34 | return -ESPIPE; 35 | switch (origin) { 36 | case 0: 37 | if (offset<0) return -EINVAL; 38 | file->f_pos=offset; 39 | break; 40 | case 1: 41 | if (file->f_pos+offset<0) return -EINVAL; 42 | file->f_pos += offset; 43 | break; 44 | case 2: 45 | if ((tmp=file->f_inode->i_size+offset) < 0) 46 | return -EINVAL; 47 | file->f_pos = tmp; 48 | break; 49 | default: 50 | return -EINVAL; 51 | } 52 | return file->f_pos; 53 | } 54 | 55 | int sys_read(unsigned int fd,char * buf,int count) 56 | { 57 | struct file * file; 58 | struct m_inode * inode; 59 | 60 | if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd])) 61 | return -EINVAL; 62 | if (!count) 63 | return 0; 64 | verify_area(buf,count); 65 | inode = file->f_inode; 66 | if (inode->i_pipe) 67 | return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO; 68 | if (S_ISCHR(inode->i_mode)) 69 | return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos); 70 | if (S_ISBLK(inode->i_mode)) 71 | return block_read(inode->i_zone[0],&file->f_pos,buf,count); 72 | if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) { 73 | if (count+file->f_pos > inode->i_size) 74 | count = inode->i_size - file->f_pos; 75 | if (count<=0) 76 | return 0; 77 | return file_read(inode,file,buf,count); 78 | } 79 | printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode); 80 | return -EINVAL; 81 | } 82 | 83 | int sys_write(unsigned int fd,char * buf,int count) 84 | { 85 | struct file * file; 86 | struct m_inode * inode; 87 | 88 | if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd])) 89 | return -EINVAL; 90 | if (!count) 91 | return 0; 92 | inode=file->f_inode; 93 | if (inode->i_pipe) 94 | return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO; 95 | if (S_ISCHR(inode->i_mode)) 96 | return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos); 97 | if (S_ISBLK(inode->i_mode)) 98 | return block_write(inode->i_zone[0],&file->f_pos,buf,count); 99 | if (S_ISREG(inode->i_mode)) 100 | return file_write(inode,file,buf,count); 101 | printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode); 102 | return -EINVAL; 103 | } 104 | -------------------------------------------------------------------------------- /lab6/report.txt: -------------------------------------------------------------------------------- 1 | Answers: 2 | 1. 将F12转义成转义字符序列 [ [ L , 对F1-F12处理类似 [ [ A -> [ [ L 3 | 2. 实现了文件输出的过滤,该过滤是通过修改fs/file_dev.c中file_write()函数,实现代码类似tty_write()函数。 4 | 具体修改如下: 5 | while (c-->0) 6 | { 7 | tmp = get_fs_byte(buf++); 8 | if(f12_flag == 1) 9 | { 10 | if((tmp>='A'&&tmp<='Z')||(tmp>='a'&&tmp<='z')||(tmp>='0'&&tmp<='9')) 11 | tmp = '*'; 12 | } 13 | *(p++) = tmp; 14 | } 15 | 如果只过滤终端输出字符,则可以去掉file_write()修改即可; 16 | -------------------------------------------------------------------------------- /lab7/proc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define set_bit(bitnr,addr) ({ \ 9 | register int __res ; \ 10 | __asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \ 11 | __res; }) 12 | 13 | char proc_buf[4096] ={'\0'}; 14 | 15 | extern int vsprintf(char * buf, const char * fmt, va_list args); 16 | 17 | int sprintf(char *buf, const char *fmt, ...) 18 | { 19 | va_list args; int i; 20 | va_start(args, fmt); 21 | i=vsprintf(buf, fmt, args); 22 | va_end(args); 23 | return i; 24 | } 25 | 26 | int get_psinfo() 27 | { 28 | int read = 0; 29 | read += sprintf(proc_buf+read,"%s","pid\tstate\tfather\tcounter\tstart_time\n"); 30 | struct task_struct **p; 31 | for(p = &FIRST_TASK ; p <= &LAST_TASK ; ++p) 32 | if (*p != NULL) 33 | { 34 | read += sprintf(proc_buf+read,"%d\t",(*p)->pid); 35 | read += sprintf(proc_buf+read,"%d\t",(*p)->state); 36 | read += sprintf(proc_buf+read,"%d\t",(*p)->father); 37 | read += sprintf(proc_buf+read,"%d\t",(*p)->counter); 38 | read += sprintf(proc_buf+read,"%d\n",(*p)->start_time); 39 | } 40 | return read; 41 | } 42 | 43 | /* 44 | * 参考fs/super.c mount_root()函数 45 | */ 46 | int get_hdinfo() 47 | { 48 | int read = 0; 49 | int i,used; 50 | struct super_block * sb; 51 | sb=get_super(0x301); /*磁盘设备号 3*256+1*/ 52 | /*Blocks信息*/ 53 | read += sprintf(proc_buf+read,"Total blocks:%d\n",sb->s_nzones); 54 | used = 0; 55 | i=sb->s_nzones; 56 | while(--i >= 0) 57 | { 58 | if(set_bit(i&8191,sb->s_zmap[i>>13]->b_data)) 59 | used++; 60 | } 61 | read += sprintf(proc_buf+read,"Used blocks:%d\n",used); 62 | read += sprintf(proc_buf+read,"Free blocks:%d\n",sb->s_nzones-used); 63 | /*Inodes 信息*/ 64 | read += sprintf(proc_buf+read,"Total inodes:%d\n",sb->s_ninodes); 65 | used = 0; 66 | i=sb->s_ninodes+1; 67 | while(--i >= 0) 68 | { 69 | if(set_bit(i&8191,sb->s_imap[i>>13]->b_data)) 70 | used++; 71 | } 72 | read += sprintf(proc_buf+read,"Used inodes:%d\n",used); 73 | read += sprintf(proc_buf+read,"Free inodes:%d\n",sb->s_ninodes-used); 74 | return read; 75 | } 76 | 77 | int get_inodeinfo() 78 | { 79 | int read = 0; 80 | int i; 81 | struct super_block * sb; 82 | struct m_inode *mi; 83 | sb=get_super(0x301); /*磁盘设备号 3*256+1*/ 84 | i=sb->s_ninodes+1; 85 | i=0; 86 | while(++i < sb->s_ninodes+1) 87 | { 88 | if(set_bit(i&8191,sb->s_imap[i>>13]->b_data)) 89 | { 90 | mi = iget(0x301,i); 91 | read += sprintf(proc_buf+read,"inr:%d;zone[0]:%d\n",mi->i_num,mi->i_zone[0]); 92 | iput(mi); 93 | } 94 | if(read >= 4000) 95 | { 96 | break; 97 | } 98 | } 99 | return read; 100 | } 101 | 102 | int proc_read(int dev, unsigned long * pos, char * buf, int count) 103 | { 104 | 105 | int i; 106 | if(*pos % 1024 == 0) 107 | { 108 | if(dev == 0) 109 | get_psinfo(); 110 | if(dev == 1) 111 | get_hdinfo(); 112 | if(dev == 2) 113 | get_inodeinfo(); 114 | } 115 | for(i=0;i 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos); 16 | extern int read_pipe(struct m_inode * inode, char * buf, int count); 17 | extern int write_pipe(struct m_inode * inode, char * buf, int count); 18 | extern int block_read(int dev, off_t * pos, char * buf, int count); 19 | extern int block_write(int dev, off_t * pos, char * buf, int count); 20 | extern int file_read(struct m_inode * inode, struct file * filp, 21 | char * buf, int count); 22 | extern int file_write(struct m_inode * inode, struct file * filp, 23 | char * buf, int count); 24 | 25 | int sys_lseek(unsigned int fd,off_t offset, int origin) 26 | { 27 | struct file * file; 28 | int tmp; 29 | 30 | if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode) 31 | || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev))) 32 | return -EBADF; 33 | if (file->f_inode->i_pipe) 34 | return -ESPIPE; 35 | switch (origin) { 36 | case 0: 37 | if (offset<0) return -EINVAL; 38 | file->f_pos=offset; 39 | break; 40 | case 1: 41 | if (file->f_pos+offset<0) return -EINVAL; 42 | file->f_pos += offset; 43 | break; 44 | case 2: 45 | if ((tmp=file->f_inode->i_size+offset) < 0) 46 | return -EINVAL; 47 | file->f_pos = tmp; 48 | break; 49 | default: 50 | return -EINVAL; 51 | } 52 | return file->f_pos; 53 | } 54 | 55 | int sys_read(unsigned int fd,char * buf,int count) 56 | { 57 | struct file * file; 58 | struct m_inode * inode; 59 | 60 | if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd])) 61 | return -EINVAL; 62 | if (!count) 63 | return 0; 64 | verify_area(buf,count); 65 | inode = file->f_inode; 66 | if (inode->i_pipe) 67 | return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO; 68 | if (S_ISPROC(inode->i_mode)) 69 | return proc_read(inode->i_zone[0],&file->f_pos,buf,count); 70 | if (S_ISCHR(inode->i_mode)) 71 | return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos); 72 | if (S_ISBLK(inode->i_mode)) 73 | return block_read(inode->i_zone[0],&file->f_pos,buf,count); 74 | if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) { 75 | if (count+file->f_pos > inode->i_size) 76 | count = inode->i_size - file->f_pos; 77 | if (count<=0) 78 | return 0; 79 | return file_read(inode,file,buf,count); 80 | } 81 | printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode); 82 | return -EINVAL; 83 | } 84 | 85 | int sys_write(unsigned int fd,char * buf,int count) 86 | { 87 | struct file * file; 88 | struct m_inode * inode; 89 | 90 | if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd])) 91 | return -EINVAL; 92 | if (!count) 93 | return 0; 94 | inode=file->f_inode; 95 | if (inode->i_pipe) 96 | return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO; 97 | if (S_ISCHR(inode->i_mode)) 98 | return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos); 99 | if (S_ISBLK(inode->i_mode)) 100 | return block_write(inode->i_zone[0],&file->f_pos,buf,count); 101 | if (S_ISREG(inode->i_mode)) 102 | return file_write(inode,file,buf,count); 103 | printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode); 104 | return -EINVAL; 105 | } 106 | -------------------------------------------------------------------------------- /lab7/report.txt: -------------------------------------------------------------------------------- 1 | Answers: 2 | 1) meminfo,可以获得内存相关信息,看那些程序占用内存较多,方便管理。 3 | 2) 是变化前的,在读取位置f_pos为0时才更新psinfo内容。 4 | 该inode对应的i_zone[0]依然存在。也就是说,只是从inode映射中取消映射该inode,但是实际上硬盘上的数据还在。 5 | -------------------------------------------------------------------------------- /lab7/stat.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_STAT_H 2 | #define _SYS_STAT_H 3 | 4 | #include 5 | 6 | struct stat { 7 | dev_t st_dev; 8 | ino_t st_ino; 9 | umode_t st_mode; 10 | nlink_t st_nlink; 11 | uid_t st_uid; 12 | gid_t st_gid; 13 | dev_t st_rdev; 14 | off_t st_size; 15 | time_t st_atime; 16 | time_t st_mtime; 17 | time_t st_ctime; 18 | }; 19 | 20 | #define S_IFMT 00170000 21 | #define S_IFREG 0100000 22 | #define S_IFBLK 0060000 23 | #define S_IFDIR 0040000 24 | #define S_IFPROC 0030000 25 | #define S_IFCHR 0020000 26 | #define S_IFIFO 0010000 27 | #define S_ISUID 0004000 28 | #define S_ISGID 0002000 29 | #define S_ISVTX 0001000 30 | 31 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 32 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 33 | #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 34 | #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) 35 | #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 36 | #define S_ISPROC(m) (((m) & S_IFMT) == S_IFPROC) 37 | 38 | #define S_IRWXU 00700 39 | #define S_IRUSR 00400 40 | #define S_IWUSR 00200 41 | #define S_IXUSR 00100 42 | 43 | #define S_IRWXG 00070 44 | #define S_IRGRP 00040 45 | #define S_IWGRP 00020 46 | #define S_IXGRP 00010 47 | 48 | #define S_IRWXO 00007 49 | #define S_IROTH 00004 50 | #define S_IWOTH 00002 51 | #define S_IXOTH 00001 52 | 53 | extern int chmod(const char *_path, mode_t mode); 54 | extern int fstat(int fildes, struct stat *stat_buf); 55 | extern int mkdir(const char *_path, mode_t mode); 56 | extern int mkfifo(const char *_path, mode_t mode); 57 | extern int stat(const char *filename, struct stat *stat_buf); 58 | extern mode_t umask(mode_t mask); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /lab8/Image: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/Image -------------------------------------------------------------------------------- /lab8/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # if you want the ram-disk device, define this to be the 3 | # size in blocks. 4 | # 5 | RAMDISK = #-DRAMDISK=512 6 | 7 | AS86 =as86 -0 -a 8 | LD86 =ld86 -0 9 | 10 | AS =as 11 | LD =ld 12 | LDFLAGS =-m elf_i386 -Ttext 0 -e startup_32 13 | CC =gcc-3.4 -march=i386 $(RAMDISK) 14 | CFLAGS =-m32 -g -Wall -O2 -fomit-frame-pointer 15 | 16 | CPP =cpp -nostdinc -Iinclude 17 | 18 | # 19 | # ROOT_DEV specifies the default root-device when making the image. 20 | # This can be either FLOPPY, /dev/xxxx or empty, in which case the 21 | # default of /dev/hd6 is used by 'build'. 22 | # 23 | ROOT_DEV= #FLOPPY 24 | 25 | ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o 26 | DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a 27 | MATH =kernel/math/math.a 28 | LIBS =lib/lib.a 29 | 30 | .c.s: 31 | $(CC) $(CFLAGS) \ 32 | -nostdinc -Iinclude -S -o $*.s $< 33 | .s.o: 34 | $(AS) -o $*.o $< 35 | .c.o: 36 | $(CC) $(CFLAGS) \ 37 | -nostdinc -Iinclude -c -o $*.o $< 38 | 39 | all: Image 40 | 41 | Image: boot/bootsect boot/setup tools/system tools/build 42 | cp -f tools/system system.tmp 43 | strip system.tmp 44 | objcopy -O binary -R .note -R .comment system.tmp tools/kernel 45 | tools/build boot/bootsect boot/setup tools/kernel $(ROOT_DEV) > Image 46 | rm system.tmp 47 | rm tools/kernel -f 48 | sync 49 | 50 | disk: Image 51 | dd bs=8192 if=Image of=/dev/fd0 52 | 53 | BootImage: boot/bootsect boot/setup tools/build 54 | tools/build boot/bootsect boot/setup none $(ROOT_DEV) > Image 55 | sync 56 | 57 | tools/build: tools/build.c 58 | gcc $(CFLAGS) \ 59 | -o tools/build tools/build.c 60 | 61 | boot/head.o: boot/head.s 62 | gcc-3.4 -m32 -g -I./include -traditional -c boot/head.s 63 | mv head.o boot/ 64 | 65 | tools/system: boot/head.o init/main.o \ 66 | $(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS) 67 | $(LD) $(LDFLAGS) boot/head.o init/main.o \ 68 | $(ARCHIVES) \ 69 | $(DRIVERS) \ 70 | $(MATH) \ 71 | $(LIBS) \ 72 | -o tools/system 73 | nm tools/system | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)'| sort > System.map 74 | 75 | kernel/math/math.a: FORCE 76 | (cd kernel/math; make) 77 | 78 | kernel/blk_drv/blk_drv.a: FORCE 79 | (cd kernel/blk_drv; make) 80 | 81 | kernel/chr_drv/chr_drv.a: FORCE 82 | (cd kernel/chr_drv; make) 83 | 84 | kernel/kernel.o: FORCE 85 | (cd kernel; make) 86 | 87 | mm/mm.o: FORCE 88 | (cd mm; make) 89 | 90 | fs/fs.o: FORCE 91 | (cd fs; make) 92 | 93 | lib/lib.a: FORCE 94 | (cd lib; make) 95 | 96 | boot/setup: boot/setup.s 97 | $(AS86) -o boot/setup.o boot/setup.s 98 | $(LD86) -s -o boot/setup boot/setup.o 99 | 100 | boot/bootsect: boot/bootsect.s 101 | $(AS86) -o boot/bootsect.o boot/bootsect.s 102 | $(LD86) -s -o boot/bootsect boot/bootsect.o 103 | 104 | tmp.s: boot/bootsect.s tools/system 105 | (echo -n "SYSSIZE = (";ls -l tools/system | grep system \ 106 | | cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s 107 | cat boot/bootsect.s >> tmp.s 108 | 109 | clean: 110 | rm -f Image System.map tmp_make core boot/bootsect boot/setup 111 | rm -f init/*.o tools/system tools/build boot/*.o 112 | (cd mm;make clean) 113 | (cd fs;make clean) 114 | (cd kernel;make clean) 115 | (cd lib;make clean) 116 | 117 | backup: clean 118 | (cd .. ; tar cf - linux | compress16 - > backup.Z) 119 | sync 120 | 121 | dep: 122 | sed '/\#\#\# Dependencies/q' < Makefile > tmp_make 123 | (for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make 124 | cp tmp_make Makefile 125 | (cd fs; make dep) 126 | (cd kernel; make dep) 127 | (cd mm; make dep) 128 | 129 | # Force make run into subdirectories even no changes on source 130 | FORCE: 131 | 132 | ### Dependencies: 133 | init/main.o: init/main.c include/unistd.h include/sys/stat.h \ 134 | include/sys/types.h include/sys/times.h include/sys/utsname.h \ 135 | include/utime.h include/time.h include/linux/tty.h include/termios.h \ 136 | include/linux/sched.h include/linux/head.h include/linux/fs.h \ 137 | include/linux/mm.h include/signal.h include/asm/system.h \ 138 | include/asm/io.h include/stddef.h include/stdarg.h include/fcntl.h 139 | -------------------------------------------------------------------------------- /lab8/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/a.out -------------------------------------------------------------------------------- /lab8/boot/bootsect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/boot/bootsect -------------------------------------------------------------------------------- /lab8/boot/bootsect.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/boot/bootsect.o -------------------------------------------------------------------------------- /lab8/boot/head.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/boot/head.o -------------------------------------------------------------------------------- /lab8/boot/setup: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/boot/setup -------------------------------------------------------------------------------- /lab8/boot/setup.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/boot/setup.o -------------------------------------------------------------------------------- /lab8/fs/bitmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/bitmap.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* bitmap.c contains the code that handles the inode and block bitmaps */ 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #define clear_block(addr) \ 14 | __asm__ __volatile__ ("cld\n\t" \ 15 | "rep\n\t" \ 16 | "stosl" \ 17 | ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr))) 18 | 19 | #define set_bit(nr,addr) ({\ 20 | register int res ; \ 21 | __asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \ 22 | "=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \ 23 | res;}) 24 | 25 | #define clear_bit(nr,addr) ({\ 26 | register int res ; \ 27 | __asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \ 28 | "=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \ 29 | res;}) 30 | 31 | #define find_first_zero(addr) ({ \ 32 | int __res; \ 33 | __asm__ __volatile__ ("cld\n" \ 34 | "1:\tlodsl\n\t" \ 35 | "notl %%eax\n\t" \ 36 | "bsfl %%eax,%%edx\n\t" \ 37 | "je 2f\n\t" \ 38 | "addl %%edx,%%ecx\n\t" \ 39 | "jmp 3f\n" \ 40 | "2:\taddl $32,%%ecx\n\t" \ 41 | "cmpl $8192,%%ecx\n\t" \ 42 | "jl 1b\n" \ 43 | "3:" \ 44 | :"=c" (__res):"c" (0),"S" (addr)); \ 45 | __res;}) 46 | 47 | void free_block(int dev, int block) 48 | { 49 | struct super_block * sb; 50 | struct buffer_head * bh; 51 | 52 | if (!(sb = get_super(dev))) 53 | panic("trying to free block on nonexistent device"); 54 | if (block < sb->s_firstdatazone || block >= sb->s_nzones) 55 | panic("trying to free block not in datazone"); 56 | bh = get_hash_table(dev,block); 57 | if (bh) { 58 | if (bh->b_count != 1) { 59 | printk("trying to free block (%04x:%d), count=%d\n", 60 | dev,block,bh->b_count); 61 | return; 62 | } 63 | bh->b_dirt=0; 64 | bh->b_uptodate=0; 65 | brelse(bh); 66 | } 67 | block -= sb->s_firstdatazone - 1 ; 68 | if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) { 69 | printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1); 70 | panic("free_block: bit already cleared"); 71 | } 72 | sb->s_zmap[block/8192]->b_dirt = 1; 73 | } 74 | 75 | int new_block(int dev) 76 | { 77 | struct buffer_head * bh; 78 | struct super_block * sb; 79 | int i,j; 80 | 81 | if (!(sb = get_super(dev))) 82 | panic("trying to get new block from nonexistant device"); 83 | j = 8192; 84 | for (i=0 ; i<8 ; i++) 85 | if ((bh=sb->s_zmap[i])) 86 | if ((j=find_first_zero(bh->b_data))<8192) 87 | break; 88 | if (i>=8 || !bh || j>=8192) 89 | return 0; 90 | if (set_bit(j,bh->b_data)) 91 | panic("new_block: bit already set"); 92 | bh->b_dirt = 1; 93 | j += i*8192 + sb->s_firstdatazone-1; 94 | if (j >= sb->s_nzones) 95 | return 0; 96 | if (!(bh=getblk(dev,j))) 97 | panic("new_block: cannot get block"); 98 | if (bh->b_count != 1) 99 | panic("new block: count is != 1"); 100 | clear_block(bh->b_data); 101 | bh->b_uptodate = 1; 102 | bh->b_dirt = 1; 103 | brelse(bh); 104 | return j; 105 | } 106 | 107 | void free_inode(struct m_inode * inode) 108 | { 109 | struct super_block * sb; 110 | struct buffer_head * bh; 111 | 112 | if (!inode) 113 | return; 114 | if (!inode->i_dev) { 115 | memset(inode,0,sizeof(*inode)); 116 | return; 117 | } 118 | if (inode->i_count>1) { 119 | printk("trying to free inode with count=%d\n",inode->i_count); 120 | panic("free_inode"); 121 | } 122 | if (inode->i_nlinks) 123 | panic("trying to free inode with links"); 124 | if (!(sb = get_super(inode->i_dev))) 125 | panic("trying to free inode on nonexistent device"); 126 | if (inode->i_num < 1 || inode->i_num > sb->s_ninodes) 127 | panic("trying to free inode 0 or nonexistant inode"); 128 | if (!(bh=sb->s_imap[inode->i_num>>13])) 129 | panic("nonexistent imap in superblock"); 130 | if (clear_bit(inode->i_num&8191,bh->b_data)) 131 | printk("free_inode: bit already cleared.\n\r"); 132 | bh->b_dirt = 1; 133 | memset(inode,0,sizeof(*inode)); 134 | } 135 | 136 | struct m_inode * new_inode(int dev) 137 | { 138 | struct m_inode * inode; 139 | struct super_block * sb; 140 | struct buffer_head * bh; 141 | int i,j; 142 | 143 | if (!(inode=get_empty_inode())) 144 | return NULL; 145 | if (!(sb = get_super(dev))) 146 | panic("new_inode with unknown device"); 147 | j = 8192; 148 | for (i=0 ; i<8 ; i++) 149 | if ((bh=sb->s_imap[i])) 150 | if ((j=find_first_zero(bh->b_data))<8192) 151 | break; 152 | if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) { 153 | iput(inode); 154 | return NULL; 155 | } 156 | if (set_bit(j,bh->b_data)) 157 | panic("new_inode: bit already set"); 158 | bh->b_dirt = 1; 159 | inode->i_count=1; 160 | inode->i_nlinks=1; 161 | inode->i_dev=dev; 162 | inode->i_uid=current->euid; 163 | inode->i_gid=current->egid; 164 | inode->i_dirt=1; 165 | inode->i_num = j + i*8192; 166 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 167 | return inode; 168 | } 169 | -------------------------------------------------------------------------------- /lab8/fs/bitmap.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/bitmap.o -------------------------------------------------------------------------------- /lab8/fs/block_dev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/block_dev.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int block_write(int dev, long * pos, char * buf, int count) 15 | { 16 | int block = *pos >> BLOCK_SIZE_BITS; 17 | int offset = *pos & (BLOCK_SIZE-1); 18 | int chars; 19 | int written = 0; 20 | struct buffer_head * bh; 21 | register char * p; 22 | 23 | while (count>0) { 24 | chars = BLOCK_SIZE - offset; 25 | if (chars > count) 26 | chars=count; 27 | if (chars == BLOCK_SIZE) 28 | bh = getblk(dev,block); 29 | else 30 | bh = breada(dev,block,block+1,block+2,-1); 31 | block++; 32 | if (!bh) 33 | return written?written:-EIO; 34 | p = offset + bh->b_data; 35 | offset = 0; 36 | *pos += chars; 37 | written += chars; 38 | count -= chars; 39 | while (chars-->0) 40 | *(p++) = get_fs_byte(buf++); 41 | bh->b_dirt = 1; 42 | brelse(bh); 43 | } 44 | return written; 45 | } 46 | 47 | int block_read(int dev, unsigned long * pos, char * buf, int count) 48 | { 49 | int block = *pos >> BLOCK_SIZE_BITS; 50 | int offset = *pos & (BLOCK_SIZE-1); 51 | int chars; 52 | int read = 0; 53 | struct buffer_head * bh; 54 | register char * p; 55 | 56 | while (count>0) { 57 | chars = BLOCK_SIZE-offset; 58 | if (chars > count) 59 | chars = count; 60 | if (!(bh = breada(dev,block,block+1,block+2,-1))) 61 | return read?read:-EIO; 62 | block++; 63 | p = offset + bh->b_data; 64 | offset = 0; 65 | *pos += chars; 66 | read += chars; 67 | count -= chars; 68 | while (chars-->0) 69 | put_fs_byte(*(p++),buf++); 70 | brelse(bh); 71 | } 72 | return read; 73 | } 74 | -------------------------------------------------------------------------------- /lab8/fs/block_dev.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/block_dev.o -------------------------------------------------------------------------------- /lab8/fs/buffer.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/buffer.o -------------------------------------------------------------------------------- /lab8/fs/char_dev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/char_dev.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | extern int tty_read(unsigned minor,char * buf,int count); 17 | extern int tty_write(unsigned minor,char * buf,int count); 18 | 19 | typedef int (*crw_ptr)(int rw,unsigned minor,char * buf,int count,off_t * pos); 20 | 21 | static int rw_ttyx(int rw,unsigned minor,char * buf,int count,off_t * pos) 22 | { 23 | return ((rw==READ)?tty_read(minor,buf,count): 24 | tty_write(minor,buf,count)); 25 | } 26 | 27 | static int rw_tty(int rw,unsigned minor,char * buf,int count, off_t * pos) 28 | { 29 | if (current->tty<0) 30 | return -EPERM; 31 | return rw_ttyx(rw,current->tty,buf,count,pos); 32 | } 33 | 34 | static int rw_ram(int rw,char * buf, int count, off_t *pos) 35 | { 36 | return -EIO; 37 | } 38 | 39 | static int rw_mem(int rw,char * buf, int count, off_t * pos) 40 | { 41 | return -EIO; 42 | } 43 | 44 | static int rw_kmem(int rw,char * buf, int count, off_t * pos) 45 | { 46 | return -EIO; 47 | } 48 | 49 | static int rw_port(int rw,char * buf, int count, off_t * pos) 50 | { 51 | int i=*pos; 52 | 53 | while (count-->0 && i<65536) { 54 | if (rw==READ) 55 | put_fs_byte(inb(i),buf++); 56 | else 57 | outb(get_fs_byte(buf++),i); 58 | i++; 59 | } 60 | i -= *pos; 61 | *pos += i; 62 | return i; 63 | } 64 | 65 | static int rw_memory(int rw, unsigned minor, char * buf, int count, off_t * pos) 66 | { 67 | switch(minor) { 68 | case 0: 69 | return rw_ram(rw,buf,count,pos); 70 | case 1: 71 | return rw_mem(rw,buf,count,pos); 72 | case 2: 73 | return rw_kmem(rw,buf,count,pos); 74 | case 3: 75 | return (rw==READ)?0:count; /* rw_null */ 76 | case 4: 77 | return rw_port(rw,buf,count,pos); 78 | default: 79 | return -EIO; 80 | } 81 | } 82 | 83 | #define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr))) 84 | 85 | static crw_ptr crw_table[]={ 86 | NULL, /* nodev */ 87 | rw_memory, /* /dev/mem etc */ 88 | NULL, /* /dev/fd */ 89 | NULL, /* /dev/hd */ 90 | rw_ttyx, /* /dev/ttyx */ 91 | rw_tty, /* /dev/tty */ 92 | NULL, /* /dev/lp */ 93 | NULL}; /* unnamed pipes */ 94 | 95 | int rw_char(int rw,int dev, char * buf, int count, off_t * pos) 96 | { 97 | crw_ptr call_addr; 98 | 99 | if (MAJOR(dev)>=NRDEVS) 100 | return -ENODEV; 101 | if (!(call_addr=crw_table[MAJOR(dev)])) 102 | return -ENODEV; 103 | return call_addr(rw,MINOR(dev),buf,count,pos); 104 | } 105 | -------------------------------------------------------------------------------- /lab8/fs/char_dev.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/char_dev.o -------------------------------------------------------------------------------- /lab8/fs/exec.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/exec.o -------------------------------------------------------------------------------- /lab8/fs/fcntl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/fcntl.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* #include */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | extern int sys_close(int fd); 17 | 18 | static int dupfd(unsigned int fd, unsigned int arg) 19 | { 20 | if (fd >= NR_OPEN || !current->filp[fd]) 21 | return -EBADF; 22 | if (arg >= NR_OPEN) 23 | return -EINVAL; 24 | while (arg < NR_OPEN) 25 | if (current->filp[arg]) 26 | arg++; 27 | else 28 | break; 29 | if (arg >= NR_OPEN) 30 | return -EMFILE; 31 | current->close_on_exec &= ~(1<filp[arg] = current->filp[fd])->f_count++; 33 | return arg; 34 | } 35 | 36 | int sys_dup2(unsigned int oldfd, unsigned int newfd) 37 | { 38 | sys_close(newfd); 39 | return dupfd(oldfd,newfd); 40 | } 41 | 42 | int sys_dup(unsigned int fildes) 43 | { 44 | return dupfd(fildes,0); 45 | } 46 | 47 | int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) 48 | { 49 | struct file * filp; 50 | 51 | if (fd >= NR_OPEN || !(filp = current->filp[fd])) 52 | return -EBADF; 53 | switch (cmd) { 54 | case F_DUPFD: 55 | return dupfd(fd,arg); 56 | case F_GETFD: 57 | return (current->close_on_exec>>fd)&1; 58 | case F_SETFD: 59 | if (arg&1) 60 | current->close_on_exec |= (1<close_on_exec &= ~(1<f_flags; 66 | case F_SETFL: 67 | filp->f_flags &= ~(O_APPEND | O_NONBLOCK); 68 | filp->f_flags |= arg & (O_APPEND | O_NONBLOCK); 69 | return 0; 70 | case F_GETLK: case F_SETLK: case F_SETLKW: 71 | return -1; 72 | default: 73 | return -1; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lab8/fs/fcntl.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/fcntl.o -------------------------------------------------------------------------------- /lab8/fs/file_dev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/file_dev.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #define MIN(a,b) (((a)<(b))?(a):(b)) 15 | #define MAX(a,b) (((a)>(b))?(a):(b)) 16 | 17 | int file_read(struct m_inode * inode, struct file * filp, char * buf, int count) 18 | { 19 | int left,chars,nr; 20 | struct buffer_head * bh; 21 | 22 | if ((left=count)<=0) 23 | return 0; 24 | while (left) { 25 | if ((nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE))) { 26 | if (!(bh=bread(inode->i_dev,nr))) 27 | break; 28 | } else 29 | bh = NULL; 30 | nr = filp->f_pos % BLOCK_SIZE; 31 | chars = MIN( BLOCK_SIZE-nr , left ); 32 | filp->f_pos += chars; 33 | left -= chars; 34 | if (bh) { 35 | char * p = nr + bh->b_data; 36 | while (chars-->0) 37 | put_fs_byte(*(p++),buf++); 38 | brelse(bh); 39 | } else { 40 | while (chars-->0) 41 | put_fs_byte(0,buf++); 42 | } 43 | } 44 | inode->i_atime = CURRENT_TIME; 45 | return (count-left)?(count-left):-ERROR; 46 | } 47 | 48 | int file_write(struct m_inode * inode, struct file * filp, char * buf, int count) 49 | { 50 | off_t pos; 51 | int block,c; 52 | struct buffer_head * bh; 53 | char * p; 54 | int i=0; 55 | 56 | /* 57 | * ok, append may not work when many processes are writing at the same time 58 | * but so what. That way leads to madness anyway. 59 | */ 60 | if (filp->f_flags & O_APPEND) 61 | pos = inode->i_size; 62 | else 63 | pos = filp->f_pos; 64 | while (ii_dev,block))) 68 | break; 69 | c = pos % BLOCK_SIZE; 70 | p = c + bh->b_data; 71 | bh->b_dirt = 1; 72 | c = BLOCK_SIZE-c; 73 | if (c > count-i) c = count-i; 74 | pos += c; 75 | if (pos > inode->i_size) { 76 | inode->i_size = pos; 77 | inode->i_dirt = 1; 78 | } 79 | i += c; 80 | while (c-->0) 81 | *(p++) = get_fs_byte(buf++); 82 | brelse(bh); 83 | } 84 | inode->i_mtime = CURRENT_TIME; 85 | if (!(filp->f_flags & O_APPEND)) { 86 | filp->f_pos = pos; 87 | inode->i_ctime = CURRENT_TIME; 88 | } 89 | return (i?i:-1); 90 | } 91 | -------------------------------------------------------------------------------- /lab8/fs/file_dev.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/file_dev.o -------------------------------------------------------------------------------- /lab8/fs/file_table.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/file_table.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | struct file file_table[NR_FILE]; 10 | -------------------------------------------------------------------------------- /lab8/fs/file_table.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/file_table.o -------------------------------------------------------------------------------- /lab8/fs/fs.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/fs.o -------------------------------------------------------------------------------- /lab8/fs/inode.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/inode.o -------------------------------------------------------------------------------- /lab8/fs/ioctl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/ioctl.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* #include */ 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | extern int tty_ioctl(int dev, int cmd, int arg); 14 | 15 | typedef int (*ioctl_ptr)(int dev,int cmd,int arg); 16 | 17 | #define NRDEVS ((sizeof (ioctl_table))/(sizeof (ioctl_ptr))) 18 | 19 | static ioctl_ptr ioctl_table[]={ 20 | NULL, /* nodev */ 21 | NULL, /* /dev/mem */ 22 | NULL, /* /dev/fd */ 23 | NULL, /* /dev/hd */ 24 | tty_ioctl, /* /dev/ttyx */ 25 | tty_ioctl, /* /dev/tty */ 26 | NULL, /* /dev/lp */ 27 | NULL}; /* named pipes */ 28 | 29 | 30 | int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 31 | { 32 | struct file * filp; 33 | int dev,mode; 34 | 35 | if (fd >= NR_OPEN || !(filp = current->filp[fd])) 36 | return -EBADF; 37 | mode=filp->f_inode->i_mode; 38 | if (!S_ISCHR(mode) && !S_ISBLK(mode)) 39 | return -EINVAL; 40 | dev = filp->f_inode->i_zone[0]; 41 | if (MAJOR(dev) >= NRDEVS) 42 | return -ENODEV; 43 | if (!ioctl_table[MAJOR(dev)]) 44 | return -ENOTTY; 45 | return ioctl_table[MAJOR(dev)](dev,cmd,arg); 46 | } 47 | -------------------------------------------------------------------------------- /lab8/fs/ioctl.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/ioctl.o -------------------------------------------------------------------------------- /lab8/fs/namei.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/namei.o -------------------------------------------------------------------------------- /lab8/fs/open.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/open.o -------------------------------------------------------------------------------- /lab8/fs/pipe.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/pipe.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | #include 10 | #include /* for get_free_page */ 11 | #include 12 | 13 | int read_pipe(struct m_inode * inode, char * buf, int count) 14 | { 15 | int chars, size, read = 0; 16 | 17 | while (count>0) { 18 | while (!(size=PIPE_SIZE(*inode))) { 19 | wake_up(&inode->i_wait); 20 | if (inode->i_count != 2) /* are there any writers? */ 21 | return read; 22 | sleep_on(&inode->i_wait); 23 | } 24 | chars = PAGE_SIZE-PIPE_TAIL(*inode); 25 | if (chars > count) 26 | chars = count; 27 | if (chars > size) 28 | chars = size; 29 | count -= chars; 30 | read += chars; 31 | size = PIPE_TAIL(*inode); 32 | PIPE_TAIL(*inode) += chars; 33 | PIPE_TAIL(*inode) &= (PAGE_SIZE-1); 34 | while (chars-->0) 35 | put_fs_byte(((char *)inode->i_size)[size++],buf++); 36 | } 37 | wake_up(&inode->i_wait); 38 | return read; 39 | } 40 | 41 | int write_pipe(struct m_inode * inode, char * buf, int count) 42 | { 43 | int chars, size, written = 0; 44 | 45 | while (count>0) { 46 | while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) { 47 | wake_up(&inode->i_wait); 48 | if (inode->i_count != 2) { /* no readers */ 49 | current->signal |= (1<<(SIGPIPE-1)); 50 | return written?written:-1; 51 | } 52 | sleep_on(&inode->i_wait); 53 | } 54 | chars = PAGE_SIZE-PIPE_HEAD(*inode); 55 | if (chars > count) 56 | chars = count; 57 | if (chars > size) 58 | chars = size; 59 | count -= chars; 60 | written += chars; 61 | size = PIPE_HEAD(*inode); 62 | PIPE_HEAD(*inode) += chars; 63 | PIPE_HEAD(*inode) &= (PAGE_SIZE-1); 64 | while (chars-->0) 65 | ((char *)inode->i_size)[size++]=get_fs_byte(buf++); 66 | } 67 | wake_up(&inode->i_wait); 68 | return written; 69 | } 70 | 71 | int sys_pipe(unsigned long * fildes) 72 | { 73 | struct m_inode * inode; 74 | struct file * f[2]; 75 | int fd[2]; 76 | int i,j; 77 | 78 | j=0; 79 | for(i=0;j<2 && if_count++; 82 | if (j==1) 83 | f[0]->f_count=0; 84 | if (j<2) 85 | return -1; 86 | j=0; 87 | for(i=0;j<2 && ifilp[i]) { 89 | current->filp[ fd[j]=i ] = f[j]; 90 | j++; 91 | } 92 | if (j==1) 93 | current->filp[fd[0]]=NULL; 94 | if (j<2) { 95 | f[0]->f_count=f[1]->f_count=0; 96 | return -1; 97 | } 98 | if (!(inode=get_pipe_inode())) { 99 | current->filp[fd[0]] = 100 | current->filp[fd[1]] = NULL; 101 | f[0]->f_count = f[1]->f_count = 0; 102 | return -1; 103 | } 104 | f[0]->f_inode = f[1]->f_inode = inode; 105 | f[0]->f_pos = f[1]->f_pos = 0; 106 | f[0]->f_mode = 1; /* read */ 107 | f[1]->f_mode = 2; /* write */ 108 | put_fs_long(fd[0],0+fildes); 109 | put_fs_long(fd[1],1+fildes); 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /lab8/fs/pipe.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/pipe.o -------------------------------------------------------------------------------- /lab8/fs/read_write.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/read_write.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos); 16 | extern int read_pipe(struct m_inode * inode, char * buf, int count); 17 | extern int write_pipe(struct m_inode * inode, char * buf, int count); 18 | extern int block_read(int dev, off_t * pos, char * buf, int count); 19 | extern int block_write(int dev, off_t * pos, char * buf, int count); 20 | extern int file_read(struct m_inode * inode, struct file * filp, 21 | char * buf, int count); 22 | extern int file_write(struct m_inode * inode, struct file * filp, 23 | char * buf, int count); 24 | 25 | int sys_lseek(unsigned int fd,off_t offset, int origin) 26 | { 27 | struct file * file; 28 | int tmp; 29 | 30 | if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode) 31 | || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev))) 32 | return -EBADF; 33 | if (file->f_inode->i_pipe) 34 | return -ESPIPE; 35 | switch (origin) { 36 | case 0: 37 | if (offset<0) return -EINVAL; 38 | file->f_pos=offset; 39 | break; 40 | case 1: 41 | if (file->f_pos+offset<0) return -EINVAL; 42 | file->f_pos += offset; 43 | break; 44 | case 2: 45 | if ((tmp=file->f_inode->i_size+offset) < 0) 46 | return -EINVAL; 47 | file->f_pos = tmp; 48 | break; 49 | default: 50 | return -EINVAL; 51 | } 52 | return file->f_pos; 53 | } 54 | 55 | int sys_read(unsigned int fd,char * buf,int count) 56 | { 57 | struct file * file; 58 | struct m_inode * inode; 59 | 60 | if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd])) 61 | return -EINVAL; 62 | if (!count) 63 | return 0; 64 | verify_area(buf,count); 65 | inode = file->f_inode; 66 | if (inode->i_pipe) 67 | return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO; 68 | if (S_ISCHR(inode->i_mode)) 69 | return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos); 70 | if (S_ISBLK(inode->i_mode)) 71 | return block_read(inode->i_zone[0],&file->f_pos,buf,count); 72 | if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) { 73 | if (count+file->f_pos > inode->i_size) 74 | count = inode->i_size - file->f_pos; 75 | if (count<=0) 76 | return 0; 77 | return file_read(inode,file,buf,count); 78 | } 79 | printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode); 80 | return -EINVAL; 81 | } 82 | 83 | int sys_write(unsigned int fd,char * buf,int count) 84 | { 85 | struct file * file; 86 | struct m_inode * inode; 87 | 88 | if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd])) 89 | return -EINVAL; 90 | if (!count) 91 | return 0; 92 | inode=file->f_inode; 93 | if (inode->i_pipe) 94 | return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO; 95 | if (S_ISCHR(inode->i_mode)) 96 | return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos); 97 | if (S_ISBLK(inode->i_mode)) 98 | return block_write(inode->i_zone[0],&file->f_pos,buf,count); 99 | if (S_ISREG(inode->i_mode)) 100 | return file_write(inode,file,buf,count); 101 | printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode); 102 | return -EINVAL; 103 | } 104 | -------------------------------------------------------------------------------- /lab8/fs/read_write.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/read_write.o -------------------------------------------------------------------------------- /lab8/fs/stat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/stat.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static void cp_stat(struct m_inode * inode, struct stat * statbuf) 16 | { 17 | struct stat tmp; 18 | int i; 19 | 20 | verify_area(statbuf,sizeof (* statbuf)); 21 | tmp.st_dev = inode->i_dev; 22 | tmp.st_ino = inode->i_num; 23 | tmp.st_mode = inode->i_mode; 24 | tmp.st_nlink = inode->i_nlinks; 25 | tmp.st_uid = inode->i_uid; 26 | tmp.st_gid = inode->i_gid; 27 | tmp.st_rdev = inode->i_zone[0]; 28 | tmp.st_size = inode->i_size; 29 | tmp.st_atime = inode->i_atime; 30 | tmp.st_mtime = inode->i_mtime; 31 | tmp.st_ctime = inode->i_ctime; 32 | for (i=0 ; i= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode)) 53 | return -EBADF; 54 | cp_stat(inode,statbuf); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /lab8/fs/stat.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/stat.o -------------------------------------------------------------------------------- /lab8/fs/super.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/super.o -------------------------------------------------------------------------------- /lab8/fs/truncate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/fs/truncate.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | #include 10 | 11 | static void free_ind(int dev,int block) 12 | { 13 | struct buffer_head * bh; 14 | unsigned short * p; 15 | int i; 16 | 17 | if (!block) 18 | return; 19 | if ((bh=bread(dev,block))) { 20 | p = (unsigned short *) bh->b_data; 21 | for (i=0;i<512;i++,p++) 22 | if (*p) 23 | free_block(dev,*p); 24 | brelse(bh); 25 | } 26 | free_block(dev,block); 27 | } 28 | 29 | static void free_dind(int dev,int block) 30 | { 31 | struct buffer_head * bh; 32 | unsigned short * p; 33 | int i; 34 | 35 | if (!block) 36 | return; 37 | if ((bh=bread(dev,block))) { 38 | p = (unsigned short *) bh->b_data; 39 | for (i=0;i<512;i++,p++) 40 | if (*p) 41 | free_ind(dev,*p); 42 | brelse(bh); 43 | } 44 | free_block(dev,block); 45 | } 46 | 47 | void truncate(struct m_inode * inode) 48 | { 49 | int i; 50 | 51 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) 52 | return; 53 | for (i=0;i<7;i++) 54 | if (inode->i_zone[i]) { 55 | free_block(inode->i_dev,inode->i_zone[i]); 56 | inode->i_zone[i]=0; 57 | } 58 | free_ind(inode->i_dev,inode->i_zone[7]); 59 | free_dind(inode->i_dev,inode->i_zone[8]); 60 | inode->i_zone[7] = inode->i_zone[8] = 0; 61 | inode->i_size = 0; 62 | inode->i_dirt = 1; 63 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /lab8/fs/truncate.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/fs/truncate.o -------------------------------------------------------------------------------- /lab8/include/asm/io.h: -------------------------------------------------------------------------------- 1 | #define outb(value,port) \ 2 | __asm__ ("outb %%al,%%dx"::"a" (value),"d" (port)) 3 | 4 | 5 | #define inb(port) ({ \ 6 | unsigned char _v; \ 7 | __asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \ 8 | _v; \ 9 | }) 10 | 11 | #define outb_p(value,port) \ 12 | __asm__ ("outb %%al,%%dx\n" \ 13 | "\tjmp 1f\n" \ 14 | "1:\tjmp 1f\n" \ 15 | "1:"::"a" (value),"d" (port)) 16 | 17 | #define inb_p(port) ({ \ 18 | unsigned char _v; \ 19 | __asm__ volatile ("inb %%dx,%%al\n" \ 20 | "\tjmp 1f\n" \ 21 | "1:\tjmp 1f\n" \ 22 | "1:":"=a" (_v):"d" (port)); \ 23 | _v; \ 24 | }) 25 | -------------------------------------------------------------------------------- /lab8/include/asm/memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTE!!! memcpy(dest,src,n) assumes ds=es=normal data segment. This 3 | * goes for all kernel functions (ds=es=kernel space, fs=local data, 4 | * gs=null), as well as for all well-behaving user programs (ds=es= 5 | * user data space). This is NOT a bug, as any user program that changes 6 | * es deserves to die if it isn't careful. 7 | */ 8 | #define memcpy(dest,src,n) ({ \ 9 | void * _res = dest; \ 10 | __asm__ ("cld;rep;movsb" \ 11 | ::"D" ((long)(_res)),"S" ((long)(src)),"c" ((long) (n)) \ 12 | ); \ 13 | _res; \ 14 | }) 15 | -------------------------------------------------------------------------------- /lab8/include/asm/segment.h: -------------------------------------------------------------------------------- 1 | static inline unsigned char get_fs_byte(const char * addr) 2 | { 3 | unsigned register char _v; 4 | 5 | __asm__ ("movb %%fs:%1,%0":"=r" (_v):"m" (*addr)); 6 | return _v; 7 | } 8 | 9 | static inline unsigned short get_fs_word(const unsigned short *addr) 10 | { 11 | unsigned short _v; 12 | 13 | __asm__ ("movw %%fs:%1,%0":"=r" (_v):"m" (*addr)); 14 | return _v; 15 | } 16 | 17 | static inline unsigned long get_fs_long(const unsigned long *addr) 18 | { 19 | unsigned long _v; 20 | 21 | __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \ 22 | return _v; 23 | } 24 | 25 | static inline void put_fs_byte(char val,char *addr) 26 | { 27 | __asm__ ("movb %0,%%fs:%1"::"r" (val),"m" (*addr)); 28 | } 29 | 30 | static inline void put_fs_word(short val,short * addr) 31 | { 32 | __asm__ ("movw %0,%%fs:%1"::"r" (val),"m" (*addr)); 33 | } 34 | 35 | static inline void put_fs_long(unsigned long val,unsigned long * addr) 36 | { 37 | __asm__ ("movl %0,%%fs:%1"::"r" (val),"m" (*addr)); 38 | } 39 | 40 | /* 41 | * Someone who knows GNU asm better than I should double check the followig. 42 | * It seems to work, but I don't know if I'm doing something subtly wrong. 43 | * --- TYT, 11/24/91 44 | * [ nothing wrong here, Linus ] 45 | */ 46 | 47 | static inline unsigned long get_fs() 48 | { 49 | unsigned short _v; 50 | __asm__("mov %%fs,%%ax":"=a" (_v):); 51 | return _v; 52 | } 53 | 54 | static inline unsigned long get_ds() 55 | { 56 | unsigned short _v; 57 | __asm__("mov %%ds,%%ax":"=a" (_v):); 58 | return _v; 59 | } 60 | 61 | static inline void set_fs(unsigned long val) 62 | { 63 | __asm__("mov %0,%%fs"::"a" ((unsigned short) val)); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /lab8/include/asm/system.h: -------------------------------------------------------------------------------- 1 | #define move_to_user_mode() \ 2 | __asm__ ("movl %%esp,%%eax\n\t" \ 3 | "pushl $0x17\n\t" \ 4 | "pushl %%eax\n\t" \ 5 | "pushfl\n\t" \ 6 | "pushl $0x0f\n\t" \ 7 | "pushl $1f\n\t" \ 8 | "iret\n" \ 9 | "1:\tmovl $0x17,%%eax\n\t" \ 10 | "movw %%ax,%%ds\n\t" \ 11 | "movw %%ax,%%es\n\t" \ 12 | "movw %%ax,%%fs\n\t" \ 13 | "movw %%ax,%%gs" \ 14 | :::"ax") 15 | 16 | #define sti() __asm__ ("sti"::) 17 | #define cli() __asm__ ("cli"::) 18 | #define nop() __asm__ ("nop"::) 19 | 20 | #define iret() __asm__ ("iret"::) 21 | 22 | #define _set_gate(gate_addr,type,dpl,addr) \ 23 | __asm__ ("movw %%dx,%%ax\n\t" \ 24 | "movw %0,%%dx\n\t" \ 25 | "movl %%eax,%1\n\t" \ 26 | "movl %%edx,%2" \ 27 | : \ 28 | : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ 29 | "o" (*((char *) (gate_addr))), \ 30 | "o" (*(4+(char *) (gate_addr))), \ 31 | "d" ((char *) (addr)),"a" (0x00080000)) 32 | 33 | #define set_intr_gate(n,addr) \ 34 | _set_gate(&idt[n],14,0,addr) 35 | 36 | #define set_trap_gate(n,addr) \ 37 | _set_gate(&idt[n],15,0,addr) 38 | 39 | #define set_system_gate(n,addr) \ 40 | _set_gate(&idt[n],15,3,addr) 41 | 42 | #define _set_seg_desc(gate_addr,type,dpl,base,limit) {\ 43 | *(gate_addr) = ((base) & 0xff000000) | \ 44 | (((base) & 0x00ff0000)>>16) | \ 45 | ((limit) & 0xf0000) | \ 46 | ((dpl)<<13) | \ 47 | (0x00408000) | \ 48 | ((type)<<8); \ 49 | *((gate_addr)+1) = (((base) & 0x0000ffff)<<16) | \ 50 | ((limit) & 0x0ffff); } 51 | 52 | #define _set_tssldt_desc(n,addr,type) \ 53 | __asm__ ("movw $104,%1\n\t" \ 54 | "movw %%ax,%2\n\t" \ 55 | "rorl $16,%%eax\n\t" \ 56 | "movb %%al,%3\n\t" \ 57 | "movb $" type ",%4\n\t" \ 58 | "movb $0x00,%5\n\t" \ 59 | "movb %%ah,%6\n\t" \ 60 | "rorl $16,%%eax" \ 61 | ::"a" (addr), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \ 62 | "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \ 63 | ) 64 | 65 | #define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),((int)(addr)),"0x89") 66 | #define set_ldt_desc(n,addr) _set_tssldt_desc(((char *) (n)),((int)(addr)),"0x82") 67 | 68 | -------------------------------------------------------------------------------- /lab8/include/const.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONST_H 2 | #define _CONST_H 3 | 4 | #define BUFFER_END 0x200000 5 | 6 | #define I_TYPE 0170000 7 | #define I_DIRECTORY 0040000 8 | #define I_REGULAR 0100000 9 | #define I_BLOCK_SPECIAL 0060000 10 | #define I_CHAR_SPECIAL 0020000 11 | #define I_NAMED_PIPE 0010000 12 | #define I_SET_UID_BIT 0004000 13 | #define I_SET_GID_BIT 0002000 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /lab8/include/ctype.h: -------------------------------------------------------------------------------- 1 | #ifndef _CTYPE_H 2 | #define _CTYPE_H 3 | 4 | #define _U 0x01 /* upper */ 5 | #define _L 0x02 /* lower */ 6 | #define _D 0x04 /* digit */ 7 | #define _C 0x08 /* cntrl */ 8 | #define _P 0x10 /* punct */ 9 | #define _S 0x20 /* white space (space/lf/tab) */ 10 | #define _X 0x40 /* hex digit */ 11 | #define _SP 0x80 /* hard space (0x20) */ 12 | 13 | extern unsigned char _ctype[]; 14 | extern char _ctmp; 15 | 16 | #define isalnum(c) ((_ctype+1)[c]&(_U|_L|_D)) 17 | #define isalpha(c) ((_ctype+1)[c]&(_U|_L)) 18 | #define iscntrl(c) ((_ctype+1)[c]&(_C)) 19 | #define isdigit(c) ((_ctype+1)[c]&(_D)) 20 | #define isgraph(c) ((_ctype+1)[c]&(_P|_U|_L|_D)) 21 | #define islower(c) ((_ctype+1)[c]&(_L)) 22 | #define isprint(c) ((_ctype+1)[c]&(_P|_U|_L|_D|_SP)) 23 | #define ispunct(c) ((_ctype+1)[c]&(_P)) 24 | #define isspace(c) ((_ctype+1)[c]&(_S)) 25 | #define isupper(c) ((_ctype+1)[c]&(_U)) 26 | #define isxdigit(c) ((_ctype+1)[c]&(_D|_X)) 27 | 28 | #define isascii(c) (((unsigned) c)<=0x7f) 29 | #define toascii(c) (((unsigned) c)&0x7f) 30 | 31 | #define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp-('A'-'a'):_ctmp) 32 | #define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp) 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /lab8/include/errno.h: -------------------------------------------------------------------------------- 1 | #ifndef _ERRNO_H 2 | #define _ERRNO_H 3 | 4 | /* 5 | * ok, as I hadn't got any other source of information about 6 | * possible error numbers, I was forced to use the same numbers 7 | * as minix. 8 | * Hopefully these are posix or something. I wouldn't know (and posix 9 | * isn't telling me - they want $$$ for their f***ing standard). 10 | * 11 | * We don't use the _SIGN cludge of minix, so kernel returns must 12 | * see to the sign by themselves. 13 | * 14 | * NOTE! Remember to change strerror() if you change this file! 15 | */ 16 | 17 | extern int errno; 18 | 19 | #define ERROR 99 20 | #define EPERM 1 21 | #define ENOENT 2 22 | #define ESRCH 3 23 | #define EINTR 4 24 | #define EIO 5 25 | #define ENXIO 6 26 | #define E2BIG 7 27 | #define ENOEXEC 8 28 | #define EBADF 9 29 | #define ECHILD 10 30 | #define EAGAIN 11 31 | #define ENOMEM 12 32 | #define EACCES 13 33 | #define EFAULT 14 34 | #define ENOTBLK 15 35 | #define EBUSY 16 36 | #define EEXIST 17 37 | #define EXDEV 18 38 | #define ENODEV 19 39 | #define ENOTDIR 20 40 | #define EISDIR 21 41 | #define EINVAL 22 42 | #define ENFILE 23 43 | #define EMFILE 24 44 | #define ENOTTY 25 45 | #define ETXTBSY 26 46 | #define EFBIG 27 47 | #define ENOSPC 28 48 | #define ESPIPE 29 49 | #define EROFS 30 50 | #define EMLINK 31 51 | #define EPIPE 32 52 | #define EDOM 33 53 | #define ERANGE 34 54 | #define EDEADLK 35 55 | #define ENAMETOOLONG 36 56 | #define ENOLCK 37 57 | #define ENOSYS 38 58 | #define ENOTEMPTY 39 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /lab8/include/fcntl.h: -------------------------------------------------------------------------------- 1 | #ifndef _FCNTL_H 2 | #define _FCNTL_H 3 | 4 | #include 5 | 6 | /* open/fcntl - NOCTTY, NDELAY isn't implemented yet */ 7 | #define O_ACCMODE 00003 8 | #define O_RDONLY 00 9 | #define O_WRONLY 01 10 | #define O_RDWR 02 11 | #define O_CREAT 00100 /* not fcntl */ 12 | #define O_EXCL 00200 /* not fcntl */ 13 | #define O_NOCTTY 00400 /* not fcntl */ 14 | #define O_TRUNC 01000 /* not fcntl */ 15 | #define O_APPEND 02000 16 | #define O_NONBLOCK 04000 /* not fcntl */ 17 | #define O_NDELAY O_NONBLOCK 18 | 19 | /* Defines for fcntl-commands. Note that currently 20 | * locking isn't supported, and other things aren't really 21 | * tested. 22 | */ 23 | #define F_DUPFD 0 /* dup */ 24 | #define F_GETFD 1 /* get f_flags */ 25 | #define F_SETFD 2 /* set f_flags */ 26 | #define F_GETFL 3 /* more flags (cloexec) */ 27 | #define F_SETFL 4 28 | #define F_GETLK 5 /* not implemented */ 29 | #define F_SETLK 6 30 | #define F_SETLKW 7 31 | 32 | /* for F_[GET|SET]FL */ 33 | #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ 34 | 35 | /* Ok, these are locking features, and aren't implemented at any 36 | * level. POSIX wants them. 37 | */ 38 | #define F_RDLCK 0 39 | #define F_WRLCK 1 40 | #define F_UNLCK 2 41 | 42 | /* Once again - not implemented, but ... */ 43 | struct flock { 44 | short l_type; 45 | short l_whence; 46 | off_t l_start; 47 | off_t l_len; 48 | pid_t l_pid; 49 | }; 50 | 51 | extern int creat(const char * filename,mode_t mode); 52 | extern int fcntl(int fildes,int cmd, ...); 53 | extern int open(const char * filename, int flags, ...); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lab8/include/linux/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | #define _CONFIG_H 3 | 4 | /* 5 | * The root-device is no longer hard-coded. You can change the default 6 | * root-device by changing the line ROOT_DEV = XXX in boot/bootsect.s 7 | */ 8 | 9 | /* 10 | * define your keyboard here - 11 | * KBD_FINNISH for Finnish keyboards 12 | * KBD_US for US-type 13 | * KBD_GR for German keyboards 14 | * KBD_FR for Frech keyboard 15 | */ 16 | #define KBD_US 17 | /*#define KBD_GR */ 18 | /*#define KBD_FR */ 19 | /*#define KBD_FINNISH */ 20 | 21 | /* 22 | * Normally, Linux can get the drive parameters from the BIOS at 23 | * startup, but if this for some unfathomable reason fails, you'd 24 | * be left stranded. For this case, you can define HD_TYPE, which 25 | * contains all necessary info on your harddisk. 26 | * 27 | * The HD_TYPE macro should look like this: 28 | * 29 | * #define HD_TYPE { head, sect, cyl, wpcom, lzone, ctl} 30 | * 31 | * In case of two harddisks, the info should be sepatated by 32 | * commas: 33 | * 34 | * #define HD_TYPE { h,s,c,wpcom,lz,ctl },{ h,s,c,wpcom,lz,ctl } 35 | */ 36 | /* 37 | This is an example, two drives, first is type 2, second is type 3: 38 | 39 | #define HD_TYPE { 4,17,615,300,615,8 }, { 6,17,615,300,615,0 } 40 | 41 | NOTE: ctl is 0 for all drives with heads<=8, and ctl=8 for drives 42 | with more than 8 heads. 43 | 44 | If you want the BIOS to tell what kind of drive you have, just 45 | leave HD_TYPE undefined. This is the normal thing to do. 46 | */ 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /lab8/include/linux/fdreg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains some defines for the floppy disk controller. 3 | * Various sources. Mostly "IBM Microcomputers: A Programmers 4 | * Handbook", Sanches and Canton. 5 | */ 6 | #ifndef _FDREG_H 7 | #define _FDREG_H 8 | 9 | extern int ticks_to_floppy_on(unsigned int nr); 10 | extern void floppy_on(unsigned int nr); 11 | extern void floppy_off(unsigned int nr); 12 | extern void floppy_select(unsigned int nr); 13 | extern void floppy_deselect(unsigned int nr); 14 | 15 | /* Fd controller regs. S&C, about page 340 */ 16 | #define FD_STATUS 0x3f4 17 | #define FD_DATA 0x3f5 18 | #define FD_DOR 0x3f2 /* Digital Output Register */ 19 | #define FD_DIR 0x3f7 /* Digital Input Register (read) */ 20 | #define FD_DCR 0x3f7 /* Diskette Control Register (write)*/ 21 | 22 | /* Bits of main status register */ 23 | #define STATUS_BUSYMASK 0x0F /* drive busy mask */ 24 | #define STATUS_BUSY 0x10 /* FDC busy */ 25 | #define STATUS_DMA 0x20 /* 0- DMA mode */ 26 | #define STATUS_DIR 0x40 /* 0- cpu->fdc */ 27 | #define STATUS_READY 0x80 /* Data reg ready */ 28 | 29 | /* Bits of FD_ST0 */ 30 | #define ST0_DS 0x03 /* drive select mask */ 31 | #define ST0_HA 0x04 /* Head (Address) */ 32 | #define ST0_NR 0x08 /* Not Ready */ 33 | #define ST0_ECE 0x10 /* Equipment chech error */ 34 | #define ST0_SE 0x20 /* Seek end */ 35 | #define ST0_INTR 0xC0 /* Interrupt code mask */ 36 | 37 | /* Bits of FD_ST1 */ 38 | #define ST1_MAM 0x01 /* Missing Address Mark */ 39 | #define ST1_WP 0x02 /* Write Protect */ 40 | #define ST1_ND 0x04 /* No Data - unreadable */ 41 | #define ST1_OR 0x10 /* OverRun */ 42 | #define ST1_CRC 0x20 /* CRC error in data or addr */ 43 | #define ST1_EOC 0x80 /* End Of Cylinder */ 44 | 45 | /* Bits of FD_ST2 */ 46 | #define ST2_MAM 0x01 /* Missing Addess Mark (again) */ 47 | #define ST2_BC 0x02 /* Bad Cylinder */ 48 | #define ST2_SNS 0x04 /* Scan Not Satisfied */ 49 | #define ST2_SEH 0x08 /* Scan Equal Hit */ 50 | #define ST2_WC 0x10 /* Wrong Cylinder */ 51 | #define ST2_CRC 0x20 /* CRC error in data field */ 52 | #define ST2_CM 0x40 /* Control Mark = deleted */ 53 | 54 | /* Bits of FD_ST3 */ 55 | #define ST3_HA 0x04 /* Head (Address) */ 56 | #define ST3_TZ 0x10 /* Track Zero signal (1=track 0) */ 57 | #define ST3_WP 0x40 /* Write Protect */ 58 | 59 | /* Values for FD_COMMAND */ 60 | #define FD_RECALIBRATE 0x07 /* move to track 0 */ 61 | #define FD_SEEK 0x0F /* seek track */ 62 | #define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */ 63 | #define FD_WRITE 0xC5 /* write with MT, MFM */ 64 | #define FD_SENSEI 0x08 /* Sense Interrupt Status */ 65 | #define FD_SPECIFY 0x03 /* specify HUT etc */ 66 | 67 | /* DMA commands */ 68 | #define DMA_READ 0x46 69 | #define DMA_WRITE 0x4A 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /lab8/include/linux/hdreg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains some defines for the AT-hd-controller. 3 | * Various sources. Check out some definitions (see comments with 4 | * a ques). 5 | */ 6 | #ifndef _HDREG_H 7 | #define _HDREG_H 8 | 9 | /* Hd controller regs. Ref: IBM AT Bios-listing */ 10 | #define HD_DATA 0x1f0 /* _CTL when writing */ 11 | #define HD_ERROR 0x1f1 /* see err-bits */ 12 | #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ 13 | #define HD_SECTOR 0x1f3 /* starting sector */ 14 | #define HD_LCYL 0x1f4 /* starting cylinder */ 15 | #define HD_HCYL 0x1f5 /* high byte of starting cyl */ 16 | #define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ 17 | #define HD_STATUS 0x1f7 /* see status-bits */ 18 | #define HD_PRECOMP HD_ERROR /* same io address, read=error, write=precomp */ 19 | #define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ 20 | 21 | #define HD_CMD 0x3f6 22 | 23 | /* Bits of HD_STATUS */ 24 | #define ERR_STAT 0x01 25 | #define INDEX_STAT 0x02 26 | #define ECC_STAT 0x04 /* Corrected error */ 27 | #define DRQ_STAT 0x08 28 | #define SEEK_STAT 0x10 29 | #define WRERR_STAT 0x20 30 | #define READY_STAT 0x40 31 | #define BUSY_STAT 0x80 32 | 33 | /* Values for HD_COMMAND */ 34 | #define WIN_RESTORE 0x10 35 | #define WIN_READ 0x20 36 | #define WIN_WRITE 0x30 37 | #define WIN_VERIFY 0x40 38 | #define WIN_FORMAT 0x50 39 | #define WIN_INIT 0x60 40 | #define WIN_SEEK 0x70 41 | #define WIN_DIAGNOSE 0x90 42 | #define WIN_SPECIFY 0x91 43 | 44 | /* Bits for HD_ERROR */ 45 | #define MARK_ERR 0x01 /* Bad address mark ? */ 46 | #define TRK0_ERR 0x02 /* couldn't find track 0 */ 47 | #define ABRT_ERR 0x04 /* ? */ 48 | #define ID_ERR 0x10 /* ? */ 49 | #define ECC_ERR 0x40 /* ? */ 50 | #define BBD_ERR 0x80 /* ? */ 51 | 52 | struct partition { 53 | unsigned char boot_ind; /* 0x80 - active (unused) */ 54 | unsigned char head; /* ? */ 55 | unsigned char sector; /* ? */ 56 | unsigned char cyl; /* ? */ 57 | unsigned char sys_ind; /* ? */ 58 | unsigned char end_head; /* ? */ 59 | unsigned char end_sector; /* ? */ 60 | unsigned char end_cyl; /* ? */ 61 | unsigned int start_sect; /* starting sector counting from 0 */ 62 | unsigned int nr_sects; /* nr of sectors in partition */ 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /lab8/include/linux/head.h: -------------------------------------------------------------------------------- 1 | #ifndef _HEAD_H 2 | #define _HEAD_H 3 | 4 | typedef struct desc_struct { 5 | unsigned long a,b; 6 | } desc_table[256]; 7 | 8 | extern unsigned long pg_dir[1024]; 9 | extern desc_table idt,gdt; 10 | 11 | #define GDT_NUL 0 12 | #define GDT_CODE 1 13 | #define GDT_DATA 2 14 | #define GDT_TMP 3 15 | 16 | #define LDT_NUL 0 17 | #define LDT_CODE 1 18 | #define LDT_DATA 2 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /lab8/include/linux/kernel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 'kernel.h' contains some often-used function prototypes etc 3 | */ 4 | void verify_area(void * addr,int count); 5 | volatile void panic(const char * str); 6 | int printf(const char * fmt, ...); 7 | int printk(const char * fmt, ...); 8 | int tty_write(unsigned ch,char * buf,int count); 9 | void * malloc(unsigned int size); 10 | void free_s(void * obj, int size); 11 | 12 | #define free(x) free_s((x), 0) 13 | 14 | /* 15 | * This is defined as a macro, but at some point this might become a 16 | * real subroutine that sets a flag if it returns true (to do 17 | * BSD-style accounting where the process is flagged if it uses root 18 | * privs). The implication of this is that you should do normal 19 | * permissions checks first, and check suser() last. 20 | */ 21 | #define suser() (current->euid == 0) 22 | 23 | -------------------------------------------------------------------------------- /lab8/include/linux/mm.h: -------------------------------------------------------------------------------- 1 | #ifndef _MM_H 2 | #define _MM_H 3 | 4 | #define PAGE_SIZE 4096 5 | 6 | extern unsigned long get_free_page(void); 7 | extern unsigned long put_page(unsigned long page,unsigned long address); 8 | extern void free_page(unsigned long addr); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lab8/include/linux/sys.h: -------------------------------------------------------------------------------- 1 | extern int sys_setup(); 2 | extern int sys_exit(); 3 | extern int sys_fork(); 4 | extern int sys_read(); 5 | extern int sys_write(); 6 | extern int sys_open(); 7 | extern int sys_close(); 8 | extern int sys_waitpid(); 9 | extern int sys_creat(); 10 | extern int sys_link(); 11 | extern int sys_unlink(); 12 | extern int sys_execve(); 13 | extern int sys_chdir(); 14 | extern int sys_time(); 15 | extern int sys_mknod(); 16 | extern int sys_chmod(); 17 | extern int sys_chown(); 18 | extern int sys_break(); 19 | extern int sys_stat(); 20 | extern int sys_lseek(); 21 | extern int sys_getpid(); 22 | extern int sys_mount(); 23 | extern int sys_umount(); 24 | extern int sys_setuid(); 25 | extern int sys_getuid(); 26 | extern int sys_stime(); 27 | extern int sys_ptrace(); 28 | extern int sys_alarm(); 29 | extern int sys_fstat(); 30 | extern int sys_pause(); 31 | extern int sys_utime(); 32 | extern int sys_stty(); 33 | extern int sys_gtty(); 34 | extern int sys_access(); 35 | extern int sys_nice(); 36 | extern int sys_ftime(); 37 | extern int sys_sync(); 38 | extern int sys_kill(); 39 | extern int sys_rename(); 40 | extern int sys_mkdir(); 41 | extern int sys_rmdir(); 42 | extern int sys_dup(); 43 | extern int sys_pipe(); 44 | extern int sys_times(); 45 | extern int sys_prof(); 46 | extern int sys_brk(); 47 | extern int sys_setgid(); 48 | extern int sys_getgid(); 49 | extern int sys_signal(); 50 | extern int sys_geteuid(); 51 | extern int sys_getegid(); 52 | extern int sys_acct(); 53 | extern int sys_phys(); 54 | extern int sys_lock(); 55 | extern int sys_ioctl(); 56 | extern int sys_fcntl(); 57 | extern int sys_mpx(); 58 | extern int sys_setpgid(); 59 | extern int sys_ulimit(); 60 | extern int sys_uname(); 61 | extern int sys_umask(); 62 | extern int sys_chroot(); 63 | extern int sys_ustat(); 64 | extern int sys_dup2(); 65 | extern int sys_getppid(); 66 | extern int sys_getpgrp(); 67 | extern int sys_setsid(); 68 | extern int sys_sigaction(); 69 | extern int sys_sgetmask(); 70 | extern int sys_ssetmask(); 71 | extern int sys_setreuid(); 72 | extern int sys_setregid(); 73 | extern int sys_make_thread(); 74 | extern int sys_thread_cancel(); 75 | extern int sys_thread_exit(); 76 | extern int sys_thread_join(); 77 | extern int sys_thread_status(); 78 | extern int sys_thread_gettid(); 79 | 80 | fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, 81 | sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, 82 | sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod, 83 | sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount, 84 | sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm, 85 | sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access, 86 | sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir, 87 | sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid, 88 | sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys, 89 | sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit, 90 | sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid, 91 | sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask, 92 | sys_setreuid,sys_setregid, sys_make_thread, sys_thread_cancel, 93 | sys_thread_exit, sys_thread_join, sys_thread_status, sys_thread_gettid}; 94 | -------------------------------------------------------------------------------- /lab8/include/linux/tty.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 'tty.h' defines some structures used by tty_io.c and some defines. 3 | * 4 | * NOTE! Don't touch this without checking that nothing in rs_io.s or 5 | * con_io.s breaks. Some constants are hardwired into the system (mainly 6 | * offsets into 'tty_queue' 7 | */ 8 | 9 | #ifndef _TTY_H 10 | #define _TTY_H 11 | 12 | #include 13 | 14 | #define TTY_BUF_SIZE 1024 15 | 16 | struct tty_queue { 17 | unsigned long data; 18 | unsigned long head; 19 | unsigned long tail; 20 | struct task_struct * proc_list; 21 | char buf[TTY_BUF_SIZE]; 22 | }; 23 | 24 | #define INC(a) ((a) = ((a)+1) & (TTY_BUF_SIZE-1)) 25 | #define DEC(a) ((a) = ((a)-1) & (TTY_BUF_SIZE-1)) 26 | #define EMPTY(a) ((a).head == (a).tail) 27 | #define LEFT(a) (((a).tail-(a).head-1)&(TTY_BUF_SIZE-1)) 28 | #define LAST(a) ((a).buf[(TTY_BUF_SIZE-1)&((a).head-1)]) 29 | #define FULL(a) (!LEFT(a)) 30 | #define CHARS(a) (((a).head-(a).tail)&(TTY_BUF_SIZE-1)) 31 | #define GETCH(queue,c) \ 32 | (void)({c=(queue).buf[(queue).tail];INC((queue).tail);}) 33 | #define PUTCH(c,queue) \ 34 | (void)({(queue).buf[(queue).head]=(c);INC((queue).head);}) 35 | 36 | #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR]) 37 | #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT]) 38 | #define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE]) 39 | #define KILL_CHAR(tty) ((tty)->termios.c_cc[VKILL]) 40 | #define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF]) 41 | #define START_CHAR(tty) ((tty)->termios.c_cc[VSTART]) 42 | #define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP]) 43 | #define SUSPEND_CHAR(tty) ((tty)->termios.c_cc[VSUSP]) 44 | 45 | struct tty_struct { 46 | struct termios termios; 47 | int pgrp; 48 | int stopped; 49 | void (*write)(struct tty_struct * tty); 50 | struct tty_queue read_q; 51 | struct tty_queue write_q; 52 | struct tty_queue secondary; 53 | }; 54 | 55 | extern struct tty_struct tty_table[]; 56 | 57 | /* intr=^C quit=^| erase=del kill=^U 58 | eof=^D vtime=\0 vmin=\1 sxtc=\0 59 | start=^Q stop=^S susp=^Z eol=\0 60 | reprint=^R discard=^U werase=^W lnext=^V 61 | eol2=\0 62 | */ 63 | #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" 64 | 65 | void rs_init(void); 66 | void con_init(void); 67 | void tty_init(void); 68 | 69 | int tty_read(unsigned c, char * buf, int n); 70 | int tty_write(unsigned c, char * buf, int n); 71 | 72 | void rs_write(struct tty_struct * tty); 73 | void con_write(struct tty_struct * tty); 74 | 75 | void copy_to_cooked(struct tty_struct * tty); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /lab8/include/signal.h: -------------------------------------------------------------------------------- 1 | #ifndef _SIGNAL_H 2 | #define _SIGNAL_H 3 | 4 | #include 5 | 6 | typedef int sig_atomic_t; 7 | typedef unsigned int sigset_t; /* 32 bits */ 8 | 9 | #define _NSIG 32 10 | #define NSIG _NSIG 11 | 12 | #define SIGHUP 1 13 | #define SIGINT 2 14 | #define SIGQUIT 3 15 | #define SIGILL 4 16 | #define SIGTRAP 5 17 | #define SIGABRT 6 18 | #define SIGIOT 6 19 | #define SIGUNUSED 7 20 | #define SIGFPE 8 21 | #define SIGKILL 9 22 | #define SIGUSR1 10 23 | #define SIGSEGV 11 24 | #define SIGUSR2 12 25 | #define SIGPIPE 13 26 | #define SIGALRM 14 27 | #define SIGTERM 15 28 | #define SIGSTKFLT 16 29 | #define SIGCHLD 17 30 | #define SIGCONT 18 31 | #define SIGSTOP 19 32 | #define SIGTSTP 20 33 | #define SIGTTIN 21 34 | #define SIGTTOU 22 35 | 36 | /* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */ 37 | #define SA_NOCLDSTOP 1 38 | #define SA_NOMASK 0x40000000 39 | #define SA_ONESHOT 0x80000000 40 | 41 | #define SIG_BLOCK 0 /* for blocking signals */ 42 | #define SIG_UNBLOCK 1 /* for unblocking signals */ 43 | #define SIG_SETMASK 2 /* for setting the signal mask */ 44 | 45 | #define SIG_DFL ((void (*)(int))0) /* default signal handling */ 46 | #define SIG_IGN ((void (*)(int))1) /* ignore signal */ 47 | 48 | struct sigaction { 49 | void (*sa_handler)(int); 50 | sigset_t sa_mask; 51 | int sa_flags; 52 | void (*sa_restorer)(void); 53 | }; 54 | 55 | void (*signal(int _sig, void (*_func)(int)))(int); 56 | int raise(int sig); 57 | int kill(pid_t pid, int sig); 58 | int sigaddset(sigset_t *mask, int signo); 59 | int sigdelset(sigset_t *mask, int signo); 60 | int sigemptyset(sigset_t *mask); 61 | int sigfillset(sigset_t *mask); 62 | int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */ 63 | int sigpending(sigset_t *set); 64 | int sigprocmask(int how, sigset_t *set, sigset_t *oldset); 65 | int sigsuspend(sigset_t *sigmask); 66 | int sigaction(int sig, struct sigaction *act, struct sigaction *oldact); 67 | 68 | #endif /* _SIGNAL_H */ 69 | -------------------------------------------------------------------------------- /lab8/include/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDARG_H 2 | #define _STDARG_H 3 | 4 | typedef char *va_list; 5 | 6 | /* Amount of space required in an argument list for an arg of type TYPE. 7 | TYPE may alternatively be an expression whose type is used. */ 8 | 9 | #define __va_rounded_size(TYPE) \ 10 | (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 11 | 12 | #ifndef __sparc__ 13 | #define va_start(AP, LASTARG) \ 14 | (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) 15 | #else 16 | #define va_start(AP, LASTARG) \ 17 | (__builtin_saveregs (), \ 18 | AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) 19 | #endif 20 | 21 | void va_end (va_list); /* Defined in gnulib */ 22 | #define va_end(AP) 23 | 24 | #define va_arg(AP, TYPE) \ 25 | (AP += __va_rounded_size (TYPE), \ 26 | *((TYPE *) (AP - __va_rounded_size (TYPE)))) 27 | 28 | #endif /* _STDARG_H */ 29 | -------------------------------------------------------------------------------- /lab8/include/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDDEF_H 2 | #define _STDDEF_H 3 | 4 | #ifndef _PTRDIFF_T 5 | #define _PTRDIFF_T 6 | typedef long ptrdiff_t; 7 | #endif 8 | 9 | #ifndef _SIZE_T 10 | #define _SIZE_T 11 | typedef unsigned long size_t; 12 | #endif 13 | 14 | #undef NULL 15 | #define NULL ((void *)0) 16 | 17 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /lab8/include/sys/stat.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_STAT_H 2 | #define _SYS_STAT_H 3 | 4 | #include 5 | 6 | struct stat { 7 | dev_t st_dev; 8 | ino_t st_ino; 9 | umode_t st_mode; 10 | nlink_t st_nlink; 11 | uid_t st_uid; 12 | gid_t st_gid; 13 | dev_t st_rdev; 14 | off_t st_size; 15 | time_t st_atime; 16 | time_t st_mtime; 17 | time_t st_ctime; 18 | }; 19 | 20 | #define S_IFMT 00170000 21 | #define S_IFREG 0100000 22 | #define S_IFBLK 0060000 23 | #define S_IFDIR 0040000 24 | #define S_IFCHR 0020000 25 | #define S_IFIFO 0010000 26 | #define S_ISUID 0004000 27 | #define S_ISGID 0002000 28 | #define S_ISVTX 0001000 29 | 30 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 31 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 32 | #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 33 | #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) 34 | #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 35 | 36 | #define S_IRWXU 00700 37 | #define S_IRUSR 00400 38 | #define S_IWUSR 00200 39 | #define S_IXUSR 00100 40 | 41 | #define S_IRWXG 00070 42 | #define S_IRGRP 00040 43 | #define S_IWGRP 00020 44 | #define S_IXGRP 00010 45 | 46 | #define S_IRWXO 00007 47 | #define S_IROTH 00004 48 | #define S_IWOTH 00002 49 | #define S_IXOTH 00001 50 | 51 | extern int chmod(const char *_path, mode_t mode); 52 | extern int fstat(int fildes, struct stat *stat_buf); 53 | extern int mkdir(const char *_path, mode_t mode); 54 | extern int mkfifo(const char *_path, mode_t mode); 55 | extern int stat(const char *filename, struct stat *stat_buf); 56 | extern mode_t umask(mode_t mask); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /lab8/include/sys/times.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIMES_H 2 | #define _TIMES_H 3 | 4 | #include 5 | 6 | struct tms { 7 | time_t tms_utime; 8 | time_t tms_stime; 9 | time_t tms_cutime; 10 | time_t tms_cstime; 11 | }; 12 | 13 | extern time_t times(struct tms * tp); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /lab8/include/sys/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_TYPES_H 2 | #define _SYS_TYPES_H 3 | 4 | #ifndef _SIZE_T 5 | #define _SIZE_T 6 | typedef unsigned int size_t; 7 | #endif 8 | 9 | #ifndef _TIME_T 10 | #define _TIME_T 11 | typedef long time_t; 12 | #endif 13 | 14 | #ifndef _PTRDIFF_T 15 | #define _PTRDIFF_T 16 | typedef long ptrdiff_t; 17 | #endif 18 | 19 | #ifndef NULL 20 | #define NULL ((void *) 0) 21 | #endif 22 | 23 | typedef int pid_t; 24 | typedef unsigned short uid_t; 25 | typedef unsigned char gid_t; 26 | typedef unsigned short dev_t; 27 | typedef unsigned short ino_t; 28 | typedef unsigned short mode_t; 29 | typedef unsigned short umode_t; 30 | typedef unsigned char nlink_t; 31 | typedef int daddr_t; 32 | typedef long off_t; 33 | typedef unsigned char u_char; 34 | typedef unsigned short ushort; 35 | 36 | typedef struct { int quot,rem; } div_t; 37 | typedef struct { long quot,rem; } ldiv_t; 38 | 39 | struct ustat { 40 | daddr_t f_tfree; 41 | ino_t f_tinode; 42 | char f_fname[6]; 43 | char f_fpack[6]; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /lab8/include/sys/utsname.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_UTSNAME_H 2 | #define _SYS_UTSNAME_H 3 | 4 | #include 5 | 6 | struct utsname { 7 | char sysname[9]; 8 | char nodename[9]; 9 | char release[9]; 10 | char version[9]; 11 | char machine[9]; 12 | }; 13 | 14 | extern int uname(struct utsname * utsbuf); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /lab8/include/sys/wait.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_WAIT_H 2 | #define _SYS_WAIT_H 3 | 4 | #include 5 | 6 | #define _LOW(v) ( (v) & 0377) 7 | #define _HIGH(v) ( ((v) >> 8) & 0377) 8 | 9 | /* options for waitpid, WUNTRACED not supported */ 10 | #define WNOHANG 1 11 | #define WUNTRACED 2 12 | 13 | #define WIFEXITED(s) (!((s)&0xFF) 14 | #define WIFSTOPPED(s) (((s)&0xFF)==0x7F) 15 | #define WEXITSTATUS(s) (((s)>>8)&0xFF) 16 | #define WTERMSIG(s) ((s)&0x7F) 17 | #define WSTOPSIG(s) (((s)>>8)&0xFF) 18 | #define WIFSIGNALED(s) (((unsigned int)(s)-1 & 0xFFFF) < 0xFF) 19 | 20 | pid_t wait(int *stat_loc); 21 | pid_t waitpid(pid_t pid, int *stat_loc, int options); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /lab8/include/time.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIME_H 2 | #define _TIME_H 3 | 4 | #ifndef _TIME_T 5 | #define _TIME_T 6 | typedef long time_t; 7 | #endif 8 | 9 | #ifndef _SIZE_T 10 | #define _SIZE_T 11 | typedef unsigned int size_t; 12 | #endif 13 | 14 | #define CLOCKS_PER_SEC 100 15 | 16 | typedef long clock_t; 17 | 18 | struct tm { 19 | int tm_sec; 20 | int tm_min; 21 | int tm_hour; 22 | int tm_mday; 23 | int tm_mon; 24 | int tm_year; 25 | int tm_wday; 26 | int tm_yday; 27 | int tm_isdst; 28 | }; 29 | 30 | clock_t clock(void); 31 | time_t time(time_t * tp); 32 | double difftime(time_t time2, time_t time1); 33 | time_t mktime(struct tm * tp); 34 | 35 | char * asctime(const struct tm * tp); 36 | char * ctime(const time_t * tp); 37 | struct tm * gmtime(const time_t *tp); 38 | struct tm *localtime(const time_t * tp); 39 | size_t strftime(char * s, size_t smax, const char * fmt, const struct tm * tp); 40 | void tzset(void); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /lab8/include/utime.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTIME_H 2 | #define _UTIME_H 3 | 4 | #include /* I know - shouldn't do this, but .. */ 5 | 6 | struct utimbuf { 7 | time_t actime; 8 | time_t modtime; 9 | }; 10 | 11 | extern int utime(const char *filename, struct utimbuf *times); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /lab8/init/main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/init/main.o -------------------------------------------------------------------------------- /lab8/kernel/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for the FREAX-kernel. 3 | # 4 | # Note! Dependencies are done automagically by 'make dep', which also 5 | # removes any old dependencies. DON'T put your own dependencies here 6 | # unless it's something special (ie not a .c file). 7 | # 8 | 9 | AR =ar 10 | AS =as --32 11 | LD =ld 12 | LDFLAGS =-m elf_i386 -x 13 | CC =gcc-3.4 -march=i386 14 | CFLAGS =-m32 -g -Wall -O -fstrength-reduce -fomit-frame-pointer \ 15 | -finline-functions -nostdinc -I../include 16 | CPP =gcc-3.4 -E -nostdinc -I../include 17 | 18 | .c.s: 19 | $(CC) $(CFLAGS) \ 20 | -S -o $*.s $< 21 | .s.o: 22 | $(AS) -o $*.o $< 23 | .c.o: 24 | $(CC) $(CFLAGS) \ 25 | -c -o $*.o $< 26 | 27 | OBJS = sched.o system_call.o traps.o asm.o fork.o \ 28 | panic.o printk.o vsprintf.o sys.o exit.o \ 29 | signal.o mktime.o thread.o 30 | 31 | kernel.o: $(OBJS) 32 | $(LD) -m elf_i386 -r -o kernel.o $(OBJS) 33 | sync 34 | 35 | clean: 36 | rm -f core *.o *.a tmp_make keyboard.s 37 | for i in *.c;do rm -f `basename $$i .c`.s;done 38 | (cd chr_drv; make clean) 39 | (cd blk_drv; make clean) 40 | (cd math; make clean) 41 | 42 | dep: 43 | sed '/\#\#\# Dependencies/q' < Makefile > tmp_make 44 | (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ 45 | $(CPP) -M $$i;done) >> tmp_make 46 | cp tmp_make Makefile 47 | (cd chr_drv; make dep) 48 | (cd blk_drv; make dep) 49 | 50 | ### Dependencies: 51 | exit.s exit.o: exit.c ../include/errno.h ../include/signal.h \ 52 | ../include/sys/types.h ../include/sys/wait.h ../include/linux/sched.h \ 53 | ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \ 54 | ../include/linux/kernel.h ../include/linux/tty.h ../include/termios.h \ 55 | ../include/asm/segment.h 56 | thread.s thread.o: thread.c ../include/errno.h ../include/linux/sched.h \ 57 | ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ 58 | ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ 59 | ../include/asm/segment.h ../include/asm/system.h 60 | fork.s fork.o: fork.c ../include/errno.h ../include/linux/sched.h \ 61 | ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ 62 | ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ 63 | ../include/asm/segment.h ../include/asm/system.h 64 | mktime.s mktime.o: mktime.c ../include/time.h 65 | panic.s panic.o: panic.c ../include/linux/kernel.h ../include/linux/sched.h \ 66 | ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ 67 | ../include/linux/mm.h ../include/signal.h 68 | printk.s printk.o: printk.c ../include/stdarg.h ../include/stddef.h \ 69 | ../include/linux/kernel.h 70 | sched.s sched.o: sched.c ../include/linux/sched.h ../include/linux/head.h \ 71 | ../include/linux/fs.h ../include/sys/types.h ../include/linux/mm.h \ 72 | ../include/signal.h ../include/linux/kernel.h ../include/linux/sys.h \ 73 | ../include/linux/fdreg.h ../include/asm/system.h ../include/asm/io.h \ 74 | ../include/asm/segment.h 75 | signal.s signal.o: signal.c ../include/linux/sched.h ../include/linux/head.h \ 76 | ../include/linux/fs.h ../include/sys/types.h ../include/linux/mm.h \ 77 | ../include/signal.h ../include/linux/kernel.h ../include/asm/segment.h 78 | sys.s sys.o: sys.c ../include/errno.h ../include/linux/sched.h \ 79 | ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ 80 | ../include/linux/mm.h ../include/signal.h ../include/linux/tty.h \ 81 | ../include/termios.h ../include/linux/kernel.h ../include/asm/segment.h \ 82 | ../include/sys/times.h ../include/sys/utsname.h 83 | traps.s traps.o: traps.c ../include/string.h ../include/linux/head.h \ 84 | ../include/linux/sched.h ../include/linux/fs.h ../include/sys/types.h \ 85 | ../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \ 86 | ../include/asm/system.h ../include/asm/segment.h ../include/asm/io.h 87 | vsprintf.s vsprintf.o: vsprintf.c ../include/stdarg.h ../include/string.h 88 | -------------------------------------------------------------------------------- /lab8/kernel/asm.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/asm.o -------------------------------------------------------------------------------- /lab8/kernel/asm.s: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/asm.s 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * asm.s contains the low-level code for most hardware faults. 9 | * page_exception is handled by the mm, so that isn't here. This 10 | * file also handles (hopefully) fpu-exceptions due to TS-bit, as 11 | * the fpu must be properly saved/resored. This hasn't been tested. 12 | */ 13 | 14 | .globl divide_error,debug,nmi,int3,overflow,bounds,invalid_op 15 | .globl double_fault,coprocessor_segment_overrun 16 | .globl invalid_TSS,segment_not_present,stack_segment 17 | .globl general_protection,coprocessor_error,irq13,reserved 18 | 19 | divide_error: 20 | pushl $do_divide_error 21 | no_error_code: 22 | xchgl %eax,(%esp) 23 | pushl %ebx 24 | pushl %ecx 25 | pushl %edx 26 | pushl %edi 27 | pushl %esi 28 | pushl %ebp 29 | push %ds 30 | push %es 31 | push %fs 32 | pushl $0 # "error code" 33 | lea 44(%esp),%edx 34 | pushl %edx 35 | movl $0x10,%edx 36 | mov %dx,%ds 37 | mov %dx,%es 38 | mov %dx,%fs 39 | call *%eax 40 | addl $8,%esp 41 | pop %fs 42 | pop %es 43 | pop %ds 44 | popl %ebp 45 | popl %esi 46 | popl %edi 47 | popl %edx 48 | popl %ecx 49 | popl %ebx 50 | popl %eax 51 | iret 52 | 53 | debug: 54 | pushl $do_int3 # _do_debug 55 | jmp no_error_code 56 | 57 | nmi: 58 | pushl $do_nmi 59 | jmp no_error_code 60 | 61 | int3: 62 | pushl $do_int3 63 | jmp no_error_code 64 | 65 | overflow: 66 | pushl $do_overflow 67 | jmp no_error_code 68 | 69 | bounds: 70 | pushl $do_bounds 71 | jmp no_error_code 72 | 73 | invalid_op: 74 | pushl $do_invalid_op 75 | jmp no_error_code 76 | 77 | coprocessor_segment_overrun: 78 | pushl $do_coprocessor_segment_overrun 79 | jmp no_error_code 80 | 81 | reserved: 82 | pushl $do_reserved 83 | jmp no_error_code 84 | 85 | irq13: 86 | pushl %eax 87 | xorb %al,%al 88 | outb %al,$0xF0 89 | movb $0x20,%al 90 | outb %al,$0x20 91 | jmp 1f 92 | 1: jmp 1f 93 | 1: outb %al,$0xA0 94 | popl %eax 95 | jmp coprocessor_error 96 | 97 | double_fault: 98 | pushl $do_double_fault 99 | error_code: 100 | xchgl %eax,4(%esp) # error code <-> %eax 101 | xchgl %ebx,(%esp) # &function <-> %ebx 102 | pushl %ecx 103 | pushl %edx 104 | pushl %edi 105 | pushl %esi 106 | pushl %ebp 107 | push %ds 108 | push %es 109 | push %fs 110 | pushl %eax # error code 111 | lea 44(%esp),%eax # offset 112 | pushl %eax 113 | movl $0x10,%eax 114 | mov %ax,%ds 115 | mov %ax,%es 116 | mov %ax,%fs 117 | call *%ebx 118 | addl $8,%esp 119 | pop %fs 120 | pop %es 121 | pop %ds 122 | popl %ebp 123 | popl %esi 124 | popl %edi 125 | popl %edx 126 | popl %ecx 127 | popl %ebx 128 | popl %eax 129 | iret 130 | 131 | invalid_TSS: 132 | pushl $do_invalid_TSS 133 | jmp error_code 134 | 135 | segment_not_present: 136 | pushl $do_segment_not_present 137 | jmp error_code 138 | 139 | stack_segment: 140 | pushl $do_stack_segment 141 | jmp error_code 142 | 143 | general_protection: 144 | pushl $do_general_protection 145 | jmp error_code 146 | 147 | -------------------------------------------------------------------------------- /lab8/kernel/blk_drv/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for the FREAX-kernel block device drivers. 3 | # 4 | # Note! Dependencies are done automagically by 'make dep', which also 5 | # removes any old dependencies. DON'T put your own dependencies here 6 | # unless it's something special (ie not a .c file). 7 | # 8 | 9 | AR =ar 10 | AS =as 11 | LD =ld 12 | LDFLAGS =-m elf_i386 -x 13 | CC =gcc-3.4 -march=i386 14 | CFLAGS =-m32 -g -Wall -O -fstrength-reduce -fomit-frame-pointer \ 15 | -finline-functions -nostdinc -I../../include 16 | CPP =gcc-3.4 -E -nostdinc -I../../include 17 | 18 | .c.s: 19 | $(CC) $(CFLAGS) \ 20 | -S -o $*.s $< 21 | .s.o: 22 | $(AS) -o $*.o $< 23 | .c.o: 24 | $(CC) $(CFLAGS) \ 25 | -c -o $*.o $< 26 | 27 | OBJS = ll_rw_blk.o floppy.o hd.o ramdisk.o 28 | 29 | blk_drv.a: $(OBJS) 30 | $(AR) rcs blk_drv.a $(OBJS) 31 | sync 32 | 33 | clean: 34 | rm -f core *.o *.a tmp_make 35 | for i in *.c;do rm -f `basename $$i .c`.s;done 36 | 37 | dep: 38 | sed '/\#\#\# Dependencies/q' < Makefile > tmp_make 39 | (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ 40 | $(CPP) -M $$i;done) >> tmp_make 41 | cp tmp_make Makefile 42 | 43 | ### Dependencies: 44 | floppy.s floppy.o: floppy.c ../../include/linux/sched.h ../../include/linux/head.h \ 45 | ../../include/linux/fs.h ../../include/sys/types.h \ 46 | ../../include/linux/mm.h ../../include/signal.h \ 47 | ../../include/linux/kernel.h ../../include/linux/fdreg.h \ 48 | ../../include/asm/system.h ../../include/asm/io.h \ 49 | ../../include/asm/segment.h blk.h 50 | hd.s hd.o: hd.c ../../include/linux/config.h ../../include/linux/sched.h \ 51 | ../../include/linux/head.h ../../include/linux/fs.h \ 52 | ../../include/sys/types.h ../../include/linux/mm.h \ 53 | ../../include/signal.h ../../include/linux/kernel.h \ 54 | ../../include/linux/hdreg.h ../../include/asm/system.h \ 55 | ../../include/asm/io.h ../../include/asm/segment.h blk.h 56 | ll_rw_blk.s ll_rw_blk.o: ll_rw_blk.c ../../include/errno.h \ 57 | ../../include/linux/sched.h ../../include/linux/head.h \ 58 | ../../include/linux/fs.h ../../include/sys/types.h \ 59 | ../../include/linux/mm.h ../../include/signal.h \ 60 | ../../include/linux/kernel.h ../../include/asm/system.h blk.h 61 | ramdisk.s ramdisk.o: ramdisk.c ../../include/string.h ../../include/linux/config.h \ 62 | ../../include/linux/sched.h ../../include/linux/head.h \ 63 | ../../include/linux/fs.h ../../include/sys/types.h \ 64 | ../../include/linux/mm.h ../../include/signal.h \ 65 | ../../include/linux/kernel.h ../../include/asm/system.h \ 66 | ../../include/asm/segment.h ../../include/asm/memory.h blk.h 67 | -------------------------------------------------------------------------------- /lab8/kernel/blk_drv/blk.h: -------------------------------------------------------------------------------- 1 | #ifndef _BLK_H 2 | #define _BLK_H 3 | 4 | #define NR_BLK_DEV 7 5 | /* 6 | * NR_REQUEST is the number of entries in the request-queue. 7 | * NOTE that writes may use only the low 2/3 of these: reads 8 | * take precedence. 9 | * 10 | * 32 seems to be a reasonable number: enough to get some benefit 11 | * from the elevator-mechanism, but not so much as to lock a lot of 12 | * buffers when they are in the queue. 64 seems to be too many (easily 13 | * long pauses in reading when heavy writing/syncing is going on) 14 | */ 15 | #define NR_REQUEST 32 16 | 17 | /* 18 | * Ok, this is an expanded form so that we can use the same 19 | * request for paging requests when that is implemented. In 20 | * paging, 'bh' is NULL, and 'waiting' is used to wait for 21 | * read/write completion. 22 | */ 23 | struct request { 24 | int dev; /* -1 if no request */ 25 | int cmd; /* READ or WRITE */ 26 | int errors; 27 | unsigned long sector; 28 | unsigned long nr_sectors; 29 | char * buffer; 30 | struct task_struct * waiting; 31 | struct buffer_head * bh; 32 | struct request * next; 33 | }; 34 | 35 | /* 36 | * This is used in the elevator algorithm: Note that 37 | * reads always go before writes. This is natural: reads 38 | * are much more time-critical than writes. 39 | */ 40 | #define IN_ORDER(s1,s2) \ 41 | ((s1)->cmd<(s2)->cmd || ((s1)->cmd==(s2)->cmd && \ 42 | ((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \ 43 | (s1)->sector < (s2)->sector)))) 44 | 45 | struct blk_dev_struct { 46 | void (*request_fn)(void); 47 | struct request * current_request; 48 | }; 49 | 50 | extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; 51 | extern struct request request[NR_REQUEST]; 52 | extern struct task_struct * wait_for_request; 53 | 54 | #ifdef MAJOR_NR 55 | 56 | /* 57 | * Add entries as needed. Currently the only block devices 58 | * supported are hard-disks and floppies. 59 | */ 60 | 61 | #if (MAJOR_NR == 1) 62 | /* ram disk */ 63 | #define DEVICE_NAME "ramdisk" 64 | #define DEVICE_REQUEST do_rd_request 65 | #define DEVICE_NR(device) ((device) & 7) 66 | #define DEVICE_ON(device) 67 | #define DEVICE_OFF(device) 68 | 69 | #elif (MAJOR_NR == 2) 70 | /* floppy */ 71 | #define DEVICE_NAME "floppy" 72 | #define DEVICE_INTR do_floppy 73 | #define DEVICE_REQUEST do_fd_request 74 | #define DEVICE_NR(device) ((device) & 3) 75 | #define DEVICE_ON(device) floppy_on(DEVICE_NR(device)) 76 | #define DEVICE_OFF(device) floppy_off(DEVICE_NR(device)) 77 | 78 | #elif (MAJOR_NR == 3) 79 | /* harddisk */ 80 | #define DEVICE_NAME "harddisk" 81 | #define DEVICE_INTR do_hd 82 | #define DEVICE_REQUEST do_hd_request 83 | #define DEVICE_NR(device) (MINOR(device)/5) 84 | #define DEVICE_ON(device) 85 | #define DEVICE_OFF(device) 86 | 87 | #elif 88 | /* unknown blk device */ 89 | #error "unknown blk device" 90 | 91 | #endif 92 | 93 | #define CURRENT (blk_dev[MAJOR_NR].current_request) 94 | #define CURRENT_DEV DEVICE_NR(CURRENT->dev) 95 | 96 | #ifdef DEVICE_INTR 97 | void (*DEVICE_INTR)(void) = NULL; 98 | #endif 99 | static void (DEVICE_REQUEST)(void); 100 | 101 | static inline void unlock_buffer(struct buffer_head * bh) 102 | { 103 | if (!bh->b_lock) 104 | printk(DEVICE_NAME ": free buffer being unlocked\n"); 105 | bh->b_lock=0; 106 | wake_up(&bh->b_wait); 107 | } 108 | 109 | static inline void end_request(int uptodate) 110 | { 111 | DEVICE_OFF(CURRENT->dev); 112 | if (CURRENT->bh) { 113 | CURRENT->bh->b_uptodate = uptodate; 114 | unlock_buffer(CURRENT->bh); 115 | } 116 | if (!uptodate) { 117 | printk(DEVICE_NAME " I/O error\n\r"); 118 | printk("dev %04x, block %d\n\r",CURRENT->dev, 119 | CURRENT->bh->b_blocknr); 120 | } 121 | wake_up(&CURRENT->waiting); 122 | wake_up(&wait_for_request); 123 | CURRENT->dev = -1; 124 | CURRENT = CURRENT->next; 125 | } 126 | 127 | #define INIT_REQUEST \ 128 | repeat: \ 129 | if (!CURRENT) \ 130 | return; \ 131 | if (MAJOR(CURRENT->dev) != MAJOR_NR) \ 132 | panic(DEVICE_NAME ": request list destroyed"); \ 133 | if (CURRENT->bh) { \ 134 | if (!CURRENT->bh->b_lock) \ 135 | panic(DEVICE_NAME ": block not locked"); \ 136 | } 137 | 138 | #endif 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /lab8/kernel/blk_drv/blk_drv.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/blk_drv/blk_drv.a -------------------------------------------------------------------------------- /lab8/kernel/blk_drv/floppy.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/blk_drv/floppy.o -------------------------------------------------------------------------------- /lab8/kernel/blk_drv/hd.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/blk_drv/hd.o -------------------------------------------------------------------------------- /lab8/kernel/blk_drv/ll_rw_blk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/blk_dev/ll_rw.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * This handles all read/write requests to block devices 9 | */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "blk.h" 16 | 17 | /* 18 | * The request-struct contains all necessary data 19 | * to load a nr of sectors into memory 20 | */ 21 | struct request request[NR_REQUEST]; 22 | 23 | /* 24 | * used to wait on when there are no free requests 25 | */ 26 | struct task_struct * wait_for_request = NULL; 27 | 28 | /* blk_dev_struct is: 29 | * do_request-address 30 | * next-request 31 | */ 32 | struct blk_dev_struct blk_dev[NR_BLK_DEV] = { 33 | { NULL, NULL }, /* no_dev */ 34 | { NULL, NULL }, /* dev mem */ 35 | { NULL, NULL }, /* dev fd */ 36 | { NULL, NULL }, /* dev hd */ 37 | { NULL, NULL }, /* dev ttyx */ 38 | { NULL, NULL }, /* dev tty */ 39 | { NULL, NULL } /* dev lp */ 40 | }; 41 | 42 | static inline void lock_buffer(struct buffer_head * bh) 43 | { 44 | cli(); 45 | while (bh->b_lock) 46 | sleep_on(&bh->b_wait); 47 | bh->b_lock=1; 48 | sti(); 49 | } 50 | 51 | static inline void unlock_buffer(struct buffer_head * bh) 52 | { 53 | if (!bh->b_lock) 54 | printk("ll_rw_block.c: buffer not locked\n\r"); 55 | bh->b_lock = 0; 56 | wake_up(&bh->b_wait); 57 | } 58 | 59 | /* 60 | * add-request adds a request to the linked list. 61 | * It disables interrupts so that it can muck with the 62 | * request-lists in peace. 63 | */ 64 | static void add_request(struct blk_dev_struct * dev, struct request * req) 65 | { 66 | struct request * tmp; 67 | 68 | req->next = NULL; 69 | cli(); 70 | if (req->bh) 71 | req->bh->b_dirt = 0; 72 | if (!(tmp = dev->current_request)) { 73 | dev->current_request = req; 74 | sti(); 75 | (dev->request_fn)(); 76 | return; 77 | } 78 | for ( ; tmp->next ; tmp=tmp->next) 79 | if ((IN_ORDER(tmp,req) || 80 | !IN_ORDER(tmp,tmp->next)) && 81 | IN_ORDER(req,tmp->next)) 82 | break; 83 | req->next=tmp->next; 84 | tmp->next=req; 85 | sti(); 86 | } 87 | 88 | static void make_request(int major,int rw, struct buffer_head * bh) 89 | { 90 | struct request * req; 91 | int rw_ahead; 92 | 93 | /* WRITEA/READA is special case - it is not really needed, so if the */ 94 | /* buffer is locked, we just forget about it, else it's a normal read */ 95 | if ((rw_ahead = (rw == READA || rw == WRITEA))) { 96 | if (bh->b_lock) 97 | return; 98 | if (rw == READA) 99 | rw = READ; 100 | else 101 | rw = WRITE; 102 | } 103 | if (rw!=READ && rw!=WRITE) 104 | panic("Bad block dev command, must be R/W/RA/WA"); 105 | lock_buffer(bh); 106 | if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) { 107 | unlock_buffer(bh); 108 | return; 109 | } 110 | repeat: 111 | /* we don't allow the write-requests to fill up the queue completely: 112 | * we want some room for reads: they take precedence. The last third 113 | * of the requests are only for reads. 114 | */ 115 | if (rw == READ) 116 | req = request+NR_REQUEST; 117 | else 118 | req = request+((NR_REQUEST*2)/3); 119 | /* find an empty request */ 120 | while (--req >= request) 121 | if (req->dev<0) 122 | break; 123 | /* if none found, sleep on new requests: check for rw_ahead */ 124 | if (req < request) { 125 | if (rw_ahead) { 126 | unlock_buffer(bh); 127 | return; 128 | } 129 | sleep_on(&wait_for_request); 130 | goto repeat; 131 | } 132 | /* fill up the request-info, and add it to the queue */ 133 | req->dev = bh->b_dev; 134 | req->cmd = rw; 135 | req->errors=0; 136 | req->sector = bh->b_blocknr<<1; 137 | req->nr_sectors = 2; 138 | req->buffer = bh->b_data; 139 | req->waiting = NULL; 140 | req->bh = bh; 141 | req->next = NULL; 142 | add_request(major+blk_dev,req); 143 | } 144 | 145 | void ll_rw_block(int rw, struct buffer_head * bh) 146 | { 147 | unsigned int major; 148 | 149 | if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV || 150 | !(blk_dev[major].request_fn)) { 151 | printk("Trying to read nonexistent block-device\n\r"); 152 | return; 153 | } 154 | make_request(major,rw,bh); 155 | } 156 | 157 | void blk_dev_init(void) 158 | { 159 | int i; 160 | 161 | for (i=0 ; i 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define MAJOR_NR 1 18 | #include "blk.h" 19 | 20 | char *rd_start; 21 | int rd_length = 0; 22 | 23 | void do_rd_request(void) 24 | { 25 | int len; 26 | char *addr; 27 | 28 | INIT_REQUEST; 29 | addr = rd_start + (CURRENT->sector << 9); 30 | len = CURRENT->nr_sectors << 9; 31 | if ((MINOR(CURRENT->dev) != 1) || (addr+len > rd_start+rd_length)) { 32 | end_request(0); 33 | goto repeat; 34 | } 35 | if (CURRENT-> cmd == WRITE) { 36 | (void ) memcpy(addr, 37 | CURRENT->buffer, 38 | len); 39 | } else if (CURRENT->cmd == READ) { 40 | (void) memcpy(CURRENT->buffer, 41 | addr, 42 | len); 43 | } else 44 | panic("unknown ramdisk-command"); 45 | end_request(1); 46 | goto repeat; 47 | } 48 | 49 | /* 50 | * Returns amount of memory which needs to be reserved. 51 | */ 52 | long rd_init(long mem_start, int length) 53 | { 54 | int i; 55 | char *cp; 56 | 57 | blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; 58 | rd_start = (char *) mem_start; 59 | rd_length = length; 60 | cp = rd_start; 61 | for (i=0; i < length; i++) 62 | *cp++ = '\0'; 63 | return(length); 64 | } 65 | 66 | /* 67 | * If the root device is the ram disk, try to load it. 68 | * In order to do this, the root device is originally set to the 69 | * floppy, and we later change it to be ram disk. 70 | */ 71 | void rd_load(void) 72 | { 73 | struct buffer_head *bh; 74 | struct super_block s; 75 | int block = 256; /* Start at block 256 */ 76 | int i = 1; 77 | int nblocks; 78 | char *cp; /* Move pointer */ 79 | 80 | if (!rd_length) 81 | return; 82 | printk("Ram disk: %d bytes, starting at 0x%x\n", rd_length, 83 | (int) rd_start); 84 | if (MAJOR(ROOT_DEV) != 2) 85 | return; 86 | bh = breada(ROOT_DEV,block+1,block,block+2,-1); 87 | if (!bh) { 88 | printk("Disk error while looking for ramdisk!\n"); 89 | return; 90 | } 91 | *((struct d_super_block *) &s) = *((struct d_super_block *) bh->b_data); 92 | brelse(bh); 93 | if (s.s_magic != SUPER_MAGIC) 94 | /* No ram disk image present, assume normal floppy boot */ 95 | return; 96 | nblocks = s.s_nzones << s.s_log_zone_size; 97 | if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) { 98 | printk("Ram disk image too big! (%d blocks, %d avail)\n", 99 | nblocks, rd_length >> BLOCK_SIZE_BITS); 100 | return; 101 | } 102 | printk("Loading %d bytes into ram disk... 0000k", 103 | nblocks << BLOCK_SIZE_BITS); 104 | cp = rd_start; 105 | while (nblocks) { 106 | if (nblocks > 2) 107 | bh = breada(ROOT_DEV, block, block+1, block+2, -1); 108 | else 109 | bh = bread(ROOT_DEV, block); 110 | if (!bh) { 111 | printk("I/O error on block %d, aborting load\n", 112 | block); 113 | return; 114 | } 115 | (void) memcpy(cp, bh->b_data, BLOCK_SIZE); 116 | brelse(bh); 117 | printk("\010\010\010\010\010%4dk",i); 118 | cp += BLOCK_SIZE; 119 | block++; 120 | nblocks--; 121 | i++; 122 | } 123 | printk("\010\010\010\010\010done \n"); 124 | ROOT_DEV=0x0101; 125 | } 126 | -------------------------------------------------------------------------------- /lab8/kernel/blk_drv/ramdisk.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/blk_drv/ramdisk.o -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for the FREAX-kernel character device drivers. 3 | # 4 | # Note! Dependencies are done automagically by 'make dep', which also 5 | # removes any old dependencies. DON'T put your own dependencies here 6 | # unless it's something special (ie not a .c file). 7 | # 8 | 9 | AR =ar 10 | AS =as --32 11 | LD =ld 12 | LDFLAGS =-m elf_i386 -x 13 | CC =gcc-3.4 -march=i386 14 | CFLAGS =-m32 -g -Wall -O -fstrength-reduce -fomit-frame-pointer \ 15 | -finline-functions -nostdinc -I../../include 16 | CPP =gcc-3.4 -m32 -g -E -nostdinc -I../../include 17 | 18 | .c.s: 19 | $(CC) $(CFLAGS) \ 20 | -S -o $*.s $< 21 | .s.o: 22 | $(AS) -o $*.o $< 23 | .c.o: 24 | $(CC) $(CFLAGS) \ 25 | -c -o $*.o $< 26 | 27 | OBJS = tty_io.o console.o keyboard.o serial.o rs_io.o \ 28 | tty_ioctl.o 29 | 30 | chr_drv.a: $(OBJS) 31 | $(AR) rcs chr_drv.a $(OBJS) 32 | sync 33 | 34 | keyboard.s: keyboard.S ../../include/linux/config.h 35 | $(CPP) -traditional keyboard.S -o keyboard.s 36 | 37 | clean: 38 | rm -f core *.o *.a tmp_make keyboard.s 39 | for i in *.c;do rm -f `basename $$i .c`.s;done 40 | 41 | dep: 42 | sed '/\#\#\# Dependencies/q' < Makefile > tmp_make 43 | (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ 44 | $(CPP) -M $$i;done) >> tmp_make 45 | cp tmp_make Makefile 46 | 47 | ### Dependencies: 48 | console.s console.o: console.c ../../include/linux/sched.h \ 49 | ../../include/linux/head.h ../../include/linux/fs.h \ 50 | ../../include/sys/types.h ../../include/linux/mm.h \ 51 | ../../include/signal.h ../../include/linux/tty.h \ 52 | ../../include/termios.h ../../include/asm/io.h \ 53 | ../../include/asm/system.h 54 | serial.s serial.o: serial.c ../../include/linux/tty.h ../../include/termios.h \ 55 | ../../include/linux/sched.h ../../include/linux/head.h \ 56 | ../../include/linux/fs.h ../../include/sys/types.h \ 57 | ../../include/linux/mm.h ../../include/signal.h \ 58 | ../../include/asm/system.h ../../include/asm/io.h 59 | tty_io.s tty_io.o: tty_io.c ../../include/ctype.h ../../include/errno.h \ 60 | ../../include/signal.h ../../include/sys/types.h \ 61 | ../../include/linux/sched.h ../../include/linux/head.h \ 62 | ../../include/linux/fs.h ../../include/linux/mm.h \ 63 | ../../include/linux/tty.h ../../include/termios.h \ 64 | ../../include/asm/segment.h ../../include/asm/system.h 65 | tty_ioctl.s tty_ioctl.o: tty_ioctl.c ../../include/errno.h ../../include/termios.h \ 66 | ../../include/linux/sched.h ../../include/linux/head.h \ 67 | ../../include/linux/fs.h ../../include/sys/types.h \ 68 | ../../include/linux/mm.h ../../include/signal.h \ 69 | ../../include/linux/kernel.h ../../include/linux/tty.h \ 70 | ../../include/asm/io.h ../../include/asm/segment.h \ 71 | ../../include/asm/system.h 72 | -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/chr_drv.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/chr_drv/chr_drv.a -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/console.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/chr_drv/console.o -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/keyboard.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/chr_drv/keyboard.o -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/rs_io.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/chr_drv/rs_io.o -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/rs_io.s: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/rs_io.s 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * rs_io.s 9 | * 10 | * This module implements the rs232 io interrupts. 11 | */ 12 | 13 | .text 14 | .globl rs1_interrupt,rs2_interrupt 15 | 16 | size = 1024 /* must be power of two ! 17 | and must match the value 18 | in tty_io.c!!! */ 19 | 20 | /* these are the offsets into the read/write buffer structures */ 21 | rs_addr = 0 22 | head = 4 23 | tail = 8 24 | proc_list = 12 25 | buf = 16 26 | 27 | startup = 256 /* chars left in write queue when we restart it */ 28 | 29 | /* 30 | * These are the actual interrupt routines. They look where 31 | * the interrupt is coming from, and take appropriate action. 32 | */ 33 | .align 2 34 | rs1_interrupt: 35 | pushl $table_list+8 36 | jmp rs_int 37 | .align 2 38 | rs2_interrupt: 39 | pushl $table_list+16 40 | rs_int: 41 | pushl %edx 42 | pushl %ecx 43 | pushl %ebx 44 | pushl %eax 45 | push %es 46 | push %ds /* as this is an interrupt, we cannot */ 47 | pushl $0x10 /* know that bs is ok. Load it */ 48 | pop %ds 49 | pushl $0x10 50 | pop %es 51 | movl 24(%esp),%edx 52 | movl (%edx),%edx 53 | movl rs_addr(%edx),%edx 54 | addl $2,%edx /* interrupt ident. reg */ 55 | rep_int: 56 | xorl %eax,%eax 57 | inb %dx,%al 58 | testb $1,%al 59 | jne end 60 | cmpb $6,%al /* this shouldn't happen, but ... */ 61 | ja end 62 | movl 24(%esp),%ecx 63 | pushl %edx 64 | subl $2,%edx 65 | call jmp_table(,%eax,2) /* NOTE! not *4, bit0 is 0 already */ 66 | popl %edx 67 | jmp rep_int 68 | end: movb $0x20,%al 69 | outb %al,$0x20 /* EOI */ 70 | pop %ds 71 | pop %es 72 | popl %eax 73 | popl %ebx 74 | popl %ecx 75 | popl %edx 76 | addl $4,%esp # jump over _table_list entry 77 | iret 78 | 79 | jmp_table: 80 | .long modem_status,write_char,read_char,line_status 81 | 82 | .align 2 83 | modem_status: 84 | addl $6,%edx /* clear intr by reading modem status reg */ 85 | inb %dx,%al 86 | ret 87 | 88 | .align 2 89 | line_status: 90 | addl $5,%edx /* clear intr by reading line status reg. */ 91 | inb %dx,%al 92 | ret 93 | 94 | .align 2 95 | read_char: 96 | inb %dx,%al 97 | movl %ecx,%edx 98 | subl $table_list,%edx 99 | shrl $3,%edx 100 | movl (%ecx),%ecx # read-queue 101 | movl head(%ecx),%ebx 102 | movb %al,buf(%ecx,%ebx) 103 | incl %ebx 104 | andl $size-1,%ebx 105 | cmpl tail(%ecx),%ebx 106 | je 1f 107 | movl %ebx,head(%ecx) 108 | 1: pushl %edx 109 | call do_tty_interrupt 110 | addl $4,%esp 111 | ret 112 | 113 | .align 2 114 | write_char: 115 | movl 4(%ecx),%ecx # write-queue 116 | movl head(%ecx),%ebx 117 | subl tail(%ecx),%ebx 118 | andl $size-1,%ebx # nr chars in queue 119 | je write_buffer_empty 120 | cmpl $startup,%ebx 121 | ja 1f 122 | movl proc_list(%ecx),%ebx # wake up sleeping process 123 | testl %ebx,%ebx # is there any? 124 | je 1f 125 | movl $0,(%ebx) 126 | 1: movl tail(%ecx),%ebx 127 | movb buf(%ecx,%ebx),%al 128 | outb %al,%dx 129 | incl %ebx 130 | andl $size-1,%ebx 131 | movl %ebx,tail(%ecx) 132 | cmpl head(%ecx),%ebx 133 | je write_buffer_empty 134 | ret 135 | .align 2 136 | write_buffer_empty: 137 | movl proc_list(%ecx),%ebx # wake up sleeping process 138 | testl %ebx,%ebx # is there any? 139 | je 1f 140 | movl $0,(%ebx) 141 | 1: incl %edx 142 | inb %dx,%al 143 | jmp 1f 144 | 1: jmp 1f 145 | 1: andb $0xd,%al /* disable transmit interrupt */ 146 | outb %al,%dx 147 | ret 148 | -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/serial.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/serial.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * serial.c 9 | * 10 | * This module implements the rs232 io functions 11 | * void rs_write(struct tty_struct * queue); 12 | * void rs_init(void); 13 | * and all interrupts pertaining to serial IO. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #define WAKEUP_CHARS (TTY_BUF_SIZE/4) 22 | 23 | extern void rs1_interrupt(void); 24 | extern void rs2_interrupt(void); 25 | 26 | static void init(int port) 27 | { 28 | outb_p(0x80,port+3); /* set DLAB of line control reg */ 29 | outb_p(0x30,port); /* LS of divisor (48 -> 2400 bps */ 30 | outb_p(0x00,port+1); /* MS of divisor */ 31 | outb_p(0x03,port+3); /* reset DLAB */ 32 | outb_p(0x0b,port+4); /* set DTR,RTS, OUT_2 */ 33 | outb_p(0x0d,port+1); /* enable all intrs but writes */ 34 | (void)inb(port); /* read data port to reset things (?) */ 35 | } 36 | 37 | void rs_init(void) 38 | { 39 | set_intr_gate(0x24,rs1_interrupt); 40 | set_intr_gate(0x23,rs2_interrupt); 41 | init(tty_table[1].read_q.data); 42 | init(tty_table[2].read_q.data); 43 | outb(inb_p(0x21)&0xE7,0x21); 44 | } 45 | 46 | /* 47 | * This routine gets called when tty_write has put something into 48 | * the write_queue. It must check wheter the queue is empty, and 49 | * set the interrupt register accordingly 50 | * 51 | * void _rs_write(struct tty_struct * tty); 52 | */ 53 | void rs_write(struct tty_struct * tty) 54 | { 55 | cli(); 56 | if (!EMPTY(tty->write_q)) 57 | outb(inb_p(tty->write_q.data+1)|0x02,tty->write_q.data+1); 58 | sti(); 59 | } 60 | -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/serial.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/chr_drv/serial.o -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/tty_io.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/chr_drv/tty_io.o -------------------------------------------------------------------------------- /lab8/kernel/chr_drv/tty_ioctl.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/chr_drv/tty_ioctl.o -------------------------------------------------------------------------------- /lab8/kernel/exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/exit.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int sys_pause(void); 17 | int sys_close(int fd); 18 | 19 | void release(struct task_struct * p) 20 | { 21 | int i; 22 | 23 | if (!p) 24 | return; 25 | for (i=1 ; i32) 38 | return -EINVAL; 39 | if (priv || (current->euid==p->euid) || suser()) 40 | p->signal |= (1<<(sig-1)); 41 | else 42 | return -EPERM; 43 | return 0; 44 | } 45 | 46 | static void kill_session(void) 47 | { 48 | struct task_struct **p = NR_TASKS + task; 49 | 50 | while (--p > &FIRST_TASK) { 51 | if (*p && (*p)->session == current->session) 52 | (*p)->signal |= 1<<(SIGHUP-1); 53 | } 54 | } 55 | 56 | /* 57 | * XXX need to check permissions needed to send signals to process 58 | * groups, etc. etc. kill() permissions semantics are tricky! 59 | */ 60 | int sys_kill(int pid,int sig) 61 | { 62 | struct task_struct **p = NR_TASKS + task; 63 | int err, retval = 0; 64 | 65 | if (!pid) while (--p > &FIRST_TASK) { 66 | if (*p && (*p)->pgrp == current->pid) 67 | if ((err=send_sig(sig,*p,1))) 68 | retval = err; 69 | } else if (pid>0) while (--p > &FIRST_TASK) { 70 | if (*p && (*p)->pid == pid) 71 | if ((err=send_sig(sig,*p,0))) 72 | retval = err; 73 | } else if (pid == -1) while (--p > &FIRST_TASK) { 74 | if ((err = send_sig(sig,*p,0))) 75 | retval = err; 76 | } else while (--p > &FIRST_TASK) 77 | if (*p && (*p)->pgrp == -pid) 78 | if ((err = send_sig(sig,*p,0))) 79 | retval = err; 80 | return retval; 81 | } 82 | 83 | static void tell_father(int pid) 84 | { 85 | int i; 86 | 87 | if (pid) 88 | for (i=0;ipid != pid) 92 | continue; 93 | task[i]->signal |= (1<<(SIGCHLD-1)); 94 | return; 95 | } 96 | /* if we don't find any fathers, we just release ourselves */ 97 | /* This is not really OK. Must change it to make father 1 */ 98 | printk("BAD BAD - no father found\n\r"); 99 | release(current); 100 | } 101 | 102 | int do_exit(long code) 103 | { 104 | int i; 105 | free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); 106 | free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); 107 | for (i=0 ; ifather == current->pid) { 109 | task[i]->father = 1; 110 | if (task[i]->state == TASK_ZOMBIE) 111 | /* assumption task[1] is always init */ 112 | (void) send_sig(SIGCHLD, task[1], 1); 113 | } 114 | for (i=0 ; ifilp[i]) 116 | sys_close(i); 117 | iput(current->pwd); 118 | current->pwd=NULL; 119 | iput(current->root); 120 | current->root=NULL; 121 | iput(current->executable); 122 | current->executable=NULL; 123 | if (current->leader && current->tty >= 0) 124 | tty_table[current->tty].pgrp = 0; 125 | if (last_task_used_math == current) 126 | last_task_used_math = NULL; 127 | if (current->leader) 128 | kill_session(); 129 | current->state = TASK_ZOMBIE; 130 | current->exit_code = code; 131 | tell_father(current->father); 132 | schedule(); 133 | return (-1); /* just to suppress warnings */ 134 | } 135 | 136 | int sys_exit(int error_code) 137 | { 138 | return do_exit((error_code&0xff)<<8); 139 | } 140 | 141 | int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options) 142 | { 143 | int flag, code; 144 | struct task_struct ** p; 145 | 146 | verify_area(stat_addr,4); 147 | repeat: 148 | flag=0; 149 | for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) { 150 | if (!*p || *p == current) 151 | continue; 152 | if ((*p)->father != current->pid) 153 | continue; 154 | if (pid>0) { 155 | if ((*p)->pid != pid) 156 | continue; 157 | } else if (!pid) { 158 | if ((*p)->pgrp != current->pgrp) 159 | continue; 160 | } else if (pid != -1) { 161 | if ((*p)->pgrp != -pid) 162 | continue; 163 | } 164 | switch ((*p)->state) { 165 | case TASK_STOPPED: 166 | if (!(options & WUNTRACED)) 167 | continue; 168 | put_fs_long(0x7f,stat_addr); 169 | return (*p)->pid; 170 | case TASK_ZOMBIE: 171 | current->cutime += (*p)->utime; 172 | current->cstime += (*p)->stime; 173 | flag = (*p)->pid; 174 | code = (*p)->exit_code; 175 | release(*p); 176 | put_fs_long(code,stat_addr); 177 | return flag; 178 | default: 179 | flag=1; 180 | continue; 181 | } 182 | } 183 | if (flag) { 184 | if (options & WNOHANG) 185 | return 0; 186 | current->state=TASK_INTERRUPTIBLE; 187 | schedule(); 188 | if (!(current->signal &= ~(1<<(SIGCHLD-1)))) 189 | goto repeat; 190 | else 191 | return -EINTR; 192 | } 193 | return -ECHILD; 194 | } 195 | 196 | 197 | -------------------------------------------------------------------------------- /lab8/kernel/exit.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/exit.o -------------------------------------------------------------------------------- /lab8/kernel/fork.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/fork.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * 'fork.c' contains the help-routines for the 'fork' system call 9 | * (see also system_call.s), and some misc functions ('verify_area'). 10 | * Fork is rather simple, once you get the hang of it, but the memory 11 | * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()' 12 | */ 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | extern void write_verify(unsigned long address); 21 | 22 | long last_pid=0; 23 | 24 | void verify_area(void * addr,int size) 25 | { 26 | unsigned long start; 27 | 28 | start = (unsigned long) addr; 29 | size += start & 0xfff; 30 | start &= 0xfffff000; 31 | start += get_base(current->ldt[2]); 32 | while (size>0) { 33 | size -= 4096; 34 | write_verify(start); 35 | start += 4096; 36 | } 37 | } 38 | 39 | int copy_mem(int nr,struct task_struct * p) 40 | { 41 | unsigned long old_data_base,new_data_base,data_limit; 42 | unsigned long old_code_base,new_code_base,code_limit; 43 | 44 | code_limit=get_limit(0x0f); 45 | data_limit=get_limit(0x17); 46 | old_code_base = get_base(current->ldt[1]); 47 | old_data_base = get_base(current->ldt[2]); 48 | if (old_data_base != old_code_base) 49 | panic("We don't support separate I&D"); 50 | if (data_limit < code_limit) 51 | panic("Bad data_limit"); 52 | new_data_base = new_code_base = nr * 0x4000000; 53 | p->start_code = new_code_base; 54 | set_base(p->ldt[1],new_code_base); 55 | set_base(p->ldt[2],new_data_base); 56 | if (copy_page_tables(old_data_base,new_data_base,data_limit)) { 57 | printk("free_page_tables: from copy_mem\n"); 58 | free_page_tables(new_data_base,data_limit); 59 | return -ENOMEM; 60 | } 61 | return 0; 62 | } 63 | 64 | /* 65 | * Ok, this is the main fork-routine. It copies the system process 66 | * information (task[nr]) and sets up the necessary registers. It 67 | * also copies the data segment in it's entirety. 68 | */ 69 | int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, 70 | long ebx,long ecx,long edx, 71 | long fs,long es,long ds, 72 | long eip,long cs,long eflags,long esp,long ss) 73 | { 74 | struct task_struct *p; 75 | int i; 76 | struct file *f; 77 | 78 | p = (struct task_struct *) get_free_page(); 79 | if (!p) 80 | return -EAGAIN; 81 | task[nr] = p; 82 | *p = *current; /* NOTE! this doesn't copy the supervisor stack */ 83 | p->state = TASK_UNINTERRUPTIBLE; 84 | p->pid = last_pid; 85 | /* 线程初始化 */ 86 | p->tid = 0; 87 | p->tid_num = 1; 88 | /* ******* */ 89 | p->father = current->pid; 90 | p->counter = p->priority; 91 | p->signal = 0; 92 | p->alarm = 0; 93 | p->leader = 0; /* process leadership doesn't inherit */ 94 | p->utime = p->stime = 0; 95 | p->cutime = p->cstime = 0; 96 | p->start_time = jiffies; 97 | p->tss.back_link = 0; 98 | p->tss.esp0 = PAGE_SIZE + (long) p; 99 | p->tss.ss0 = 0x10; 100 | p->tss.eip = eip; 101 | p->tss.eflags = eflags; 102 | p->tss.eax = 0; 103 | p->tss.ecx = ecx; 104 | p->tss.edx = edx; 105 | p->tss.ebx = ebx; 106 | p->tss.esp = esp; 107 | p->tss.ebp = ebp; 108 | p->tss.esi = esi; 109 | p->tss.edi = edi; 110 | p->tss.es = es & 0xffff; 111 | p->tss.cs = cs & 0xffff; 112 | p->tss.ss = ss & 0xffff; 113 | p->tss.ds = ds & 0xffff; 114 | p->tss.fs = fs & 0xffff; 115 | p->tss.gs = gs & 0xffff; 116 | p->tss.ldt = _LDT(nr); 117 | p->tss.trace_bitmap = 0x80000000; 118 | if (last_task_used_math == current) 119 | __asm__("clts ; fnsave %0"::"m" (p->tss.i387)); 120 | if (copy_mem(nr,p)) { 121 | task[nr] = NULL; 122 | free_page((long) p); 123 | return -EAGAIN; 124 | } 125 | for (i=0; ifilp[i])) 127 | f->f_count++; 128 | if (current->pwd) 129 | current->pwd->i_count++; 130 | if (current->root) 131 | current->root->i_count++; 132 | if (current->executable) 133 | current->executable->i_count++; 134 | set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss)); 135 | set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt)); 136 | p->state = TASK_RUNNING; /* do this last, just in case */ 137 | return last_pid; 138 | } 139 | 140 | int find_empty_process(void) 141 | { 142 | int i; 143 | 144 | repeat: 145 | if ((++last_pid)<0) last_pid=1; 146 | for(i=0 ; ipid == last_pid) goto repeat; 148 | for(i=1 ; i tmp_make 39 | (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ 40 | $(CPP) -M $$i;done) >> tmp_make 41 | cp tmp_make Makefile 42 | 43 | ### Dependencies: 44 | -------------------------------------------------------------------------------- /lab8/kernel/math/math.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/math/math.a -------------------------------------------------------------------------------- /lab8/kernel/math/math_emulate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/math/math_emulate.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * This directory should contain the math-emulation code. 9 | * Currently only results in a signal. 10 | */ 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | void math_emulate(long edi, long esi, long ebp, long sys_call_ret, 19 | long eax,long ebx,long ecx,long edx, 20 | unsigned short fs,unsigned short es,unsigned short ds, 21 | unsigned long eip,unsigned short cs,unsigned long eflags, 22 | unsigned short ss, unsigned long esp) 23 | { 24 | unsigned char first, second; 25 | 26 | /* 0x0007 means user code space */ 27 | if (cs != 0x000F) { 28 | printk("math_emulate: %04x:%08x\n\r",cs,eip); 29 | panic("Math emulation needed in kernel"); 30 | } 31 | first = get_fs_byte((char *)((*&eip)++)); 32 | second = get_fs_byte((char *)((*&eip)++)); 33 | printk("%04x:%08x %02x %02x\n\r",cs,eip-2,first,second); 34 | current->signal |= 1<<(SIGFPE-1); 35 | } 36 | 37 | void math_error(void) 38 | { 39 | __asm__("fnclex"); 40 | if (last_task_used_math) 41 | last_task_used_math->signal |= 1<<(SIGFPE-1); 42 | } 43 | -------------------------------------------------------------------------------- /lab8/kernel/math/math_emulate.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/math/math_emulate.o -------------------------------------------------------------------------------- /lab8/kernel/mktime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/mktime.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * This isn't the library routine, it is only used in the kernel. 11 | * as such, we don't care about years<1970 etc, but assume everything 12 | * is ok. Similarly, TZ etc is happily ignored. We just do everything 13 | * as easily as possible. Let's find something public for the library 14 | * routines (although I think minix times is public). 15 | */ 16 | /* 17 | * PS. I hate whoever though up the year 1970 - couldn't they have gotten 18 | * a leap-year instead? I also hate Gregorius, pope or no. I'm grumpy. 19 | */ 20 | #define MINUTE 60 21 | #define HOUR (60*MINUTE) 22 | #define DAY (24*HOUR) 23 | #define YEAR (365*DAY) 24 | 25 | /* interestingly, we assume leap-years */ 26 | static int month[12] = { 27 | 0, 28 | DAY*(31), 29 | DAY*(31+29), 30 | DAY*(31+29+31), 31 | DAY*(31+29+31+30), 32 | DAY*(31+29+31+30+31), 33 | DAY*(31+29+31+30+31+30), 34 | DAY*(31+29+31+30+31+30+31), 35 | DAY*(31+29+31+30+31+30+31+31), 36 | DAY*(31+29+31+30+31+30+31+31+30), 37 | DAY*(31+29+31+30+31+30+31+31+30+31), 38 | DAY*(31+29+31+30+31+30+31+31+30+31+30) 39 | }; 40 | 41 | long kernel_mktime(struct tm * tm) 42 | { 43 | long res; 44 | int year; 45 | 46 | year = tm->tm_year - 70; 47 | /* magic offsets (y+1) needed to get leapyears right.*/ 48 | res = YEAR*year + DAY*((year+1)/4); 49 | res += month[tm->tm_mon]; 50 | /* and (y+2) here. If it wasn't a leap-year, we have to adjust */ 51 | if (tm->tm_mon>1 && ((year+2)%4)) 52 | res -= DAY; 53 | res += DAY*(tm->tm_mday-1); 54 | res += HOUR*tm->tm_hour; 55 | res += MINUTE*tm->tm_min; 56 | res += tm->tm_sec; 57 | return res; 58 | } 59 | -------------------------------------------------------------------------------- /lab8/kernel/mktime.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/mktime.o -------------------------------------------------------------------------------- /lab8/kernel/panic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/panic.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * This function is used through-out the kernel (includeinh mm and fs) 9 | * to indicate a major problem. 10 | */ 11 | #define PANIC 12 | 13 | #include 14 | #include 15 | 16 | void sys_sync(void); /* it's really int */ 17 | 18 | volatile void panic(const char * s) 19 | { 20 | printk("Kernel panic: %s\n\r",s); 21 | if (current == task[0]) 22 | printk("In swapper task - not syncing\n\r"); 23 | else 24 | sys_sync(); 25 | for(;;); 26 | } 27 | -------------------------------------------------------------------------------- /lab8/kernel/panic.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/panic.o -------------------------------------------------------------------------------- /lab8/kernel/printk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/printk.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * When in kernel-mode, we cannot use printf, as fs is liable to 9 | * point to 'interesting' things. Make a printf with fs-saving, and 10 | * all is well. 11 | */ 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | static char buf[1024]; 18 | 19 | extern int vsprintf(char * buf, const char * fmt, va_list args); 20 | 21 | int printk(const char *fmt, ...) 22 | { 23 | va_list args; 24 | int i; 25 | 26 | va_start(args, fmt); 27 | i=vsprintf(buf,fmt,args); 28 | va_end(args); 29 | __asm__("push %%fs\n\t" 30 | "push %%ds\n\t" 31 | "pop %%fs\n\t" 32 | "pushl %0\n\t" 33 | "pushl $buf\n\t" 34 | "pushl $0\n\t" 35 | "call tty_write\n\t" 36 | "addl $8,%%esp\n\t" 37 | "popl %0\n\t" 38 | "pop %%fs" 39 | ::"r" (i):"ax","cx","dx"); 40 | return i; 41 | } 42 | -------------------------------------------------------------------------------- /lab8/kernel/printk.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/printk.o -------------------------------------------------------------------------------- /lab8/kernel/sched.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/sched.o -------------------------------------------------------------------------------- /lab8/kernel/signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/signal.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | volatile void do_exit(int error_code); 14 | 15 | int sys_sgetmask() 16 | { 17 | return current->blocked; 18 | } 19 | 20 | int sys_ssetmask(int newmask) 21 | { 22 | int old=current->blocked; 23 | 24 | current->blocked = newmask & ~(1<<(SIGKILL-1)); 25 | return old; 26 | } 27 | 28 | static inline void save_old(char * from,char * to) 29 | { 30 | int i; 31 | 32 | verify_area(to, sizeof(struct sigaction)); 33 | for (i=0 ; i< sizeof(struct sigaction) ; i++) { 34 | put_fs_byte(*from,to); 35 | from++; 36 | to++; 37 | } 38 | } 39 | 40 | static inline void get_new(char * from,char * to) 41 | { 42 | int i; 43 | 44 | for (i=0 ; i< sizeof(struct sigaction) ; i++) 45 | *(to++) = get_fs_byte(from++); 46 | } 47 | 48 | int sys_signal(int signum, long handler, long restorer) 49 | { 50 | struct sigaction tmp; 51 | 52 | if (signum<1 || signum>32 || signum==SIGKILL) 53 | return -1; 54 | tmp.sa_handler = (void (*)(int)) handler; 55 | tmp.sa_mask = 0; 56 | tmp.sa_flags = SA_ONESHOT | SA_NOMASK; 57 | tmp.sa_restorer = (void (*)(void)) restorer; 58 | handler = (long) current->sigaction[signum-1].sa_handler; 59 | current->sigaction[signum-1] = tmp; 60 | return handler; 61 | } 62 | 63 | int sys_sigaction(int signum, const struct sigaction * action, 64 | struct sigaction * oldaction) 65 | { 66 | struct sigaction tmp; 67 | 68 | if (signum<1 || signum>32 || signum==SIGKILL) 69 | return -1; 70 | tmp = current->sigaction[signum-1]; 71 | get_new((char *) action, 72 | (char *) (signum-1+current->sigaction)); 73 | if (oldaction) 74 | save_old((char *) &tmp,(char *) oldaction); 75 | if (current->sigaction[signum-1].sa_flags & SA_NOMASK) 76 | current->sigaction[signum-1].sa_mask = 0; 77 | else 78 | current->sigaction[signum-1].sa_mask |= (1<<(signum-1)); 79 | return 0; 80 | } 81 | 82 | void do_signal(long signr,long eax, long ebx, long ecx, long edx, 83 | long fs, long es, long ds, 84 | long eip, long cs, long eflags, 85 | unsigned long * esp, long ss) 86 | { 87 | unsigned long sa_handler; 88 | long old_eip=eip; 89 | struct sigaction * sa = current->sigaction + signr - 1; 90 | int longs; 91 | unsigned long * tmp_esp; 92 | 93 | sa_handler = (unsigned long) sa->sa_handler; 94 | if (sa_handler==1) 95 | return; 96 | if (!sa_handler) { 97 | if (signr==SIGCHLD) 98 | return; 99 | else 100 | do_exit(1<<(signr-1)); 101 | } 102 | if (sa->sa_flags & SA_ONESHOT) 103 | sa->sa_handler = NULL; 104 | *(&eip) = sa_handler; 105 | longs = (sa->sa_flags & SA_NOMASK)?7:8; 106 | *(&esp) -= longs; 107 | verify_area(esp,longs*4); 108 | tmp_esp=esp; 109 | put_fs_long((long) sa->sa_restorer,tmp_esp++); 110 | put_fs_long(signr,tmp_esp++); 111 | if (!(sa->sa_flags & SA_NOMASK)) 112 | put_fs_long(current->blocked,tmp_esp++); 113 | put_fs_long(eax,tmp_esp++); 114 | put_fs_long(ecx,tmp_esp++); 115 | put_fs_long(edx,tmp_esp++); 116 | put_fs_long(eflags,tmp_esp++); 117 | put_fs_long(old_eip,tmp_esp++); 118 | current->blocked |= sa->sa_mask; 119 | } 120 | -------------------------------------------------------------------------------- /lab8/kernel/signal.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/signal.o -------------------------------------------------------------------------------- /lab8/kernel/sys.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/kernel/sys.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int sys_ftime() 17 | { 18 | return -ENOSYS; 19 | } 20 | 21 | int sys_break() 22 | { 23 | return -ENOSYS; 24 | } 25 | 26 | int sys_ptrace() 27 | { 28 | return -ENOSYS; 29 | } 30 | 31 | int sys_stty() 32 | { 33 | return -ENOSYS; 34 | } 35 | 36 | int sys_gtty() 37 | { 38 | return -ENOSYS; 39 | } 40 | 41 | int sys_rename() 42 | { 43 | return -ENOSYS; 44 | } 45 | 46 | int sys_prof() 47 | { 48 | return -ENOSYS; 49 | } 50 | 51 | int sys_setregid(int rgid, int egid) 52 | { 53 | if (rgid>0) { 54 | if ((current->gid == rgid) || 55 | suser()) 56 | current->gid = rgid; 57 | else 58 | return(-EPERM); 59 | } 60 | if (egid>0) { 61 | if ((current->gid == egid) || 62 | (current->egid == egid) || 63 | (current->sgid == egid) || 64 | suser()) 65 | current->egid = egid; 66 | else 67 | return(-EPERM); 68 | } 69 | return 0; 70 | } 71 | 72 | int sys_setgid(int gid) 73 | { 74 | return(sys_setregid(gid, gid)); 75 | } 76 | 77 | int sys_acct() 78 | { 79 | return -ENOSYS; 80 | } 81 | 82 | int sys_phys() 83 | { 84 | return -ENOSYS; 85 | } 86 | 87 | int sys_lock() 88 | { 89 | return -ENOSYS; 90 | } 91 | 92 | int sys_mpx() 93 | { 94 | return -ENOSYS; 95 | } 96 | 97 | int sys_ulimit() 98 | { 99 | return -ENOSYS; 100 | } 101 | 102 | int sys_time(long * tloc) 103 | { 104 | int i; 105 | 106 | i = CURRENT_TIME; 107 | if (tloc) { 108 | verify_area(tloc,4); 109 | put_fs_long(i,(unsigned long *)tloc); 110 | } 111 | return i; 112 | } 113 | 114 | /* 115 | * Unprivileged users may change the real user id to the effective uid 116 | * or vice versa. 117 | */ 118 | int sys_setreuid(int ruid, int euid) 119 | { 120 | int old_ruid = current->uid; 121 | 122 | if (ruid>0) { 123 | if ((current->euid==ruid) || 124 | (old_ruid == ruid) || 125 | suser()) 126 | current->uid = ruid; 127 | else 128 | return(-EPERM); 129 | } 130 | if (euid>0) { 131 | if ((old_ruid == euid) || 132 | (current->euid == euid) || 133 | suser()) 134 | current->euid = euid; 135 | else { 136 | current->uid = old_ruid; 137 | return(-EPERM); 138 | } 139 | } 140 | return 0; 141 | } 142 | 143 | int sys_setuid(int uid) 144 | { 145 | return(sys_setreuid(uid, uid)); 146 | } 147 | 148 | int sys_stime(long * tptr) 149 | { 150 | if (!suser()) 151 | return -EPERM; 152 | startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ; 153 | return 0; 154 | } 155 | 156 | int sys_times(struct tms * tbuf) 157 | { 158 | if (tbuf) { 159 | verify_area(tbuf,sizeof *tbuf); 160 | put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime); 161 | put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime); 162 | put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime); 163 | put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime); 164 | } 165 | return jiffies; 166 | } 167 | 168 | int sys_brk(unsigned long end_data_seg) 169 | { 170 | if (end_data_seg >= current->end_code && 171 | end_data_seg < current->start_stack - 16384) 172 | current->brk = end_data_seg; 173 | return current->brk; 174 | } 175 | 176 | /* 177 | * This needs some heave checking ... 178 | * I just haven't get the stomach for it. I also don't fully 179 | * understand sessions/pgrp etc. Let somebody who does explain it. 180 | */ 181 | int sys_setpgid(int pid, int pgid) 182 | { 183 | int i; 184 | 185 | if (!pid) 186 | pid = current->pid; 187 | if (!pgid) 188 | pgid = current->pid; 189 | for (i=0 ; ipid==pid) { 191 | if (task[i]->leader) 192 | return -EPERM; 193 | if (task[i]->session != current->session) 194 | return -EPERM; 195 | task[i]->pgrp = pgid; 196 | return 0; 197 | } 198 | return -ESRCH; 199 | } 200 | 201 | int sys_getpgrp(void) 202 | { 203 | return current->pgrp; 204 | } 205 | 206 | int sys_setsid(void) 207 | { 208 | if (current->leader && !suser()) 209 | return -EPERM; 210 | current->leader = 1; 211 | current->session = current->pgrp = current->pid; 212 | current->tty = -1; 213 | return current->pgrp; 214 | } 215 | 216 | int sys_uname(struct utsname * name) 217 | { 218 | static struct utsname thisname = { 219 | "linux .0","nodename","release ","version ","machine " 220 | }; 221 | int i; 222 | 223 | if (!name) return -ERROR; 224 | verify_area(name,sizeof *name); 225 | for(i=0;iumask; 233 | 234 | current->umask = mask & 0777; 235 | return (old); 236 | } 237 | -------------------------------------------------------------------------------- /lab8/kernel/sys.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/sys.o -------------------------------------------------------------------------------- /lab8/kernel/system_call.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/system_call.o -------------------------------------------------------------------------------- /lab8/kernel/thread.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/thread.o -------------------------------------------------------------------------------- /lab8/kernel/traps.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/traps.o -------------------------------------------------------------------------------- /lab8/kernel/vsprintf.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/kernel/vsprintf.o -------------------------------------------------------------------------------- /lab8/lib/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for some libs needed in the kernel. 3 | # 4 | # Note! Dependencies are done automagically by 'make dep', which also 5 | # removes any old dependencies. DON'T put your own dependencies here 6 | # unless it's something special (ie not a .c file). 7 | # 8 | 9 | AR =ar 10 | AS =as 11 | LD =ld 12 | LDFLAGS =-m elf_i386 -x 13 | CC =gcc-3.4 -march=i386 14 | CFLAGS =-m32 -g -Wall -O -fstrength-reduce -fomit-frame-pointer \ 15 | -finline-functions -nostdinc -I../include 16 | CPP =gcc-3.4 -E -nostdinc -I../include 17 | 18 | .c.s: 19 | $(CC) $(CFLAGS) \ 20 | -S -o $*.s $< 21 | .s.o: 22 | $(AS) -o $*.o $< 23 | .c.o: 24 | $(CC) $(CFLAGS) \ 25 | -c -o $*.o $< 26 | 27 | OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \ 28 | execve.o wait.o string.o malloc.o 29 | 30 | lib.a: $(OBJS) 31 | $(AR) rcs lib.a $(OBJS) 32 | sync 33 | 34 | clean: 35 | rm -f core *.o *.a tmp_make 36 | for i in *.c;do rm -f `basename $$i .c`.s;done 37 | 38 | dep: 39 | sed '/\#\#\# Dependencies/q' < Makefile > tmp_make 40 | (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ 41 | $(CPP) -M $$i;done) >> tmp_make 42 | cp tmp_make Makefile 43 | 44 | ### Dependencies: 45 | _exit.s _exit.o : _exit.c ../include/unistd.h ../include/sys/stat.h \ 46 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 47 | ../include/utime.h 48 | close.s close.o : close.c ../include/unistd.h ../include/sys/stat.h \ 49 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 50 | ../include/utime.h 51 | ctype.s ctype.o : ctype.c ../include/ctype.h 52 | dup.s dup.o : dup.c ../include/unistd.h ../include/sys/stat.h \ 53 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 54 | ../include/utime.h 55 | errno.s errno.o : errno.c 56 | execve.s execve.o : execve.c ../include/unistd.h ../include/sys/stat.h \ 57 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 58 | ../include/utime.h 59 | malloc.s malloc.o : malloc.c ../include/linux/kernel.h ../include/linux/mm.h \ 60 | ../include/asm/system.h 61 | open.s open.o : open.c ../include/unistd.h ../include/sys/stat.h \ 62 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 63 | ../include/utime.h ../include/stdarg.h 64 | setsid.s setsid.o : setsid.c ../include/unistd.h ../include/sys/stat.h \ 65 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 66 | ../include/utime.h 67 | string.s string.o : string.c ../include/string.h 68 | wait.s wait.o : wait.c ../include/unistd.h ../include/sys/stat.h \ 69 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 70 | ../include/utime.h ../include/sys/wait.h 71 | write.s write.o : write.c ../include/unistd.h ../include/sys/stat.h \ 72 | ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \ 73 | ../include/utime.h 74 | -------------------------------------------------------------------------------- /lab8/lib/_exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/_exit.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | 10 | volatile void _exit(int exit_code) 11 | { 12 | __asm__("int $0x80"::"a" (__NR_exit),"b" (exit_code)); 13 | } 14 | -------------------------------------------------------------------------------- /lab8/lib/_exit.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/_exit.o -------------------------------------------------------------------------------- /lab8/lib/close.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/close.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | 10 | _syscall1(int,close,int,fd) 11 | -------------------------------------------------------------------------------- /lab8/lib/close.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/close.o -------------------------------------------------------------------------------- /lab8/lib/ctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/ctype.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | char _ctmp; 10 | unsigned char _ctype[] = {0x00, /* EOF */ 11 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ 12 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ 13 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ 14 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ 15 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ 16 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ 17 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ 18 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ 19 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ 20 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ 21 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ 22 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ 23 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ 24 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ 25 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ 26 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ 27 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ 28 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ 29 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 160-175 */ 30 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 176-191 */ 31 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 192-207 */ 32 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 208-223 */ 33 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 224-239 */ 34 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* 240-255 */ 35 | 36 | -------------------------------------------------------------------------------- /lab8/lib/ctype.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/ctype.o -------------------------------------------------------------------------------- /lab8/lib/dup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/dup.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | 10 | _syscall1(int,dup,int,fd) 11 | -------------------------------------------------------------------------------- /lab8/lib/dup.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/dup.o -------------------------------------------------------------------------------- /lab8/lib/errno.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/errno.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | int errno; 8 | -------------------------------------------------------------------------------- /lab8/lib/errno.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/errno.o -------------------------------------------------------------------------------- /lab8/lib/execve.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/execve.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | 10 | _syscall3(int,execve,const char *,file,char **,argv,char **,envp) 11 | -------------------------------------------------------------------------------- /lab8/lib/execve.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/execve.o -------------------------------------------------------------------------------- /lab8/lib/lib.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/lib.a -------------------------------------------------------------------------------- /lab8/lib/malloc.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/malloc.o -------------------------------------------------------------------------------- /lab8/lib/open.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/open.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | #include 10 | 11 | int open(const char * filename, int flag, ...) 12 | { 13 | register int res; 14 | va_list arg; 15 | 16 | va_start(arg,flag); 17 | __asm__("int $0x80" 18 | :"=a" (res) 19 | :"0" (__NR_open),"b" (filename),"c" (flag), 20 | "d" (va_arg(arg,int))); 21 | if (res>=0) 22 | return res; 23 | errno = -res; 24 | return -1; 25 | } 26 | -------------------------------------------------------------------------------- /lab8/lib/open.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/open.o -------------------------------------------------------------------------------- /lab8/lib/setsid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/setsid.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | 10 | _syscall0(pid_t,setsid) 11 | -------------------------------------------------------------------------------- /lab8/lib/setsid.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/setsid.o -------------------------------------------------------------------------------- /lab8/lib/string.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/string.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #ifndef __GNUC__ 8 | #error I want gcc! 9 | #endif 10 | 11 | #define extern 12 | #define inline 13 | #define __LIBRARY__ 14 | #include 15 | -------------------------------------------------------------------------------- /lab8/lib/string.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/string.o -------------------------------------------------------------------------------- /lab8/lib/wait.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/wait.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | #include 10 | 11 | _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) 12 | 13 | pid_t wait(int * wait_stat) 14 | { 15 | return waitpid(-1,wait_stat,0); 16 | } 17 | -------------------------------------------------------------------------------- /lab8/lib/wait.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/wait.o -------------------------------------------------------------------------------- /lab8/lib/write.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/write.c 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | #define __LIBRARY__ 8 | #include 9 | 10 | _syscall3(int,write,int,fd,const char *,buf,off_t,count) 11 | -------------------------------------------------------------------------------- /lab8/lib/write.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/lib/write.o -------------------------------------------------------------------------------- /lab8/memtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MEM_SIZE 0x20000 8 | #define MAX_TH_NUM 10 9 | 10 | unsigned long test_addr[MAX_TH_NUM]; 11 | int times; 12 | int tid[MAX_TH_NUM]; 13 | int result[MAX_TH_NUM]; 14 | 15 | int memtest(unsigned long start_addr) 16 | { 17 | int i,j,flag=1,tmp,counter=0; 18 | unsigned char * p; 19 | p = (unsigned char*)start_addr; 20 | for(i=0;i>>"); 72 | fflush(stdout); 73 | scanf(" %s",tmp); 74 | if(strcmp(tmp,"times") == 0) 75 | { 76 | scanf(" %d",×); 77 | continue; 78 | } 79 | if(strcmp(tmp,"thread") == 0) 80 | { 81 | scanf(" %d",&num); 82 | continue; 83 | } 84 | if(strcmp(tmp,"exit") == 0) 85 | { 86 | exit(0); 87 | } 88 | if(strcmp(tmp,"go") == 0) 89 | { 90 | for(i=0;i tmp_make 32 | (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make 33 | cp tmp_make Makefile 34 | 35 | ### Dependencies: 36 | memory.o: memory.c ../include/signal.h ../include/sys/types.h \ 37 | ../include/asm/system.h ../include/linux/sched.h \ 38 | ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \ 39 | ../include/linux/kernel.h 40 | -------------------------------------------------------------------------------- /lab8/mm/memory.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/mm/memory.o -------------------------------------------------------------------------------- /lab8/mm/mm.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/mm/mm.o -------------------------------------------------------------------------------- /lab8/mm/page.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/mm/page.o -------------------------------------------------------------------------------- /lab8/mm/page.s: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/mm/page.s 3 | * 4 | * (C) 1991 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * page.s contains the low-level page-exception code. 9 | * the real work is done in mm.c 10 | */ 11 | 12 | .globl page_fault 13 | 14 | page_fault: 15 | xchgl %eax,(%esp) 16 | pushl %ecx 17 | pushl %edx 18 | push %ds 19 | push %es 20 | push %fs 21 | movl $0x10,%edx 22 | mov %dx,%ds 23 | mov %dx,%es 24 | mov %dx,%fs 25 | movl %cr2,%edx 26 | pushl %edx 27 | pushl %eax 28 | testl $1,%eax 29 | jne 1f 30 | call do_no_page 31 | jmp 2f 32 | 1: call do_wp_page 33 | 2: addl $8,%esp 34 | pop %fs 35 | pop %es 36 | pop %ds 37 | popl %edx 38 | popl %ecx 39 | popl %eax 40 | iret 41 | -------------------------------------------------------------------------------- /lab8/pthread.c: -------------------------------------------------------------------------------- 1 | #define __LIBRARY__ 2 | #include 3 | #include 4 | #include 5 | 6 | _syscall2(int,make_thread,fn_ptr,func,int,sp); 7 | _syscall2(int,thread_join,int,tid,int*,retval); 8 | _syscall1(int,thread_exit,int,retval); 9 | _syscall1(int,thread_cancel,int,tid); 10 | _syscall1(int,thread_status,int,tid); 11 | _syscall0(int,thread_gettid); 12 | 13 | int pthread_create(pthread_t* tid,fn_ptr start_routine, int arg) 14 | { 15 | int *p = (int*)malloc(STACK_SIZE*sizeof(int)); 16 | *(p+STACK_SIZE-1) = arg; 17 | /* *(p+STACK_SIZE-2): Return Address 18 | */ 19 | *tid = make_thread(start_routine,(long)(p+STACK_SIZE-2)); 20 | if(*tid > 0 && *tid <10) 21 | return 0; 22 | return -1; 23 | } 24 | 25 | void pthread_exit(int val) 26 | { 27 | thread_exit(val); 28 | } 29 | 30 | void pthread_cancel(int tid) 31 | { 32 | thread_cancel(tid); 33 | } 34 | 35 | void pthread_join(int tid,int* retval) 36 | { 37 | thread_join(tid,retval); 38 | } 39 | 40 | int pthread_status(int tid) 41 | { 42 | return thread_status(tid); 43 | } 44 | 45 | int pthread_gettid() 46 | { 47 | return thread_gettid(); 48 | } -------------------------------------------------------------------------------- /lab8/pthread.h: -------------------------------------------------------------------------------- 1 | #ifndef PTHREAD_H 2 | #define PTHREAD_H 3 | 4 | 5 | #define STACK_SIZE 1024 6 | 7 | typedef int (*fn_ptr)(int); 8 | typedef int pthread_t; 9 | 10 | #endif -------------------------------------------------------------------------------- /lab8/test.c: -------------------------------------------------------------------------------- 1 | #define __LIBRARY__ 2 | #include 3 | 4 | typedef int (*fn_ptr)(); 5 | _syscall3(int,make_thread,fn_ptr,sum,int,ss,int,sp) 6 | _syscall1(void,thread_exit,int,ret) 7 | _syscall2(void,thread_join,int,tid,int*,ret) 8 | 9 | int test; 10 | 11 | int sum(int a) 12 | { 13 | test = 2; 14 | printf("\n\nsum=%d\n\n",a); 15 | thread_exit(123); 16 | return 12; 17 | } 18 | 19 | int main() 20 | { 21 | test =1; 22 | int ret; 23 | int *p = malloc(1024*sizeof(int)); 24 | *(p+1023) = 0x20; 25 | ret = make_thread(sum,p+1022,p+1022); 26 | thread_join(ret,&ret); 27 | printf("ret from thread is:%d\n",ret); 28 | printf("test is:%d\n",test); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /lab8/tools/build: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/tools/build -------------------------------------------------------------------------------- /lab8/tools/system: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoverwinter/HIT-OSLab/a4534bb3ed970965358f40a9af2d0277333b636d/lab8/tools/system --------------------------------------------------------------------------------