ucoreラボ8
練習0:既存の実験を記入
あなたが実験この実験は、注釈付きのコードに対応する部分「LAB1」/「LAB2」/「LAB3」/「LAB4」/「LAB5」/「LAB6」/「LAB7」の操作を行うコードを記入してください。そしてを通じてそのコンパイラを確保します。注:正しいコードが完了したテストアプリケーションlab8を実行できるようにするには、さらなる改善のため1/2/3/4/5/6/7実験する必要があるかもしれません。
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复制父进程的fs到子进程中
if (copy_fs(clone_flags, proc) != 0) {
goto bad_fork_cleanup_kstack;
}
}
演習1:完全な読み取りファイル操作に(必要なコーディング)の実装
最初の実装はsfs_io_nolockのsfs_inode.cは、ファイルを読み取るコードで記述されたデータという、プロセスフローは、ファイルを開いて理解して、プロセス分析のこのファイルの読み取りおよび書き込み操作をテストするために参照してください。
static int sfs_io_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, void *buf, off_t offset, size_t *alenp, bool write) {
// 先判断第一块的情况 如果没对齐 就从偏移的地方读取
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--;
}
// 中间对齐的情况
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--;
}
// 末尾最后一块没对齐的情况
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;
}
}
演習2:プログラム実行メカニズムベースのファイルシステムの実装を完了(コーディングが必要です)
ファイルシステムに基づいて、プログラムの実施のためのメカニズムを実装し、load_icode機能および他の関連機能にproc.c書き換えます。実行:メイクQEMU。あなたは、基本的には成功したユーザプログラム実行Shインタフェースに見ることができます。あなたはSHユーザーインターフェース上のSFSファイルシステムに配置された他のを実行するために、「LS」、「こんにちは」と他のプログラムを実行することができれば、それはこの実験の成功に不可欠と考えることができます。
代わりに、メモリに直接読み込むのディスクからの読み取りに読書ラボ7 ELFファイルに変更
スタックレイアウト上のパラメータ:
| High Address |
----------------
| Argument |
| n |
----------------
| ... |
----------------
| Argument |
| 1 |
----------------
| padding |
----------------
| null ptr |
----------------
| Ptr Arg n |
----------------
| ... |
----------------
| Ptr Arg 1 |
----------------
| Arg Count | <-- user esp
----------------
| Low Address |
実装:
static int load_icode(int fd, int argc, char **kargv) {
//setup argc, argv
//先算出所有参数加起来的长度
uint32_t argv_size=0, i;
for (i = 0; i < argc; i ++) {
argv_size += strnlen(kargv[i],EXEC_MAX_ARG_LEN ) + 1;
}
//用户栈顶减去所有参数加起来的长度,再4字节对齐,找到真正存放字符串参数的栈的位置
char *arg_str = (USTACKTOP - argv_size) & 0xfffffffc;
//放字符串参数的栈的位置的下面,是存放指向字符串参数的指针
int32_t *arg_ptr = (int32_t *)arg_str - argc;
//指向字符串参数的指针下面是参数的个数
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;
}
}
参考:
[記事](