/* * switch_to(n) should switch tasks to task nr n, first * checking that n isn't the current task, in which case it does nothing. * This also clears the TS-flag if the task we switched to has used * tha math co-processor latest. */ #define switch_to(n) {\ struct {long a,b;} __tmp; \ __asm__("cmpl %%ecx,_current\n\t" \ "je 1f\n\t" \ "movw %%dx,%1\n\t" \ "xchgl %%ecx,_current\n\t" \ //强行切到进程0 "ljmp %0\n\t" \ //第一次执行完 for pause 这一行执行完了执行 _syscall0的 if(__res >=0) || 看这里 copy_process: p->tss.eip = eip; "cmpl %%ecx,_last_task_used_math\n\t" \ //进程0回到for pause "jne 1f\n\t" \ "clts\n" \ "1:" \ ::"m" (*&__tmp.a),"m" (*&__tmp.b), \ //IA32 任务切换 "d" (_TSS(n)),"c" ((long) task[n])); \ }
/* * This function is used through-out the kernel (includeinh mm and fs) * to indicate a major problem. */ #include<linux/kernel.h> #include<linux/sched.h>
/* * add-request adds a request to the linked list. * It disables interrupts so that it can muck with the * request-lists in peace. */ staticvoidadd_request(struct blk_dev_struct * dev, struct request * req) { ..... if (!(tmp = dev->current_request)) { dev->current_request = req; sti(); (dev->request_fn)(); // return; } ..... }
问的是,以下代码 if (!(tmp = dev->current_request)) { dev->current_request = req;
问的是这一段代码是什么意思 if (--CURRENT->nr_sectors) { do_hd = &read_intr; //再来一次 return; }
请求项的结构体在哪?
kernel/lkd_drv/blk.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* * Ok, this is an expanded form so that we can use the same * request for paging requests when that is implemented. In * paging, 'bh' is NULL, and 'waiting' is used to wait for * read/write completion. */ structrequest { int dev; /* -1 if no request */ int cmd; /* READ or WRITE */ int errors; unsignedlong sector; unsignedlong nr_sectors; char * buffer; structtask_struct * waiting; structbuffer_head * bh; structrequest * next; };
35、bread()函数代码中为什么要做第二次if (bh->b_uptodate)判断?
p112、134. 赵炯 p342
第一次是在找有没有被使用过的
fs/buffer.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* * bread() reads a specified block and returns the buffer that contains * it. It returns NULL if the block was unreadable. */ struct buffer_head * bread(int dev,int block) { structbuffer_head * bh; // if (!(bh=getblk(dev,block))) //找不到就应该继续等,所以不应该为空 panic("bread: getblk returned NULL\n"); if (bh->b_uptodate) return bh; ll_rw_block(READ,bh); //开始读写硬盘了,硬盘驱动 wait_on_buffer(bh); if (bh->b_uptodate) return bh; brelse(bh); returnNULL; }
36、getblk()函数中,两次调用wait_on_buffer()函数,两次的意思一样吗?
p125 bread里面一次
37、getblk()函数中 do { if (tmp->b_count) continue; if (!bh || BADNESS(tmp)<BADNESS(bh)) { bh = tmp; if (!BADNESS(tmp)) break; }/* and repeat until we find something good */ } while ((tmp = tmp->b_next_free) != free_list);说明什么情况下执行continue、break。
38、make_request()函数 if (req < request) { if (rw_ahead) { unlock_buffer(bh); return; } sleep_on(&wait_for_request); goto repeat;