├── 11-io.md ├── 10-filesystem.md ├── book.json ├── 06-sched.md ├── .gitignore ├── README.md ├── SUMMARY.md ├── 08-semaphore.md ├── 07-sync.md ├── 04-vmm.md ├── 05-process-thread.md ├── 03-pmm.md ├── 02-interrupt-exception-syscall.md ├── 01-intro.md ├── 09-deadlock-ipc.md ├── 00-tool-manual.md ├── QQTalk.md └── others.md /11-io.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | ##Ucore实验相关 3 | 4 | -------------------------------------------------------------------------------- /10-filesystem.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | ##Ucore实验相关 3 | 4 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "quizzes" 4 | ] 5 | } -------------------------------------------------------------------------------- /06-sched.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | 3 | 在某些地方看到说LRU算法不会出现belady现象,但貌似记得老师上课说过可以找到一个队列也使LRU出现belady现象。或许是我自己记错了。 4 | what about clock or second chance? 5 | Thanks~ 6 | 答: 7 | 你记错了。 8 | 9 | 10 | ##Ucore实验相关 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf 17 | 18 | # swap 19 | *~ 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 操作系统课程问答 2 | 3 | * [工具使用帮助](00-tool-manual.md) 4 | * [操作系统介绍](01-intro.md) 5 | * [中断、异常和系统调用](02-interrupt-exception-syscall.md) 6 | * [物理内存管理](03-pmm.md) 7 | * [虚拟内存管理](04-vmm.md) 8 | * [进程、线程管理](05-process-thread.md) 9 | * [CPU调度](06-sched.md) 10 | * [同步](07-sync.md) 11 | * [信号量](08-semaphore.md) 12 | * [死锁和进程间通信](09-deadlock-ipc.md) 13 | * [文件系统](10-filesystem.md) 14 | * [I/O子系统](11-io.md) 15 | * [其他](others.md) 16 | * [QQ群精彩答疑](QQTalk.md) 17 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # 操作系统课程问答 2 | 3 | 如果有问题,请mail: xuyongjiande@gmail.com 4 | 5 | * [工具使用](00-tool-manual.md) 6 | * [操作系统介绍](01-intro.md) 7 | * [中断、异常和系统调用](02-interrupt-exception-syscall.md) 8 | * [物理内存管理](03-pmm.md) 9 | * [虚拟内存管理](04-vmm.md) 10 | * [进程、线程管理](05-process-thread.md) 11 | * [CPU调度](06-sched.md) 12 | * [同步](07-sync.md) 13 | * [信号量](08-semaphore.md) 14 | * [死锁和进程间通信](09-deadlock-ipc.md) 15 | * [文件系统](10-filesystem.md) 16 | * [I/O子系统](11-io.md) 17 | * [其他](others.md) 18 | * [QQ群精彩答疑](QQTalk.md) 19 | -------------------------------------------------------------------------------- /08-semaphore.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | 3 | 老师,假设使用管程和条件变量实现,符不符合题目要求利用信号量实现的范畴? 4 | 答: 5 | 从概念上来说,管程与信号量是不同的。通常在题目中会明确指出要求。 6 | 7 | 关于写者优先部分,课间中给出的伪代码为什么要在P(rsem)前P(z) 8 | 我在wiki上找到的伪码不需要这步操作。我觉得P(z)和P(rsem)有重复的感 9 | > 觉,没有必要把……请您解释下~ 10 | > 谢谢! 11 | 答: 12 | 对于写者优先的读者-写者问题的解法的解释: 13 | 对写者优先的实现在William Stallings的第五版教材的表5.5中有一个比较清楚的描述。即把所有可能的情况分成4种情况:1)只有读者;2)只有写者;3)同时有读者和写者,且当前正在读;4)同时有读者和写者,且当前正在写。有了这个分类,再来理解下面的解释会容易一些。 14 | 如果没有信号量z,在下面情况时会有大量的读者等待在信号量rsem上。这种情况是,当前正在进行写操作,随后有大量读者到达。 15 | 随后写者们完成了最后一个写操作,可以进行读操作了。于是所有等待在信号量rsem上的读者开始逐一获得信号量rsem,然后申请信号量x,检查自己是否是第一个读者,确认不是第一个后开始读操作。如果这时的读者的数目很多,这个过程需要一定的时间。 16 | 设想这时又有一个写者到达,它就没有办法赶在正在逐一申请信号量x的读者前面进行写操作了。 17 | 如果这时有信号量z的作用,这个写者就可以在第一时间挡住正在获得信号量rsem的读者,最大限度地实现写者优先。 18 | 19 | 20 | 21 | ##Ucore实验相关 22 | 23 | -------------------------------------------------------------------------------- /07-sync.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | 3 | 在第九讲ppt的P42页中提到了一种用非spin lock解决互斥方案,他用一个queue记录了所有正在等待锁的进程(具体伪码如下)。可是感觉这个方案实现的时候好像有点问题: 4 | class Lock { 5 | int value = 0; 6 | WaitQueue q; 7 | } 8 | Lock::Acquire() { 9 | while (test-and-set(value)) { 10 | add this TCB to wait queue q; (注意这一句!!!) 11 | schedule(); 12 | } 13 | } 14 | Lock::Release() { 15 | value = 0; 16 | remove one thread t from q; 17 | wakeup(t); 18 | } 19 | 由于queue是一个共享的变量,所以我标出的那一句应该仍然需要是一个原子操作,而将一个元素加入queue中显然是不能用一条指令完成的,所以这个时候就需要为这句话再加上一个互斥锁。也就是为了实现一个互斥锁,我们要用另外一个互斥锁,这样的话不就会无穷递归下去了吗? 20 | 不知道是不是哪儿想的有问题,希望大家指正! 21 | 答: 22 | 在single-cpu下,Lock::Acquire()和Lock::Release()放在Kernel下做吧 23 | 我觉得把 24 | Lock::Acquire() { 25 | while (test-and-set(value)) { 26 | add this TCB to wait queue q; 27 | schedule(); 28 | } 29 | } 30 | 改成 31 | Lock::Acquire() { 32 | if (test-and-set(value)) { 33 | add this TCB to wait queue q; 34 | schedule(); 35 | } 36 | } 37 | 就可以了吧。 38 | 39 | 40 | ##Ucore实验相关 41 | 42 | -------------------------------------------------------------------------------- /04-vmm.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | ##Ucore实验相关 3 | 4 | I am tring to do the first part of lab3. 5 | Checking the content of memory by the internal debug command, I know i have copy the the right code and date into the memory. So I set the breakpoint at the last instrucion of the func env_pop_tf, and step to the next the instruction. The bochs debugger told me cpu has get the first instruction of the app, then I try to run next instruction again. the eip suddenly changed to a strange value, it seems jump back to the first instruction of BIOS. Did anynoe know this problem? 6 | attachment: I didn't touch the func idt_init(), i don't know whether that can cause the phenomeon. 7 | 答: 8 | I had the same experience as you before. 9 | In my case, the app code, CR3, the stack, and CS:EIP were all initialized correctly (confirmed with bochs debugger). But when the first instruction was being executed, a general protection exception happened and therefore the system rebooted. 10 | I spent a lot of time on it and finally found out that I didn't grant PTE_U permission to a new page directory entry, created within pgdir_walk() of pmap.c, as I remember. 11 | This bug shows up only when in user-mode. For the previous lab, it just doesn't matter. 12 | You may have a different bug. But if the app initialization is indeed correct, it is very possibly permission-related, too. 13 | You may try first to run the app in kernel mode by temporarily changing CPLs of CS & SS to 0. 14 | Paul 15 | -------------------------------------------------------------------------------- /05-process-thread.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | 3 | 是否一般认为fork后父子进程的先后执行顺序是不确定的,vfork出来的子进程必定先于父进程执行? 4 | 答: 5 | fork后父子进程的先后执行顺序是不确定的。 6 | vfork后父进程会等子进程结束或调用exec()。 7 | 详细描述参见: 8 | http://www.google.com/url?sa=D&q=http://en.wikipedia.org/wiki/Fork_%2528operating_system%2529&usg=AFQjCNGPk2EeS_rM888sdYOXTiO081-DBg 9 | 10 | 【无文件系统的情况下能起一个进程吗?】 11 | 答: 12 | 可以。 13 | 所谓文件系统,无非是把一个永久的外部存储阵列抽象成文件树的形式。这个概念应该是和进程独立的。 14 | 即,操作系统要创建进程,有多种途径,可以不用文件系统。 15 | 1. 类似多线程,直接以一个函数为入口建立进程。 16 | 2. fork直接从已有的进程建立。 17 | 等等。。 18 | 当然,上面都是举出特别的例子来说明这个问题。 19 | 实际还是从文件读二进制到内存中在建立进程比较方便。 20 | 21 | 22 | 23 | ##Ucore实验相关 24 | 【lab4文档问题】 25 | 各位老师同学: 26 | 在做lab4的时候发现文档中的一个问题,其中两次谈到priority>1,由于priority为整数,因此等价于priority>=2(不考虑机器表示¬)。按照priority>=2,bigstride理应为0xffffffff。我一开始就是这样做的,结果调试的时候才发现是由于priority取1导致¬的错误。 27 | 在此提醒一下各位同学,也希望助教能够修订一下,谢谢! 28 | 程芃祺 29 | 【lab4的问题】 30 | 老师您好: 31 | 问一个关于lab4的问题,为什么我lab4完成之后make grade的时候primer总是wrong的,但是我单独运行primer的时候却没有问题呢? 32 | -- 33 | 付心仪 34 | 答: 35 | 看 grade.sh 里面,primer 应该输出的是1000个左右素数。 36 | grade.sh 只测试了部分素数以及部分输出。你确定你的单独运行的输出里面,他测试的地方都存在就好了。 37 | 【lab4文档】 38 | lab4的文档上说“running的进程不会放在run-queue中”,但后面又说“所有从running态变成其他状态的进程都要出run-queue,¬反之被放入某个run-queue中”,怎么感觉两者有矛盾…… 39 | 答: 40 | 你说的是lab4的实验文档吗?还是oslab-chap4.pdf文档? 41 | "所有从running态变成其他状态的进程都要出run-queue,反之被放入某个run-queue中"这句话有误。 42 | 我的理解是: 43 | 1 处于就绪态且没有占用CPU执行的进程都被放到run-queue中。 44 | 2 如果run-queue中的某进程被schedule函数选择做为下一个占用CPU运行的进程,则此进程将从run-queue中去掉。 45 | 3 占用CPU运行的进程其实其proc->state还是PROC_RUNNABLE,只是它不在run-queue中。 46 | 4 占用CPU运行的进程如果自愿放弃CPU(sys_yield)or 时间片到了(RR调度算法设计),则会重新放放入到run-queue中。 47 | 5 占用CPU运行的进程如果由于等待某资源(比如空闲内存)或事件(定时器),则会挂到等待队列或timer_list定时器队列中,对应的proc->stat¬e会是PROC_SLEEPING。一旦资源或事件得到满足,其proc->state会变成PROC_RUNNABLE,并重新放放入到run-queue中¬。 48 | 49 | -------------------------------------------------------------------------------- /03-pmm.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | 3 | Q1: 除了存储进程的trapframe,内核堆栈还有什么用呢? 4 | 我看进程拷贝的时候只拷贝了trapframe,并没有拷贝整个内核堆栈 5 | 6 | A1: 7 | 堆栈是两个东西,heap 和 stack. 8 | Stack是用来维护execution flow. stack存储了一些临时数据,包括 local data and return address. 9 | Kernel stack 就是在kernel mode 下的 stack, 也一样包括了 local data and return 10 | address(包括切换回user mode的). Kernel stack也是用来维护execution flow的,kernel mode 下的execution flow 包括 thread 和 interrupt handler. 11 | 至于是不是每一个thread都需要一个stack, interrupt handler 使用谁的stack, 这个在实现时候都可以按需要考虑。 12 | 肤浅的理解,欢迎纠正 :) 13 | 14 | 哦,我对你的提问的理解是:程序的运行总是需要 stack 的,比如函数 call、局部变量等等,在内核里面也一样,从用户程序进入内核以后,执行内核代码所使用的 stack 就是你在进程创建的时候分配的 stack。其次,在由用户程序进入内核的时候,这个 stack 还有一个作用就是保存当前所有的 寄存器 的值,参见 trapasm.S。当然,从内核回到用户程序,也需要类似的操作。所以,这个 stack 很有用。 15 | 至于你说为什么不拷贝内核堆栈,是指 fork 的时候吧,不拷贝,因为确实是没有用。这个 stack 对于用户程序而言,就是一个临时的东西。 16 | 17 | 可以从下一个进程是否会重用kernel stack来理解fork时拷贝。只要下一个进程不会占用的,就可以不复制。这样,就只有寄存器是必须复制的了,其他的都可以不复制。 18 | 19 | 20 | Q2: 看到考试上的一些题目问到某个页式管理机制最多一共有多少个页表。 21 | 那如果考虑自映射机制的话,一级页表的其中一个表项指向的是一级页表本身,是否应该在统计的时候减1? 22 | 23 | A2: 24 | 你的理解是正确的。自映射的页表占了两个位置。 25 | 26 | 27 | Q3: 线性地址、物理地址、虚拟地址具体的联系和区别是什么? 28 | 29 | A3: 30 | 这个,看IA32手册吧。 31 | 简单来说 32 | Virtual Address ------ Segment ------> 33 | Linear Address ------ Paging ---------> 34 | Physical Address 35 | 最后Physical Address 即是访问物理内存的地址。 36 | 37 | 38 | ##Ucore实验相关 39 | 40 | Q4: 41 | lab2的ucore的小os的load addr和link addr分别是多少? 42 | 我从kernel.ld得到load addr是0xC0100000,但不知道link addr从哪里得到,需要虚拟地址还是物理地址?希望老师给出答案。 43 | 44 | A4: 45 | ucore 设定了ucore运行中的虚地址空间,具体设置可看 memlayout.h "Virtual memory map: "图 46 | 所以 tools/kernel.ld描述的是 link_addr , link addr是0xC0100000 是一个虚地址,在ucore建立内核用页表时,设定的虚实映射关系是: 47 | phy addr + 0xC0000000 = virtual addr 48 | 但bootloader把OS load到内存,那时还没有启动页表映射,用的是bootloader阶段设置的段模式,其映射关系(bootasm.S最后有段描述符表)是: 49 | linear addr = phy addr = virtual addr 50 | 所以查看 bootloader的实现代码 bootmain::bootmain.c 51 | readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); 52 | p_va=0xC0XXXXXX 53 | 但 ph->p_va & 0xFFFFFF= 0x0XXXXXX 54 | 了所以bootloader load OS的load addr是0x0XXXXXX, 是物理地址,这个是通过分析bootmain函数的实现得到的。 55 | 简言之: OS的link addr 在tools/kernel.ld中设置好了,是一个虚地址 56 | OS的load addr在bootmain函数中指定了,是一个物理地址 57 | -------------------------------------------------------------------------------- /02-interrupt-exception-syscall.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | 3 | Q1: 4 | 段寄存器的内容是否就是段选择子? 5 | 段选择子中的RPL部分除了在CS的情况下有判断请求特权级的作用之外,对DS、SS等其他段寄存器而言是否有意义? 6 | 7 | A1: 8 | 下面链接很好地解释了DPL、RPL和CPL的含义和关系。 9 | http://hi.baidu.com/ozwarld/item/fa6120471e4d91e7bdf45182 10 | 11 | ##Ucore实验相关 12 | 13 | Q1: 14 | 请问end是在哪里定义的 15 | 16 | 文档说bootloader加载ucore的结束地址放在变量end里面了,但是我grep end都是extern char end[]的declaration,并不是定义。我把所有二进制文件nm了一遍都显示Undefined,但是编译没有错误,求教这个变量是在哪里定义的。。 17 | 18 | A1: 19 | end是由链接脚本tools/kernel.ld定义的,请查看该文件中类似于PROVIDE(xxx = .);这样的行 20 | 21 | lab2里练习5的第一问需要设置Page Fault的中断处理程序,中间需要调用一个叫做pgfault_handler的函数,我看过所有的.h文件里面都没有这个函数。请问助教 22 | 这个函数在哪里,它的原型是什么? 23 | ps.应该不是直接调用do_pgfault函数,这个函数需要Struct mm*作为参数,在中 24 | 断处理过程中是根本无法获得它的 25 | 答: 26 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OS2011/lab2%3Faction%3DAttachFile%26do%3Dget%26target%3Dlab2-20110316-v2.tar.bz2&usg=AFQjCNEgiM0QS1kpMoSzjX6oL-oa70ANQQ 27 | 28 | homework2实验相关第二题:lab2的ucore的小os的load addr和link addr分别是多少? 29 | 我从kernel.ld得到load addr是0xC0100000,但不知道link addr从哪里得到,需要虚拟地址还是物理地址?希望老师给出答案。 30 | 答: 31 | ucore 设定了ucore运行中的虚地址空间,具体设置可看 memlayout.h "Virtual memory map: "图 32 | 所以 tools/kernel.ld描述的是 link_addr , link addr是0xC0100000 是一个虚地址,在ucore建立内核用页表时,设定的虚实映射关系是: 33 | phy addr + 0xC0000000 = virtual addr 34 | 但bootloader把OS load到内存,那时还没有启动页表映射,用的是bootloader阶段设置的段模式,其映射关系(bootasm.S最后有段描述符表)是: 35 | linear addr = phy addr = virtual addr 36 | 所以查看 bootloader的实现代码 bootmain::bootmain.c 37 | readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); 38 | p_va=0xC0XXXXXX 39 | 但 ph->p_va & 0xFFFFFF= 0x0XXXXXX 40 | 了所以bootloader load OS的load addr是0x0XXXXXX, 是物理地址,这个是通过分析bootmain函数的实现得到的。 41 | 简言之: OS的link addr 在tools/kernel.ld中设置好了,是一个虚地址 42 | OS的load addr在bootmain函数中指定了,是一个物理地址 43 | 44 | 陈老师: 45 | > 我在做elf解析那部分的时候发现proj2的ucore.img编译过程中会发生错误。错误是ld 46 | > 生成出来的bootblock..out的大小是560字节超过了510字节...... 47 | > 我想是不是我的编译工具的版本不对还是别的问题。 48 | > 我的环境是Fedora16, gcc 4.6.2 , ld 2.21.53.0.1-6.fc16 49 | > proj1生成的bootblock.out的大小是456字节,如果这个也和标准结果不一样那就很有可能是环境的问题。 50 | > 祝好! 51 | 答: 52 | 这种现象主要是由于GCC照成的。新版本的GCC在生成执行代码时产生了更多的数据,导致bootloader的size超过了510字节。 53 | 建议的解决方法: 54 | 1 在Makfile中增加gcc的编译选项 -Os , 目的是做空间优化,减少生成代码的size。 55 | 2 用老版本的gcc, 比如gcc 4.3等,我记得fedora和ubuntu中也可以安装老版本的gcc软件包 56 | 3 用 virtualbox 57 | http://www.google.com/url?sa=D&q=http://www.virtualbox.org&usg=AFQjCNG4LsAoAEACyWRaH97HSLecwplLew和做好的磁盘镜像 58 | (http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OS2011%3Faction%3DAttachFile%26do%3Dget%26target%3Dlab4student2011.7z&usg=AFQjCNFEu7K1oRwWaDRnP6QeBK-OiFbLKA)。 59 | 磁盘镜像中的ubuntu linux包含了编译和运行labs需要的各种软件。 60 | -------------------------------------------------------------------------------- /01-intro.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | 3 | ##uCore实验相关 4 | 5 | 1 能否不使用提供的虚拟机镜像来完成实验? 6 | 7 | ``` 8 | 可以,只需要uCore的编译环境(编译器系列工具),QEMU(模拟器)就可以编译和运行uCore 9 | ``` 10 | 11 | 2 make qemu或者make qemu-nox之后如何停止? 12 | 13 | ``` 14 | 鼠标点击QEMU窗口的'x'按钮,或者开启新的命令行窗口输入'killall qemu-system-i386' 15 | ``` 16 | 17 | 3 Windows下如何配置uCore实验环境? 18 | 19 | ``` 20 | 可参考一个学生的配置教程[链接](http://pan.baidu.com/s/1i3JxZZR) 21 | ``` 22 | 23 | 4 明明安装了QEMU,却依然报 Couldn't find a working QEMU executable. 24 | 25 | ``` 26 | 大部分时候安装QEMU的可执行文件名叫qemu-system-i386或者其他,而不是叫qemu 27 | 针对这种情况只需要: 28 | 1. which qemu-system-i386 29 | 查看 qemu-system-i386 的完整路径,例如 /usr/bin/qemu-system-i386 30 | 2. ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu 31 | 用刚才查到的qemu-system-i386的绝对路径创建一个软链接 32 | ``` 33 | 34 | 5 之前没用过arm,在配置到android list avd显示 35 | Available Android Virtual Devices: 36 | Name: ucore 37 | Path: /home/lyk423/.android/avd/ucore.avd 38 | Target: Android 4.1.2 (API level 16) 39 | ABI: armeabi-v7a 40 | Skin: WVGA800 41 | 之后执行./uCore_run出现了 42 | AVD not specified. Fetch the first avd from "android list avd" and get "ucore" 43 | emulator: ERROR: Could not load OpenGLES emulation library: libOpenglRender.so: cannot open shared object file: No such file or directory 44 | emulator: WARNING: Could not initialize OpenglES emulation, using software renderer. 45 | 无法启动是什么原因呢? 46 | 47 | ``` 48 | 请检查/bin/sh指向的是哪个shell,如果是dash的话会因为dash不支持某些shell语法导致编出来的image里初始地址不正确,把/bin/sh指向/bin/bash即可。 49 | ``` 50 | 51 | 6 下断点但是程序根本停不下来 52 | 53 | ``` 54 | 我这里是自己原来的Ubuntu 12.04 32bit, 使用 apt-get 直接安装的 qemu,版本为 QEMU emulator version 1.0 (qemu-kvm-1.0),遇到的问题是下0x7c00的断点但是并不能停止而是直接继续启动完了。 55 | 56 | 后来查到相关问题,偶然尝试而解决,方法是在启动 qemu 时加入参数 -no-kvm,可以加到 Makefile 里方便使用。 57 | 58 | 在正常运行的同学那里看到,在用 qemu -monitor stdio 启用 qemu 自己的命令行中使用 info kvm 可以看到默认为禁用的,但是我这里默认为启用。 59 | 60 | 默认设置为什么不一样,原因不明…… kvm 支持为什么会造成断点失效,原因不明……解决方法仅供参考~ 61 | ``` 62 | 63 | 7 64 | 我在做elf解析那部分的时候发现proj2的ucore.img编译过程中会发生错误。错误是ld 65 | 生成出来的bootblock..out的大小是560字节超过了510字节...... 66 | 我想是不是我的编译工具的版本不对还是别的问题。 67 | 我的环境是Fedora16, gcc 4.6.2 , ld 2.21.53.0.1-6.fc16 68 | proj1生成的bootblock.out的大小是456字节,如果这个也和标准结果不一样那就很有可能是环境的问题。 69 | 70 | ``` 71 | 这种现象主要是由于GCC照成的。新版本的GCC在生成执行代码时产生了更多的数据,导致bootloader的size超过了510字节。 72 | 建议的解决方法: 73 | 1 在Makfile中增加gcc的编译选项 -Os , 目的是做空间优化,减少生成代码的size。 74 | 2 用老版本的gcc, 比如gcc 4.3等,我记得fedora和ubuntu中也可以安装老版本的gcc软件包 75 | 3 用 virtualbox 和做好的磁盘镜像, 磁盘镜像中的ubuntu linux包含了编译和运行labs需要的各种软件。 76 | ``` 77 | 78 | 8 79 | 操作系统课程的实验部分有时候需要汇编语言的知识。然后有些语法一时很难查到具体什么意思。不知到有没专门此类介绍汇编语言语法的网站呢?或者说还是先略过这些实验然后先对操­作系统有一个大致的了解(比如看后续的课件)? 80 | 81 | ``` 82 | OS实验用的是GNU AS 汇编器和GNU CC内联汇编技术,相关文档如下: 83 | X86的指令集详细文档,可查到所有的X86汇编:ia32-instrset.pdf 84 | http://www.bytelabs.org/pub/ct/arch/intel/ia32-instrset.pdf 85 | 是所有的机器指令说明文档。此目录下的另外两个文档对理解x86硬件工作模式和硬件系统系编程很有帮助。 86 | 中文介绍文档:Linux 中 x86 的内联汇编 87 | http://www.ibm.com/developerworks/cn/linux/sdk/assemble/inline/index.html 88 | 英文GNU汇编专业电子书,掌握此书,将是汇编绝对高手 89 | 《Professional Assembly Language》英文版 ,作者 Richard Blum 90 | http://forum.eviloctal.com/thread-31189-1-4.html 91 | 另外可以通过 google等搜索 "GNU" "Assembly" 或 “GNU” “汇编”等查找相关信息 92 | ``` 93 | 94 | -------------------------------------------------------------------------------- /09-deadlock-ipc.md: -------------------------------------------------------------------------------- 1 | ##基础知识 2 | ##Ucore实验相关 3 | 4 | lab5中我用make build-sem_wf(以及cdt_pc),然后make qemu,发现程序输出完全正确(多次尝试也正确,只不过有时顺序会稍有不同),但是make grade时却报错,提示缺少很多输出error: missing ......,不知这可能是什么原因? 5 | 而且有时候并没有改程序,只不过跑两次make grade,结果却不一样…… 6 | 希望老师或助教解答一下,谢谢。 7 | 答: 8 | “error:> missing ....”的问题是因为现在的makegrade会存在执行顺序的检查,而一旦顺序不同就会报错。 9 | 我在实验报告中说明了不同的机器上由于使用的qemu版本的不同或者虚拟机配置的不同,可能造成的运行结果可能会不同,这也是为什么我在实验报告中增加了一些实¬验结果的原因。 10 | 现在的makegrade是在我的虚拟机上测试通过的(也就是最终给大家计算成绩的机器),而且在最后计算成绩的时候,我也会重新检查makegrade出问题¬的同学。所以如果大家在makegrade时测试的结果出了问题,也不用紧张,可以检查一下自己的结果,如果确信结果正确可以直接提交。 11 | 【lab5的问题】 12 | 什么情况下exit函数中的schedule函数会返回,导致panic("zombie exit")? 13 | 我的程序在执行完大概六七个子进程后会panic("zombie exit"),不知道什么原因。 14 | 15 | 答: 16 | 我个人理解是变成zombie状态的进程应该不能占用CPU执行了。如果zombie状态的进程执行完schedule函数后,还能够占用CPU,则会执行到p¬anic("zombie exit") 这条语句。这是一种错误,所以系统报错。 17 | 你是如何导致这种现象出现的?很有意思!希望能够在里的实验报告中详细说明此事。 18 | ---------------------------------------------------------------------------------------------------------------------------- 19 | 【Implement of lib/fork.c】 20 | hi,everyone~ 21 | i have a question about the implemention of lib/fork.c. 22 | the comment says we should remap the page above the UTOP with the perm of COW is proper to use the sys_page_map to implement the lib routine? 23 | as far as i know, the sys_page_map must chech the perm parameter. 24 | // perm -- PTE_U | PTE_P must be set, PTE_AVAIL | PTE_W may or may not be set, 25 | // but no other bits may be set. 26 | i think it says the COW mark could not be set, shen use the sys_page_map to map the parent's address space into child's address space. 27 | so, how could I fix the makrs int the pte? 28 | 29 | 答: 30 | PTE_COW is one bit of PTE_AVAIL. And your 'above' should be 'below', I 31 | suppose. 32 | 【关于SLUB的参考资料】 33 | 下面链接有几个关于SLUB的文档可参考。 34 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OS2012/lab2%23head-3ca8e9d38a1d7519e114ce05d9d71b1aa4495079&usg=AFQjCNHC93RKzLX0kTkoFafikNwJ12wBNA 35 | --向勇 36 | 【address order first-fit 算法】 37 | 根据题目要求和default_pmm.c:default_check的assert序列要求,似乎是要实现address order first-fit算法. 38 | 这个算法需要保持地址有序,每次分配都从最低地址拿一个符合要求的block 39 | 但line146 assert((p0 = alloc_page()) == p2 + 1);好像不对啊 40 | 125 list_entry_t free_list_store = free_list; 41 | 126 list_init(&free_list); 42 | 127 assert(list_empty(&free_list)); 43 | 128 assert(alloc_page() == NULL); 44 | 129 45 | 130 unsigned int nr_free_store = nr_free; 46 | 131 nr_free = 0; 47 | 132 48 | 以上建立一个空free_list 49 | 133 free_pages(p0 + 2, 3); 50 | 此时前五页为 51 | | 0 | 0 | 1 | 1 | 1 | 52 | 1=空,0=占用 53 | 134 assert(alloc_pages(4) == NULL); 54 | 135 assert(PageProperty(p0 + 2) && p0[2].property == 3); 55 | 136 assert((p1 = alloc_pages(3)) != NULL); 56 | 此时前五页为 57 | | 0 | 0 | 0 | 0 | 0 | 58 | | | 59 | p0 p1 60 | 137 assert(alloc_page() == NULL); 61 | 138 assert(p0 + 2 == p1); 62 | 139 63 | 140 p2 = p0 + 1; 64 | 141 free_page(p0); 65 | | 1 | 0 | 0 | 0 | 0 | 66 | | | | 67 | p0 p2 p1 68 | 142 free_pages(p1, 3); 69 | | 1 | 0 | 1 | 1 | 1 | 70 | | | | 71 | p0 p2 p1 72 | 143 assert(PageProperty(p0) && p0->property == 1); 73 | 144 assert(PageProperty(p1) && p1->property == 3); 74 | 145 75 | 146 assert((p0 = alloc_page()) == p2 + 1); 76 | line146 buggy? 77 | 按照first-fit,p0即第一个单元以空,地址最低 78 | 此时alloc_page()用第一个Page即可 79 | p0==p2-1,不应该是p2 + 1吧 80 | 难道我理解错了? 81 | 答: 82 | 你的分析是对的。 83 | 我会尽快更新代码,并放到wiki和网络学堂上。 84 | 谢谢! 85 | 【first/best/worst fit算法问题】 86 | 前面的和cyh同学的分析一样了。 87 | 在assert((p0 = alloc_page()) == p2 - 1);之前,有 88 | p2 = p0 + 1; 89 | free_page(p0); 90 | free_pages(p1, 3); 91 | 这样三行代码,在free的过程中,由原来的(1表示占用,0表示空余)。 92 | 1 1 1 1 1 93 | p0 p2 p1 94 | 变成了 95 | 0 1 0 0 0 96 | p0 p2 p1 97 | 我想问的是,在free的时候,四块空的会不会combine成一块?free_list是双向的(环形),如果在free的时候进行combine, 那么p1位置的三块是不是会与p0的那块合并成一块? 98 | 如果是这样的话,那么在assert((p0 = alloc_page()) == p2 - 1);的时候,p0应该是位于如下所标示的位置吧?这样的话应该是p0 = p2 + 1吧。 99 | 0 1 0 0 0 100 | p2 p1 101 | p0 102 | 请老师指导。 103 | 答: 104 | 注意,我记得我课堂上说过是first/best/worst fit算法是用于分配和回收地址连续的空闲内存块。 105 | p1位置的三块与前面p0的那块无法合并成一个地址连续的空闲块,所以这样合并貌似与需求不符。 106 | 【空间分配问题】 107 | 请问这个函数的实现是不是有问题阿?无论如何都会报错…… 108 | 具体的实现里面 109 | nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; 110 | 之后会用这个数nu * sizeof(Header)来调用kalloc,这样的话正常情况下都不会是PAGE的倍数阿…… 111 | 或者我理解错了?bow! 112 | 答: 113 | 我今早看到了此email。大家分析很认真,这是值得鼓励的事情! 114 | 我的理解是, malloc的调用关系是: 115 | malloc->morecore->sbrk(user level)->(kernel level)sys_sbrk->growproc->kalloc 116 | malloc传给morecore的是 nunits=(nbytes + sizeof(Header) - 1)/sizeof(Header) + 1 117 | morecore传给sbrk的是 if nunits<4096 then 4096 * sizeof(Header) else nunits* sizeof(Header) 118 | 设定此参数为 n,且一定>=4KB 119 | sbrk->sys_brk->growproc->kmalloc的值没有调整,都为n 120 | 关键是kmalloc如何处理的: 121 | .... 122 | nr = n / PAGE; 123 | p = __alloc_pages(nr); 124 | ...... 125 | 这保证了分配的空间一定是page的倍数。但由于 morecore只用到了n,所以没有充分利用kmalloc分配的空间,但不会有错。 126 | 【list_entry_t问题】 127 | 有人不知道 list_entry_t 是干什么的,不知道文档里面是不是解释了。 128 | 这个是 linux kernel 里面的实现,实现的漂亮。 129 | 所有的 le2xxx 实际上都是 macro,调用的 list.h 里面的 to_struct,也是宏。读懂它就知道这个双向链表是怎么实现的了。 130 | 其实就是计算包含某个 list_entry_t 成员变量的数据结构里面该变量的偏移量,从而利用该 list_entry_t 的地址得到数据结构的起始地址,再强制类型转换成相应数据结构的指针。÷ 131 | 【代码调试问题】 132 | 各位老师同学: 133 | 请问大家是如何利用gdb调试lab2及以后的程序的?由于entry.S重置了gdt,将内核代码地址设置到3GB以上,从0xc0100000处开始真正的¬kern_init,而gdb却不能正确识别。如果直接用给的gdbinit,会找不到断点,从而一直执行。目前我的办法是b *0x100000,然后经过两次call以后到达真正的kern_init。但是之后设置的断点仍然无法识别,只能单步运行,并且next的执行效果和ste¬p一样了。请问老师有什么办法解决这个问题吗?非常感谢! 134 | 程芃祺 135 | 136 | 答: 137 | 弄反了?内核从 3G 以上地址 link 的。entry.S 设置 gdt 保证内核被加载到低地址的物理内存时候也能工作。 138 | 一种比较难看的方法是,编译两个版本的内核。 139 | 一个是从 0x00100000 开始的,另一个是从 0xc0100000 开始的。调试的时候先用第一个,pmm.c 里面,lgdt 以后,开始用第二个。 140 | 1. 可以这么复制 tools/kernel.ld 比如到,tools/tmp.ld,修改 tmp.ld 里面的 0xC0100000 改成 0x00100000. 141 | 2/ 然后 Makefile 里面的 142 | $(V)$(LD) $(LDFLAGS) -T tools/kernel.ld -o $@ $(KOBJS) 143 | 后面添上一个: 144 | $(V)$(LD) $(LDFLAGS) -T tools/tmp.ld -o bin/tmp $(KOBJS) 145 | 完成实验记得改回来。 146 | ps, 实际上,gdb 只 binary 来识别符号。 147 | 【shared memory的作用】 148 | 那个shared memory是用来记录等待队列的么? 149 | 用count和那个attach可以得到多少读者进程, 如果是写者优先的话呢? 怎么知道有没有写者进程呢? 150 | 谢谢~ 151 | 答: 152 | shared memory 用于记录当前在读的读者的个数。 153 | 【调度策略问题】 154 | 请问,练习1中为什么对sub_sched_class进行了初始化,可是没有对sched_class进行初始化?关于这两个调度策略我不是很明白,是否有人¬可以帮忙解释下,谢谢! 155 | 答: 156 | sub_sched_class用于MLFQ,RR中要不到。 157 | sched_class_RR定义了RR涉及的函数,在pinit中完成了对一个rq的sched_class的设置。 158 | 这是我理解的初始化。 159 | -------------------------------------------------------------------------------- /00-tool-manual.md: -------------------------------------------------------------------------------- 1 | # 操作系统课需要的各种软件的使用方便 2 | 3 | 参考文献:[Building and Running an edX Course](http://edx-partner-course-staff.readthedocs.org/en/latest/creating_content/index.html) 4 | 5 | ## 学堂在线平台的课程维护 6 | 7 | ### 学堂在线平台上新加视频课程的方法 8 | 先上传字幕,再上传视频文件,经过转码后,以上可以看到有字幕的视频了。下面具体操作步骤。 9 | 10 | #### 助教上传字幕 11 | 1. 登录studio.xuetangx.com网站,进入操作系统课 12 | 1. 点击“内容”菜单,选择“文件上传及管理”,打开"文件上传及管理"页面 13 | 1. 点击右上角的“上传新文件”按钮,选择要上传的字幕srt文件(可多选)。 14 | * 必须保证srt文件是UTF-8编码的,如果不是,可使用notepad++、geany等工具转换为UTF-8编码。 15 | 1. 上传后应记住字幕文件的URL,如/c4x/TsinghuaX/30240243X/asset/lab0-1.srt等。 16 | 17 | #### 助教上传视频 18 | 1. 点击“内容”菜单,选择“大纲”,进入"课程大纲"页面 19 | 1. 展开需要添加视频的章节,点击“添加新单元” 20 | 1. 将“显示名称”文本框中的内容改为“视频”(或其它便于学生理解的文字) 21 | 1. 在添加新组件提示的下方选择“视频”按钮,并在出现的菜单中选择“默认”,几秒钟后页面加载出视频播放器; 22 | 1. 在播放器的右上方点击“编辑”按钮,在弹出的对话框中右上角点击“设置”按钮,这时会出现四个文本框,分别为“显示名称”、“视频地址”、“视频字幕(中文)”、“视频字幕(英文)” 23 | 1. 在“视频地址”右侧点击上传视频按钮,浏览器会打开一个新的“上传视频”页面; 24 | 1. 在“上传视频”页面中点击“浏览”按钮,选择要上传的视频文件 25 | 1. 然后点击“上传”按钮,等待页面中部的进度条从灰色的0%慢慢变成绿色的100%,这里上传速度比较慢,100M的视频大约需要15~20分钟; 26 | 1. 当上传进度到100%时,关闭“上传视频”页面,回到原页面,可以发现“视频地址”文本框已经自动填写了视频的URL; 27 | 1. 在“视频字幕(中文)”填写上一步中记下的字幕的URL,点击“保存”按钮。此时可以看到页面中黑色的视频播放器(或显示“正在转码”)。注意,这一步中的“保存”操作可以在上传进展没有达到100%前进行,并还会影响上传过程的继续进行。 28 | 1. 在右上方“单元设置”栏的“是否公开”下拉框中选择“公开”。 29 | 2. 在学生(或工作人员)界面中等待和检查网站转码是否正常完成(约1~2分钟)。出现过转码几个小时也不结束的情况,这时需要重新上传视频文件。 30 | 3. 在学生(或工作人员)界面中检查视频与字幕是否正常播放。至此,整个视频添加完毕。 31 | 32 | #### 由学堂在线技术人员上传视频和字幕文件的方法 33 | 1. 制作方完成视频文件、字幕文件和文件的MD5校验和生成,然后通知任课教师; 34 | 1. 任课教师确认视频文件和字幕合格后,共享相应的360云盘目录; 35 | * 如: http://yunpan.cn/cmNj7HmZYvHmf (提取码:59c5) 36 | 1. 学堂在线技术人员从360云盘下载所有文件到学堂在线后台存储,确认MD5是正确的,并把所有文件的CCID信息回复给任课教师; 37 | * 如: {{{C4ABEF86BB881D099C33DC5901307461 操作系统-第5周-lecture09(7-1)V2.0.mp4}}} 38 | 1. 任课教师安排助教更新课程页面的视频和字幕显示,并确认播放无异常。 39 | 40 | #### 视频上传问题:我在页面中看到的是,100%完成上传。用户如何能知道上传不成功? 41 | 42 | 这个目前还没有好的办法。视频转码一般需要30min-1个小时,如果同时上传的视频很多,可能会再慢一些,要是等了4、5个小时还没有转码完成,估计就是视频没有传上去了。要后台可以查看视频的source id,然后到CC的视频列表里查询id是否有对应视频。目前在进行转码前能判断还不能判断是否成功。 43 | 44 | ### 上传和设置练习题的方法 45 | 1. 上传练习题 46 | 2. 设置练习题分数 47 | * 每个小题一分;有多少个题,这次练习就是多少分;课堂思考题也一样处理。最后学期结束时,所有练习的分数加到一起,加权成10分。 48 | 3. 设置练习题截止时间 49 | * 建议前几周作业的截止日期宽限一些,给后加入课程的人机会。所有练习的完成时间是公开后一周,实验报告是公开后10天。前4周的截止时间不早于开课后30天。 50 | 51 | ### 已公开练习题的修改方法 52 | 1. 进入学堂在线系统后台的“课程大纲”页面 53 | 2. 找到需要修改的“练习”单元,点击“练习题”进入单元“单元”页面 54 | 3. 点击页面右侧的“编辑草稿”,进入“编辑草稿”页面 55 | 4. 点击需要修改的单元题的“编辑”后,进入“编辑”页面 56 | 5. 进行修改,完成后点击“保存”后,回到“编辑草稿”页面 57 | 6. 点击页面右侧的“使用本草稿进行替换”就完成修改了### 已公开练习题的修改方法 58 | 59 | ### piazza讨论区以及互评题的添加(相关文档已上传至wiki附件) 60 | 1. [wiki上传附件地址](http://os.cs.tsinghua.edu.cn/oscourse/OsMooc2014#head-03e8ce3bdd8cdcc4a45e0366dad6a0ee43f3ade0) 61 | * piazza讨论区的添加方法 62 | * 互评区相关操作帮助 63 | 64 | ## 学堂在线平台的使用 65 | 66 | ## 清华网络学堂(新版) 67 | 68 | ### 视频上传 69 | 1. 对于每一讲首先添加标题:点击红色的“维护课程结构”,鼠标悬停至“MOOC视频”,点击右边绿色加号,填写本讲标题等信息后确定,并关闭“维护课程结构”窗口。 70 | 2. **此时界面会变空白,刷新之后出现新添加的一讲标题。** 71 | 3. 对于每一个视频,点击所属第几讲下面的红色“新增文件”,资源类型“教学录像”,标题对应填写,最下面选择上传文件。 72 | 4. **等待上传文件完成后,**点击确定关闭窗口。 73 | 5. (“课程管理”->“学生界面浏览”可以确认效果。上传完成后学生不会立即看到视频,网络学堂需要几分钟进行转码。) 74 | 75 | ## 较少依赖VPN访问IBM超能云上“操作系统在线练习和实验环境”的方法 76 | 77 | 背景:由于此前用于访问IBM超能云(supervessel)的VPN很不稳定,在IBM中国研究院的大力支持下,我们完成了这个可较依赖VPN访问IBM超能云上操作系统课实验docker的方法,以方便学习操作系统课的同学们在IBM超能云上“操作系统在线练习和实验环境”。在这个环境中,可在线完成操作系统课的练习、用docker做ucore实验、浏览和编辑ucore代码,以及搜索piazza讨论区的历史记录。 78 | 79 | ### 1. 注册学堂在线,并选修操作系统课; 80 | 1. 学堂在线注册链接 http://www.xuetangx.com/ 81 | 1. 注册成功的标志是,页面右上角第二行的图标是你自己的图标。 82 | 1. 如果你是通过QQ等第三方登录学堂在线,请先绑定邮箱,并设置自己的学堂在线用户名(否则在内部平台的登录名将为随机字符串)。建议用户名请勿包含特殊字符。 83 | 1. 查找“操作系统(2016春)”课程,并选修该课程。 84 | 1. 选修成功的标志是,访问链接 http://www.xuetangx.com/courses/course-v1:TsinghuaX+30240243X+2016_T1/courseware/14def9edc58e4936abd418333f899836/ 可以看到第一行的“TsinghuaX: 30240243X 操作系统 (2016春)”。 85 | 86 | ### 2. 注册或关联操作系统课的piazza讨论区 87 | 1. 访问下面链接 http://www.xuetangx.com/courses/course-v1:TsinghuaX+30240243X+2016_T1/courseware/14def9edc58e4936abd418333f899836/a99db084082345c1875ca1d963c42f38/ 并点击”在新窗口中查看资源”即可访问此课程在piazza中的交流平台。 88 | 2. 第一次使用的用户需要填写邮箱(要求使用学堂在线注册的邮箱,不要求一定是清华大学的邮箱)及密码(已注册过Piazza的用户不用输入密码)进行注册。建议设置用户名为实名加学号,例如“张三2010011234”。在此过程中需要输入操作系统课号“30240243x”和年份编号“2015”。 89 | 3. 注册或关联成功的标志是,访问链接 https://piazza.com/tsinghua.edu.cn/spring2015/30240243x/home 可以看到第二行的“Tsinghua University - Spring 2015”和第三行的“30240243X: Principles of Operating Systems”,并且右上角是你自己的用户名。 90 | 91 | ### 3. 访问学堂在线网站,完成IBM超能云上访问“操作系统在线练习和实验环境”需要的用户注册。 92 | 93 | 1. 在学堂在线注册学习操作系统课后,就可以访问链接 http://www.xuetangx.com/courses/course-v1:TsinghuaX+30240243X+2016_T1/courseware/14def9edc58e4936abd418333f899836/37afa0e088164343aab65b4d077fb372/2 获取进行IBM超能云上的用户注册工作。 94 | 2. “实验账号初始化”操作会随网络系统负载情况,等待几十秒到几分钟不等。操作完成后会看到类似如下显示的信息。“supernova account”是在IBM超能云上的注册邮箱,在获取VPN账号时会用到,这个邮箱必须是你在学堂在线上的注册邮箱;在IBM超能云上的注册过程中包括一个邮件激活的操作,可能出现没有收到激活邮件等问题,可以不理它,这不会影响openedx和docker的访问。在“shibboleth account”是访问IBM超能云上的openedx、gitlab和docker的用户名;“password”是访问IBM超能云上所有服务所需要的密码。请妥善保存这三个信息。 95 | 96 | IBM supernova account: 97 | 98 | xxxxxx@qq.com 99 | 100 | shibboleth account(for edx and gitlab): 101 | 102 | ea23cbdac0xxxxxxxxxx 103 | 104 | password: 105 | 106 | 18IFxxxx 107 | 108 | 109 | ### 4. 初始化IBM超能云上“操作系统在线练习和实验环境”设置,并登录并访问IBM超能云上的openedx系统 110 | 111 | 1. 访问IBM超能云上的“内部实验平台测试课程”链接 http://crl.ptopenlab.com:8811/courses/edX/DemoX/Demo_Course/about ,并点击“登录”后会跳转到如下shibboleth登录界面 https://crl.ptopenlab.com:8800/idp/Authn/UserPassword 。这一步有些鬼异,目的是绕到shibboleth的登录界面,对“操作系统在线练习和实验环境”中的openedx进行初始化。输入你在前面步骤中得到的“shibboleth account”和“password”。 112 | 2. 登录openedx系统并初始化成功的标志是,登录后的页面右上角有你的“shibboleth account”信息。这时你能链接 http://crl.ptopenlab.com:8811/courses/Tsinghua/CS101/2015_T1/courseware/65a2e6de0e7f4ec8a261df82683a2fc3/ ,并看到“Tsinghua: CS101 操作系统内核实验”中的操作系统课实验和练习页面。 113 | 3. 登录之后需要补充用户名(请与给出的shibboleth账号保持一致)。 114 | 115 | ### 5. 配置访问IBM超能云内部网络的VPN,并初始化gitlab上的ucore基准代码(只有这一步依赖VPN) 116 | 1. 访问链接 http://www.xuetangx.com/courses/course-v1:TsinghuaX+30240243X+2016_T1/courseware/14def9edc58e4936abd418333f899836/37afa0e088164343aab65b4d077fb372/1 ,获取配置VPN所需要需要的账号和密码信息。 117 | 1. 参见帮助 https://services.ptopenlab.com/mediawiki/index.php/VPN%E7%9A%84%E4%BD%BF%E7%94%A8 设置访问IBM超能云内部网络的VPN。 118 | 1. VPN连接成功的标志是,命令“ping 172.16.13.236”确认能连gitlab服务器。 119 | 1. 访问gitlab服务器的登录页面 http://172.16.13.236/users/sign_in ,点击“Shibboleth”按钮,页面会跳转到shibboleth的登录页面,输入你在前面步骤中得到的“shibboleth account”和“password”。 120 | 1. gitlab初始化成功的标志是,浏览器页面自动到你的gitlab主页,页面左下角有你的用户名。 121 | 122 | ### 6. 在IBM超能云上的openedx系统中创建自己的操作系统课实验docker 123 | 124 | 访问下面链接,并阅读关于docker和gitlab的使用帮助。 125 | 126 | http://crl.ptopenlab.com:8811/courses/Tsinghua/CS101/2015_T1/courseware/65a2e6de0e7f4ec8a261df82683a2fc3/7be9a21ca62e4f5d8325d27b66a0c9bf/1 127 | 128 | 然后访问下面链接,点击“Create Docker”创建自己的操作系统课实验docker。 129 | 130 | http://crl.ptopenlab.com:8811/courses/Tsinghua/CS101/2015_T1/courseware/65a2e6de0e7f4ec8a261df82683a2fc3/7be9a21ca62e4f5d8325d27b66a0c9bf/2 131 | 132 | 创建成功后,你就会在“DockersList”列表中看到自己的docker信息。 133 | 134 | 由于docker创建和初始化的过程有些慢或多个用户同时进行docker创建,可能出现“看不到创建的docker”或“较长时间没有反应”的情况。这个过程通常会在3-4分钟的时间。4分钟以上可能会失去响应,这时可手动刷新浏览器页面或再次点击“Create Docker”。 135 | 136 | 刷新docker状态,不会导致重复创建。重复点击创建只会刷新页面,而且只是读状态,响应应该比刷新页面快。 137 | 138 | ### 7. 访问自己的操作系统课实验docker 139 | 140 | 点击docker创建页面上的“Webshell”,跳转到类似如下链接的docker的web shell页面。 141 | 142 | https://crl.ptopenlab.com:8800/webshell/vzuFSEpyxxxxxxxx/ 143 | 144 | 输入自己的“shibboleth account”和“password”,即可进入字符界面的实验环境。 145 | 146 | 注意:每个docker只有创建者和管理员可以访问。 147 | 148 | 至此,所有注册和初始化工作全部完成。 149 | 150 | ### 8. 确认所有注册和初始化工作完成 151 | 152 | 成功标志是,可以直接在浏览器中访问下面链接来访问IBM超能云上“操作系统在线练习和实验环境”中的各种功能。 153 | 1. 创建和访问docker: http://crl.ptopenlab.com:8811/courses/Tsinghua/CS101/2015_T1/courseware/65a2e6de0e7f4ec8a261df82683a2fc3/7be9a21ca62e4f5d8325d27b66a0c9bf/2 154 | 2. ucore实验代码浏览和编辑: http://crl.ptopenlab.com:8811/courses/Tsinghua/CS101/2015_T1/courseware/65a2e6de0e7f4ec8a261df82683a2fc3/400f7c812c254b799e66194d24b297ae/ 155 | 3. 搜索piazza上的历史记录: http://crl.ptopenlab.com:8811/courses/Tsinghua/CS101/2015_T1/courseware/65a2e6de0e7f4ec8a261df82683a2fc3/896b56b6156047869eecd8b519852558/ 156 | 4. 完成在线练习题: http://crl.ptopenlab.com:8811/courses/Tsinghua/CS101/2015_T1/courseware/65a2e6de0e7f4ec8a261df82683a2fc3/73a7712ec5084f7598c97c129ba9ff52/1 157 | -------------------------------------------------------------------------------- /QQTalk.md: -------------------------------------------------------------------------------- 1 | # QQ群聊天记录精选(请勿转载) 2 | 3 | ## 20141016QA 4 | 5 | A:同学在实验中碰到的问题,由于我们目前还缺少直接连接到同学实验环境的手段,所以目前想到的方法是请做实验的同学能够在github上fork mooc os lab, 建立自己的git repo(通过github网站可很容易完成)。然后把出现的问题直接写到github上对应实验的目录下。比如完成了lab1,把lab1合并到lab2代码中,然后完成lab2的过程出了错误,需要帮助,则可以在lab2下写一个文档test_err.txt,内容是你碰到的问题,把输出也写出来,你的困惑等。我们的助教会争取在同一个目录下写test_err_feedback.txt;说明我们的想法,对问题的理解,以及可能的修改等,这需要请各位把我们的助教的id加为你的git repo的contributor。目前,可以尝试加入chyyuu objectkuan xuyongjiande。我们的email是 yuchen@tsinghua.edu.cn ,xuyongjiande@gmail.com ,objectkuan@gmail.com 。 6 | 7 | Q:那tss该定义在gdt段里还是ldt段里 8 | 9 | A:Gdt里面 10 | 11 | Q:我定义一个ldt段时 其对应的dpl和rpl有什么意义 12 | 13 | A:ucore实验不用考虑有ldt,tss在gdt中定义了,可以看实验的视频和代码。有讲到。x86的硬件细节比较复杂,为了减少学生学习的负担,我尽量不讲与ucore实验无关或对OS原理等不太必要的细节,否则会成为另外一门课“计算机原理”了。另外,尹治宏(yinzhihong12@msn.com)同学在lab1学习中增加了一个有趣的功能“用键盘实现用户模式内核模式切换”,我已经添加到 https://github.com/chyyuu/mooc_os_lab中,mooc_os_lab 下的 14 | labcodes_answer/lab1_result/下 ,主要修改了trap.c代码,有兴趣的同学可以看看! 15 | 任务切换其实应该到讲进程时才涉及到。慢慢来吧。lab2还有其他挑战。 16 | 17 | Q:default_pmm.c里面default_check通过的话,可以保证default_alloc_pages和default_free_pages正确吗?我的代码可以通过测试,不过和答案里面的差别挺大 18 | 19 | A:通过测试表明测试的那些用例下代码是对的。 20 | 21 | 陈渝老师:在 http://chyyuu.github.io/mooc_os/  和 http://chyyuu.gitbooks.io/mooc_os_info/content/ 上更新了答疑信息,请大家有空看看。希望这样答疑更有效率。 22 | @操作系统公开课的学生 如果没有解决,可以看看试试基于github的实验交互方式?目前已经把代码放到了github上,也把其他大部分资料(音视频不适合,除外)放到github上了,这样大家共享会更加方便。接下来是完善扩展内容。我们也希望和鼓励大家一起完善资料(指出我们的错误,帮助我们增加或改进代码和文档内容),使得我们一起进步。多谢! 23 | 24 | ## 20141018QA 25 | 26 | Q:bootmain系统启动的时候为什么p_va & 0xffffff,为什么要&操作 27 | 28 | A: 这是地址转换操作 29 | http://blog.chinaunix.net/uid-368446-id-2414228.html 30 | lab 1: 从bootloader跳转到内核。 31 | http://geezer.osdevbrasil.net/osd/ram/index.htm 32 | Physical memory layout of the PC 33 | 34 | Q:ucore和日本人写的《30天自制操作系统》有什么差异? 35 | 36 | A:区别很大,基本的操作系统原理都差不多,但是里面内容差的很多;段页式内存管理,虚存管理,用户进程,VFS,文件系统方面ucore深入些,那本书在界面方面很丰富。 37 | 由于有些问题或答案是由图片形式给出的,在聊天记录中没有体现,无法整理,敬请谅解。 38 | 39 | ## 20141025QA 40 | 41 | Q:之前没有计算机编程和计算机原理等方面基础,做实验感觉不知道从何入手。不知道您是否可以给些建议。 42 | 43 | A:如果这样,建议在听课的同时或之前,自己学习一下计算机原理,了解基本的CPU和计算机系统结构,然后就可以看OS原理方面的视屏了。如果要想动手编程,最好再自学C语言(有比较好的网上教学视屏),如果没有学习C语言或基本的数据结构知识,建议不必做实验 44 | 45 | Q:可否推荐一下C语言方面视频或者链接? 46 | 47 | A:google 搜索一下“李明 C语言” 48 | 49 | Q:计算机原理方面,看什么比较好呢 50 | 51 | A:软件硬件接口 csapp 是很好的课。 52 | 易->难或先后顺序: python, tsql, C, 数据结构,计算机原理,OS;tsql不是必须的。 53 | 英语对搞计算机的来说还是很重要的。数据结构可以看清华的学堂在线的邓俊辉老师的课,”计算机组成与设计:硬件/软件接口“和CMU的一本书“深入理解计算机系统”是很不错的计算机原理的书 54 | COLDFIRE:我建议先学C语言,搞懂结构体,链表等,然后数据结构,算法导论,操作系统原理,编译原理 55 | 56 | Q:关于帮助理解硬件方面的那个手册有没有书?Intel方面的 57 | 58 | A:http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html 59 | https://www.coursera.org/course/pkuco 60 | https://www.coursera.org/course/comparch 61 | 62 | Q:老师 x86 mmu是硬件实现的(记得课程有说)mips 是软件? 那 arm也是软件? 63 | 64 | A:MMU都是硬件实现的,只是MMU中的TLB单元产生了TLB项缺失的时候,是硬件自动完成从页表到TLB的拷贝,还是硬件产生中断,由软件来完成这个拷贝工作。这是两种选择。x86, arm是第一种选择;mips是第二种选择,这里说的x86, arm, mips都是指的硬件架构,或CPU架构,cpu architecture决定了这个cpu的指令集和功能等。 65 | 计算机领域学习路线图 https://github.com/halida/blog/blob/master/%E8%AE%A1%E7%AE%97%E6%9C%BA%E9%A2%86%E5%9F%9F%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF%E5%9B%BE.rst 66 | arm是架构,mips也是架构,也是指令集 67 | 68 | 陈渝老师:lab3的实验指导书已经更新,大家可以访问  69 | http://objectkuan.gitbooks.io/ucore-docs/ 70 | 答案在:https://github.com/chyyuu/mooc_os_lab/tree/master/labcodes_answer 71 | 如果没有时间做,也可看看是如何具体实现的。 72 | 73 | ## 20141122QA 74 | 75 | Q:context switch的时候线程的状态是不是要保存 76 | 77 | A:是,主要是线程的上下文信息,线程可以看成是进程的一部分(表示进程的控制流),或者是一种特殊的进程(比如linux os) 78 | 79 | Q:那进程间可以切换,线程间可以吗 80 | 81 | A:也可以切换呀。 82 | 83 | Q:关于进程切换代价大,具体是大在哪里呢? 84 | 85 | A:进程切换需要切换页表。处于同一进程内的线程切换不需要切换页表。这会导致TLB中的页表项缓存都失效了,使得内存访问开销大了。 86 | 87 | Q:陈老师还有一个问题,在一个arm平台移植了Linux内核,如何给他构建发行版呢? 88 | 89 | A:我没做过。不过我记得ubuntu, fedora都有arm版本。现在还没有ARM的桌面机或服务器,不过我觉得明年就会有了! 90 | 91 | Q:两个任务,编译任务和视频播放任务,都耗cpu,都有io和睡眠,在cpu超负荷的情况下,调度器肿么保证视频播放的实时性,怎么保证视频不卡。调度器肿么知道对视频播放任务必须要比编译任务好? 92 | 93 | A:如果是linux或其他通用OS,编译任务和视频播放任务都不是实时进程。现在有显卡硬解码,所以视频播放任务基本上耗CPU不大。如果没有类似linux cgroup机制,其实现在的调度器没法保证视频播放的实时性。调度器不知道对视频播放任务必须要比编译任务好。但通过类似linux cgroup机制,可以确保给视频播放任务的CPU占用比率,从而在一定程度上可以保证频播放的实时性。编译任务,比如编译linux kernel的任务,其实算是CPU密集型。现在的linux的O(1), CFS等调度器,在进程没有耗尽cpu的情况下,其实主要基于分时进行调度,且保证一定的公平性,这样一般就够了。 94 | 95 | Q:在PC机上,VMware,Virtual Box这样虚拟化以后可以运行windows,linux 96 | 那在ARM,手机芯片上有没有做这样的软件,虚拟化后跑android的和IOS。(IOS好像不开放,PC上VMware不知道是不是支持) 97 | 98 | A:新一代的ARM CPU支持一定程度的硬件虚拟化,明年arm64用于服务器后,应该可以有这样的能力。 99 | www.rtems.com www.baike.com/wiki/rtems 100 | http://www.sylixos.com/ 101 | 102 | Q:就是作为学生 有必要深入理解makefile么 103 | 104 | A:如果是学os, 不必。或者说非不得已,没必要深入理解makefile。其实你只需看makefile带来的编译过程即可,这是为了你知道一个os是如何编译出来的。至于它如何编写,其实在lab1中没有要求。 105 | 106 | Q:请问"屏障管理"有什么用途? 107 | 108 | A:屏障管理,我理解是 barrier机制,是一种同步手段。 109 | 110 | Q:并行文件系统GPFS设计和普通的文件系统设计有什么不同?需要特定的硬件支持吗? 111 | 112 | A:不同很大呀,一个面向集群系统,一个只是单机系统可以这样实现。比如google fs--GFS也是这么做的,且实现在用户态。 113 | 也有实现在内核态的分布式并行文件系统,比如linux中的ceph,然后进了内核。 114 | 115 | ## 20141203QA 116 | 117 | 陈渝老师:http://os.cs.tsinghua.edu.cn/oscourse/ 有清华历年os课的一些wiki记录 118 | 119 | 向勇老师:http://os.cs.tsinghua.edu.cn/oscourse/OS2013/projects/U12 ,我不确定同学们是否能访问。如果可能,在完成课程的8个基本实验后,仍然有兴趣的同学,可以参与到我们的ucore+完善工作中。 120 | 121 | Q:linux内核的问题。内存管理部分有点各种绕不明白,有个小问题希望大家帮忙... 122 | 在内存管理的初始化阶段,Linux内核使用buddy system替换初始阶段的bootmem分配器,在meminit()实现 123 | 124 | ``` 125 | meminit() 126 | |--->free_unused_memmap_node(node); 127 | |--->free_memmap(node, prev_bank_end, bank_start); 128 | |--->free_bootmem_node(NODE_DATA(node), pg, pgend - pg); 129 | 130 | ``` 131 | 132 | free_unused_memmap_node这个函数搞不懂,看名字大概就是说释放掉未使用的页。我的理解,unused的意思大概也就是说bank与bank之间有些不可用的地址,需要找到这些地址,然后把它从可分配的地址空间中刨除。在操作系统自动为申请内存操作分配页框时,就不会把这些未使用的内存地址分配出去。这个刨除unused地址区域的函数到最后调用的是free_bootmem_node(),让我搞不懂的地方来了,这个函数是将bitmap中相应的页框置0,表示可分配的页。明明这个地址对应的页框未使用,后面又将bitmap中对应的位设置为可分配,是什么原因呢?这些bitmap中设置为0的区域将来应该是要交给buddy system管理的可供分配的内存啊?是我理解有问题么? 133 | 134 | A:我还没有这么深入地分析linux内核。我看到的一本对较新的Linux内核分析比较好的书: Linux内核设计与实现(原书第3版),深入linux内核架构, 较老的有:《Linux内核源代码情景分析》上、下,O'Reilly:深入理解LINUX内核(第3版),最早的linux内核分析:Linux内核设计的艺术:图解Linux操作系统架构设计与实现原理, Linux内核完全剖析,0.11版本内核。不过,我也没有彻底读完和读懂这些书。 135 | 136 | 陈渝老师:我们现在有一个git mirror 站点, http://coop.tuna.tsinghua.edu.cn/git 137 | http://huaiyusched.github.io/ 是一个大四本科生上这个课,做实验等写的一些记录。 138 | 139 | Q:copy on write只需要在虚拟内存管理vmm.c pgfault里面加一段就可以了吗? 140 | 141 | A:这是在有进程fork后可以具有的一个性能优化手段。即lab5可以做。基本功能设计process fork, vmm, irq 等方面的综合实现。不是“设计”,而是“涉及'。 142 | 143 | Q:思路是process 里面要判断是读还是写,如果是写,就调用中断再copy一次, 144 | 145 | A:不仅仅这样。要看这个地址是否是合法的mm, 注意vma中的描述,在vma中合法,且能读写。但在页表中,设置的是只读。这样的页符合copy on write的特征,所以在中断处理时,查看有这样的地址,就需要复制一份,实现了copy on write的目标。 146 | 147 | Q:有相关的答案或者测试方法吗 148 | 149 | A:其实有一个参考实现,但没有公布。建议你在github or bitbucket上放置你的实现源码,这样我可以帮你看看你的实现。鼓励尝试挑战! 150 | 151 | Q:老师,清华对推免硕士会比较看重什么呢? 152 | 153 | A:对于计算机系而言,更看重博士。硕士量也很少,因为他们一般还有出国的考虑。总体而言,对于硕士,看排名,获奖,工程能力。 154 | 155 | Q:谁知道老师提供的做好的虚拟硬盘的mooc-os密码呀? 156 | 157 | A:一个空格 158 | 159 | Q:老师,请问一下rt mutex的应用场景 160 | 161 | A:rt_mutex应该是用在rt-linux中的吧? 162 | http://www.mjmwired.net/kernel/Documentation/rt-mutex-design.txt 163 | 164 | Q:陈老师,关于生产者消费者问题,银行家问题会在后面课程里面有讲授吗? 165 | 166 | A:银行家算法应该在死锁章节讲,会讲。 167 | http://wiki.0xffffff.org 是一个西邮的大四本科生写的,做得很不错。大家有空可看看。生产者消费者问题,哲学家问题,读者写者问题都会讲。http://cdmd.cnki.com.cn/Article/CDMD-10532-2006131961.htm 有一些相关的内容。可以参考一些。西邮的陈莉君老师组织了一个很好的,有较长历史的linux兴趣小组,他们Linux讲的比较深入,吸引了一批同学加入小组,有不少都做得很好,毕业后去了大公司做linux开发。他的几本书不错。 168 | 169 | Q:陈老师您觉得在多核系统上,做一些内存管理,和进程管理的project意义大吗。 170 | 171 | A:os for 多核从2006年以来有了很多研究。在调度方面,我觉得创新性的空间不大了。在内存管理,IO管理方面,vmm方面还是有很多需要研究的。不过挑战较大。在调度方面,我觉得创新性的空间不大了。在内存管理,IO管理方面,vmm方面还是有很多需要研究的。不过挑战较大。我记得前几年(2010?)有一篇hpca的best paper,讲异构(指令相同,但性能不同的异构cpu core)调度。 172 | 173 | Q:OS理论对功耗方面、电源管理、温控管理意义大吗? 174 | 175 | A:功耗方面,电源管理是移动端os的一个难点和要害。不过只靠os比较难做。 176 | 177 | 风行烈:我是一直做调度的,不过不是在OS层,而是异构环境,我觉得空间还是蛮大的 178 | 179 | 陈渝:我记得前几年(2010?)有一篇hpca的best paper,讲异构(指令相同,但性能不同的异构cpu core)调度。 180 | 181 | 风行烈:片上的异构重庆大学吴凯劫做的还是挺好的 182 | 183 | 陈渝:你说的片上异构是体系结构方面的研究吗?还是for os的研究。 184 | 185 | 风行烈:现在做能耗都是在数据中心层的调度 186 | 187 | 陈渝:对于分布式系统,有很广阔的研究点。我知道的有berkeley的AMPLab, MIT的PDOS组都做得很好。 188 | 189 | 风行烈:是的。单从OS角度,对于我来说太难了 190 | 191 | 陈渝:我对分布式系统涉及很少,不过这个方向很好,但问题和实验环境在互联网公司。建议多与公司合作。其实还有一个方向目前国内外都很热,就是系统安全。我们最近的一个研究就是找os的bug,挺有意思,也挺有挑战的。 192 | 193 | 风行烈:Linux的吗? 194 | 195 | 陈渝:做这方面的有UCSD的周圆圆,芝加哥大学的卢山,华盛顿大学的王曦,berkeley的dang song, UIUC的谢涛,太多华人在这方面的了。 196 | 197 | 风行烈:安全还是bug方面? 198 | 199 | 陈渝:我比较关注的是分析linux kernel 或其他os kernel的bug/漏洞。严重的bug就成了安全问题了。bug好一些。漏洞还有有POC的攻击代码。更麻烦一些。比如前段时间爆出了底层漏洞,很多网络支付公司都紧急升级,做系统安全方面,我接触过的国内有名的有keen team公司。 200 | http://soft.cs.tsinghua.edu.cn/os2atc2014/ppt/keynote/keynote-niesen.pdf 他们的一个年轻专家前些日子做过一个报告。大家有兴趣可以看看。 201 | 202 | 风行烈:这会涉及指令系统吗? 203 | 204 | 陈渝:我说的都还是软件方面的系统bug/安全。 205 | 206 | 风行烈:谢涛在搞大数据了? 207 | 208 | 陈渝:我刚看到一篇asplos14的paper,谢涛教授和MSRA的研究员在找windows的性能异常方面的问题。国内外也有做硬件安全(攻防)方面的研究。硬件有张焕国。 209 | 210 | Q:编译器方面的问题 211 | 212 | A:我记得群里有人问编译器方面,我们最近找bug,用到程序分析技术,主要的一个工具就是LLVM,如果大家有兴趣,也可以看看。我觉得它比gcc在很多方面都好一些。唯一不足的是还不能完全编译Linux kernel,需要打patch. 213 | 214 | 陈渝老师:我对大家的一个建议是:其实OS学习不是非要很聪明的人学才学的好,主要是坚持,深入。太聪明了也许学不好,或不愿意学OS 215 | 216 | https://class.coursera.org/compilers/lecture/preview 我觉得这个课应该不错吧。一个小的麻雀,从零开始,即使是读懂,理解,而不是自己做,收获也会很大。 217 | 218 | 旅叶:Compilers课程 219 | https://class.stanford.edu/courses/Engineering/Compilers/Fall2014/about 220 | 221 | Q:我们这门课的lab经常会给人摸不着头脑的感觉 222 | 223 | A:对于lab,我们也一直在摸索,感觉很难让学生很容易理解和完成实验。也许我应该讲讲:如果是我是一个学生来做,应该如何一步一步低完成这些实验。我下次尝试一下。 224 | 225 | Q:课堂讲的太少,还是看书多,现在觉得书也讲的不深,想看论文 226 | 227 | A:想彻底懂,需要动手实践,看是远远不够的。每周与大家聊的时间还是很短。争取从下周开始,每周三晚上有半个小时与大家再交流一下。 228 | 风行烈:我个人学Linux的切入是从写驱动开始,如果开始就去研究进程和内存管理会很枯燥 229 | 陈渝:每个人特点和基础不同,没有绝对的学习方式。希望大家能够探索一条适合自己的路。比如,对于学习os而言,我比较喜欢分析一个小的但比较全面的可实际工作的os。理解比较清楚后,再看linux的相关东西,并写写kernel module。 230 | 231 | Q:老师,minix怎样: 232 | 233 | A:minix不错呀。不过现在体检也很大了。我个人觉得微内核架构与单体内核架构差别还是较大。除非你照着minix作者的教材“操作系统设计与实现--基于minix”学,那我建议你看minix.。design and implementation 这本书就是围绕minix。 234 | 235 | Q:您提到的小的os,就是我们实验用的那个吗 236 | 237 | A:小os有很多,xv6, ucore,....,还有国内的linux-0.11等,harvard 的OS161, U of Maryland:geek os, berkeley: nachos,stanford: pintos,我比较欣赏xv6,简单! 238 | 239 | ## 2014/12/17 240 | 241 | Q:陈老师,您觉得哪本书对实现一个操作系统比较合适? 242 | 243 | A:推荐计算机专业的同学我推荐看 于渊的《Orange’s:一个操作系统的实现》,及其早期写的《自己动手写操作系统》;《30天自制操作系统》,不过感觉有点不深入;《Linux内核完全剖析:基于0.12内核》,赵炯,很细,不过对于为什么这么做解释的较少。《Linux内核源代码情景分析》毛德操,说明了怎么做,也说明了为什么这么做,挺不错的书,不过难度和深度较大。推荐非计算机专业的同学看《嵌入式实时操作系统μC/OS-II》邵贝贝老师翻译的,简单易懂。 244 | 245 | Q:OS领域那些会议或者期刊的论文值得关注? 246 | 247 | A:OS领域以会议为主,期刊较弱。顶级会议包括SOSP、OSDI、ASPLOS;一流会议包括USENIX、EUROSYS、VEE、HOTOS、FAST;不错的会议APSYS;领域沾边的会议NSDI、HPCA、MOBISYS、SIGCOM…。 期刊有IEEE Trans of Computer,ACM Trans of …,还有系统安全领域、软件工程领域,都与OS沾边。 248 | 249 | Q:单cpu情况下,操作系统在调度进程时候,如何调度操作系统本身? 250 | 251 | A:操作系统本身是不需要调度的,只是被动的提供服务,用户进程/线程和内核线程需要OS调度。 252 | 253 | Q:软件工程学到什么程度会和操作系统打交道? 254 | 255 | A:软件工程不是学来的,而是实践中体会到的,所以两者不存在依赖关系。 256 | 257 | Q:https://www.cs.purdue.edu/homes/cs252/ 课程怎么样? 258 | 259 | A:这个课程还不错,但不是分析理解OS的实现,而是理解如何正确使用OS。 260 | 261 | Q:老师,介绍点linux os paper。 262 | 263 | A:直接到网址上看每年的SOSP,OSDI,USENIX,EUROSYS的paper、ppt、video,网上都是免费的,ACM这点做的不错。 264 | 还有:https://www.usenix.org/conference/osdi14/technical-sessions 265 | http://sigops.org/sosp/sosp13/program.html 266 | https://www.usenix.org/conference/atc13/technical-sessions 267 | 268 | Q:对于刚接触操作系统,只有操作系统原理的一些基础,怎样编写代码实践,比如linux内核,光看书也不知道如何实践? 269 | 270 | A:看邵贝贝老师的《嵌入式实时操作系统μC/OS-II》吧,然后把代码理解,编译,运行。 271 | 272 | Q:如果不想简单的抄代码,而是能够修改,应该这么做? 273 | 274 | A:先重复吧,如果重复完了,并且理解了,再尝试修改,一口吃不成胖子,一步一步来。 275 | -------------------------------------------------------------------------------- /others.md: -------------------------------------------------------------------------------- 1 | 1 在configure中enable swap之后,发现check_mm_swap过不去。 2 | 然后把代码切回到最原始的版本,依旧如此。也就是说目前提供的ucore_plus代码是有问题的。 3 | 但是我想当初把swap合并进来的人应该能成功测试通过的。。所以我想请问能否联系到原作者。 4 | 5 | 如果我没有记错,这一部分工作应该是王乃峥做的。你可以尝试给他(wnzheng@gmail.com)发邮件问一下。 6 | 7 | OS子系统功能验证与代码演化:相关材料 8 | 以下是一些与OS子系统功能验证与代码演化相关的现有工作和工具。 9 | 10 | 1. 系统建模、测试与验证 11 | 1.1 工具: 12 | Coq(http://coq.inria.fr):交互定理证明(ITP)工具 13 | Z3(http://z3.codeplex.com):SMT可满足性求解工具 14 | Alloy(http://alloy.mit.edu/alloy):基于Relational Calculus的模型检测工具 15 | BLAST(http://mtc.epfl.ch/software-tools/blast/index-epfl.php):基于CEGAR框架的通用模型检测工具 16 | NuSMV(http://nusmv.fbk.eu):符号模型检测工具 17 | 1.2 参考工作: 18 | SLAM/SDV(http://research.microsoft.com/en-us/projects/slam):面向Windows驱动的模型检测工具 19 | Formal Verification of the Heap Manager of an Operating System using Separation Logic:基于Coq和Separation Logic的堆管理验证(http://dl.acm.org/citation.cfm?id=2105412) 20 | seL4:基于Isabella/HOL和Haskell的L4微内核验证(http://ssrg.nicta.com.au/projects/seL4) 21 | Verification of mutual exclusion algorithms with SMV system:基于Symbolic Model Checking的同步互斥算法正确性验证(http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=1248127) 22 | Commuter:基于抽象建模的系统调用并行性分析(http://pdos.csail.mit.edu/commuter/) 23 | 24 | 2. Linux子系统接口演化 25 | 2.1 相关资料: 26 | Linux开发流程:http://www.linuxfoundation.org/content/how-participate-linux-community(第2部分) 27 | Documenting and automating collateral evolutions in linux device drivers(http://dl.acm.org/citation.cfm?id=1352592.1352618) 28 | 2.2 工具: 29 | Coccinelle(http://coccinelle.lip6.fr):C代码重构工具(语义补丁) 30 | 31 | 32 | 【关于arm的配置】 33 | 之前没用过arm,在配置到android list avd显示 34 | Available Android Virtual Devices: 35 | Name: ucore 36 | Path: /home/lyk423/.android/avd/ucore.avd 37 | Target: Android 4.1.2 (API level 16) 38 | ABI: armeabi-v7a 39 | Skin: WVGA800 40 | 之后执行./uCore_run出现了 41 | AVD not specified. Fetch the first avd from "android list avd" and get "ucore" 42 | emulator: ERROR: Could not load OpenGLES emulation library: libOpenglRender.so: cannot open shared object file: No such file or directory 43 | emulator: WARNING: Could not initialize OpenglES emulation, using software renderer. 44 | 无法启动是什么原因呢? 45 | 46 | 除了存储进程的trapframe,内核堆栈还有什么用呢? 47 | 我看进程拷贝的时候只拷贝了trapframe,并没有拷贝整个内核堆栈 48 | 49 | 答: 50 | 堆栈是两个东西,heap 和 stack. 51 | Stack是用来维护execution flow. stack存储了一些临时数据,包括 local data and return address. 52 | Kernel stack 就是在kernel mode 下的 stack, 也一样包括了 local data and return 53 | address(包括切换回user mode的). Kernel stack也是用来维护execution flow的,kernel mode 下的execution flow 包括 thread 和 interrupt handler. 54 | 至于是不是每一个thread都需要一个stack, interrupt handler 使用谁的stack, 这个在实现时候都可以按需要考虑。 55 | 肤浅的理解,欢迎纠正 :) 56 | 57 | 哦,我对你的提问的理解是:程序的运行总是需要 stack 的,比如函数 call、局部变量等等,在内核里面也一样,从用户程序进入内核以后,执行内核代码所使用的 stack 就是你在进程创建的时候分配的 stack。其次,在由用户程序进入内核的时候,这个 stack 还有一个作用就是保存当前所有的 寄存器 的值,参见 trapasm.S。当然,从内核回到用户程序,也需要类似的操作。所以,这个 stack 很有用。 58 | 至于你说为什么不拷贝内核堆栈,是指 fork 的时候吧,不拷贝,因为确实是没有用。这个 stack 对于用户程序而言,就是一个临时的东西。 59 | 60 | 可以从下一个进程是否会重用kernel stack来理解fork时拷贝。只要下一个进程不会占用的,就可以不复制。这样,就只有寄存器是必须复制的了,其他的都可以不复制。 61 | --向勇 62 | 【XV6 虚存管理】 63 | XV6 虚存管理 64 | http://www.google.com/url?sa=D&q=http://docs.google.com/Doc%3Fid%3Ddhn9b47f_0gj39xzhd%26invite%3D&usg=AFQjCNFW_PmrUR8_2tDKIowPGEDMKdH7-A 65 | 【xv6内存管理】 66 | 各位 67 | xv6在原版的基础上,经过老师和学长们不断的改进,添加了页式内存管理的支持。由于开发消息队列的需要,我们组阅读了xv6内存管理的代码,并对它进行了测试¬。发现了以下问题: 68 | 1. 代码混乱 69 | 首先,原有代码被注释掉,同时原来的注释还留着,这样容易引起混淆。 70 | 现有系统与内存管理有关的接口有: 71 | // buddy.h 72 | struct Page * __alloc_pages(int nr); 73 | void __free_pages(struct Page *page, int nr); 74 | struct Page *alloc_pages_bulk(int order); 75 | void free_pages_bulk(struct Page *page, int order); 76 | // defs.h 77 | char *kalloc(int sz); 78 | void kfree(char *addr, int sz); 79 | int growproc(int n); 80 | // pmap.h 81 | char *alloc_page(); 82 | int map_segment(pde_t *pgdir, paddr_t pa, vaddr_t la, uint size, uint perm); 83 | 其中pmap.h中的alloc_page应该放在buddy中。 84 | 由于历史原因,页式管理的一部分初始化在kalloc中。 85 | 2. 内存分配浪费 86 | 现有的分配下,如果需要10byte的空间,会在buddy中一个页。对__alloc_pages来说,如果要9个页,则实际会分配16个页。这样的空间浪费¬实在太大。出了代码编写本身的问题外,接口的设计也是问题。 87 | 3. 有严重bug 88 | a)安全性 89 | 初始化页表将所有页都设了PG_USER。这有严重安全问题。 90 | 譬如在用户态读取0x80008000,即可获得e820返回的内存表个数(6)。 91 | b)执行usertests会产生Triple Fault 这个问题还在查找中... 92 | 针对以上问题,我们拟重新设计内存相关接口,但保持原有实现不变。新接口具有如下形式: 93 | // buddy.h 94 | struct Page * alloc_pages(int order); 95 | void free_pages(struct Page *page); 96 | // pmap.h 97 | int map_segment(pde_t *pgdir, paddr_t pa, vaddr_t la, uint size, uint perm); 98 | // kalloc.h 99 | void kinit(); 100 | char *kalloc(int sz); 101 | void kfree(char *addr); 102 | 这个设计的关键是明确各个组件的功能。buddy专门负责2的幂次的物理页的管理,kalloc,kfree专门面向内核提供形如malloc,free的服务¬。而需要分配页进行映射时,则采用alloc_pages, map_segment的组合。这里的一个重要变化是取消了任意连续物理页的分配(因为有了页式管理的机制,对连续物理页的需求大大减少)。如果未来有需要,可¬以考虑在buddy中加入这一功能。 103 | 这个,改动中,除了改变接口,一个主要功能就是重写kalloc,和kfree。这拟由我们组完成。 104 | 另外,我们准备改正上面找到的bug 105 | 【页式管理机制】 106 | 看到考试上的一些题目问到某个页式管理机制最多一共有多少个页表。 107 | 那如果考虑自映射机制的话,一级页表的其中一个表项指向的是一级页表本身,是否应该在统计的时候减1? 108 | 答: 109 | 你的理解是正确的。自映射的页表占了两个位置。 110 | --向勇 111 | 【线性地址、物理地址、虚拟地址】 112 | 线性地址、物理地址、虚拟地址具体的联系和区别是什么? 113 | 答: 114 | 这个,看IA32手册吧。 115 | 简单来说 116 | Virtual Address ------ Segment ------> 117 | Linear Address ------ Paging ---------> 118 | Physical Address 119 | 最后Physical Address 即是访问物理内存的地址。 120 | 【管程的实现】 121 | 各位老师同学: 122 | 课余研究了一下Hansen和Hoare两种管程的实现,对证明有了一点简单的了解,希望跟大家讨论 123 | 附件中是hoare证明monitor=semaphore的论文证明分为两个部分: 124 | 第一部分:monitor>=semaphore,亦即管程可以实现二值信号量(等价于多值)。 125 | 第二部分:semaphore>=monitor即证明两者等价。 126 | 重点在于第一部分 127 | 第2页给出了管程的实现,可以发现代码中的acquire和release两个函数和二值信号量的p/v能完全一一对应在代码下面的注记2中提及:acquire中使用if而非while,是由release的立即唤醒所保证,且过程中不被打断。 128 | 在使用if的情况下,代码和二值信号量的p/v才完全对应,从而才能证明monitor>=semaphore 129 | Hansen-style没有立即唤醒,因此使用while,正是这一点导致其无法与二值信号量直接对应,因此证明有一定难度。 130 | 以上是本人的一点拙见,若有谬误还望老师指正,欢迎大家探讨! 131 | 程芃祺 132 | 133 | 答: 134 | 程芃祺,你好: 135 | 我理解你对论文的解释是对的。另外,其实monitor的机制在java/pascal/mesa等语言中有体现,在Linux的pthread有线程的实现(¬用的是Hansen-style,即需要while)最终要用到linux 136 | kernel的semaphore机制来实现,这在一定程度上也说明了可以用sema来实现条件变量。 137 | 但我观察到在Linux和其他通用os中好像都没有monitor的实现,甚至没有condition variable的实现。我猜想主要是由于如下几点: 138 | 1 用semaphore可以实现monitor的功能 139 | 2 monitor主要体现了一种更加简单一些的编程方式,在语言级支持monitor可能更好。Linux等采用的是C语言,在语言级别无法扩展monitor,¬这样还不如用semaphore的函数方式实现类似monitor的功能更加比较容易做。 140 | 3 如果采用hoare style方式,虽然证明容易了,但实现复杂,特别是在在scheduler方面,需要确保signal的线程和被唤醒的wait线程之间不会有其他线程或因素¬存在导致wait的条件又为真了。 141 | 4 如果采用Hansen-style,则用lock + sema方式实现也很直观,在内核里面,好像也不太需要monitor这一层的抽象了。 142 | 【Darwin的资料】 143 | 下面两个链接是OS专题训练课上提到的Darwin的相关信息。有兴趣的同学,可深入阅读。 144 | http://www.google.com/url?sa=D&q=http://en.wikipedia.org/wiki/Darwin_%2528operating_system%2529&usg=AFQjCNHyddi-y12_1gQsKQNiqg2bx4j5hg 145 | http://www.google.com/url?sa=D&q=http://sourceforge.net/projects/darwinsource/&usg=AFQjCNH2HktgzcJPBb4gYs0ElseZJeAMHg 146 | --xyong 147 | 【进程优先级】 148 | 是否一般认为fork后父子进程的先后执行顺序是不确定的,vfork出来的子进程必定先于父进程执行? 149 | 答: 150 | fork后父子进程的先后执行顺序是不确定的。 151 | vfork后父进程会等子进程结束或调用exec()。 152 | 详细描述参见: 153 | http://www.google.com/url?sa=D&q=http://en.wikipedia.org/wiki/Fork_%2528operating_system%2529&usg=AFQjCNGPk2EeS_rM888sdYOXTiO081-DBg 154 | --向勇 155 | 【LRU算法】 156 | 在某些地方看到说LRU算法不会出现belady现象,但貌似记得老师上课说过可以找到一个队列也使LRU出现belady现象。或许是我自己记错了。 157 | what about clock or second chance? 158 | Thanks~ 159 | 答: 160 | 你记错了。 161 | 【面包店算法】 162 | > 向勇老师您好!我想问您一个有关面包店算法的问题。主要是关于那个choosing 163 | > 数组的必要性。从程序上看,choosing数组的主要作用是当进程Pj在“取号”, 164 | > 也就是设置number[j]的时候,不允许其它进程访问number[j]。而对于choosing 165 | > 数组的必要性,从代码number[j] = max(number[0], 166 | > number[1].......number[n-1])+1上来看感觉不太明显,但是如果将取号部分的 167 | > 程序改为 168 | > for (i = 0; i < N; i++) 169 | > if (number[ i ] > number[ j ]) 170 | > number[ j ] = number[ i ]; 171 | > number[ j ]++; 172 | > 那么用choosing加锁的必要性主要就体现在当for循环没有终止时,当前 173 | > number[ j ]的值是不正确的。因此必须要做完number[ j ]++后才可以访问 174 | > number[ j ]。不知道我的这个理解是否正确。 175 | > 另外,如果“取号”部分的代码改为 176 | > int temp = number[0]; 177 | > for (i = 0; i < N; i++) 178 | > if (number[ i ] > temp ) 179 | > temp = number[ i ]; 180 | > number[ j ] = temp + 1; 181 | > 想请问一下这样做(也就是number[ j ]的唯一一次赋值操作得到的正确的“号 182 | > 码”值)的话,是否还需要利用choosing数组加锁。 183 | 答: 184 | 关于choosing数组的作用是避免两个进程同时依据当前的number[]来计算自己的 185 | number[j]。如果不用choosing数组,会出现下面情况,这时会出现两个进程同时 186 | 进入临界区。 187 | 假定使用你的第二种max函数实现进行最后的赋值,且j 系统缓冲区(I/o 缓冲区 在内存中) -> 硬盘缓存 ->磁盘 ? 309 | 还有个问题,就是关于I/o缓冲区的,这个缓冲区是不是操作系统内核管理的?对用户来说是透明的? 如果要将数据输出是不是都要经历这么几个过程? 310 | 将在进程自己内存空间的数据复制到 I/o缓冲区 然后再输出 (进程不能直接操作I/O缓冲区,也就是省去第一步直接将要输出的数据放到I/O缓冲区中) 311 | 如果从外设读数据,是不是也要先读到系统I/O缓冲区,然后进程复制到自己的内存空间中使用,进程不能直接从 系统I/O缓冲区取数据使用? 312 | 我对这里面的过程不清楚,麻烦向老师帮助我解答,谢谢! 313 | 祝您:工作顺利,身体健康! 314 | 敬礼! 315 | 316 | 答: 317 | 1)硬盘上的缓存和内存中的缓存作用是类似的,都是读写缓存和频繁读写数据的暂存。不同之处在于,内存的缓存是由操作系统控制的,而操作系统只能启用或禁用硬盘上的缓存功能,不能对缓存算法进行控制。我从网上找到一段文字(http://www.google.com/url?sa=D&q=http://article.pchome.net/&usg=AFQjCNF3jVedGxN1-exMfKjMl_s9Nm3UeAcontent-447812-2.html),比较准确地说明了硬盘缓存的作用;而硬盘上缓存的大小对性能的影响主要体现在延迟写入上(http://www.google.com/url?sa=D&q=http://article.pchome.net/content-447812-3.html%EF%BC%89&usg=AFQjCNFDoICqV3Cv77jN6cveitMGoBqU9A,这也引入了数据安全问题,需要小心使用。 318 | 2)关于写数据到硬盘的过程,你说的基本正确。一个小的修正是,硬盘缓存对写入数据的缓存是可以由操作系统禁用的。 319 | 3)内存中I/O缓存是由操作系统管理的,通常对用户透明;但也有例外,数据库系统通常是不用操作系统的缓存机制的,它会自己来管理缓存。 320 | 4)关于用户进程是否能直接从I/O缓存读取数据来使用,我不确定。可能的线索是,通常用户进程不能直接访问系统的I/O缓存;但如果使用文件映射,我就说不太清楚I/O缓存的作用了。也许可以设计一个实验测试一下。 321 | --向勇 322 | 【磁盘工作原理】 323 | 在实际的操作系统中,通常能顺序被唤醒,但相关文档描述并不保证被阻塞进程按顺序被唤醒。好象Windows的API文档就专门说到这一点。 324 | 我认为PC机上是使用通道技术的。SCSI硬盘接口卡应该就是用的通道方式。也许你 325 | 可以查一下IDE硬盘接口的工作原理,也许它也是的。如果可能,你可以把查到的 326 | 结果告诉我一下。谢谢! 327 | --向勇 328 | 答: 329 | 对于第一个问题,我补充一下,其实在大部分OS的实现中关于唤醒的具体实现有如下几种: 330 | 1 由于阻塞进程是按照被阻塞的先后顺序挂在一个链表上,这样如果只唤醒一个进程,可以很方便地安装FIFO的方式实现唤醒 331 | 2 对于实时进程而言,由于进程的优先级很重要,高优先级需要先执行,所以会存在某个数据结构来按优先级的方式顺序存放被阻塞进程,这样可以基于优先级来唤醒进程 332 | 3 发生某个事件后,也可能需要唤醒所有阻塞的进程,但容易出现“惊群”现象 333 | 但进程和等待队列的具体定义会有很多属性,比如某些进程在等待时有timeout、等待队列有EXCLUSIVE、优先级级考虑等属性,导致实际情况下无法保证任意情况下按FIFO顺序唤醒。 334 | 具体实现可以看看Linux的sched.c的__wake_up_common、sleep_on_common等函数 335 | 对于第二个问题, 336 | SCSI的通道是一个属于SCSI领域的概念,实际上是用来描述SCSI设备的总线(BUS)。对于PC而言,它也有自己的总线,比如PCI,SCSI卡也需要¬插在PCI或PCIe总线上,从这点上看,连接在PCI上的设备还是需要通过中断和DMA来与CPU、MEM交互的。 337 | 【FAT32资料】 338 | XV6下的FAT32支持进展:http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OsTrain2009/VFS&usg=AFQjCNH3JRh4c2cSc_xGYB__6CVYnRQ6pw 339 | --xyong 340 | 【写者优先】 341 | > 向老师: 342 | > 您好! 343 | > 关于写者优先部分,课间中给出的伪代码为什么要在P(rsem)前P(z) 344 | > 阿,我在wiki上找到的伪码不需要这步操作。我觉得P(z)和P(rsem)有重复的感 345 | > 觉,没有必要把……请您解释下~ 346 | > 谢谢! 347 | 答: 348 | 对于写者优先的读者-写者问题的解法的解释: 349 | 对写者优先的实现在William Stallings的第五版教材的表5.5中有一个比较清楚的描述。即把所有可能的情况分成4种情况:1)只有读者;2)只有写者;3)同时有读者和写者,且当前正在读;4)同时有读者和写者,且当前正在写。有了这个分类,再来理解下面的解释会容易一些。 350 | 如果没有信号量z,在下面情况时会有大量的读者等待在信号量rsem上。这种情况是,当前正在进行写操作,随后有大量读者到达。 351 | 随后写者们完成了最后一个写操作,可以进行读操作了。于是所有等待在信号量rsem上的读者开始逐一获得信号量rsem,然后申请信号量x,检查自己是否是第一个读者,确认不是第一个后开始读操作。如果这时的读者的数目很多,这个过程需要一定的时间。 352 | 设想这时又有一个写者到达,它就没有办法赶在正在逐一申请信号量x的读者前面进行写操作了。 353 | 如果这时有信号量z的作用,这个写者就可以在第一时间挡住正在获得信号量rsem的读者,最大限度地实现写者优先。 354 | 355 | cueroqu: 操作系统课程的实验部分有时候需要汇编语言的知识。然后有些语法一时很难查到具体什么意思。不知到有没专门此类介绍汇编语言语法的网站呢?或者说还是先略过这些实验然后先对操¬作系统有一个大致的了解(比如看后续的课件)? 356 | 答: 357 | chyyuu: 358 | OS实验用的是GNU AS 汇编器和GNU CC内联汇编技术,相关文档如下: 359 | X86的指令集详细文档,可查到所有的X86汇编:ia32-instrset.pdf 360 | http://www.google.com/url?sa=D&q=http://www.bytelabs.org/pub/ct/arch/intel/ia32-instrset.pdf&usg=AFQjCNEf14eSMFxGAQT_V2hwsKuzf11sig 361 | 是所有的机器指令说明文档。此目录下的另外两个文档对理解x86硬件工作模式和硬件系统系编程很有帮助。 362 | 中文介绍文档:Linux 中 x86 的内联汇编 363 | http://www.google.com/url?sa=D&q=http://www.ibm.com/developerworks/cn/linux/sdk/assemble/inline/index.html&usg=AFQjCNGsJhhoKP0uHuZL7ZlJRyefhQwRtw 364 | 英文GNU汇编专业电子书,掌握此书,将是汇编绝对高手 365 | 《Professional Assembly Language》英文版 ,作者 Richard Blum 366 | http://www.google.com/url?sa=D&q=http://forum.eviloctal.com/thread-31189-1-4.html&usg=AFQjCNGCnNrpdZtqNFxDEyEFjgmyHFv8mA 367 | 另外可以通过 google等搜索 "GNU" "Assembly" 或 “GNU” “汇编”等查找相关信息 368 | 【扩展实验:用户态与系统态】 369 | 陈老师, 370 | 今天根据课上讲的我试做了扩展实验1,现在碰到一个问题一晚上无法解决,还请帮忙指教: 371 | 我的程序先从系统态跳到了用户态,然后在用户态下执行了int 0x80,结果出现错误: 372 | qemu: fatal: invalid tss type 373 | qemu直接关闭。 374 | 然后我试着查阅tss相关资料,了解到tss是task上下文切换用的,在用户态到系统态发生特权等级变化时要用到。而我们的proj4默认没有设置tss的操¬作,我便试着在gdt中加入tss项: 375 | SEG_ASM(0x89, 0x00000, 0x20ab) 376 | 然后ltr进去0x28 377 | 这样操作后,遇到第一个call或者jmp指令就会导致qemu重启。然后试了很久毫无进展,还望老师指导一下。 378 | 具体错误log: 379 | (qemu) qemu: fatal: invalid tss type 380 | EAX=00100028 EBX=00010094 ECX=00000528 EDX=00000010 381 | ESI=00010094 EDI=00000000 EBP=0013fffc ESP=0013ffd4 382 | EIP=0010000a EFL=00003202 [-------] CPL=3 II=0 A20=1 SMM=0 HLT=0 383 | ES =0000 00000000 00000000 00000000 384 | CS =001b 00000000 ffffffff 00cffa00 DPL=3 CS32 [-R-] 385 | SS =0023 00000000 ffffffff 00cff200 DPL=3 DS [-W-] 386 | DS =0000 00000000 00000000 00000000 387 | FS =0000 00000000 00000000 00000000 388 | GS =0000 00000000 00000000 00000000 389 | LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT 390 | TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy 391 | GDT= 00007c54 0000002f 392 | IDT= 0010f040 000007ff 393 | CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 394 | DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 395 | DR6=ffff0ff0 DR7=00000400 396 | CCS=00000028 CCD=0013ffd4 CCO=SUBL 397 | EFER=0000000000000000 398 | FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80 399 | FPR0=0000000000000000 0000 FPR1=0000000000000000 0000 400 | FPR2=0000000000000000 0000 FPR3=0000000000000000 0000 401 | FPR4=0000000000000000 0000 FPR5=0000000000000000 0000 402 | FPR6=0000000000000000 0000 FPR7=0000000000000000 0000 403 | XMM00=00000000000000000000000000000000 404 | XMM01=00000000000000000000000000000000 405 | XMM02=00000000000000000000000000000000 406 | XMM03=00000000000000000000000000000000 407 | XMM04=00000000000000000000000000000000 408 | XMM05=00000000000000000000000000000000 409 | XMM06=00000000000000000000000000000000 410 | XMM07=00000000000000000000000000000000 411 | Aborted 412 | ----Shengwei Ren 413 | 答: 414 | challenge 代码给的可能不是很全。 415 | tss 应该在 gdt 里面,实际上 boot 到 kernel 以后还会再设置一次 gdt。里面会设置 tss。不过 proj4 还没有给这段程序。 然后 tss 里面得设置 stack 位置(查看 intel 手册 / google 了解一下这个 stack 的作用) 416 | SEG_ASM(0x89, 0x00000, 0x20ab) 这个似乎不对。而且这个不是 challenge 的重点。不过你可以先自己尝试一下设计一个。 417 | 我问问陈老师,看看是不是稍后给出缺的那段程序。 418 | 【内存管理算法】 419 | 向老师: 420 | > 您好! 421 | > 我们是做内存管理小组的。 422 | > 目前我们把proj7.1的swap相关文件嵌入了ucore-mp64文件,同时仿造已有算法的框架完成了另外三个算法的实现。 423 | > 但是现在我们对于tick_event操作的调用地方没有概念,在咨询助教后放在了trap里的时钟中断调用里,但是这样会产生一个进程,在qemu运行最后无¬法消除。 424 | > 另外,因为已有的working_set和自己实现的lru/page_fault_frequency算法需要tick_event操作,不断地更新每个节点¬对应的调用时间,所以无法进行测试。所以我们想问一下向老师有什么建议? 425 | > 计81 元升高 426 | > 2011-12-17 427 | 答: 428 | tick_event是应该由时钟中断触发,可以借见的做法是Windows中的延迟过程调用。大致的的意思是,中断中触发或设置一个tick_event任务¬,在延迟过程调用中执行,它的执行是优先于所有进程执行的。目前ucore还没有对它的支持。一种可能做法是,把tick_event直接放在中断服务例程中执¬行。 429 | 关于你说的“这样会产生一个进程,在qemu运行最后无法消除”,没有太明白。系统中会有一直存在的进程,如IDLE进程就是一直存在的。 430 | 关于测试的事,可以通过输出日志,并在事后进行统计来完成。如果日志太多,可以在内核中维护一些调试数据结构,只输出统计结果。当可以跟踪算法状态后,还需要写¬一些进行特定操作的应用程序,从而测试算法的特征。 431 | 如果仍有问题,请与我约时间当面交流。 432 | 【kernel启动问题】 433 | > 向老师, 434 | > 您好,我今天开始尝试扩展实验,目前做到把GRUB安装在U盘上。我自己查了一 435 | > 些相关资料,但是使用kernel启动不行,而使用ucore.img直接启动,以及添加 436 | > multiboot header到ucore.img,都停在[Linux-zImage, setup=0x800, 437 | > size=0xbe00](这个img是否不是zImage?)。不知道主要还需要对其做什么修 438 | > 改,有什么资料可以参考,还请您告诉我,谢谢! 439 | 答: 440 | ucore应该是只能直接启动,它已包含了GRUB的部分功能。在上学期也有同学做过尝试,相关结果参见下面链接。 441 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OsTrain2009/FlashDisk&usg=AFQjCNHOz8aVMNbSiEpVKOW5jHpXgYhx7g 442 | 这些尝试对应的代码可从下面链接找到。 443 | git://cherry.cs.tsinghua.edu.cn/xv6-usb-2010 444 | 希望你的尝试能有新进展。 445 | --向勇 446 | 【进程同步算法】 447 | > 老师你好,我操统实验二选择了进程同步,这个在操统课lab5里是有相应的实现 448 | > 的, 449 | > 但是wiki上的版本里边没有信号量的相应实现。 450 | > 向老师求救。 451 | > 谢谢! 452 | 453 | 答: 454 | 是的。在目前的版本中有的进程同步机制是管道(pipe.c)和消息(sysmsg.c),没有信号量。你可以对这两种机制进行测试。 455 | 另外,自旋锁(spinlock.c)也与同步机制密切相关,但我没有想明白如何能用用 456 | 户态测试对它进行一些测试。你也可以考虑是否有可能对它进行测试。 457 | --向勇 458 | 459 | fork后父子进程的先后执行顺序是不确定的。 460 | vfork后父进程会等子进程结束或调用exec()。 461 | 详细描述参见: 462 | http://www.google.com/url?sa=D&q=http://en.wikipedia.org/wiki/Fork_%2528operating_system%2529&usg=AFQjCNGPk2EeS_rM888sdYOXTiO081-DBg 463 | --向勇 464 | 【USB bootloader资料】 465 | 今天我又在网上找了一些关于USB bootloader的信息,见下面的列表。 466 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OsTrain2009/FlashDisk%23head-d2da5a334828683b20f00739aa4b73cf00895240&usg=AFQjCNHjYCaoefCuU1w0C6E_xMj00VN5rw 467 | --向勇 468 | 【显卡驱动的已有工作】 469 | > 向老师: 470 | > 您好,我报名了课程设计中的U14,不知道上次答疑时提到的之前实现的可以显示jpeg的简单实现在哪里?在2011年的project里面找不到。 471 | > 另外本次lab1作业中,challenge部分对于报名课程设计的是不是必做呢?另外challenge部分提到说在1周内在另外开的窗口提交,但是现在网络¬学堂还没有看到,不清楚是不是今天交。另外challenge部分实验内容不太清楚,完成switch to user和switch to kernel就可以通过make grade了,不知道提到的使用sys_call获取当前时钟ticks是否需要做,有没有规范如何写的要求。 472 | 473 | 答: 474 | 显卡驱动的工作是2010年,可参见下面链接。 475 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OsTrain2010/DriverReuse&usg=AFQjCNGaj82Z1B1QwZ6L9tiu5iCZVAgR_w 476 | 关于实验中的选做部分,对于报名课程设计的同学是必做的,与基本要求一起在网络学堂中提交。如果你还没有提交,可以发给我。这一部分目前没有特别的报告撰写要求¬。 477 | --向勇 478 | 【syscall功能扩展】 479 | 想做第一个Challenge B,即扩展proj4,增加syscall 功能,即增加一用户态函数(可执行一特定系统调用:获得时钟计数值),当内核初始完毕后,可从内核态返回到用户态的函数,而用户态的函数又通过系统调用得到内核¬态的服务。 480 | 想问下这里如何可以返回到用户态?一般来说是否需要内存管理和进程管理,但这些在lab1中都还没有。 481 | ------------------------------------- 482 | 主要是如何完成 x86的ring0<->ring3之间的正确切换,需要了解x86相关细节,也可看xv6了解。不需要内存管理和进程管理。 483 | 484 | 答: 485 | 如果选作,我觉得,大体可以按照下面要求完成: 486 | 1. lab1 里面整个都是 kernel 态的。kern/init/init.c 最后是 while(1) 循环;在此之前请插入一段函数,完成从kernel mode -> user mode -> kernel mode 的函数,可以通过 int 指令实现(syscall)。 感兴趣的同学也可以通过 callgate 实现(这个实现非常复杂,也不容易理解,但是查阅相关资料对了解 x86 特权级保护有很大帮助。) 487 | 2. 比如插入 switch_mode 函数完成切换,能够依次调用 switch2kern, switch2user, switch2kern 完成状态切换。每次完成切换以后,能够通过在 switch_mode 函数里面,打印出当前状态的 cs/ss/ds/es (fs,gs) 寄存器状态表示当前的身份状态。 488 | 3. HINTS:硬件在中断发生时,特权级变化和不变化时压栈和弹桟的行为是不是一样?特别是 iret 指令。(参见 intel 手册) 489 | 谨慎函数桟的维护 490 | 【Android内核编译】 491 | 请问有没有同学编译过android内核,遇到一些问题想请教一下。 492 | 谢谢! 493 | 494 | 答: 495 | U10小组的同学应该编译过 android for x86。可咨询这两位同学。 ("张超" , "EndlessRoad1991" ,) 496 | 我的一个研究生刘金钊编译过 android for ARM (HTC G7),也可咨询一下。 "inno mentats" 497 | 【ucore代码问题】 498 | 【add_timer函数】 499 | 问题:kern/schedule/Sched.c中的add_timer函数,了解大概意思就是在time_list这个静态的表中去找,找到具体位置之后插¬入到链表中去,但下面这段代码就不懂了: 500 | while (le != &timer_list) { 501 | timer_t *next = le2timer(le, timer_link); 502 | if (timer->expires < next->expires) { 503 | next->expires -= timer->expires; 504 | break; 505 | } 506 | timer->expires -= next->expires; 507 | le = list_next(le); 508 | } 509 | 尤其是这句: next->expires -= timer->expires 为什么改变next的睡眠时间呢? 510 | 511 | 答: 512 | timer 是一个链表。里面每一个元素的实际 sleep 的时间实际上是从链表头到该元素所有经过的 timer_t 的 expires 的和。 513 | 这样的好处是,每次产生时钟中断的时候,只需要检查链表头确定是否有 timer 到期了。而不是遍历整个链表。 514 | add_timer 把 le 插入到链表里面了。那么必然需要更新它插入的位置后面元素的 timer_t 的 expires 的值。 515 | 516 | 陈渝老师,您好: 517 | 最近在做作业的过程中有一些未能理解的地方,不知是我理解不当还是 manual的瑕疵,望老师不吝指正: 518 | 1.1.6 519 | 1. grade.sh中检验输出时用了"grep -F"(line 218),但根据grep的说明,-F之 后的PATTERN "is a set of newline-separated fixed strings",而PATTERN实际用的是regexp,似乎没办法用来校验结果...... 520 | 1.1.7.5: 521 | 1. "中断向量表"指的是实模式下使用的中断向量表还是中断描述符表? 522 | "实验&报告要求"中: 523 | 1. proj3_your_proj和proj6_1_your_proj不存在;若指proj3.1和proj4,应交原 目录还是make 524 | handin得到的打包文件? 525 | 2. tar不接受jzf("Conflicting compression options"),选项是否应该是cjf? 526 | 盼复,并祝好。 527 | 您的学生 528 | 茅俊杰 529 | 答: 530 | grade.sh 里 grep 有 2 种方法,-E 和 -F. 531 | lab1 的测试用的是 -E。 532 | 533 | 1.1.7.5: 534 | 1. 那个指的是idt表,可以结合第二问理解 535 | 实验报告要求: 536 | 1. 指的是proj3.1和proj4。请在目录中执行make handin之后,将生成的压缩包复制到lab1_result中,并且与报告一起打包上传。 537 | 2. 正确选项为cjf,也可以用jcf,jcvf...... 538 | 【panic错误】 539 | 运行答案时,有非常小的几率出现panic错误,也就是结果不稳定。 540 | 发现get_proc_RR函数中,num_procs_moved = (rq->proc_num)/2;这条语句在最前面。之后有一个测试输出的 541 | 部分: 542 | #ifdef LOAD_BALANCE_OUTPUT 543 | if(num_procs_moved != 0) 544 | { 545 | cprintf("before load_balance\n"); 546 | release(&(rq->rq_lock)); 547 | procdump(); 548 | acquire(&(rq->rq_lock)); 549 | } 550 | #endif 551 | 这中间释放了锁,那就有可能在这里出现问题,比如num_procs_moved=2,在释放锁的瞬间rq减少了3个进程,则会出现在后面转移的时候出错。不知道理解的对不对? 552 | 553 | 答: 554 | 恩,我感觉也是这里的问题。 555 | 在LOAD_BALANCE_OUTPUT的前后num_procs_moved可能不同,所以下面遍历数组时再用到num_procs_moved就有可能出现错误。 556 | LOAD_BALANCE_OUTPUT后面也就是#endif后面再加一句num_procs_moved = (rq->proc_num)/2;就没有错误了,但就是前面output的东西没有意义了。。。干脆LOAD_BALANCE_OUTPUT部分不要算了。。。 8核时候出现的错误也来源于这里,只要去掉LOAD_BALANCE_OUTPUT后八核也能正常运行了。 557 | 【HOME_DIR问题】 558 | I have the problem during setting bochsrc. 559 | What does this instruction mean? (cp 2008-spring/tools/bochsrc$HOME_DIR/.bochsrc) in this command line, what is $HOME_DIR? (means address in detail). 560 | thanks. 561 | 562 | 答: 563 | $HOME_DIR is an environment variable, for example: /home/username/ 564 | 565 | $HOME_DIR is an environment variable, which indicates the location of your "home". 566 | It should be '/root' if you're using 'root', or '/home/os' if you're using 'os' user. 567 | And the "home" of Linux is like "My Documents" on Windows system. :) 568 | 【kernel.asm问题】 569 | Here is a piece of code in kernel.asm: 570 | f0100adf : 571 | f0100adf: 55 push %ebp 572 | f0100ae0: 89 e5 mov %esp,%ebp 573 | f0100ae2: 57 push %edi 574 | f0100ae3: 56 push %esi 575 | f0100ae4: 53 push %ebx 576 | f0100ae5: 83 ec 3c sub $0x3c,%esp 577 | f0100ae8: 8b 7d 08 mov 0x8(%ebp),%edi 578 | f0100aeb: 8b 5d 10 mov 0x10(%ebp),%ebx 579 | f0100aee: eb 03 jmp f0100af3 580 | f0100af0: 8b 5d e8 mov 0xffffffe8(%ebp),%ebx 581 | f0100af3: 0f b6 03 movzbl (%ebx),%eax 582 | f0100af6: 43 inc %ebx 583 | f0100af7: 3c 25 cmp $0x25,%al 584 | gdb thought f0100af0 is the start of the function, while many calls of does not touch this address because of the jmp instruction above it. 585 | When I step into this function(command s in gdb), gdb will tell bochs to set breakpoint on 586 | f0100af0. The problem is it never stops... 587 | Is it a bug of gdb? Or some problems on my gcc? 588 | How to solve it? Thx 589 | 590 | 答: 591 | None of us (40ers) used gdb when we were doing this lab. Maybe you should come to 50ers, or we can explore it together. 592 | this lab needs to trace every line of functions in .c 593 | how do you trace it without gdb? 594 | it seems that bochs only supplies asm-level debug... 595 | 596 | Maybe they just read the source code and figured it all out directly. 597 | Besides value fmt and ap, it seems that other values such as *fmt, *ap and c can be calculated from the source code. 598 | 【addr格式】 599 | All materials tell the command to be: 600 | (qemu) b addr 601 | But what's the format of 'addr'? How to indicate the 0xf section? 602 | 603 | 答: 604 | addr format is 0x127f OR 1234 605 | Hex format or decimal format is ok 606 | what is oxf section? 607 | 608 | a)首先在分段情况下,应该如何计算地址,一般来说,应该是 [$段寄存器 << 4 + $偏移量] 来得到目的地址。也就是说 lab1 里面提到的地址 0xF:0xFFF0 对应的应该是 0xF0 + 0xFFF0。不过,这个地址不是 bios 的地址,实际上文档写错了,应该是0xF000:0xFFF0,那么对应的线地址就应该是0xF0000 + 0xFFF0 = 0xFFFF0所以可以使用如下命令来添加这个断点: 609 | b 0xFFFF0不过需要说明的是,这样设置断点也是不正确的。正确的设置应该是: 610 | b 0xFFFFFFF0 611 | 另外,bios 是开机以后第一个运行的程序,所以,应该不可能快到直接给 bios 入口加断点。不过,如果 qemu 使用 -S 参数开启的话,就可以让 qemu 开机后停止,此时已经是 bios 的入口了,可以使用 r 命令查看当前的寄存器,s 命令进行单步进入 bios,不需要再额外的插入断点。 612 | b) 很遗憾,qemu 目前还不能够通过 0xF000:0xFFF0 来直接设置断点,所以必须先把这个断点算出来,然后用breakpoint_insert 来手动的插入。 613 | 【调度器报错】 614 | When I ran the test file for scheduler, it printed that: 615 | [ 80.296404] BUG: unable to handle kernel NULL pointer dereference at 616 | 00000000 617 | [ 80.296409] IP: [] rb_erase+0x112/0x250 618 | [ 80.296417] *pde = 00000000 619 | [ 80.296422] Oops: 0000 [#1] 620 | [ 80.296425] Modules linked in: kvm_amd kvm 621 | [ 80.296428] 622 | [ 80.296432] Pid: 3068, comm: test Not tainted (2.6.27.5 #124) 623 | [ 80.296436] EIP: 0060:[] EFLAGS: 00010046 CPU: 0 624 | [ 80.296440] EIP is at rb_erase+0x112/0x250 625 | ...... 626 | how to find the location where it crash? 627 | 答: 628 | you can use objdump to disassemble the vmlinux, then you can search the rb_erase src code and assemble code, and will find some error in the rb_erase function. 629 | 【linux启动】 630 | how to make linux boot info in serial: 631 | qemu/kvm parameters: 632 | Change 633 | qemu -hda userver.img 634 | TO 635 | qemu -hda userver.img -serial stdio 636 | OR 637 | Change 638 | kvm -hda userver.img 639 | TO 640 | kvm -hda userver.img -serial stdio 641 | Change grub's menu.lst 642 | kernel ... 643 | TO 644 | kernel .... console=ttyS0,9600 console=tty0 645 | then, then you can see boot messages in host console. 646 | 【oprofile问题】 647 | while using oprofile, I met some troubles: 648 | 1. if i install oprofile with apt-get, opreport would report "opreport error: basic_string::erase" whatever i've done, e.g: 649 | >opcontrol --init 650 | >opcontrol --start --no-vmlinux 651 | >opreport 652 | ... 653 | 2.after that i tried to compile & install oprofile from source code 0.9.4, while compiling, i met 654 | "error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT in second argument needs 3 arguments", and I found a patch from http://www.google.com/url?sa=D&q=http://www.nabble.com/arguments-of-open()-td14924588.html&usg=AFQjCNGYfzlZsU74mdysoGhPzqdCZ4fISA, and patched /usr/include/bits/fcntl2.h, then completely passed make and make install. But then when i tried: 655 | >opcontrol 656 | but it told me no opcontrol found at /usr/bin/opcontrol... 657 | Thx~ 658 | 答: 659 | oprofile usage: 660 | 1 you should build a oprofile enabled kernel. 661 | make menuconfig 662 | General setup 663 | --> OProfile system profiling (EXPERIMENTAL) 664 | should be choose. 665 | then, the .config file should have line 666 | CONFIG_OPROFILE =y 667 | or 668 | CONFIG_OPROFILE=m 669 | 2 now get the oprofile package 670 | apt-get install oprofile 671 | or you can get a gui package 672 | apt-get installoprofile-gui 673 | 3 use oprofile to measure a benchmark 674 | you can write a shell to do the work 675 | ------- 676 | #!/bin/sh 677 | echo "profile the kernel:" 678 | opcontrol --vmlinux=/boot/vmlinux 679 | opcontrol --setup --event=CPU_CLK_UNHALTED:90000::1:1 680 | opcontrol --start-daemon 681 | opcontrol --reset 682 | opcontrol --start 683 | ./BENCHMARK pipe 1 thread 5000 64 16 684 | opcontrol --stop 685 | opcontrol --dump 686 | opreport --symbols > log.out 687 | opcontrol --shutdown 688 | 【网卡的中断处理】 689 | 我在做代码注释和分析的实验。 690 | 用的ucore版本是20110913-xinhaoyuan-ucore-mp64-8000c4c.zip 691 | 我选择的题目是各类设备的中断处理过程。 692 | 我在trap.c和trap.h中都没有找到网卡的中断处理函数,请问是本来就没有,还是我应该到其他文件中找? 693 | 是否有同学老师遇到过相关的问题?谢谢! 694 | 答: 695 | 貌似这个版本就不支持网络吧 696 | 我在最新的版本里大概的找了一下,没有找到和网络有关的东西。 697 | 网络支持也是上学期的扩展,还没有合并到我们分析的代码中。相关代码请参见下面链接。 698 | http://www.google.com/url?sa=D&q=http://code.google.com/p/u5proj/source/checkout&usg=AFQjCNGsfUFVerdW7Yjg6BPROTdg6Yjbpg 699 | --向勇 700 | 【串口中断】 701 | >> 老师好,关于串口的中断处理函数的分析我也遇到了一个类似的问题。就是case语句中没有执行任何操作: 702 | >> case IRQ_OFFSET + IRQ_COM1: 703 | >> case IRQ_OFFSET + IRQ_KBD: 704 | >> …… 705 | >> 请问这是为什么,我在写代码注释和文档分析的时候应该怎么说明这个问题?谢谢。 706 | 答: 707 | 按下面的函数调用顺序,中断信号会触发串口的处理操作。 708 | kcons_getc() 709 | cons_getc() 710 | serial_intr() 711 | cons_intr() 712 | serial_proc_data() 713 | 【管道容量】 714 | > 向老师,袁助教: 715 | > 您好,代码分析部分实验的插图我按照那个链接提示把图片放到附件里并链接到相应的位置去了,具体链接如下: 716 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OsTrain2011/ca/6_1%EF%BC%8C&usg=AFQjCNG3y4Pu9LpJKJkMiK-OsU5N5HEdrQ 717 | 但是我不小心将图片也作为附件添加到如下位置去了: 718 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OsTrain2011/test/fs%3Faction%3DAttachFile%EF%BC%8C&usg=AFQjCNFdo9i1F1gXrr3qq8UN7IPjra6LVA我好像不能删除。 719 | > 另外,代码测试部分实验我觉得usr-core里面的关于文件系统(fs)的测试部分已经很全面了,我选择管道这样一个很小的方面进行测试(当然usr-cor¬e里面已经存在与管道相关的测试文件)。根据我自己测的结果,在一个进程里面,当使用管道传递超过4000字节的内容qemu会崩溃(多进程不会出现这种情况)¬,相关链接如下: 720 | http://www.google.com/url?sa=D&q=http://os.cs.tsinghua.edu.cn/oscourse/OsTrain2011/test/fs%EF%BC%8C&usg=AFQjCNEa5pjW7zZEFF38o9zv8HkHW6W5Kg我不知道这样理解是不是正确的。如果这样理解是正确的话,我是不是可以尝试下修改VFS或SFS里的内容使之在单进程中不能使用管道或者使用管道有限制? 721 | > 此致, 722 | > 敬礼! 723 | 724 | 答: 725 | 我已删除你错放在“/test/fs”中的图片,并更正了在“/ca/6_1”中的图片显示格式。现可在页面中正常看到你的图片了。 726 | 关于管道的容量问题,任何管道都是会有容量的限制,不管是一个进程内还是在两个进程用管道。你测试到的情况表明,ucore中的管道实现是不完善的。你可以对比¬一下Linux和ucore中你的例子时的区别。如果可能,把你比较的结果和原因分析告诉我。 727 | --向勇 728 | 【管道容量】 729 | > 向老师: 730 | > 您好,今天我做了一些小的测试,分别在ubuntu和ucore的qemu中测试了管道的容量,我的感觉是,好像在多个进程之间管道的容量好像并不受限制,我测¬试了1000000字节,完全没问题,可能我测的数量还不够多。另外,在单进程之间有一些差异,ubuntu在65536字节时还能正常保证管道正常运行,但在¬65537字节时就不行了;而ucore的这一数据是4000/4001。我没有查到真正的理论数值,只是觉得ucore可能也想取2的整数倍(4096),不¬过由于自身结构占去了一部分字节。而在ubuntu中对这一问题做了相应的修改,在定义时附加了这一部分控件,使之能成为2^16,不过这也只是我自己的想法。¬不过相同的一点是,在同一进程时,ubuntu和ucore中在管道容量越界之后都会死掉不执行。 731 | > 在这两部分中我使用了相同构架的代码,具体的结果我通过截图的形式保存来了起来,分别保存为"Linux_ubuntu.PNG"、"Linux_ucore.¬PNG",其中在ubuntu中我在越界时使用"Ctrl+C"退出,在ucore中我直接在终端中使用命令"q"退出,所以在qumu中会有"_",我将两张¬截图都放在了附件中。 732 | > 此致, 733 | > 敬礼! 734 | 735 | 答: 736 | 现在你可以查一下ucore和Linux的实现代码,就能解释你现在看到的现象。对这个现象的探究能让你真正理解管道的容量的含义。下面是一些提示。 737 | 1)ucore-mp中文件“pipe_state.c”中定义的“PIPE_BUFSIZE”就是管道容量的上限,只要在管道读写的过程中已写入但没有读出的¬数据不超过这个上限,读写操作就能正常返回。你可以通过交替读写的例子来测试在这个边界处的现象。 738 | 2)Linux中与pipe容量相关的代码如下: 739 | http://www.google.com/url?sa=D&q=http://lxr.linux.no/linux%2Bv3.1/include/linux/pipe_fs_i.h%23L21&usg=AFQjCNHw4bzBK8qtQw0vq0ttjuu_QDjeyw 740 | 相关数据结构: 741 | struct pipe_buffer 742 | struct pipe_inode_info 743 | unsigned int pipe_max_size = 1048576; 744 | 相关内核函数: 745 | pipe_write 746 | pipe_set_size 747 | pipe_fcntl 748 | 相关手册: 749 | http://www.google.com/url?sa=D&q=http://linux.die.net/man/7/pipe&usg=AFQjCNGonXa74EstcEbYyNenCnHoCSpM9A 750 | pipe(7) - Linux man page 751 | http://www.google.com/url?sa=D&q=http://linux.die.net/man/2/fcntl&usg=AFQjCNHGvKHUDLDdU3Wmo-1S0-Jg1n5_Lw 752 | Changing the capacity of a pipe 753 | --向勇 754 | 【磁盘管理】 755 | 1.free_pages_bulk的时候要检查相邻的块是不是可以合并,按理说应该前后相邻都要检查,而函数中使用语句buddy_idx = page_idx ^ size,只检查了一个方向啊?这有什么说法吗。 756 | 2.free_pages_bulk的while循环中是不是应该在末尾增加语句size=size<<1,让块合并继续下去呢 757 | 3.UVPT和VPT是什么 758 | 759 | 答: 760 | 每个buddy都是预先分好的,譬如在order=3这一层,1101000就和1100000一组。(注意,低三位为0) 761 | orz..我也觉得是这样 762 | Virtual Page Table。 页表的物理地址? 763 | 764 | First,设计不是完美的,可以改进,如果你能够用例子说明你的改进是有效的,just do it! 765 | 1 没有说法,可能是例子考虑不周 766 | 2 可以的。 767 | 3 UVPT是给用户态用的,完成基本要求可以不考虑UVPT. 768 | 【调度算法】 769 | > 老师好, 770 | > 我是祥明,计72的。我在弄调度算法,想分析各算法的吞吐率,等待反应时间 771 | > 等。。不过xv6好像不能直接用c库中的time.h,是不是想访问系统时间要像 772 | > printf那样从新编写一个单独函数?另外,测试性能时能否不用时间而用中断次 773 | > 数来判断? 774 | 答: 775 | xv6中目前没有获取系统时间的系统调用,你需要写一个相关的系统调用来获取当前时间。系统中有多种不同精度的时间,利用时钟中断的计时就是一种。 776 | --向勇 777 | 【磁盘中断】 778 | > 向老师你好,我是李曦泽(2008011418),我在做第一次实验(代码注释)的过程遇到了一个问题,想问你一下。 779 | > 我选的是各类设备中断处理的这个题目,关于磁盘I/O中断的部分我找到了中断信息的定义: 780 | > IRQ_IDE,然后在trap.c中的dispatch函数里的一个switch语句中找到了它的处理过程,但是这个函数中是这样写的: 781 | > case IRQ_OFFSET + IRQ_IDE1: 782 | > case IRQ_OFFSET + IRQ_IDE2: 783 | > /* do nothing */ 784 | > break; 785 | > 也就是对IDE中断什么也不做,请问这是为什么(或者是我没有找到正确的中断处理函数)? 786 | 答: 787 | 这是因为目前在“https://github.com/xinhaoyuan/ucore-mp64”中的IDE操作并没有使用中断方式,而是在磁盘读写操作时直接使用轮询方式完成的,参见“ide.c”中的函数。 788 | 对这一部分的改进工作可参见“http://www.google.com/url?sa=D&q=http://code.google.com/p/u9proj/source/checkout%E2%80%9D&usg=AFQjCNFp5yEFrXvnEtVur8pJHJX7KlD0XQ。这是上学期操作系统课时完成的一个扩展,支持IDE的中断和DMA。 789 | 790 | 陈老师、王师兄,你们好: 791 | 我试了试Proj1,能单步跟踪什么的,也看了下代码,有几个问题需要请教: 792 | 1. bootmain.c中,串口和并口如果不空闲,delay一段时间后,就直接输出字符了,如果此时仍旧忙呢? 793 | 2. 我试了试oslab-chapt2-13.pdf中2.1.7中的调试: 794 | .pdf中说的断点设置68行"mov1 $start,%esp"处,源代码中该行在69行 795 | .我这边一往下执行直接到for循环那了,没有停在bootmain(void)处 796 | .最后移0x7c00数据的地址在0x7c45而不是0x7c40 797 | .请参见附件的69.jpg和70.jpg拷屏 798 | 799 | 3. 开发时,像printf和abs等c的库函数是否在bootloader和后续的os中的代码都不能用?都得自己实现 800 | ? 801 | 非常感谢~ 802 | 答: 803 | 和Darmen讨论了下,关于第3个问题,是否应该取决于gcc,看能对什么样的语法进行编译,转化为机器码? 804 | 哪些基础函数不需要在操作系统中进行实现就可以直接使用? 805 | 这里面串口和并口都是连接输出的,没有考虑如果依旧忙的情况。但是给了足够长的时间让他把字符输出到console,而且这些输出都是调试相关的,不影响内核实现。不用考虑100%的正确情况吧。99.99%就行了 :") 806 | pdf 的行号以及函数不能保证完全一致,因为我正在往里面加注释。也可能随时修改里面的函数调用过程,比如修改bug。文档的内容用做参考。能找到就行。 807 | 关于断点的设置。编译的时候,会在 obj 目录下生成 .asm 反汇编的内容以及 .sym 符号表。一切以生成的为准。以后文档会依照代码进行适当的修改。:'( 所以,看的时候,应该打开这些文件找到相应的符号位置。 808 | 程序中所有的函数都需要重新实现。没有现成的。以往写普通程序,因为libc已经实现好了。但是ucore目前没有libc,所有的函数都是自己实现的。如果需¬要,但是没有,那么你们就得自己写。 809 | 【lab1问题】 810 | 陈老师您好! 811 | homework1中我有下面几个问题不太明白。 812 | 1、ucore操作系统是单体内核还是微内核组织架构?为什么? 813 | 2、在lab1/proj3中,在bootloader中,当执行到bootmain函数时,栈(stack)的起始地址(base)是多少?bootload¬er启动的OS执行到init.c中kern_init函数时,栈的起始地址(base)是多少?是否会出现栈溢出的现象?简要说明答案的缘由。 814 | 这个问题是要通过静态分析代码得到答案吗?如何分析? 815 | 3、请告知lab1/proj3中的init.c中的kern_init函数的逻辑地址、线性地址和物理地址分别是多少? 816 | 这个问题也是要通过静态分析代码得到答案吗?如何分析?如果用gdb查看,可以看到cs和eip,但不知怎样看到物理地址?另外,lab1没有分页,线性地址和¬物理地址应该是一样的吧? 817 | 希望老师解答,谢谢! 818 | 答: 819 | 单体内核。因为它把内存管理、文件系统、进程管理等传统操作系统的重要组成部分都放在内核中实现,可通过function call来相互访问,而不像微内核组织架构那样,有用户态的server实现, server之间通过IPC机制来相互访问。 820 | 821 | 静态分析就可以了。 看看SP的赋值是多少,如果做push操作过多,压栈所用的内存空间以前是否有用,覆盖后对后续 bootloader和OS有影响? 822 | 823 | 可以静态分析也可以动态分析,重点了解段表中的段表项中的地址映射关系。 824 | 用gdb查看,可以看到cs和eip是逻辑地址,物理地址可根据段地址映射关系静态算出来的。 825 | lab1没有分页,线性地址和物理地址是一样的。 826 | 【lab1和其扩展实验的问题】 827 | 基本把Lab1+challenge实现了一下,发现了一个问题: 828 | 用qemu纯软件模拟时没有问题。 829 | 但用一台带虚拟化技术的CPU+kvm模块(qemu会自动检测使用kvm) 行时貌似有bug?开启kvm 830 | proj3.1什么都不改时,make grade命令根本不会返回(是Makefile脚本的问题?)rmmod kvm-intel ;rmmod kvm;后一切正常。 831 | proj4加上基本的中断初始化(0-255 -> trap) 832 | 在print system footprint后会触发 833 | 1 ++ setup timer interrupts 834 | 2 trapframe at 0x7b80 835 | 3 edi 0x00000000 836 | 4 esi 0x00010094 837 | 5 ebp 0x00007be8 838 | 6 oesp 0x00007ba0 839 | 7 ebx 0x00010094 840 | 8 edx 0x000000a1 841 | 9 ecx 0x00000000 842 | 10 eax 0x000000ff 843 | 11 es 0x----0010 844 | 12 ds 0x----0010 845 | 13 trap 0x0000002f Hardware Interrupt 846 | 14 err 0x00000000 847 | 15 eip 0x001016a9 848 | 16 cs 0x----0008 849 | 17 flag 0x00000206 PF,IF,IOPL=0 850 | 18 kernel panic at kern/trap/trap.c:240: 851 | 19 unexpected trap in kernel. 852 | trap 0x0000002f Hardware Interrupt 这个中断在无kvm时不会发生。。 853 | 另外,中断时eip 0x001016a9,在initr_enable里,sti后两条指令。 854 | 这个是因为kvm把host的硬件中断调度到虚拟机里面了? 855 | 还是什么原因呢? 856 | 总而言之,硬件虚拟话貌似会改变系统运行情况。。??? 857 | 答: 858 | kvm 修改了qemu作为它的device (当然也是模拟的),与qemu也许有些不同。 859 | ox2f中断可能是其模拟的某个设备产生的。ucore收到这个中断认为是错误,其实可以简单的修改ucore,即不把0x2f中断的产生当成错误,而是丢掉不¬管。 860 | 总而言之,如果这个中断是kvm模拟的硬件环境中的某个外设产生的,ucore不处理其实没啥。 861 | 【lab2调试问题】 862 | 在lab2--proj6--lapic.c 中58-62行完成了SMP方式下的时钟中断初始化工作。所以如果大家在用qemu调试时,注意要加上smp 参数,比如: 863 | qemu -smp 2 -hda xv6.img 864 | 如果把default_pmm.c中的defult_check函数改为 865 | ----------------------------------- 866 | static void 867 | default_check(void) { 868 | basic_check(); 869 | } 870 | ---------------------------------- 871 | 那么你会发现pmm.c中的check_alloc_page函数会通过,并输出检查成功信息: 872 | "check_alloc_page() succeeded!\n" 873 | 这说明目前default_pmm中给出的空闲块分配算法可用,但很简单,不是first fit算法,所以在没有比较正确的first fit算法实现的情况下,defult_check函数中的某处会出错。 874 | 之前chyh1...@gmail.com给出的email中有很好的first fit执行过程的分析思路,请大家参考。 875 | 【lab2的问题】 876 | In part 1 of lab2, I meet with a problem, which occurs in this position: 877 | pmap.c / check_page_alloc(): 878 | LIST_FOREACH(pp0, &page_free_list, pp_link) 879 | memset(page2kva(pp0), 0x97, 128); 880 | The error info is: 881 | Physical memory: 32768K available, base = 640K, extended = 31744K 882 | kernel panic at bx_dbg_read_linear: physical memory read error 883 | (phy=0xa7979797, lin=0xa7979797 884 | Next at t=9812888 885 | (0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; 886 | ea5be000f0 887 | before the position, there is a hint that is as follows: 888 | // if there's a page that shouldn't be on 889 | // the free list, try to make sure it 890 | // eventually causes trouble. 891 | So I think maybe that's the problem. However, I can't fix it in the end. Does anybody know how to solve this problem? 892 | 答: 893 | It seems that your code does something malicious, causing Bochs panicking. Find out what physical address access causing this panic. 894 | 895 | You must have made some mistake in page_init() when building page_free_list. 896 | Make sure you add only VALID & FREE physical memory pages to the list. 897 | 898 | Yes, this is the problem because when I make the page above the EXTPHYSMEM used, check_page_alloc() can work. However it is not correct as it is said in page_init(): 899 | // 4) Then extended memory [EXTPHYSMEM, ...). 900 | // Some of it is in use, some is free. Where is the kernel? 901 | // Which pages are used for page tables and other data 902 | structures? 903 | I read many resources about this , but I can't get it. What structure does the physical address is? How can I get the address of " pages used for page tables and other data 904 | structures" ? Thx! 905 | 906 | PADDR(va) translates virtual address va to phys. address. 907 | IOPHYSMEM, EXTPHYSMEM, etc are already physical addresses. 908 | PPN(pa) gives you the index of pages[] for phys. address pa. 909 | BTW, I suggest you spend several minutes to read carefully inc/memlayout.h inc/mmu.h kern/pmap.h and understand what's going on there. That will help you much. 910 | --------------------------------------------------------------------------------