Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ $U/initcode: $U/initcode.S
tags: $(OBJS) _init
etags *.S *.c

ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/umalloc.o
ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/guy2.o $U/umalloc.o

_%: %.o $(ULIB)
$(LD) $(LDFLAGS) -T $U/user.ld -o $@ $^
Expand All @@ -103,7 +103,7 @@ $U/usys.o : $U/usys.S
$U/_forktest: $U/forktest.o $(ULIB)
# forktest has less library code linked in - needs to be small
# in order to be able to max out the proc table.
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $U/_forktest $U/forktest.o $U/ulib.o $U/usys.o $U/umalloc.o $U/printf.o
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $U/_forktest $U/forktest.o $U/ulib.o $U/usys.o $U/guy2.o $U/umalloc.o $U/printf.o
$(OBJDUMP) -S $U/_forktest > $U/forktest.asm

mkfs/mkfs: mkfs/mkfs.c $K/fs.h $K/param.h
Expand All @@ -120,6 +120,7 @@ UPROGS=\
$U/_echo\
$U/_forktest\
$U/_grep\
$U/_guy\
$U/_init\
$U/_kill\
$U/_ln\
Expand Down
20 changes: 20 additions & 0 deletions docs/guy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Documentation for guy:

For project01, I created a guy.c file that connects to a guy2.c file containing a graphics library for anyone to use.

All of the functions within user.h under guy.c are available for use directly in any program that you would wish.

When starting up FogOS, you will see the first animation of guy, and you can see more by typing guy.info. You can also use ls or rm to see more animations I added in to xv6.

To create this guy library, I had to add a sleep_ms() system call to the kernel, which uses ceiling division to calculate the number of misk rotations in a milisecond, and in turn, sleep for
one milisecond. This is used within each animation, giving the code time to gather each image before printing it out. I also utilized a clear_screen() function, which works the same way as colors do for
this OS.

The animations execute by running sleep, clear screen and print in a loop. If the CPU is struggling or already handling a lot, sleep_ms may lag some, resulting in a less pretty animation.

To fix this, quit other applications on your machine.

Challenges and road blocks in creating this:

Reduced the lag in my animation by writing the entire thing to a buffer, then printing the buffer rather than running a few individual loops at once. See man_run() for an example of this.
Furhter, I really wanted the animation to work when a seg fault occurs, but this is pretty difficult since FogOS doesn't have signals yet. I spent around 2 hours troubleshooting possible ways to get this to work. Since a seg faulting is caught and handled in the hardware and kernel, having the usertrap() function communicate with the user space would take a lot of extra work.
2 changes: 2 additions & 0 deletions kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ extern uint64 sys_dup(void);
extern uint64 sys_getpid(void);
extern uint64 sys_sbrk(void);
extern uint64 sys_sleep(void);
extern uint64 sys_sleep_ms(void);
extern uint64 sys_uptime(void);
extern uint64 sys_open(void);
extern uint64 sys_write(void);
Expand All @@ -118,6 +119,7 @@ static uint64 (*syscalls[])(void) = {
[SYS_getpid] sys_getpid,
[SYS_sbrk] sys_sbrk,
[SYS_sleep] sys_sleep,
[SYS_sleep_ms] sys_sleep_ms,
[SYS_uptime] sys_uptime,
[SYS_open] sys_open,
[SYS_write] sys_write,
Expand Down
1 change: 1 addition & 0 deletions kernel/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_sleep_ms 22
23 changes: 23 additions & 0 deletions kernel/sysproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,29 @@ sys_sleep(void)
release(&tickslock);
return 0;
}
uint64
sys_sleep_ms(void)
{
int n;
uint ticks0;

argint(0, &n);
acquire(&tickslock);

uint target_ticks = (n + 1000 - 1) / 1000;

ticks0 = ticks;

while(ticks - ticks0 < target_ticks){
if(killed(myproc())){
release(&tickslock);
return -1;
}
sleep(&ticks, &tickslock);
}
release(&tickslock);
return 0;
}

uint64
sys_kill(void)
Expand Down
193 changes: 193 additions & 0 deletions user/FogOSGraphix
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#include "kernel/types.h"
#include "kernel/stat.h"
#include "kernel/fcntl.h"
#include "user/user.h"

//
// wrapper so that it's OK if main() does not call exit().
//
void
_main()
{
extern int main();
main();
exit(0);
}

char*
strcpy(char *s, const char *t)
{
char *os;

os = s;
while((*s++ = *t++) != 0)
;
return os;
}

int
strcmp(const char *p, const char *q)
{
while(*p && *p == *q)
p++, q++;
return (uchar)*p - (uchar)*q;
}

uint
strlen(const char *s)
{
int n;

for(n = 0; s[n]; n++)
;
return n;
}

void*
memset(void *dst, int c, uint n)
{
char *cdst = (char *) dst;
int i;
for(i = 0; i < n; i++){
cdst[i] = c;
}
return dst;
}

char*
strchr(const char *s, char c)
{
for(; *s; s++)
if(*s == c)
return (char*)s;
return 0;
}

char*
gets(char *buf, int max)
{
fgets(0, buf, max);
return buf;
}

int
fgets(int fd, char *buf, int max)
{
int i, cc;
char c;

for(i=0; i+1 < max; ){
cc = read(fd, &c, 1);
if(cc < 1)
break;
buf[i++] = c;
if(c == '\n' || c == '\r')
break;
}
buf[i] = '\0';
return i;
}

int
getline(char **lineptr, uint *n, int fd)
{
if (*lineptr == 0 && *n == 0) {
*n = 128;
*lineptr = malloc(*n);
}

char *buf = *lineptr;
uint total_read = 0;
while (1) {
int read_sz = fgets(fd, buf + total_read, *n - total_read);
if (read_sz == 0) {
return total_read;
} else if (read_sz == -1) {
// error
return -1;
}

total_read += read_sz;
if (buf[total_read - 1] == '\n') {
break;
}

uint new_n = *n * 2;
char *new_buf = malloc(new_n);
memcpy(new_buf, buf, *n);
free(buf);

buf = new_buf;

*n = new_n;
*lineptr = buf;
}

return total_read;
}


int
stat(const char *n, struct stat *st)
{
int fd;
int r;

fd = open(n, O_RDONLY);
if(fd < 0)
return -1;
r = fstat(fd, st);
close(fd);
return r;
}

int
atoi(const char *s)
{
int n;

n = 0;
while('0' <= *s && *s <= '9')
n = n*10 + *s++ - '0';
return n;
}

void*
memmove(void *vdst, const void *vsrc, int n)
{
char *dst;
const char *src;

dst = vdst;
src = vsrc;
if (src > dst) {
while(n-- > 0)
*dst++ = *src++;
} else {
dst += n;
src += n;
while(n-- > 0)
*--dst = *--src;
}
return vdst;
}

int
memcmp(const void *s1, const void *s2, uint n)
{
const char *p1 = s1, *p2 = s2;
while (n-- > 0) {
if (*p1 != *p2) {
return *p1 - *p2;
}
p1++;
p2++;
}
return 0;
}

void *
memcpy(void *dst, const void *src, uint n)
{
return memmove(dst, src, n);
}
19 changes: 19 additions & 0 deletions user/guy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "user/user.h"
#include "kernel/types.h"

int main (int argc, char *argv[]) {
if (argc == 1) {
print_guy();
} else if (strcmp(argv[1], "run") == 0) {
guy_run();
} else if ((strcmp(argv[1], "gets") == 0) && (strcmp(argv[2], "mad") == 0)) {
guy_mad();
} else if (strcmp(argv[1], "info") == 0) {
guy_info();
} else if (strcmp(argv[1], "celebrate") == 0) {
guy_celebrate();
} else {
printf("Mistyped, try again");
}
return 0;
}
6 changes: 6 additions & 0 deletions user/guy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef MYFILE_H
#define MYFILE_H

void guy_color();

#endif // MYFILE_H
Loading