├── .gitignore ├── README.md ├── amd64 ├── mount-hdc └── run ├── common ├── bochs-and-hdc.tar.gz ├── files │ ├── memtest │ ├── process.c │ ├── stat_log.py │ ├── testlab2.c │ └── testlab2.sh └── linux-0.11.tar.gz ├── gcc-3.4 ├── amd64 │ ├── cpp-3.4_3.4.6-8ubuntu2_amd64.deb │ ├── gcc-3.4-base_3.4.6-8ubuntu2_amd64.deb │ └── gcc-3.4_3.4.6-8ubuntu2_amd64.deb └── i386 │ ├── cpp-3.4_3.4.6-8ubuntu2_i386.deb │ ├── gcc-3.4-base_3.4.6-8ubuntu2_i386.deb │ └── gcc-3.4_3.4.6-8ubuntu2_i386.deb ├── hit.icon ├── i386 ├── bochs │ ├── bochs-dbg │ └── bochs-gdb ├── dbg-asm ├── dbg-c ├── gdb ├── gdb-cmd.txt ├── mount-hdc ├── run └── rungdb └── setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *~ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | hit-oslab 2 | ========= 3 | 4 | 本仓库涵盖了哈尔滨工业大学《操作系统》课程实验指导手册、实验环境(64位支持)及源码。旨在针对32位和64位的Ubuntu系统,一键式搭建好环境,为同学们节省环境配置时间。 5 | 6 | ## 在线学习与实验 7 | 8 | ![hit](https://cloud.githubusercontent.com/assets/895809/7827659/834a4424-045c-11e5-9442-43a73b8e6991.jpg) 9 | 10 | 11 | 由于历史原因,推荐大家使用实验楼提供的实验环境。本项目只做归档使用。 12 | 13 | + [操作系统之基础 - 网易云课堂](http://mooc.study.163.com/learn/HIT-1000002004?tid=1000002003#/learn/announce) 14 | + [操作系统原理与实践 - 实验楼](https://www.shiyanlou.com/courses/115) 15 | 16 | ## 安装 17 | 18 | 本安装脚本会将实验环境安装在用户目录下,文件名为oslab。如果有特殊需要,请自行移动文件夹位置。注意,请不要使用超级用户执行此安装命令,当有需要时hit-oslab会请求超级用户权限。 19 | 20 | ```shell 21 | git clone https://github.com/DeathKing/hit-oslab.git ~/hit-oslab 22 | cd ~/hit-oslab 23 | ./setup.sh 24 | ``` 25 | 26 | 如果想要跳过软件源更新步骤,请在`./setup.sh`后加上参数`-s`或`--skip-update`。 27 | 28 | ## 复原 29 | 30 | 考虑到操作系统试验每次需要重置linux-0.11目录,oslab特别添加了重置功能。本功能由`./run`命令提供。 31 | 32 | ```shell 33 | # in oslab directory 34 | ./run init 35 | ``` 36 | 37 | ## 反馈 38 | 39 | 本项目可以确保bochs能够正确启动,但某些64位系统在编译linux-0.11时会提示缺少某些文件,如果遇到类似问题的同学,请发issue。 40 | -------------------------------------------------------------------------------- /amd64/mount-hdc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export OSLAB_PATH=$(dirname `which $0`) 3 | sudo mount -t minix -o loop,offset=1024 $OSLAB_PATH/hdc-0.11.img $OSLAB_PATH/hdc 4 | -------------------------------------------------------------------------------- /amd64/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export OSLAB_PATH=$(dirname `which $0`) 3 | 4 | if [ "$1" ] && [ "$1" = "init" ] ; then 5 | if [ -f $OSLAB_PATH/linux-0.11.tar.gz ]; then 6 | [ -d $OSLAB_PATH/linux-0.11 ] && rm -rf $OSLAB_PATH/linux-0.11 7 | mkdir $OSLAB_PATH/linux-0.11 8 | tar zxf $OSLAB_PATH/linux-0.11.tar.gz -C $OSLAB_PATH/linux-0.11 9 | echo "Successfully recover linux-0.11." 10 | exit 0 11 | else 12 | echo "Error: oslab cant't find a backup file named linux-0.11.tar.gz!" 13 | exit 1 14 | fi 15 | fi 16 | 17 | if [ ! -e "$OSLAB_PATH/hdc/umounted" ]; then 18 | echo umount hdc first 19 | sudo umount $OSLAB_PATH/hdc 20 | if [ "$?" != "0" ]; then 21 | exit 22 | fi 23 | fi 24 | 25 | bochs -q -f $OSLAB_PATH/bochs/bochsrc.bxrc 26 | -------------------------------------------------------------------------------- /common/bochs-and-hdc.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/common/bochs-and-hdc.tar.gz -------------------------------------------------------------------------------- /common/files/memtest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/common/files/memtest -------------------------------------------------------------------------------- /common/files/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 | 59 | -------------------------------------------------------------------------------- /common/files/stat_log.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | import copy 4 | 5 | P_NULL = 0 6 | P_NEW = 1 7 | P_READY = 2 8 | P_RUNNING = 4 9 | P_WAITING = 8 10 | P_EXIT = 16 11 | 12 | S_STATE = 0 13 | S_TIME = 1 14 | 15 | HZ = 100 16 | 17 | graph_title = r""" 18 | -----===< COOL GRAPHIC OF SCHEDULER >===----- 19 | 20 | [Symbol] [Meaning] 21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22 | number PID or tick 23 | "-" New or Exit 24 | "#" Running 25 | "|" Ready 26 | ":" Waiting 27 | / Running with 28 | "+" -| Ready 29 | \and/or Waiting 30 | 31 | -----===< !!!!!!!!!!!!!!!!!!!!!!!!! >===----- 32 | """ 33 | 34 | usage = """ 35 | Usage: 36 | %s /path/to/process.log [PID1] [PID2] ... [-x PID1 [PID2] ... ] [-m] [-g] 37 | 38 | Example: 39 | # Include process 6, 7, 8 and 9 in statistics only. (Unit: tick) 40 | %s /path/to/process.log 6 7 8 9 41 | 42 | # Exclude process 0 and 1 from statistics. (Unit: tick) 43 | %s /path/to/process.log -x 0 1 44 | 45 | # Include process 6 and 7 only and print a COOL "graphic"! (Unit: millisecond) 46 | %s /path/to/process.log 6 7 -m -g 47 | 48 | # Include all processes and print a COOL "graphic"! (Unit: tick) 49 | %s /path/to/process.log -g 50 | """ 51 | 52 | class MyError(Exception): 53 | pass 54 | 55 | class DuplicateNew(MyError): 56 | def __init__(self, pid): 57 | args = "More than one 'N' for process %d." % pid 58 | MyError.__init__(self, args) 59 | 60 | class UnknownState(MyError): 61 | def __init__(self, state): 62 | args = "Unknown state '%s' found." % state 63 | MyError.__init__(self, args) 64 | 65 | class BadTime(MyError): 66 | def __init__(self, time): 67 | args = "The time '%d' is bad. It should >= previous line's time." % time 68 | MyError.__init__(self, args) 69 | 70 | class TaskHasExited(MyError): 71 | def __init__(self, state): 72 | args = "The process has exited. Why it enter '%s' state again?" % state 73 | MyError.__init__(self, args) 74 | 75 | class BadFormat(MyError): 76 | def __init__(self): 77 | args = "Bad log format" 78 | MyError.__init__(self, args) 79 | 80 | class RepeatState(MyError): 81 | def __init__(self, pid): 82 | args = "Previous state of process %d is identical with this line." % (pid) 83 | MyError.__init__(self, args) 84 | 85 | class SameLine(MyError): 86 | def __init__(self): 87 | args = "It is a clone of previous line." 88 | MyError.__init__(self, args) 89 | 90 | class NoNew(MyError): 91 | def __init__(self, pid, state): 92 | args = "The first state of process %d is '%s'. Why not 'N'?" % (pid, state) 93 | MyError.__init__(self, args) 94 | 95 | class statistics: 96 | def __init__(self, pool, include, exclude): 97 | if include: 98 | self.pool = process_pool() 99 | for process in pool: 100 | if process.getpid() in include: 101 | self.pool.add(process) 102 | else: 103 | self.pool = copy.copy(pool) 104 | 105 | if exclude: 106 | for pid in exclude: 107 | if self.pool.get_process(pid): 108 | self.pool.remove(pid) 109 | 110 | def list_pid(self): 111 | l = [] 112 | for process in self.pool: 113 | l.append(process.getpid()) 114 | return l 115 | 116 | def average_turnaround(self): 117 | if len(self.pool) == 0: 118 | return 0 119 | sum = 0 120 | for process in self.pool: 121 | sum += process.turnaround_time() 122 | return float(sum) / len(self.pool) 123 | 124 | def average_waiting(self): 125 | if len(self.pool) == 0: 126 | return 0 127 | sum = 0 128 | for process in self.pool: 129 | sum += process.waiting_time() 130 | return float(sum) / len(self.pool) 131 | 132 | def begin_time(self): 133 | begin = 0xEFFFFF 134 | for p in self.pool: 135 | if p.begin_time() < begin: 136 | begin = p.begin_time() 137 | return begin 138 | 139 | def end_time(self): 140 | end = 0 141 | for p in self.pool: 142 | if p.end_time() > end: 143 | end = p.end_time() 144 | return end 145 | 146 | def throughput(self): 147 | return len(self.pool) * HZ / float(self.end_time() - self.begin_time()) 148 | 149 | def print_graphic(self): 150 | begin = self.begin_time() 151 | end = self.end_time() 152 | 153 | print graph_title 154 | 155 | for i in range(begin, end+1): 156 | line = "%5d " % i 157 | for p in self.pool: 158 | state = p.get_state(i) 159 | if state & P_NEW: 160 | line += "-" 161 | elif state == P_READY or state == P_READY | P_WAITING: 162 | line += "|" 163 | elif state == P_RUNNING: 164 | line += "#" 165 | elif state == P_WAITING: 166 | line += ":" 167 | elif state & P_EXIT: 168 | line += "-" 169 | elif state == P_NULL: 170 | line += " " 171 | elif state & P_RUNNING: 172 | line += "+" 173 | else: 174 | assert False 175 | if p.get_state(i-1) != state and state != P_NULL: 176 | line += "%-3d" % p.getpid() 177 | else: 178 | line += " " 179 | print line 180 | 181 | class process_pool: 182 | def __init__(self): 183 | self.list = [] 184 | 185 | def get_process(self, pid): 186 | for process in self.list: 187 | if process.getpid() == pid: 188 | return process 189 | return None 190 | 191 | def remove(self, pid): 192 | for process in self.list: 193 | if process.getpid() == pid: 194 | self.list.remove(process) 195 | 196 | def new(self, pid, time): 197 | p = self.get_process(pid) 198 | if p: 199 | if pid != 0: 200 | raise DuplicateNew(pid) 201 | else: 202 | p.states=[(P_NEW, time)] 203 | else: 204 | p = process(pid, time) 205 | self.list.append(p) 206 | return p 207 | 208 | def add(self, p): 209 | self.list.append(p) 210 | 211 | def __len__(self): 212 | return len(self.list) 213 | 214 | def __iter__(self): 215 | return iter(self.list) 216 | 217 | class process: 218 | def __init__(self, pid, time): 219 | self.pid = pid 220 | self.states = [(P_NEW, time)] 221 | 222 | def getpid(self): 223 | return self.pid 224 | 225 | def change_state(self, state, time): 226 | last_state, last_time = self.states[-1] 227 | if state == P_NEW: 228 | raise DuplicateNew(pid) 229 | if time < last_time: 230 | raise BadTime(time) 231 | if last_state == P_EXIT: 232 | raise TaskHasExited(state) 233 | if last_state == state and self.pid != 0: # task 0 can have duplicate state 234 | raise RepeatState(self.pid) 235 | 236 | self.states.append((state, time)) 237 | 238 | def get_state(self, time): 239 | rval = P_NULL 240 | combo = P_NULL 241 | if self.begin_time() <= time <= self.end_time(): 242 | for state, s_time in self.states: 243 | if s_time < time: 244 | rval = state 245 | elif s_time == time: 246 | combo |= state 247 | else: 248 | break 249 | if combo: 250 | rval = combo 251 | return rval 252 | 253 | def turnaround_time(self): 254 | return self.states[-1][S_TIME] - self.states[0][S_TIME] 255 | 256 | def waiting_time(self): 257 | return self.state_last_time(P_READY) 258 | 259 | def cpu_time(self): 260 | return self.state_last_time(P_RUNNING) 261 | 262 | def io_time(self): 263 | return self.state_last_time(P_WAITING) 264 | 265 | def state_last_time(self, state): 266 | time = 0 267 | state_begin = 0 268 | for s,t in self.states: 269 | if s == state: 270 | state_begin = t 271 | elif state_begin != 0: 272 | assert state_begin <= t 273 | time += t - state_begin 274 | state_begin = 0 275 | return time 276 | 277 | 278 | def begin_time(self): 279 | return self.states[0][S_TIME] 280 | 281 | def end_time(self): 282 | return self.states[-1][S_TIME] 283 | 284 | # Enter point 285 | if len(sys.argv) < 2: 286 | print usage.replace("%s", sys.argv[0]) 287 | sys.exit(0) 288 | 289 | # parse arguments 290 | include = [] 291 | exclude = [] 292 | unit_ms = False 293 | graphic = False 294 | ex_mark = False 295 | 296 | try: 297 | for arg in sys.argv[2:]: 298 | if arg == '-m': 299 | unit_ms = True 300 | continue 301 | if arg == '-g': 302 | graphic = True 303 | continue 304 | if not ex_mark: 305 | if arg == '-x': 306 | ex_mark = True 307 | else: 308 | include.append(int(arg)) 309 | else: 310 | exclude.append(int(arg)) 311 | except ValueError: 312 | print "Bad argument '%s'" % arg 313 | sys.exit(-1) 314 | 315 | # parse log file and construct processes 316 | processes = process_pool() 317 | 318 | f = open(sys.argv[1], "r") 319 | 320 | # Patch process 0's New & Run state 321 | processes.new(0, 40).change_state(P_RUNNING, 40) 322 | 323 | try: 324 | prev_time = 0 325 | prev_line = "" 326 | for lineno, line in enumerate(f): 327 | 328 | if line == prev_line: 329 | raise SameLine 330 | prev_line = line 331 | 332 | fields = line.split("\t") 333 | if len(fields) != 3: 334 | raise BadFormat 335 | 336 | pid = int(fields[0]) 337 | s = fields[1].upper() 338 | 339 | time = int(fields[2]) 340 | if time < prev_time: 341 | raise BadTime(time) 342 | prev_time = time 343 | 344 | p = processes.get_process(pid) 345 | 346 | state = P_NULL 347 | if s == 'N': 348 | processes.new(pid, time) 349 | elif s == 'J': 350 | state = P_READY 351 | elif s == 'R': 352 | state = P_RUNNING 353 | elif s == 'W': 354 | state = P_WAITING 355 | elif s == 'E': 356 | state = P_EXIT 357 | else: 358 | raise UnknownState(s) 359 | if state != P_NULL: 360 | if not p: 361 | raise NoNew(pid, s) 362 | p.change_state(state, time) 363 | except MyError, err: 364 | print "Error at line %d: %s" % (lineno+1, err) 365 | sys.exit(0) 366 | 367 | # Stats 368 | stats = statistics(processes, include, exclude) 369 | att = stats.average_turnaround() 370 | awt = stats.average_waiting() 371 | if unit_ms: 372 | unit = "ms" 373 | att *= 1000/HZ 374 | awt *= 1000/HZ 375 | else: 376 | unit = "tick" 377 | print "(Unit: %s)" % unit 378 | print "Process Turnaround Waiting CPU Burst I/O Burst" 379 | for pid in stats.list_pid(): 380 | p = processes.get_process(pid) 381 | tt = p.turnaround_time() 382 | wt = p.waiting_time() 383 | cpu = p.cpu_time() 384 | io = p.io_time() 385 | 386 | if unit_ms: 387 | print "%7d %10d %7d %9d %9d" % (pid, tt*1000/HZ, wt*1000/HZ, cpu*1000/HZ, io*1000/HZ) 388 | else: 389 | print "%7d %10d %7d %9d %9d" % (pid, tt, wt, cpu, io) 390 | print "Average: %10.2f %7.2f" % (att, awt) 391 | print "Throughout: %.2f/s" % (stats.throughput()) 392 | 393 | if graphic: 394 | stats.print_graphic() 395 | -------------------------------------------------------------------------------- /common/files/testlab2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Compile: "gcc testlab2.c" 3 | * Run: "./a.out" 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #define __LIBRARY__ 12 | #include 13 | 14 | _syscall2(int, whoami,char*,name,unsigned int,size); 15 | _syscall1(int, iam, const char*, name); 16 | 17 | #define MAX_NAME_LEN 23 18 | #define NAMEBUF_SIZE (MAX_NAME_LEN + 1) 19 | /* truncate a long name to SHORT_NAME_LEN for display */ 20 | #define SHORT_NAME_LEN (MAX_NAME_LEN + 2) 21 | 22 | /* name score */ 23 | #define TEST_CASE { \ 24 | {"x", 10, 1, NAMEBUF_SIZE, 1},\ 25 | {"sunner", 10, 6, NAMEBUF_SIZE, 6},\ 26 | {"Twenty-three characters", 5, 23, NAMEBUF_SIZE, 23},\ 27 | {"123456789009876543211234", 5, -1, 0, -1},\ 28 | {"abcdefghijklmnopqrstuvwxyz", 5, -1, 0, -1},\ 29 | {"Linus Torvalds", 5, 14, NAMEBUF_SIZE, 14},\ 30 | {"", 5, 0, NAMEBUF_SIZE, 0},\ 31 | {"whoami(0xbalabala, 10)", 5, 22, 10, -1},\ 32 | {NULL, 0, 0, 0, 0} /* End of cases */ \ 33 | } 34 | /*改动一:增加size,和rval2*/ 35 | 36 | int test(const char* name, int max_score, int expected_rval1, int size, int expected_rval2); 37 | void print_message(const char* msgfmt, const char* name); 38 | 39 | struct test_case 40 | { 41 | char *name; 42 | int score; 43 | int rval1; /* return value of iam() */ 44 | /*改动2:增加size,和rval2定义*/ 45 | int size; /*Patch for whoami,2009.11.2*/ 46 | int rval2; /* return value of whoami() */ 47 | }; 48 | 49 | int main(void) 50 | { 51 | struct test_case cases[] = TEST_CASE; 52 | 53 | int total_score=0, i=0; 54 | 55 | while (cases[i].score != 0) 56 | { 57 | int score; 58 | 59 | printf("Test case %d:", i+1); 60 | 61 | /*改动3:增加size,和rval2的参数阿*/ 62 | score = test( cases[i].name, 63 | cases[i].score, 64 | cases[i].rval1, 65 | cases[i].size, 66 | cases[i].rval2 ); 67 | 68 | total_score += score; 69 | i++; 70 | } 71 | 72 | printf("Final result: %d%%\n", total_score); 73 | return 0; 74 | 75 | } 76 | /*改动4:增加size,和rval2的声明*/ 77 | int test(const char* name, int max_score, int expected_rval1, int size, int expected_rval2) 78 | { 79 | int rval; 80 | int len; 81 | char * gotname; 82 | int score=-1; 83 | 84 | assert(name != NULL); 85 | 86 | print_message("name = \"%s\", length = %d...", name); 87 | 88 | /*Test iam()*/ 89 | len = strlen(name); 90 | rval = iam(name); 91 | /* printf("Return value = %d\n", rval);*/ 92 | 93 | /*改动5:增加的expected_rval1*/ 94 | if (rval == expected_rval1) 95 | { 96 | if (rval == -1 && errno == EINVAL) /*The system call can detect bad name*/ 97 | { 98 | /* print_message("Long name, %s(%d), detected.\n", name);*/ 99 | printf("PASS\n"); 100 | score = max_score; 101 | } 102 | else if (rval == -1 && errno != EINVAL) 103 | { 104 | printf("\nERROR iam(): Bad errno %d. It should be %d(EINVAL).\n", errno, EINVAL); 105 | score = 0; 106 | } 107 | /* iam() is good. Test whoami() next. */ 108 | } 109 | else 110 | { 111 | printf("\nERROR iam(): Return value is %d. It should be %d.\n", rval, expected_rval1); 112 | score = 0; 113 | } 114 | 115 | if (score != -1) 116 | return score; 117 | 118 | /*Test whoami()*/ 119 | gotname = (char*)malloc(len+1); 120 | if (gotname == NULL) 121 | exit(-1); 122 | 123 | memset(gotname, 0, len+1); 124 | 125 | /* printf("Get: buffer length = %d.\n", len+1); */ 126 | 127 | rval = whoami(gotname, size); 128 | /* printf("Return value = %d\n", rval); */ 129 | 130 | /*改动6:增加的expected_rval2*/ 131 | /*改动++:比较多 ,但还是顺序的改改*/ 132 | 133 | if(rval == expected_rval2) 134 | { 135 | if(rval == -1) 136 | { 137 | printf("PASS\n"); 138 | score = max_score; 139 | } 140 | else 141 | { 142 | if (strcmp(gotname, name) == 0) 143 | { 144 | /* print_message("Great! We got %s(%d) finally!\n", gotname); */ 145 | printf("PASS\n"); 146 | score = max_score; 147 | } 148 | else 149 | { 150 | print_message("\nERROR whoami(): we got %s(%d). ", gotname); 151 | print_message("It should be %s(%d).\n", name); 152 | score = 0; 153 | } 154 | } 155 | } 156 | else if (rval == -1) 157 | { 158 | printf("\nERROR whoami(): Return value is -1 and errno is %d. Why?\n", errno); 159 | score = 0; 160 | } 161 | else 162 | { 163 | printf("\nERROR whoami(): Return value should be %d, not %d.\n", expected_rval2, rval); 164 | score = 0; 165 | } 166 | 167 | free(gotname); 168 | assert(score != -1); 169 | 170 | return score; 171 | } 172 | 173 | void print_message(const char* msgfmt, const char* name) 174 | { 175 | char short_name[SHORT_NAME_LEN + 4] = {0}; 176 | int len; 177 | 178 | len = strlen(name); 179 | 180 | if (len == 0) 181 | { 182 | strcpy(short_name, "NULL"); 183 | } 184 | else if (len <= SHORT_NAME_LEN) 185 | { 186 | strcpy(short_name, name); 187 | } 188 | else 189 | { 190 | memset(short_name, '.', SHORT_NAME_LEN+3); 191 | memcpy(short_name, name, SHORT_NAME_LEN); 192 | } 193 | 194 | printf(msgfmt, short_name, len); 195 | } 196 | -------------------------------------------------------------------------------- /common/files/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 | -------------------------------------------------------------------------------- /common/linux-0.11.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/common/linux-0.11.tar.gz -------------------------------------------------------------------------------- /gcc-3.4/amd64/cpp-3.4_3.4.6-8ubuntu2_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/gcc-3.4/amd64/cpp-3.4_3.4.6-8ubuntu2_amd64.deb -------------------------------------------------------------------------------- /gcc-3.4/amd64/gcc-3.4-base_3.4.6-8ubuntu2_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/gcc-3.4/amd64/gcc-3.4-base_3.4.6-8ubuntu2_amd64.deb -------------------------------------------------------------------------------- /gcc-3.4/amd64/gcc-3.4_3.4.6-8ubuntu2_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/gcc-3.4/amd64/gcc-3.4_3.4.6-8ubuntu2_amd64.deb -------------------------------------------------------------------------------- /gcc-3.4/i386/cpp-3.4_3.4.6-8ubuntu2_i386.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/gcc-3.4/i386/cpp-3.4_3.4.6-8ubuntu2_i386.deb -------------------------------------------------------------------------------- /gcc-3.4/i386/gcc-3.4-base_3.4.6-8ubuntu2_i386.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/gcc-3.4/i386/gcc-3.4-base_3.4.6-8ubuntu2_i386.deb -------------------------------------------------------------------------------- /gcc-3.4/i386/gcc-3.4_3.4.6-8ubuntu2_i386.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/gcc-3.4/i386/gcc-3.4_3.4.6-8ubuntu2_i386.deb -------------------------------------------------------------------------------- /hit.icon: -------------------------------------------------------------------------------- 1 | +-------------------------------------------------------------------+ 2 | | _ _ _____ _______ ____ _____ _ _ | 3 | | | | | |_ _|__ __| / __ \ / ____| | | | | 4 | | | |__| | | | | | ______ | | | | (___ | | __ _| |__ | 5 | | | __ | | | | | |______| | | | |\___ \| | / _` | '_ \ | 6 | | | | | |_| |_ | | | |__| |____) | |___| (_| | |_) | | 7 | | |_| |_|_____| |_| \____/|_____/|______\__,_|_.__/ | 8 | +-------------------------------------------------------------------+ 9 | -------------------------------------------------------------------------------- /i386/bochs/bochs-dbg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/i386/bochs/bochs-dbg -------------------------------------------------------------------------------- /i386/bochs/bochs-gdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/i386/bochs/bochs-gdb -------------------------------------------------------------------------------- /i386/dbg-asm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export OSLAB_PATH=$(dirname `which $0`) 3 | $OSLAB_PATH/bochs/bochs-dbg -q -f $OSLAB_PATH/bochs/bochsrc.bxrc 4 | -------------------------------------------------------------------------------- /i386/dbg-c: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export OSLAB_PATH=$(dirname `which $0`) 3 | $OSLAB_PATH/bochs/bochs-gdb -q -f $OSLAB_PATH/bochs/bochsrc-gdb.bxrc 4 | -------------------------------------------------------------------------------- /i386/gdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeathKing/hit-oslab/f604b8ee5fe416b180d37185c13498343465d55a/i386/gdb -------------------------------------------------------------------------------- /i386/gdb-cmd.txt: -------------------------------------------------------------------------------- 1 | break main 2 | target remote localhost:1234 3 | handle all nostop noprint 4 | continue 5 | -------------------------------------------------------------------------------- /i386/mount-hdc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export OSLAB_PATH=$(dirname `which $0`) 3 | sudo mount -t minix -o loop,offset=1024 $OSLAB_PATH/hdc-0.11.img $OSLAB_PATH/hdc 4 | -------------------------------------------------------------------------------- /i386/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export OSLAB_PATH=$(dirname `which $0`) 3 | 4 | if [ "$1" ] && [ "$1" = "init" ] ; then 5 | if [ -f $OSLAB_PATH/linux-0.11.tar.gz ]; then 6 | [ -d $OSLAB_PATH/linux-0.11 ] && rm -rf $OSLAB_PATH/linux-0.11 7 | mkdir $OSLAB_PATH/linux-0.11 8 | tar zxf $OSLAB_PATH/linux-0.11.tar.gz -C $OSLAB_PATH/linux-0.11 9 | echo "Successfully recover linux-0.11." 10 | exit 0 11 | else 12 | echo "Error: oslab cant't find a backup file named linux-0.11.tar.gz!" 13 | exit 1 14 | fi 15 | fi 16 | 17 | if [ ! -e "$OSLAB_PATH/hdc/umounted" ]; then 18 | echo umount hdc first 19 | sudo umount $OSLAB_PATH/hdc 20 | if [ "$?" != "0" ]; then 21 | exit 22 | fi 23 | fi 24 | 25 | $OSLAB_PATH/bochs/bochs-gdb -q -f $OSLAB_PATH/bochs/bochsrc.bxrc 26 | -------------------------------------------------------------------------------- /i386/rungdb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export OSLAB_PATH=$(dirname `which $0`) 3 | 4 | if [ ! -e "$OSLAB_PATH/hdc/umounted" ]; then 5 | echo umount hdc first 6 | sudo umount $OSLAB_PATH/hdc 7 | if [ "$?" != "0" ]; then 8 | exit 9 | fi 10 | fi 11 | 12 | $OSLAB_PATH/gdb -x $OSLAB_PATH/gdb-cmd.txt $OSLAB_PATH/linux-0.11/tools/system 13 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Harbin Insitute of Technology 4 | # Operating System - Setup Script v0.0.1 5 | # 6 | # $Author$: Deng Xiongfei 7 | # $Date$: 2014-10-10 8 | export OSLAB_INSTALL_PATH=$HOME/oslab 9 | cat hit.icon 10 | echo "| Environment Setup Script v0.0.1 |" 11 | echo "| $ \033[34mDeng Xiongfei\033[0m $ |" 12 | echo "+-------------------------------------------------------------------+" 13 | 14 | install_gcc34_amd64() { 15 | echo -n "* Install gcc-3.4 for x86_64(amd64) arch now......" 16 | if [ -z `which gcc-3.4` ]; then 17 | sudo dpkg -i gcc-3.4/amd64/gcc-3.4-base_3.4.6-8ubuntu2_amd64.deb > /dev/null 18 | sudo dpkg -i gcc-3.4/amd64/cpp-3.4_3.4.6-8ubuntu2_amd64.deb > /dev/null 19 | sudo dpkg -i gcc-3.4/amd64/gcc-3.4_3.4.6-8ubuntu2_amd64.deb > /dev/null 20 | echo "\033[34mDone\033[0m" 21 | else 22 | echo "\033[32mSipped\033[0m" 23 | fi 24 | } 25 | 26 | install_gcc34_i386() { 27 | echo -n "* Install gcc-3.4 for x86(i386) arch now......" 28 | if [ -z `which gcc-3.4` ]; then 29 | sudo dpkg -i gcc-3.4/i386/gcc-3.4-base_3.4.6-8ubuntu2_i386.deb > /dev/null 30 | sudo dpkg -i gcc-3.4/i386/cpp-3.4_3.4.6-8ubuntu2_i386.deb > /dev/null 31 | sudo dpkg -i gcc-3.4/i386/gcc-3.4_3.4.6-8ubuntu2_i386.deb > /dev/null 32 | echo "\033[34mDone\033[0m" 33 | else 34 | echo "\033[33mSkipped\033[0m" 35 | fi 36 | } 37 | 38 | install_dep_i386() { 39 | echo "* Install dependencies for x86(i386) arch now......" 40 | sudo apt-get install bin86 41 | sudo apt-get install build-essential 42 | echo "* Install dependencies for x86(i386) arch now......\033[34mDone\033[0m" 43 | } 44 | 45 | install_dep_amd64() { 46 | echo "* Install dependencies for x86_64(amd64) arch now......" 47 | sudo apt-get install bin86 48 | sudo apt-get install gcc-multilib 49 | sudo apt-get install build-essential 50 | sudo apt-get install bochs bochs-x bochs-sdl 51 | echo "* Install dependencies for x86_64(amd64) arch now......\033[34mDone\033[0m" 52 | } 53 | 54 | configure_for_i386() { 55 | echo -n "* Copy rest files to oslab......" 56 | cp -r i386/* $OSLAB_INSTALL_PATH 57 | echo "\033[34mDone\033[0m" 58 | } 59 | 60 | configure_for_amd64() { 61 | # 64-bit version bochs has to show in sdl mode, bochs-sdl required 62 | echo -n "* Change bochs:display_library into sdl......" 63 | echo "display_library: sdl" >> $OSLAB_INSTALL_PATH/bochs/bochsrc.bxrc 64 | echo "\033[34mDone\033[0m" 65 | 66 | echo -n "* Copy run script to oslab......" 67 | cp -r amd64/* $OSLAB_INSTALL_PATH 68 | echo "\033[34mDone\033[0m" 69 | } 70 | 71 | # Common Code 72 | if [ "$1" ] && ([ "$1" = "-s" ] || [ "$1" = "--skip-update" ]); then 73 | echo -n "* Begin to setup......\033[33m3\033[0m sec to start"; sleep 1 74 | echo -n "\r* Begin to setup......\033[33m2\033[0m sec to start"; sleep 1 75 | echo -n "\r* Begin to setup......\033[33m1\033[0m sec to start"; sleep 1 76 | echo "\r* Begin to setup...... \033[0m" 77 | else 78 | echo -n "* Update apt sources......\033[33m3\033[31m sec to start"; sleep 1 79 | echo -n "\r* Update apt sources......\033[33m2\033[31m sec to start"; sleep 1 80 | echo -n "\r* Update apt sources......\033[33m1\033[31m sec to start"; sleep 1 81 | echo "\r* Update apt sources...... " 82 | sudo apt-get update 83 | fi 84 | 85 | echo -n "* Create oslab main directory......" 86 | [ -d $OSLAB_INSTALL_PATH ] || mkdir $OSLAB_INSTALL_PATH 87 | echo "\033[34mDone\033[0m" 88 | 89 | echo -n "* Create linux-0.11 directory......" 90 | [ -d $OSLAB_INSTALL_PATH/linux-0.11 ] || mkdir $OSLAB_INSTALL_PATH/linux-0.11 91 | echo "\033[34mDone\033[0m" 92 | 93 | # Extract linux-0.11 94 | echo -n "* Extract linux-0.11......" 95 | tar zxf common/linux-0.11.tar.gz -C $OSLAB_INSTALL_PATH/linux-0.11 96 | cp common/linux-0.11.tar.gz $OSLAB_INSTALL_PATH 97 | echo "\033[34mDone\033[0m" 98 | 99 | # Extract bochs and hdc image 100 | echo -n "* Extract bochs configuration file and hdc image......" 101 | tar zxf common/bochs-and-hdc.tar.gz -C $OSLAB_INSTALL_PATH/ 102 | echo "\033[34mDone\033[0m" 103 | 104 | # Copy common files 105 | echo -n "* Copy common files......" 106 | cp -r common/files $OSLAB_INSTALL_PATH 107 | echo "\033[034mDone\033[0m" 108 | 109 | # `getconf LONG_BIT` works better than `uname -a` 110 | if [ `getconf LONG_BIT` = "64" ] 111 | then 112 | install_dep_amd64 113 | install_gcc34_amd64 114 | configure_for_amd64 115 | else 116 | install_dep_i386 117 | install_gcc34_i386 118 | configure_for_i386 119 | fi 120 | 121 | echo "\033[34m* Installation finished. Ciao~\033[0m" 122 | --------------------------------------------------------------------------------