ucore lab 8
練習(xí)0:填寫已有實(shí)驗(yàn)
請(qǐng)把你做的實(shí)驗(yàn)代碼填入本實(shí)驗(yàn)中代碼中有“LAB1”/“LAB2”/“LAB3”/“LAB4”/“LAB5”/“LAB6” /“LAB7”的注釋相應(yīng)部分。并確保編譯通過。注意:為了能夠正確執(zhí)行l(wèi)ab8的測(cè)試應(yīng)用程序,可能需對(duì)已完成的實(shí)驗(yàn)1/2/3/4/5/6/7的代碼進(jìn)行進(jìn)一步改進(jìn)。
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="c" cid="n8" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> vmm.c default_pmm.c pmm.c proc.c swap_fifo.c trap.c check_sync.c
proc.c:
static struct proc_struct *alloc_proc(void) {
//初始化PCB下的fs
proc->filesp = NULL;
}
int do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
//使用copy_fs復(fù)制父進(jìn)程的fs到子進(jìn)程中
if (copy_fs(clone_flags, proc) != 0) {
goto bad_fork_cleanup_kstack;
}
}</pre>
練習(xí)1: 完成讀文件操作的實(shí)現(xiàn)(需要編碼)
首先了解打開文件的處理流程,然后參考本實(shí)驗(yàn)后續(xù)的文件讀寫操作的過程分析,編寫在sfs_inode.c中sfs_io_nolock讀文件中數(shù)據(jù)的實(shí)現(xiàn)代碼。
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="c" cid="n17" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> static int sfs_io_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, void *buf, off_t offset, size_t *alenp, bool write) {
// 先判斷第一塊的情況 如果沒對(duì)齊 就從偏移的地方讀取
if ((blkoff = offset % SFS_BLKSIZE) != 0) {
// 判斷 endpos 和 offset 是否在同一塊中
// 若為同一塊 則 size 為 endpos - offset
// 若不為同一塊 則 size 為 SFS_BLKSIZE - blkoff(偏移) 為 第一塊要讀的大小
size = (nblks != 0) ? (SFS_BLKSIZE - blkoff) : (endpos - offset);
if ((ret = sfs_bmap_load_nolock(sfs, sin, blkno, &ino)) != 0) {
goto out;
}
if ((ret = sfs_buf_op(sfs, buf, size, ino, blkoff)) != 0) {
goto out;
}
alen += size;
if (nblks == 0) {
goto out;
}
buf += size, blkno++; nblks--;
}
?
// 中間對(duì)齊的情況
size = SFS_BLKSIZE;
while (nblks != 0) {
if ((ret = sfs_bmap_load_nolock(sfs, sin, blkno, &ino)) != 0) {
goto out;
}
if ((ret = sfs_block_op(sfs, buf, ino, 1)) != 0) {
goto out;
}
alen += size, buf += size, blkno++, nblks--;
}
?
// 末尾最后一塊沒對(duì)齊的情況
if ((size = endpos % SFS_BLKSIZE) != 0) {
if ((ret = sfs_bmap_load_nolock(sfs, sin, blkno, &ino)) != 0) {
goto out;
}
if ((ret = sfs_buf_op(sfs, buf, size, ino, 0)) != 0) {
goto out;
}
alen += size;
}
}</pre>
練習(xí)2: 完成基于文件系統(tǒng)的執(zhí)行程序機(jī)制的實(shí)現(xiàn)(需要編碼)
改寫proc.c中的load_icode函數(shù)和其他相關(guān)函數(shù),實(shí)現(xiàn)基于文件系統(tǒng)的執(zhí)行程序機(jī)制。執(zhí)行:make qemu。如果能看看到sh用戶程序的執(zhí)行界面,則基本成功了。如果在sh用戶界面上可以執(zhí)行”ls”,”hello”等其他放置在sfs文件系統(tǒng)中的其他執(zhí)行程序,則可以認(rèn)為本實(shí)驗(yàn)基本成功。
在 Lab 7 的基礎(chǔ)上進(jìn)行修改 讀elf文件變成了從磁盤上讀 而不是直接在內(nèi)存中讀
參數(shù)在棧中的布局:
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="c" cid="n22" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> | High Address |
| Argument |
| n |
| ... |
| Argument |
| 1 |
| padding |
| null ptr |
| Ptr Arg n |
| ... |
| Ptr Arg 1 |
| Arg Count | <-- user esp
| Low Address |</pre>
實(shí)現(xiàn):
<pre mdtype="fences" cid="n32" lang="" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px 0px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> static int load_icode(int fd, int argc, char **kargv) {
//setup argc, argv
//先算出所有參數(shù)加起來的長(zhǎng)度
uint32_t argv_size=0, i;
for (i = 0; i < argc; i ++) {
argv_size += strnlen(kargv[i],EXEC_MAX_ARG_LEN ) + 1;
}
//用戶棧頂減去所有參數(shù)加起來的長(zhǎng)度,再4字節(jié)對(duì)齊,找到真正存放字符串參數(shù)的棧的位置
char *arg_str = (USTACKTOP - argv_size) & 0xfffffffc;
//放字符串參數(shù)的棧的位置的下面,是存放指向字符串參數(shù)的指針
int32_t *arg_ptr = (int32_t *)arg_str - argc;
//指向字符串參數(shù)的指針下面是參數(shù)的個(gè)數(shù)
int32_t *stacktop = arg_ptr - 1;
*stacktop = argc;
for (i = 0; i < argc; i ++){
uint32_t arg_len = strnlen(kargv[i], EXEC_MAX_ARG_LEN);
strncpy(arg_str, kargv[i], argv_size);
*arg_ptr = arg_str;
arg_str += arg_len + 1;
++arg_ptr;
}
}</pre>

參考: