Skip to content

Commit

Permalink
wrapping up summer work
Browse files Browse the repository at this point in the history
  • Loading branch information
josehu07 committed Aug 20, 2021
1 parent 1e8289e commit eee2b62
Show file tree
Hide file tree
Showing 24 changed files with 604 additions and 171 deletions.
Binary file modified README-demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 8 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ Hux - An x86 32-bit single-CPU toy operating system kernel built from scratch, f

## Tutorial / Development Doc

I document the whole development process of Hux - its skeleton, related theories, practice pitfalls, plus everything I reckon important as a complete set of tutorials. They can be found at:

- The [**WIKI pages 📝**](https://github.com/josehu07/hux-kernel/wiki) of this repo ✭
- The Hux kernel dev doc PDF (identical, WIP)
I document the whole development process of Hux as a complete set of tutorials. They can be found at the [**WIKI pages 📝**](https://github.com/josehu07/hux-kernel/wiki) of this GitHub repository ✭.

If there are any typos / mistakes / errors, please raise an issue!

Expand All @@ -30,23 +27,20 @@ Requires a Linux host development environment. Tested on Ubuntu Xenial, Bionic,
Clone the repo, set up a development cross-compilation toolchain following [this wiki page](https://github.com/josehu07/hux-kernel/wiki/02.-The-Very-First-Skeleton), then build Hux by:

```bash
$ make clean
$ make
```

Or, if you just want to try out Hux without a development toolchain, download both the released kernel image `hux.iso` and the initial file system image `vsfs.img` to the folder.

(The images have bot been uploaded yet. The first release of Hux is coming soon.)
Or, if you just want to try out Hux without a development toolchain, download both the released kernel image `hux.iso` and the initial file system image `vsfs.img` to the folder. (The images have bot been uploaded yet. The first release of Hux is coming soon.)

To run Hux in QEMU, do:
To run Hux in QEMU (currently only supports GUI VGA mode, "nographics" mode is coming soon), do:

```bash
$ make qemu
```

You will see the QEMU GUI popping up with GRUB loaded. Choose the "`Hux`" option with <kbd>Enter</kbd> to boot into Hux.

A random screenshot of the system at current progress:

<p align=center> <img src="README-demo.gif" width=720px align=center /> </p>

For development setup & instructions, please check out the wiki pages (recommended). I have every single detail documented there.
Expand Down Expand Up @@ -99,11 +93,12 @@ Check the "References" section [here](https://github.com/josehu07/hux-kernel/wik
- [x] Essential system calls
- [x] Time-sharing scheduler
- [x] Basic IDE disk driver
- [ ] Very simple file system
- [x] Very simple file system
- [ ] More user-level utilities
- [ ] Thorough user-level tests
- [ ] Caching, swapping, & logging
- [ ] Multi-threading concurrency
- [x] Synchronization primitives
- [ ] Multi-threading concurrency
- [ ] Move to APIC & IOAPIC
- [ ] Direct memory access
- [ ] Summary of current flaws
- [ ] Extend Hux to Rux with Rust
2 changes: 2 additions & 0 deletions src/common/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,8 @@ _vsnprintf(char *buf, size_t count, const char *fmt, va_list va)
seg_end++;
fmt++;
}

*buf = '\0';
}


Expand Down
7 changes: 4 additions & 3 deletions src/filesys/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,19 @@ exec_program(mem_inode_t *inode, char *filename, char **argv)
goto fail;
sp = sp - (strlen(argv[argc]) + 1);
sp &= 0xFFFFFFFC; /** Align to 32-bit words. */
memcpy((char *) (paddr_top - (USER_MAX - sp)), argv[argc],
memcpy((char *) (paddr_top + PAGE_SIZE - (USER_MAX - sp)), argv[argc],
strlen(argv[argc]) + 1);
ustack[3 + argc] = sp;
}
ustack[3 + argc] = 0; /** End of argv list. */

ustack[2] = sp - (argc + 1) * 4; /** `argv` */
ustack[1] = argc; /** `argv` */
ustack[1] = argc; /** `argc` */
ustack[0] = 0x0000DEAD; /** Fake return address. */

sp -= (3 + argc + 1) * 4;
memcpy((char *) (paddr_top - (USER_MAX - sp)), ustack, (3 + argc + 1) * 4);
memcpy((char *) (paddr_top + PAGE_SIZE - (USER_MAX - sp)), ustack,
(3 + argc + 1) * 4);

/** Change process name. */
strncpy(proc->name, filename, strlen(filename));
Expand Down
15 changes: 15 additions & 0 deletions src/filesys/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "file.h"
#include "block.h"
#include "vsfs.h"
#include "sysfile.h"

#include "../common/debug.h"
#include "../common/string.h"
Expand Down Expand Up @@ -521,3 +522,17 @@ file_put(file_t *file)
/** Actually closing, put inode. */
inode_put(inode);
}


/** Get metadata information of a file. */
void
file_stat(file_t *file, file_stat_t *stat)
{
inode_lock(file->inode);

stat->inumber = file->inode->inumber;
stat->type = file->inode->d_inode.type;
stat->size = file->inode->d_inode.size;

inode_unlock(file->inode);
}
3 changes: 3 additions & 0 deletions src/filesys/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <stddef.h>

#include "vsfs.h"
#include "sysfile.h"

#include "../common/spinlock.h"
#include "../common/parklock.h"
Expand Down Expand Up @@ -73,5 +74,7 @@ file_t *file_get();
void file_ref(file_t *file);
void file_put(file_t *file);

void file_stat(file_t *file, file_stat_t *stat);


#endif
17 changes: 17 additions & 0 deletions src/filesys/sysfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,20 @@ syscall_exec(void)
}
return SYS_FAIL_RC;
}

/** int32_t fstat(int32_t fd, file_stat_t *stat); */
int32_t
syscall_fstat(void)
{
int32_t fd;
file_stat_t *stat;

if (!sysarg_get_int(0, &fd))
return SYS_FAIL_RC;
if (!sysarg_get_mem(1, (char **) &stat, sizeof(file_stat_t)))
return SYS_FAIL_RC;

if (!filesys_fstat(fd, stat))
return SYS_FAIL_RC;
return 0;
}
10 changes: 10 additions & 0 deletions src/filesys/sysfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
#define CREATE_DIR 0x2


/** For the `fstat()` syscall. */
struct file_stat {
uint32_t inumber;
uint32_t type;
uint32_t size;
};
typedef struct file_stat file_stat_t;


int32_t syscall_open();
int32_t syscall_close();
int32_t syscall_create();
Expand All @@ -28,6 +37,7 @@ int32_t syscall_write();
int32_t syscall_chdir();
int32_t syscall_getcwd();
int32_t syscall_exec();
int32_t syscall_fstat();


#endif
15 changes: 15 additions & 0 deletions src/filesys/vsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,21 @@ filesys_exec(char *path, char **argv)
}


/** Get metadata information about an open file. */
bool
filesys_fstat(int8_t fd, file_stat_t *stat)
{
file_t *file = _find_process_file(fd);
if (file == NULL) {
warn("fstat: cannot find file for fd %d", fd);
return false;
}

file_stat(file, stat);
return true;
}


/** Flush the in-memory modified bitmap block to disk. */
bool
inode_bitmap_update(uint32_t slot_no)
Expand Down
4 changes: 4 additions & 0 deletions src/filesys/vsfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <stdbool.h>
#include <stddef.h>

#include "sysfile.h"

#include "../common/bitmap.h"


Expand Down Expand Up @@ -126,6 +128,8 @@ bool filesys_getcwd(char *buf, size_t limit);

bool filesys_exec(char *path, char **argv);

bool filesys_fstat(int8_t fd, file_stat_t *stat);

bool inode_bitmap_update(uint32_t slot_no);
bool data_bitmap_update(uint32_t slot_no);

Expand Down
3 changes: 2 additions & 1 deletion src/interrupt/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ static syscall_t syscall_handlers[] = {
[SYSCALL_WRITE] syscall_write,
[SYSCALL_CHDIR] syscall_chdir,
[SYSCALL_GETCWD] syscall_getcwd,
[SYSCALL_EXEC] syscall_exec
[SYSCALL_EXEC] syscall_exec,
[SYSCALL_FSTAT] syscall_fstat
};

#define NUM_SYSCALLS ((int32_t) (sizeof(syscall_handlers) / sizeof(syscall_t)))
Expand Down
1 change: 1 addition & 0 deletions src/interrupt/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#define SYSCALL_CHDIR 17
#define SYSCALL_GETCWD 18
#define SYSCALL_EXEC 19
#define SYSCALL_FSTAT 20


/**
Expand Down
6 changes: 4 additions & 2 deletions user/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


#include <stdint.h>
#include <stddef.h>

#include "lib/syscall.h"
#include "lib/debug.h"
Expand All @@ -22,8 +23,9 @@ main(void)

if (shell_pid == 0) {
/** Child: exec the command line shell. */
char *argv[1];
argv[0] = 0;
char *argv[2];
argv[0] = "shell";
argv[1] = NULL;
exec("shell", argv);
error("init: failed to exec the shell program");

Expand Down
2 changes: 2 additions & 0 deletions user/lib/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,8 @@ _vsnprintf(char *buf, size_t count, const char *fmt, va_list va)
seg_end++;
fmt++;
}

*buf = '\0';
}

/** Wrapper over string printing for `printf()` and `cprintf()`. */
Expand Down
24 changes: 24 additions & 0 deletions user/lib/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@
#define CREATE_FILE 0x1
#define CREATE_DIR 0x2

/** Struct & type code for `fstat()`. */
#define INODE_TYPE_EMPTY 0
#define INODE_TYPE_FILE 1
#define INODE_TYPE_DIR 2

struct file_stat {
uint32_t inumber;
uint32_t type;
uint32_t size;
};
typedef struct file_stat file_stat_t;

/** Struct of a directory entry, see `vsfs.h`. */
#define DENTRY_SIZE 128
#define MAX_FILENAME 100

struct dentry {
uint32_t valid;
uint32_t inumber;
char filename[DENTRY_SIZE - 8];
} __attribute__((packed));
typedef struct dentry dentry_t;


/**
* Externed from ASM `syscall.s`.
Expand All @@ -50,6 +73,7 @@ extern int32_t write(int32_t fd, char *src, uint32_t len);
extern int32_t chdir(char *path);
extern int32_t getcwd(char *buf, uint32_t limit);
extern int32_t exec(char *path, char **argv);
extern int32_t fstat(int32_t fd, file_stat_t *stat);


#endif
1 change: 1 addition & 0 deletions user/lib/syscall.s
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ SYSCALL_LIBGEN write, SYSCALL_WRITE
SYSCALL_LIBGEN chdir, SYSCALL_CHDIR
SYSCALL_LIBGEN getcwd, SYSCALL_GETCWD
SYSCALL_LIBGEN exec, SYSCALL_EXEC
SYSCALL_LIBGEN fstat, SYSCALL_FSTAT
1 change: 1 addition & 0 deletions user/lib/syslist.s
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ SYSCALL_WRITE = 16
SYSCALL_CHDIR = 17
SYSCALL_GETCWD = 18
SYSCALL_EXEC = 19
SYSCALL_FSTAT = 20
Loading

0 comments on commit eee2b62

Please sign in to comment.