Under the pretext of a school volunteer project, I chose to dig into xv6 OS to understand how processes work in a given operating system. First, I had to download every tool needed to launch xv6 from Windows 10's command line. I also had to download xv6 itself.
Modifications on xv6
Quick start: hello and shutdown system calls
In the root directory where xv6 is located, there are so many files that could confuse the untrained eye. Other xv6 repositories seem better organized than this one out there just so you know, it is a matter of making a couple of searches.
I initially chose to write a small and basic system call named hello which would just print any message in the terminal (some sort of Hello World). To implement the system call shutdown, a system call called halt will also be included.
A few modifications were needed in the files syscall.c, syscall.h, user.h, usys.s, sysproc.c, and Makefile besides new files called hello.c, shutdown.c, and halt.c.
Modifications in syscall.h
// System call numbers
#define SYS_fork 1
#define SYS_exit 2
// (...)
#define SYS_close 21
#define SYS_halt 22 // Added
#define SYS_hello 23 // Added
Modifications in syscall.c
extern int sys_chdir(void);
extern int sys_close(void);
extern int sys_dup(void);
// (...)
extern int sys_uptime(void);
extern int sys_halt(void); // Added
extern int sys_hello(void); // Added
static int (*syscalls[])(void) = {
[SYS_fork] sys_fork,
[SYS_exit] sys_exit,
// (...)
[SYS_close] sys_close,
[SYS_halt] sys_halt, // Added
[SYS_hello] sys_hello // Added
};
Modifications in usys.s
SYSCALL(fork)
SYSCALL(exit)
SYSCALL(wait)
// (...)
SYSCALL(uptime)
SYSCALL(halt) // Added
SYSCALL(hello) // Added
Modifications in user.h
// system calls
int fork(void);
int exit(void) __attribute__((noreturn));
// (...)
int uptime(void);
int halt(void); // Added
int hello(void); // Added
Modifications in sysproc.c
// (...)
int
sys_hello(void)
{
cprintf("### Hello World ###\n");
return 0;
}
int
sys_halt(void)
{
outb(0xf4, 0x00);
return 0;
}
Modifications in Makefile
# (...)
UPROGS=\
_cat\
_echo\
# (...)
_shutdown\ # Added
_hello\ # Added
# (...)
QEMUOPTS = -drive file=fs.img,index=1,media=disk,format(...)
-device isa-debug-exit,iobase=0xf4,iosize=0x04 # Added
# (...)
EXTRA=\
# (...)
shutdown.c\ # Added
hello.c\ # Added
printf.c umalloc.c\
# (...)
Content of hello.c
#include "types.h"
#include "user.h"
int main(void)
{
hello();
/*
* Unlike another OS, in xv6 it is needed to call exit() so resources can be freed.
* Otherwise, this will not finish its execution correctly and error messages will rise.
*/
exit();
}
Content of halt.c
int
sys_halt(void)
{
outb(0xf4, 0x00);
return 0;
}
Content of shutdown.c
#include "types.h"
#include "user.h"
int main(void){
halt();
exit();
}
With these changes, it is now possible to launch both the hello and shutdown system calls. The hello system call simply prints a message in the command line. The shutdown system call shuts the system down.
All the information I needed to implement the shutdown system call: "Adding New System Calls to xv6."
Checking processes status using the ps system call
To implement the process status system call I had to retrieve the code from andear@github, which reorganizes the xv6 project in a much more comprehensive way using modules.
Changes in the files syscall.h, syscall.c, user.h, usys.s, sysproc.c, sysfunc.h, makefile.mk, proc.c, and defs.h were needed. Also, two new files ProcessInfo.h and ps.c were created.
Modifications in syscall.h
// (...)
#define SYS_getprocs number
Modifications in syscall.c
// (...)
[SYS_getprocs] sys_getprocs
Modifications in user.h
// system calls
int fork(void);
int exit(void) __attribute__((noreturn));
// (...)
int getprocs(struct ProcessInfo* processInfoTable); // Added
int halt(void);
int hello(void);
Modifications in usys.s
SYSCALL(fork)
SYSCALL(exit)
// (...)
SYSCALL(getprocs) // Added
SYSCALL(halt)
SYSCALL(hello)
Modifications in sysproc.c
#include "ProcessInfo.h" *
// (...)
int
sys_getprocs(void){
struct ProcessInfo *processInfoTable;
if(argptr(0,(char**)&processInfoTable,sizeof(struct ProcessInfo) * NPROC) < 0) {
return -1;
}
return getprocs(processInfoTable);
}
Modifications in sysfunc.h
// System call handlers
int sys_chdir(void);
int sys_close(void);
// (...)
int sys_getprocs(void); // Added
int sys_hello(void);
int sys_halt(void);
Modifications in makefile.mk
USER_PROGS := \
cat\
echo\
# (...)
ps\ # Added
shutdown\
hello\
Modifications in proc.c
#include "ProcessInfo.h" *
// (...)
int
getprocs(struct ProcessInfo* processInfoTable){
struct proc *p;
int count = 0;
int i;
for (i = 0, p = ptable.proc; p < &ptable.proc[NPROC] && i < NPROC; i++,p++)
{
if(p->state == UNUSED)
{
continue;
}
count++;
processInfoTable[i].pid = p->pid;
if(i == 0){
processInfoTable[i].ppid = 0;
}
else{
processInfoTable[i].ppid = p->parent->pid;
}
processInfoTable[i].state = p->state;
processInfoTable[i].sz = p->sz;
for (int j = 0; j < 16; j++)
{
processInfoTable[i].name[j] = p->name[j];
}
}
p = NULL;
return count;
}
Modifications in defs.h
// proc.c
// (...)
void yield(void);
int getprocs(struct ProcessInfo*); // Added
Content of ProcessInfo.h
#ifndef _PROCESSINFO_H_
#define _PROCESSINFO_H_
#include "types.h"
struct ProcessInfo{
int pid;
int ppid;
int state;
uint sz;
char name[16];
};
#endif
Content of ps.c
#include "ProcessInfo.h"
#include "types.h"
#include "stat.h"
#include "user.h"
#include "param.h"
int main(void)
{
enum procstate { UNUSED, EMBRYO, BLOCKED, READY, ACTIVE, ZOMBIE };
static char *states[] = {
[UNUSED] "UNUSED ",
[EMBRYO] "EMBRYO ",
[BLOCKED] "BLOCKED",
[READY] "READY",
[ACTIVE] "ACTIVE ",
[ZOMBIE] "ZOMBIE "
};
printf(1, "\n PID\sSTATUS\t\tMEM\tPROC\n");
printf(1,"\n");
struct ProcessInfo processInfoTable[NPROC];
int numbers = getprocs(processInfoTable);
int lineNumber;
for (int i = 0; i < numbers; i++)
{
lineNumber = i + 1;
printf(1, "%d %d\t%s\t%d\t%s",
lineNumber,
processInfoTable[i].pid,
states[processInfoTable[i].state],
processInfoTable[i].sz,
processInfoTable[i].name);
printf(1, "\n");
}
exit();
}
A brief demonstration of what has been implemented
Launching xv6 on Windows 10 through the command line
Calling to hello, ps, sh, and kill system calls
The shutdown system call
This post is also available in Spanish "Implementar la llamada al sistema 'ps' en xv6 | Sistemas Operativos @US".
No hay comentarios:
Publicar un comentario