100% Guaranteed Results


COMP9201 – Assignment 2 Solved
$ 24.99
Category:

Description

5/5 – (1 vote)

The Basic ASST2 Spec
• Implement open(), read(), write(), lseek(), close(), and dup2()
• Assume you need to support fork()
• Document the concurrency issues introduced by fork()
• However, you should not synchronise the actual code
• Can assume we will only test with a single process at a time.
• Your data structures should not need significant changes to support fork()
• Except for synchronisation
• User-level exists
• asst2
• C libraries
• An existing framework and code for:
• system call dispatching,
• VFS
• Emufs
• drivers
Overview
• Overall structure
• User-level
• Process structure • In-kernel
• The storage stack
• Overview of VFS and emufs functionality
• Details
• Understanding the system interface
• Argument passing
• System call dispatching
• Moving data across the user-kernel boundary
• Connecting the interface to the VFS
Structure of a Computer System

kseg2
kseg1
kseg0
Proc 3 kuseg
Proc 1 kuseg Proc 2 kuseg
0xFFFFFFFF
R3000 Address Space Layout
0xC0000000
• ksegX not accessible in usermode
• Switching processes switches the
application view of memory 0xA0000000
(translation stored in a page table) for kuseg
0x80000000
0x00000000
0xffffffff
Process Layout
0xC0000000
• Where is asst2 code/data (from asst2.c)?
0xA0000000
0x80000000
0x10000000
0x04000000
0x00000000
0xffffffff
Calling open()
0xC0000000
int open(const char *filename, int flags, …);
0xA0000000 • Where is the function “open()”?
0x80000000
0x10000000
0x04000000
0x00000000
Structure of a Computer System

Application
OS/161 storage stack
Syscall dispatching

FD table
OF table
VFS
FS
Device driver

0xffffffff
open()?
0xC0000000
int open(const char *filename, int flags, …);
0xA0000000
• Where is “open()’s” implementation?
• By convention, it’s called sys_open() in the
0x80000000
0x10000000
0x04000000
0x00000000
Application
Existing storage stack
Syscall dispatching

FD table
OF table
VFS

FS
Device driver

Details
System Call Interface
int open(const char *filename, int flags); int open(const char *filename, int flags, mode_t mode); int close(int fd); ssize_t read(int fd, void *buf, size_t buflen); ssize_t write(int fd, const void *buf, size_t nbytes); int dup2(int oldfd, int newfd); off_t lseek(int fd, off_t pos, int whence);
Solution should work with fork() if implemented pid_t fork(void);
open/close
int open(const char *filename, int flags); int open(const char *filename, int flags, mode_t mode); int close(int fd);
Read/write
ssize_t read(int fd, void *buf, size_t buflen); ssize_t write(int fd, const void *buf, size_t nbytes);
dup2
int dup2(int oldfd, int newfd);
lseek
off_t lseek(int fd, off_t pos, int whence);
fork
pid_t fork(void);
Argument passing
#include <unistd.h> int reboot(int code);
Description
reboot reboots or shuts down the system. The specific action depends on the code passed:
RB_REBOOT The system is rebooted.
RB_HALT The system is halted.
RB_POWEROFF The system is powered off.
Return Values
On success, reboot does not return. On error, -1 is returned, and errno is set according to the error encountered.
ra
fp
sp
gp
k1
k0
s7

s0
t9

t0
a3
a2
a1
a0
v1
v0
AT
zero
ra
fp
sp
gp
k1
k0
s7

s0
t9

t0
a3
a2
a1
a0
v1
v0
AT
zero
Preserved
Convention
Convention for for kernel
kernel entryexit
Preserved for C
calling
convention Preserved
Success?
Args in
Result
SysCall No.
struct trapframe { u_int32_t tf_vaddr; /* vaddr register */ Kernel Stack

epc
s8
sp
gp
k1
k0
t9
t8

at
ra
hi
lo
cause
status
vaddr
u_int32_t tf_status; /* status register */ u_int32_t tf_cause; /* cause register */ u_int32_t tf_lo; u_int32_t tf_hi; u_int32_t tf_ra; /* Saved register 31 */ u_int32_t tf_at; /* Saved register 1 (AT) */ u_int32_t tf_v0; /* Saved register 2 (v0) */ u_int32_t tf_v1; /* etc. */
u_int32_t tf_a0; u_int32_t tf_a1; u_int32_t tf_a2; u_int32_t tf_a3; u_int32_t tf_t0;
⁞ u_int32_t tf_t7; u_int32_t tf_s0;
⁞ u_int32_t tf_s7; u_int32_t tf_t8; u_int32_t tf_t9; u_int32_t tf_k0;
*/ u_int32_t tf_k1; u_int32_t tf_gp; u_int32_t tf_sp; u_int32_t tf_s8; u_int32_t tf_epc;
};
syscall(struct trapframe *tf)
{ callno = tf->tf_v0; retval = 0;
switch (callno) { case SYS_reboot:
err = sys_reboot(tf->tf_a0); break; /* Add stuff here */
default: kprintf(“Unknown syscall %d “, callno); err = ENOSYS; break;
}
if (err) { tf->tf_v0 = err; tf->tf_a3 = 1; /* signal an error */
} else { /* Success. */ tf->tf_v0 = retval; tf->tf_a3 = 0; /* signal no error */
}
tf->tf_epc += 4;
}
System Call Interface
int open(const char *filename, int flags); int open(const char *filename, int flags, mode_t mode); int close(int fd); ssize_t read(int fd, void *buf, size_t buflen); ssize_t write(int fd, const void *buf, size_t nbytes); int dup2(int oldfd, int newfd); off_t lseek(int fd, off_t pos, int whence);
lseek() Offset
uint64_t offset; int whence; off_t retval64;
join32to64(tf->tf_a2, tf->tf_a3, &offset);
copyin((userptr_t)tf->tf_sp + 16, &whence, sizeof(int));
split64to32(retval64, &tf->tf_v0, &tf->tf_v1);

Pointers
0xC0000000
• What about the first argument to
open() 0xA0000000
• It’s a string?
• What are the problems with accessing a string (i.e. user-specified region of 0x80000000 memory)?
0x10000000
Copy in/out(str)
0xC0000000
int copyin(const_userptr_t usersrc, void *dest, size_t len);
int copyout(const void *src, userptr_t userdest,
0xA0000000
size_t len);
int copyinstr(const_userptr_t usersrc, char *dest, size_t len, size_t *got);
int copyoutstr(const char *src, userptr_t userdest, size_t len, size_t *got); 0x80000000
0x10000000
Buffers – e.g. read()
• Kernel framework for safely handling 0xC0000000 buffers
• Does error/range/validity checking for
you 0xA0000000
ssize_t read(int fd, void *buf, size_t buflen);
0x80000000
struct iovec { union {
userptr_t iov_ubase; /* user-supplied pointer */
void *iov_kbase; /* kernel-supplied pointer */
};
size_t iov_len; /* Length of data */
};
0x10000000

VFS READ
A macro with sanity checking
VOP_READ(vn, uio)
Invokes a function point of following prototype:
int (*vop_read)(struct vnode *file, struct uio *uio);
What are the arguments?
UIO
/* Source/destination. */ enum uio_seg {
UIO_USERISPACE, /* User process code. */
UIO_USERSPACE, /* User process data. */
UIO_SYSSPACE,
};
struct uio { /* Kernel. */
struct iovec *uio_iov; /* Data blocks */
unsigned uio_iovcnt; /* Number of iovecs */
off_t uio_offset; /* Desired offset into object */
size_t uio_resid; /* Remaining amt of data to xfer */
enum uio_seg uio_segflg; /* What kind of pointer we have */
enum uio_rw uio_rw; /* Whether op is a read or write */
struct addrspace *uio_space; /* Address space for user pointer */
};
Sample Helper function
uio_uinit(struct iovec *iov, struct uio *u, userptr_t buf, size_t len, off_t offset, enum uio_rw rw)
{ iov->iov_ubase = buf; iov->iov_len = len; u->uio_iov = iov; u->uio_iovcnt = 1; u->uio_offset = offset; u->uio_resid = len; u->uio_segflg = UIO_USERSPACE; u->uio_rw = rw; u->uio_space = proc_getas();
}
System call implementation
1. sys_open()
2. sys_close() 3. sys_read()
4. sys_write()
5. sys_lseek()
6. sys_dup2() 1. vfs_open()
• copyinstr()
2. vfs_close()
3. VOP_READ()
4. VOP_WRITE()
5. VOP_ISSEEKABLE()
6. VOP_STAT()

Reviews

There are no reviews yet.

Be the first to review “COMP9201 – Assignment 2 Solved”

Your email address will not be published. Required fields are marked *

Related products