From a7ef49da0e07e0a1195794b527fa400c0235fcc7 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 29 Apr 2025 20:59:46 -0400 Subject: tarfs --- kernel/fs/fs.c | 7 +- kernel/fs/tar.c | 262 ++++++++++++++++++++++++++++++++++++++++++ kernel/include/comus/fs/tar.h | 18 +++ kernel/include/comus/user.h | 2 +- kernel/main.c | 38 +++++- kernel/user.c | 36 +++--- 6 files changed, 338 insertions(+), 25 deletions(-) create mode 100644 kernel/fs/tar.c create mode 100644 kernel/include/comus/fs/tar.h (limited to 'kernel') diff --git a/kernel/fs/fs.c b/kernel/fs/fs.c index a887ca4..01dea20 100644 --- a/kernel/fs/fs.c +++ b/kernel/fs/fs.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -50,9 +51,9 @@ static void load_fs(struct disk *disk) fs->fs_id = disk->d_id; fs->fs_present = 1; - // // try examplefs - // if (example_mount(fs) == SUCCESS) - // return; + // try tarfs + if (tar_mount(fs) == SUCCESS) + return; fs->fs_present = 0; WARN("failed to load fs on disk %u", disk->d_id); diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c new file mode 100644 index 0000000..7f34107 --- /dev/null +++ b/kernel/fs/tar.c @@ -0,0 +1,262 @@ +#include +#include + +struct tar_hdr { + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; + char unused[12]; +}; + +struct tar_file { + struct file file; + struct file_system *fs; + size_t len; + size_t offset; + size_t sect; +}; + +#define TAR_SECT_SIZE 512 + +#define TMAGIC "ustar" +#define TMAGLEN 6 +#define TVERSION "00" +#define TVERSLEN 2 + +#define REGTYPE '0' +#define DIRTYPE '5' + +static int read_tar_hdr(struct disk *disk, uint32_t sect, struct tar_hdr *hdr) +{ + if (disk_read(disk, sect * TAR_SECT_SIZE, TAR_SECT_SIZE, hdr) < + TAR_SECT_SIZE) + return 1; + + // check magic + if (memcmp(hdr->magic, TMAGIC, TMAGLEN) != 0) + return 1; + + // check version + if (memcmp(hdr->version, TVERSION, TVERSLEN) != 0) + return 1; + + return 0; +} + +static int tar_to_fs_type(char typeflag) +{ + switch (typeflag) { + case REGTYPE: + return F_REG; + case DIRTYPE: + return F_DIR; + default: + return -1; + } +} + +static int tar_locate(struct file_system *fs, const char *path, + struct tar_hdr *out_hdr, size_t *out_sect, + size_t *in_sect, bool partial) +{ + struct tar_hdr hdr; + size_t sect = 0; + + if (in_sect != NULL) + sect = *in_sect; + + while (1) { + size_t filesize, sects; + int cmp; + + if (read_tar_hdr(fs->fs_disk, sect, &hdr)) + return 1; + + filesize = strtoull(hdr.size, NULL, 8); + sects = (filesize + TAR_SECT_SIZE - 1) / TAR_SECT_SIZE; + + if (partial) { + size_t len = MIN(strlen(path), strlen(hdr.name)); + cmp = memcmp(hdr.name, path, len); + } else { + cmp = memcmp(hdr.name, path, strlen(path) + 1); + } + + if (cmp) { + // not our file, goto next + sect += sects + 1; + continue; + } + + // we found our file! + *out_hdr = hdr; + *out_sect = sect; + if (in_sect != NULL) + *in_sect = sect + sects + 1; + return 0; + } + + return 1; +} + +int tar_read(struct file *in, char *buf, size_t len) +{ + struct tar_file *file = (struct tar_file *)in; + size_t max_bytes = file->len - file->offset; + long bytes = MIN(max_bytes, len); + + if (file->file.f_type != F_REG) + return 1; + + if (bytes < 1) + return 0; + + bytes = disk_read(file->fs->fs_disk, + (file->sect + 1) * TAR_SECT_SIZE + file->offset, bytes, + buf); + if (bytes < 0) + return bytes; // return err code + + file->offset += bytes; + return bytes; +} + +int tar_write(struct file *in, const char *buf, size_t len) +{ + (void)in; + (void)buf; + (void)len; + + // cannot write to tar balls + return -1; +} + +int tar_seek(struct file *in, long int off, int whence) +{ + struct tar_file *file = (struct tar_file *)in; + switch (whence) { + case SEEK_SET: + file->offset = off; + return 0; + case SEEK_CUR: + file->offset += off; + return 0; + case SEEK_END: + file->offset = file->len + off; + return 0; + default: + return 1; + } +} + +int tar_ents(struct file *in, struct dirent *ent, size_t entry) +{ + struct tar_file *file; + struct tar_hdr dir, hdr; + size_t sect; + size_t sect_off = 0; + size_t idx = 0; + + file = (struct tar_file *)in; + sect = 0; + + if (file->file.f_type != F_DIR) + return -1; + + if (read_tar_hdr(file->fs->fs_disk, sect, &dir)) + return 1; + + while (1) { + if (tar_locate(file->fs, dir.name, &hdr, §, §_off, true)) + return 1; + + if (idx != entry) { + idx++; + continue; + } + + ent->d_offset = entry; + ent->d_namelen = strlen(hdr.name); + memcpy(ent->d_name, hdr.name, ent->d_namelen + 1); + return 0; + } + + return 1; +} + +void tar_close(struct file *file) +{ + kfree(file); +} + +int tar_open(struct file_system *fs, const char *path, struct file **out) +{ + struct tar_file *file; + struct tar_hdr hdr; + size_t sect; + + if (tar_locate(fs, path, &hdr, §, NULL, false)) + return 1; + + file = kalloc(sizeof(struct tar_file)); + if (file == NULL) + return 1; + + file->file.f_type = tar_to_fs_type(hdr.typeflag); + file->file.read = tar_read; + file->file.write = tar_write; + file->file.seek = tar_seek; + file->file.ents = tar_ents; + file->file.close = tar_close; + file->fs = fs; + file->len = strtoull(hdr.size, NULL, 8); + file->offset = 0; + file->sect = sect; + *out = (struct file *)file; + + return 0; +} + +int tar_stat(struct file_system *fs, const char *path, struct stat *stat) +{ + struct tar_hdr hdr; + size_t sect; + + if (tar_locate(fs, path, &hdr, §, NULL, false)) + return 1; + + stat->s_length = strtoull(hdr.size, NULL, 8); + stat->s_type = tar_to_fs_type(hdr.typeflag); + + return 0; +} + +int tar_mount(struct file_system *fs) +{ + struct tar_hdr hdr; + + // if first tar hdr is valid, assume valid tarball + if (read_tar_hdr(fs->fs_disk, 0, &hdr)) + return 1; + + fs->fs_present = true; + fs->fs_name = "tar"; + fs->open = tar_open; + fs->stat = tar_stat; + + INFO("loaded tarfs on disk %d", fs->fs_disk->d_id); + return 0; +} diff --git a/kernel/include/comus/fs/tar.h b/kernel/include/comus/fs/tar.h new file mode 100644 index 0000000..084c8bd --- /dev/null +++ b/kernel/include/comus/fs/tar.h @@ -0,0 +1,18 @@ +/** + * @file tar.h + * + * Tarball + */ + +#ifndef TAR_FS_H_ +#define TAR_FS_H_ + +#include + +/** + * Attempts to mount tar filesystem on disk + * @returns 0 on success + */ +int tar_mount(struct file_system *fs); + +#endif /* fs.h */ diff --git a/kernel/include/comus/user.h b/kernel/include/comus/user.h index f51ada5..a1a718b 100644 --- a/kernel/include/comus/user.h +++ b/kernel/include/comus/user.h @@ -15,7 +15,7 @@ /** * Load a user elf program from a file into a pcb */ -int user_load(struct pcb *pcb, struct disk *disk); +int user_load(struct pcb *pcb, struct file *file); /** * Clone a user process. Used for fork(). diff --git a/kernel/main.c b/kernel/main.c index c15c38d..a306e2b 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -22,6 +22,36 @@ void kreport(void) gpu_report(); } +void load_init(void) +{ + struct file_system *fs; + struct file *file; + + if (pcb_alloc(&init_pcb)) + return; + + // get root fs + fs = fs_get_root_file_system(); + if (fs == NULL) + return; + + // get init bin + if (fs->open(fs, "bin/apple", &file)) + return; + + if (user_load(init_pcb, file)) { + file->close(file); + return; + } + + // close file + file->close(file); + + // schedule and dispatch init + schedule(init_pcb); + dispatch(); +} + __attribute__((noreturn)) void main(long magic, volatile void *mboot) { // initalize idt and pic @@ -49,11 +79,7 @@ __attribute__((noreturn)) void main(long magic, volatile void *mboot) kreport(); // load init process - pcb_alloc(&init_pcb); - if (user_load(init_pcb, &fs_disks[0])) - panic("failed to load init"); + load_init(); - // schedule and dispatch init - schedule(init_pcb); - dispatch(); + panic("failed to load init"); } diff --git a/kernel/user.c b/kernel/user.c index e22248a..4007383 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -14,13 +14,13 @@ #define USER_STACK_LEN (4 * PAGE_SIZE) #define BLOCK_SIZE (PAGE_SIZE * 1000) -static uint8_t *load_buffer = NULL; +static char *load_buffer = NULL; #define USER_CODE 0x18 #define USER_DATA 0x20 #define RING3 3 -static int user_load_segment(struct pcb *pcb, struct disk *disk, int idx) +static int user_load_segment(struct pcb *pcb, struct file *file, int idx) { Elf64_Phdr hdr; size_t mem_bytes, mem_pages; @@ -56,14 +56,17 @@ static int user_load_segment(struct pcb *pcb, struct disk *disk, int idx) if (mapADDR == NULL) return 1; + // seek to start of segment + if (file->seek(file, hdr.p_offset, SEEK_SET)) + return 1; + // load data size_t total_read = 0; while (total_read < file_bytes) { size_t read = BLOCK_SIZE; if (read > file_bytes - total_read) read = file_bytes - total_read; - if ((read = disk_read(disk, hdr.p_offset + total_read, read, - load_buffer)) < 1) { + if ((read = file->read(file, load_buffer, read)) < 1) { kunmapaddr(mapADDR); return 1; } @@ -79,7 +82,7 @@ static int user_load_segment(struct pcb *pcb, struct disk *disk, int idx) return 0; } -static int user_load_segments(struct pcb *pcb, struct disk *disk) +static int user_load_segments(struct pcb *pcb, struct file *file) { int ret = 0; @@ -91,7 +94,7 @@ static int user_load_segments(struct pcb *pcb, struct disk *disk) return 1; for (int i = 0; i < pcb->n_elf_segments; i++) - if ((ret = user_load_segment(pcb, disk, i))) + if ((ret = user_load_segment(pcb, file, i))) return ret; if (pcb->heap_start == NULL) { @@ -144,11 +147,13 @@ static int validate_elf_hdr(struct pcb *pcb) return 0; } -static int user_load_elf(struct pcb *pcb, struct disk *disk) +static int user_load_elf(struct pcb *pcb, struct file *file) { int ret = 0; - ret = disk_read(disk, 0, sizeof(Elf64_Ehdr), &pcb->elf_header); + if (file->seek(file, 0, SEEK_SET)) + return 1; + ret = file->read(file, (char *)&pcb->elf_header, sizeof(Elf64_Ehdr)); if (ret < 0) return 1; @@ -156,9 +161,10 @@ static int user_load_elf(struct pcb *pcb, struct disk *disk) return 1; pcb->n_elf_segments = pcb->elf_header.e_phnum; - ret = disk_read(disk, pcb->elf_header.e_phoff, - sizeof(Elf64_Phdr) * pcb->elf_header.e_phnum, - &pcb->elf_segments); + if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET)) + return 1; + ret = file->read(file, (char *)&pcb->elf_segments, + sizeof(Elf64_Phdr) * pcb->elf_header.e_phnum); if (ret < 0) return 1; @@ -199,10 +205,10 @@ static int user_setup_stack(struct pcb *pcb) return 0; } -int user_load(struct pcb *pcb, struct disk *disk) +int user_load(struct pcb *pcb, struct file *file) { // check inputs - if (pcb == NULL || disk == NULL) + if (pcb == NULL || file == NULL) return 1; // allocate memory context @@ -211,11 +217,11 @@ int user_load(struct pcb *pcb, struct disk *disk) goto fail; // load elf information - if (user_load_elf(pcb, disk)) + if (user_load_elf(pcb, file)) goto fail; // load segments into memory - if (user_load_segments(pcb, disk)) + if (user_load_segments(pcb, file)) goto fail; // setup process stack -- cgit v1.2.3-freya From 1a10a3725e7bea67e558715f6e9f78abcb415b3a Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Wed, 30 Apr 2025 21:07:46 -0400 Subject: finish syscall impls --- kernel/fs/tar.c | 15 ++-- kernel/include/comus/fs.h | 11 ++- kernel/include/comus/limits.h | 4 + kernel/include/comus/procs.h | 4 + kernel/include/comus/syscalls.h | 3 +- kernel/include/comus/user.h | 4 +- kernel/main.c | 5 +- kernel/procs.c | 3 +- kernel/syscall.c | 181 +++++++++++++++++++++++++++++++++++++++- kernel/user.c | 59 +++++++++++-- user/include/stdio.h | 6 +- user/include/sys/types.h | 15 ++++ user/include/unistd.h | 16 ++-- user/init.c | 75 +++++++++++++++++ user/lib/entry.S | 5 +- user/lib/fclose.c | 10 +++ user/lib/fseek.c | 16 ++++ user/lib/syscall.S | 3 + 18 files changed, 398 insertions(+), 37 deletions(-) create mode 100644 user/include/sys/types.h create mode 100644 user/init.c create mode 100644 user/lib/fclose.c create mode 100644 user/lib/fseek.c (limited to 'kernel') diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 7f34107..86af81f 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -150,15 +150,15 @@ int tar_seek(struct file *in, long int off, int whence) switch (whence) { case SEEK_SET: file->offset = off; - return 0; + return file->offset; case SEEK_CUR: file->offset += off; - return 0; + return file->offset; case SEEK_END: file->offset = file->len + off; - return 0; + return file->offset; default: - return 1; + return -1; } } @@ -202,12 +202,17 @@ void tar_close(struct file *file) kfree(file); } -int tar_open(struct file_system *fs, const char *path, struct file **out) +int tar_open(struct file_system *fs, const char *path, int flags, + struct file **out) { struct tar_file *file; struct tar_hdr hdr; size_t sect; + // cannot create or write files + if (flags != O_RDONLY) + return 1; + if (tar_locate(fs, path, &hdr, §, NULL, false)) return 1; diff --git a/kernel/include/comus/fs.h b/kernel/include/comus/fs.h index 2f678b6..044330b 100644 --- a/kernel/include/comus/fs.h +++ b/kernel/include/comus/fs.h @@ -148,6 +148,15 @@ struct file { void (*close)(struct file *file); }; +/// open flags +enum { + O_CREATE = 0x01, + O_RDONLY = 0x02, + O_WRONLY = 0x04, + O_APPEND = 0x08, + O_RDWR = 0x10, +}; + /// file system vtable, used for opening /// and stating files. filesystem mount functions must /// set fs_name, fs_disk, open, and stat. @@ -200,7 +209,7 @@ struct file_system { /// filesystem name const char *fs_name; /// opens a file - int (*open)(struct file_system *fs, const char *fullpath, + int (*open)(struct file_system *fs, const char *fullpath, int flags, struct file **out); /// stats a file int (*stat)(struct file_system *fs, const char *fullpath, diff --git a/kernel/include/comus/limits.h b/kernel/include/comus/limits.h index 4cb348d..1ef13b4 100644 --- a/kernel/include/comus/limits.h +++ b/kernel/include/comus/limits.h @@ -12,6 +12,10 @@ /// max number of processes #define N_PROCS 256 +/// process limits +#define N_OPEN_FILES 64 +#define N_ARGS 64 + /// max nubmer of pci devices #define N_PCI_DEV 256 diff --git a/kernel/include/comus/procs.h b/kernel/include/comus/procs.h index 7b1a70a..3df31c3 100644 --- a/kernel/include/comus/procs.h +++ b/kernel/include/comus/procs.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,9 @@ struct pcb { char *heap_start; size_t heap_len; + // open files + struct file *open_files[N_OPEN_FILES]; + // elf metadata Elf64_Ehdr elf_header; Elf64_Phdr elf_segments[N_ELF_SEGMENTS]; diff --git a/kernel/include/comus/syscalls.h b/kernel/include/comus/syscalls.h index f714184..8b671c2 100644 --- a/kernel/include/comus/syscalls.h +++ b/kernel/include/comus/syscalls.h @@ -30,9 +30,10 @@ #define SYS_poweroff 17 #define SYS_drm 18 #define SYS_ticks 19 +#define SYS_seek 20 // UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED! -#define N_SYSCALLS 20 +#define N_SYSCALLS 21 // interrupt vector entry for system calls #define VEC_SYSCALL 0x80 diff --git a/kernel/include/comus/user.h b/kernel/include/comus/user.h index a1a718b..1b35ac4 100644 --- a/kernel/include/comus/user.h +++ b/kernel/include/comus/user.h @@ -9,13 +9,15 @@ #ifndef USER_H_ #define USER_H_ +#include "comus/memory.h" #include #include /** * Load a user elf program from a file into a pcb */ -int user_load(struct pcb *pcb, struct file *file); +int user_load(struct pcb *pcb, struct file *file, const char **args, + mem_ctx_t args_ctx); /** * Clone a user process. Used for fork(). diff --git a/kernel/main.c b/kernel/main.c index a306e2b..72a6668 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -26,6 +26,7 @@ void load_init(void) { struct file_system *fs; struct file *file; + const char *init_vector[] = { NULL }; if (pcb_alloc(&init_pcb)) return; @@ -36,10 +37,10 @@ void load_init(void) return; // get init bin - if (fs->open(fs, "bin/apple", &file)) + if (fs->open(fs, "bin/init", O_RDONLY, &file)) return; - if (user_load(init_pcb, file)) { + if (user_load(init_pcb, file, init_vector, kernel_mem_ctx)) { file->close(file); return; } diff --git a/kernel/procs.c b/kernel/procs.c index 9bf7508..d471416 100644 --- a/kernel/procs.c +++ b/kernel/procs.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include #include @@ -218,7 +219,7 @@ void pcb_zombify(struct pcb *victim) status = (int *)PCB_ARG2(parent); if (pid == 0 || pid == victim->pid) { - PCB_RET(parent) = zchild->pid; + PCB_RET(parent) = victim->pid; assert( pcb_queue_remove(syscall_queue[SYS_waitpid], parent) == SUCCESS, diff --git a/kernel/syscall.c b/kernel/syscall.c index 96d2fcf..44ebfa0 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1,3 +1,5 @@ +#include "comus/fs.h" +#include "lib/kio.h" #include #include #include @@ -23,6 +25,16 @@ static struct pcb *pcb; #define stdout 1 #define stderr 2 +static struct file *get_file_ptr(int fd) +{ + // valid index? + if (fd < 3 || fd >= (N_OPEN_FILES + 3)) + return NULL; + + // will be NULL if not open + return pcb->open_files[fd - 3]; +} + __attribute__((noreturn)) static int sys_exit(void) { ARG1(int, status); @@ -36,6 +48,33 @@ __attribute__((noreturn)) static int sys_exit(void) static int sys_waitpid(void) { + ARG1(pid_t, pid); + ARG2(int *, status); + + struct pcb *child; + for (int i = 0; i < N_PROCS; i++) { + child = &ptable[i]; + if (child->state != PROC_STATE_ZOMBIE) + continue; + if (child->parent != pcb) + continue; + + // we found a child! + if (pid && pid != child->pid) + continue; + + // set status + mem_ctx_switch(pcb->memctx); + *status = child->exit_status; + mem_ctx_switch(kernel_mem_ctx); + + // clean up child process + pcb_cleanup(child); + + // return + return child->pid; + } + // arguments are read later // by procs.c pcb->state = PROC_STATE_BLOCKED; @@ -60,6 +99,125 @@ static int sys_fork(void) return 0; } +static int sys_exec(void) +{ + ARG1(const char *, in_filename); + ARG2(const char **, in_args); + + struct file_system *fs; + struct file *file; + char filename[N_FILE_NAME]; + struct pcb save; + + // save data + file = NULL; + save = *pcb; + + // read filename + mem_ctx_switch(pcb->memctx); + memcpy(filename, in_filename, strlen(in_filename) + 1); + mem_ctx_switch(kernel_mem_ctx); + + // get binary + fs = fs_get_root_file_system(); + if (fs == NULL) + goto fail; + if (fs->open(fs, filename, O_RDONLY, &file)) + goto fail; + + // load program + save = *pcb; + if (user_load(pcb, file, in_args, save.memctx)) + goto fail; + file->close(file); + mem_ctx_free(save.memctx); + schedule(pcb); + dispatch(); + +fail: + *pcb = save; + if (file) + file->close(file); + return 1; +} + +static int sys_open(void) +{ + ARG1(const char *, in_filename); + ARG2(int, flags); + + char filename[N_FILE_NAME]; + struct file_system *fs; + struct file **file; + int fd; + + // read filename + mem_ctx_switch(pcb->memctx); + memcpy(filename, in_filename, strlen(in_filename)); + mem_ctx_switch(kernel_mem_ctx); + + // get fd + for (fd = 3; fd < (N_OPEN_FILES + 3); fd++) { + if (pcb->open_files[fd - 3] == NULL) { + file = &pcb->open_files[fd - 3]; + break; + } + } + + // could not find fd + if (fd == (N_OPEN_FILES + 3)) + return -1; + + // open file + fs = fs_get_root_file_system(); + if (fs == NULL) + return -1; + if (fs->open(fs, filename, flags, file)) + return -1; + + // file opened + return fd; +} + +static int sys_close(void) +{ + ARG1(int, fd); + + struct file *file; + file = get_file_ptr(fd); + if (file == NULL) + return 1; + + file->close(file); + return 0; +} + +static int sys_read(void) +{ + ARG1(int, fd); + ARG2(void *, buffer); + ARG3(size_t, nbytes); + + struct file *file; + char *map_buf; + + map_buf = kmapuseraddr(pcb->memctx, buffer, nbytes); + if (map_buf == NULL) + return -1; + + file = get_file_ptr(fd); + if (file == NULL) + goto fail; + + nbytes = file->read(file, map_buf, nbytes); + kunmapaddr(map_buf); + return nbytes; + +fail: + kunmapaddr(map_buf); + return -1; +} + static int sys_write(void) { ARG1(int, fd); @@ -324,17 +482,34 @@ static int sys_ticks(void) return 0; } +static int sys_seek(void) +{ + RET(long int, ret); + ARG1(int, fd); + ARG2(long int, off); + ARG3(int, whence); + + struct file *file; + file = get_file_ptr(fd); + if (file == NULL) + return -1; + + *ret = file->seek(file, off, whence); + return 0; +} + static int (*syscall_tbl[N_SYSCALLS])(void) = { [SYS_exit] = sys_exit, [SYS_waitpid] = sys_waitpid, - [SYS_fork] = sys_fork, [SYS_exec] = NULL, - [SYS_open] = NULL, [SYS_close] = NULL, - [SYS_read] = NULL, [SYS_write] = sys_write, + [SYS_fork] = sys_fork, [SYS_exec] = sys_exec, + [SYS_open] = sys_open, [SYS_close] = sys_close, + [SYS_read] = sys_read, [SYS_write] = sys_write, [SYS_getpid] = sys_getpid, [SYS_getppid] = sys_getppid, [SYS_gettime] = sys_gettime, [SYS_getprio] = sys_getprio, [SYS_setprio] = sys_setprio, [SYS_kill] = sys_kill, [SYS_sleep] = sys_sleep, [SYS_brk] = sys_brk, [SYS_sbrk] = sys_sbrk, [SYS_poweroff] = sys_poweroff, [SYS_drm] = sys_drm, [SYS_ticks] = sys_ticks, + [SYS_seek] = sys_seek, }; void syscall_handler(void) diff --git a/kernel/user.c b/kernel/user.c index 4007383..9612710 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -57,7 +57,7 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) return 1; // seek to start of segment - if (file->seek(file, hdr.p_offset, SEEK_SET)) + if (file->seek(file, hdr.p_offset, SEEK_SET) < 0) return 1; // load data @@ -151,7 +151,7 @@ static int user_load_elf(struct pcb *pcb, struct file *file) { int ret = 0; - if (file->seek(file, 0, SEEK_SET)) + if (file->seek(file, 0, SEEK_SET) < 0) return 1; ret = file->read(file, (char *)&pcb->elf_header, sizeof(Elf64_Ehdr)); if (ret < 0) @@ -161,7 +161,7 @@ static int user_load_elf(struct pcb *pcb, struct file *file) return 1; pcb->n_elf_segments = pcb->elf_header.e_phnum; - if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET)) + if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET) < 0) return 1; ret = file->read(file, (char *)&pcb->elf_segments, sizeof(Elf64_Phdr) * pcb->elf_header.e_phnum); @@ -171,14 +171,56 @@ static int user_load_elf(struct pcb *pcb, struct file *file) return 0; } -static int user_setup_stack(struct pcb *pcb) +static int user_setup_stack(struct pcb *pcb, const char **args, + mem_ctx_t args_ctx) { - // allocate stack + /* args */ + int argbytes = 0; + int argc = 0; + + mem_ctx_switch(args_ctx); + + while (args[argc] != NULL) { + int n = strlen(args[argc]) + 1; + if ((argbytes + n) > USER_STACK_LEN) { + // oops - ignore this and any others + break; + } + argbytes += n; + argc++; + } + + // round to nearest multiple of 8 + argbytes = (argbytes + 7) & 0xfffffffffffffff8; + + // allocate arg strings on kernel stack + char argstrings[argbytes]; + char *argv[argc + 1]; + memset(argstrings, 0, sizeof(argstrings)); + memset(argv, 0, sizeof(argv)); + + // Next, duplicate the argument strings, and create pointers to + // each one in our argv. + char *tmp = argstrings; + for (int i = 0; i < argc; ++i) { + int nb = strlen(args[i]) + 1; + strcpy(tmp, args[i]); + argv[i] = tmp; + tmp += nb; + } + + // trailing NULL pointer + argv[argc] = NULL; + + mem_ctx_switch(kernel_mem_ctx); + + /* stack */ if (mem_alloc_pages_at(pcb->memctx, USER_STACK_LEN / PAGE_SIZE, (void *)(USER_STACK_TOP - USER_STACK_LEN), F_WRITEABLE | F_UNPRIVILEGED) == NULL) return 1; + /* regs */ memset(&pcb->regs, 0, sizeof(struct cpu_regs)); // pgdir @@ -189,7 +231,7 @@ static int user_setup_stack(struct pcb *pcb) pcb->regs.es = USER_DATA | RING3; pcb->regs.ds = USER_DATA | RING3; // registers - pcb->regs.rdi = 0; // argc + pcb->regs.rdi = argc; // argc pcb->regs.rsi = 0; // argv // intruction pointer pcb->regs.rip = pcb->elf_header.e_entry; @@ -205,7 +247,8 @@ static int user_setup_stack(struct pcb *pcb) return 0; } -int user_load(struct pcb *pcb, struct file *file) +int user_load(struct pcb *pcb, struct file *file, const char **args, + mem_ctx_t args_ctx) { // check inputs if (pcb == NULL || file == NULL) @@ -225,7 +268,7 @@ int user_load(struct pcb *pcb, struct file *file) goto fail; // setup process stack - if (user_setup_stack(pcb)) + if (user_setup_stack(pcb, args, args_ctx)) goto fail; // success diff --git a/user/include/stdio.h b/user/include/stdio.h index fe29c9d..bb57c6d 100644 --- a/user/include/stdio.h +++ b/user/include/stdio.h @@ -252,7 +252,7 @@ extern size_t fwrite(const void *restrict ptr, size_t size, size_t n, * @param stream - the stream to seek * @param off - the offset from whence * @param whence - where to seek from (SEEK_SET, SEEK_CUR, SEEK_END) - * @returns 0 on success, -1 on error setting errno + * @returns new offset on success, -1 on error */ extern int fseek(FILE *stream, long int off, int whence); @@ -260,9 +260,9 @@ extern int fseek(FILE *stream, long int off, int whence); * return the current position of stream * * @param stream - the stream to tell - * @return the position on success, -1 on error setting errno + * @returns new offset on success, -1 on error */ -extern long int ftell(FILE *stream); +extern long ftell(FILE *stream); /** * rewing to the begining of a stream diff --git a/user/include/sys/types.h b/user/include/sys/types.h new file mode 100644 index 0000000..f1b3266 --- /dev/null +++ b/user/include/sys/types.h @@ -0,0 +1,15 @@ +/** + * @file types.h + * + * @author Freya Murphy + * + * System types + */ + +#ifndef _TYPES_H +#define _TYPES_H + +typedef long int off_t; +typedef unsigned short pid_t; + +#endif /* types.h */ diff --git a/user/include/unistd.h b/user/include/unistd.h index cad3a81..4f582d2 100644 --- a/user/include/unistd.h +++ b/user/include/unistd.h @@ -11,11 +11,10 @@ #include #include +#include /* System Call Definitions */ -typedef unsigned short pid_t; - enum { S_SET = 0, S_CUR = 1, @@ -27,7 +26,7 @@ enum { O_RDONLY = 0x02, O_WRONLY = 0x04, O_APPEND = 0x08, - O_RDWR = O_RDONLY | O_WRONLY, + O_RDWR = 0x010, }; /** @@ -67,11 +66,9 @@ extern int fork(void); * * @param prog - program table index of the program to exec * @param args - the command-line argument vector - * - * Does not return if it succeeds; if it returns, something has - * gone wrong. + * @returns error code on failure */ -extern void exec(const char *filename, char **args); +extern int exec(const char *filename, const char **args); /** * open a stream with a given filename @@ -85,8 +82,9 @@ extern int open(const char *filename, int flags); * closes a stream with the given file descriptior * * @param fd - the file descriptior of the open stream + * @returns 0 on success, error code on invalid fd */ -extern void close(int fd); +extern int close(int fd); /** * read into a buffer from a stream @@ -116,7 +114,7 @@ extern int write(int fd, const void *buffer, size_t nbytes); * @param whence - whence to seek * @return 0 on success, or an error code */ -extern int seek(int fd, long int off, int whence); +extern off_t seek(int fd, off_t off, int whence); /** * gets the pid of the calling process diff --git a/user/init.c b/user/init.c new file mode 100644 index 0000000..18e70a2 --- /dev/null +++ b/user/init.c @@ -0,0 +1,75 @@ +#include +#include + +#define MAX_ARGS 4 + +struct proc { + pid_t pid; + const char *filename; + const char *args[MAX_ARGS]; +}; + +static struct proc spawn_table[] = { + // apple + { 0, "bin/apple", { NULL } }, + // end, + { 0, NULL, { NULL } }, +}; + +static int spawn(const char *filename, const char **args) +{ + int ret; + + // fork init + if ((ret = fork()) != 0) + return ret; + + // call exec + if ((ret = exec(filename, args))) + exit(ret); + + // should not happen! + exit(1); +} + +int main(void) +{ + struct proc *proc; + + // spawn our processes + for (proc = spawn_table; proc->filename != NULL; proc++) { + int pid; + pid = spawn(proc->filename, proc->args); + if (pid < 0) + fprintf(stderr, "init: cannot exec '%s': %d\n", proc->filename, + pid); + proc->pid = pid; + } + + // clean up dead on restart ours + while (1) { + int pid, status; + + pid = waitpid(0, &status); + if (pid < 0) + continue; + + printf("init: pid %d exited with %d\n", pid, status); + + // figure out if this is one of ours + for (proc = spawn_table; proc->filename != NULL; proc++) { + if (proc->pid == pid) { + proc->pid = 0; + pid = spawn(proc->filename, proc->args); + if (pid < 0) + fprintf(stderr, "init: cannot exec '%s': %d\n", + proc->filename, pid); + proc->pid = pid; + break; + } + } + } + + // very very bad! + return 1; +} diff --git a/user/lib/entry.S b/user/lib/entry.S index 40570b5..efaa652 100644 --- a/user/lib/entry.S +++ b/user/lib/entry.S @@ -5,7 +5,6 @@ .section .text .code64 _start: - call main - subq $16, %rsp # ??? - pushq %rax + call main + movq %rax, %rdi call exit diff --git a/user/lib/fclose.c b/user/lib/fclose.c new file mode 100644 index 0000000..be31421 --- /dev/null +++ b/user/lib/fclose.c @@ -0,0 +1,10 @@ +#include +#include + +void fclose(FILE *stream) +{ + int fd; + + fd = (uintptr_t)stream; + close(fd); +} diff --git a/user/lib/fseek.c b/user/lib/fseek.c new file mode 100644 index 0000000..a7a3377 --- /dev/null +++ b/user/lib/fseek.c @@ -0,0 +1,16 @@ +#include +#include + +int fseek(FILE *stream, long off, int whence) +{ + int fd; + fd = (uintptr_t)stream; + return seek(fd, off, whence); +} + +long ftell(FILE *stream) +{ + int fd; + fd = (uintptr_t)stream; + return seek(fd, 0, SEEK_CUR); +} diff --git a/user/lib/syscall.S b/user/lib/syscall.S index 2ba4dc0..9f7025e 100644 --- a/user/lib/syscall.S +++ b/user/lib/syscall.S @@ -13,6 +13,8 @@ SYSCALL exit SYS_exit SYSCALL waitpid SYS_waitpid SYSCALL fork SYS_fork SYSCALL exec SYS_exec +SYSCALL open SYS_open +SYSCALL close SYS_close SYSCALL read SYS_read SYSCALL write SYS_write SYSCALL getpid SYS_getpid @@ -27,3 +29,4 @@ SYSCALL sbrk SYS_sbrk SYSCALL poweroff SYS_poweroff SYSCALL drm SYS_drm SYSCALL ticks SYS_ticks +SYSCALL seek SYS_seek -- cgit v1.2.3-freya From 34247153636c4f38116907eb1421868113cae50d Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:52:25 -0400 Subject: comment out non contigous phys page allocator, its causing problems and this is due tomorrow, dear god aaaaaaaaa --- kernel/memory/paging.c | 114 ++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 49 deletions(-) (limited to 'kernel') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 763bdce..9dfa236 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1025,64 +1025,80 @@ void *mem_alloc_pages(mem_ctx_t ctx, size_t count, unsigned int flags) void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, unsigned int flags) { - size_t pages_needed = count; - - struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; - struct phys_page_slice phys_pages; + void *phys = NULL; if (virtaddr_take(&ctx->virtctx, virt, count)) return NULL; - while (pages_needed > 0) { - phys_pages = alloc_phys_page_withextra(pages_needed); - if (phys_pages.pagestart == NULL) { - goto mem_alloc_pages_at_fail; - } - - { - // allocate the first page and store in it the physical address of the - // previous chunk of pages - // TODO: skip this if there are already enough pages from first alloc - void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, - F_PRESENT | F_WRITEABLE); - if (pageone == NULL) { - panic("kernel out of virtual memory"); - } - *((struct phys_page_slice *)pageone) = prev_phys_block; - prev_phys_block = phys_pages; - kunmapaddr(pageone); - } - - // index into virtual page array at index [count - pages_needed] - void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); - - assert(pages_needed >= phys_pages.num_pages, "overflow"); - pages_needed -= phys_pages.num_pages; + phys = alloc_phys_pages_exact(count); + if (phys == NULL) + return NULL; - if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, - phys_pages.pagestart, flags, phys_pages.num_pages)) { - goto mem_alloc_pages_at_fail; - } + if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, count)) { + free_phys_pages(phys, count); + return NULL; } return virt; -mem_alloc_pages_at_fail: - while (prev_phys_block.pagestart) { - void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, - F_PRESENT | F_WRITEABLE); - if (!virtpage) { - // memory corruption, most likely a bug - // could also ERROR here and exit with leak - panic("unable to free memory from failed mem_alloc_pages_at call"); - } - struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; - prev_phys_block = prev; - free_phys_pages_slice(prev); - kunmapaddr(virtpage); - } - - return NULL; +// size_t pages_needed = count; +// +// struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; +// struct phys_page_slice phys_pages; +// +// if (virtaddr_take(&ctx->virtctx, virt, count)) +// return NULL; +// +// while (pages_needed > 0) { +// phys_pages = alloc_phys_page_withextra(pages_needed); +// if (phys_pages.pagestart == NULL) { +// goto mem_alloc_pages_at_fail; +// } +// +// { +// // allocate the first page and store in it the physical address of the +// // previous chunk of pages +// // TODO: skip this if there are already enough pages from first alloc +// void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, +// F_PRESENT | F_WRITEABLE); +// if (pageone == NULL) { +// panic("kernel out of virtual memory"); +// } +// *((struct phys_page_slice *)pageone) = prev_phys_block; +// prev_phys_block = phys_pages; +// kunmapaddr(pageone); +// } +// +// // index into virtual page array at index [count - pages_needed] +// void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); +// +// assert(pages_needed >= phys_pages.num_pages, "overflow"); +// pages_needed -= phys_pages.num_pages; +// +// if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, +// phys_pages.pagestart, flags, phys_pages.num_pages)) { +// goto mem_alloc_pages_at_fail; +// } +// } +// +// return virt; +// +//mem_alloc_pages_at_fail: +// while (prev_phys_block.pagestart) { +// void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, +// F_PRESENT | F_WRITEABLE); +// if (!virtpage) { +// // memory corruption, most likely a bug +// // could also ERROR here and exit with leak +// panic("unable to free memory from failed mem_alloc_pages_at call"); +// } +// struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; +// prev_phys_block = prev; +// free_phys_pages_slice(prev); +// kunmapaddr(virtpage); +// } +// +// return NULL; } void mem_free_pages(mem_ctx_t ctx, const void *virt) -- cgit v1.2.3-freya From fa9f4baeecd1e18fc2db9192660d0de5d8b54e8c Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:52:41 -0400 Subject: FUCKING OFF BY ONE ERRORS --- kernel/lib/kalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/lib/kalloc.c b/kernel/lib/kalloc.c index 0141149..02e9457 100644 --- a/kernel/lib/kalloc.c +++ b/kernel/lib/kalloc.c @@ -34,7 +34,7 @@ static struct page_header *get_header(void *ptr) static void *alloc_new(size_t size) { - size_t pages = ((size + header_len) / PAGE_SIZE) + 1; + size_t pages = ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; void *addr = kalloc_pages(pages); void *mem = (char *)addr + header_len; @@ -180,7 +180,7 @@ void kfree(void *ptr) for (neighbor = header->prev; neighbor != NULL; neighbor = neighbor->prev) { if (neighbor->node_number != header->node_number) break; - if (neighbor->used && header->used) + if (neighbor->used || header->used) break; neighbor->free += header->free + header_len; neighbor->next = header->next; -- cgit v1.2.3-freya From 27afee24b6f89b11399033ed46278900cc0a43fa Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:53:02 -0400 Subject: more data! --- kernel/memory/virtalloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/memory/virtalloc.h b/kernel/memory/virtalloc.h index 5033242..44bf8d7 100644 --- a/kernel/memory/virtalloc.h +++ b/kernel/memory/virtalloc.h @@ -13,7 +13,7 @@ #include #include -#define BOOTSTRAP_VIRT_ALLOC_NODES 64 +#define BOOTSTRAP_VIRT_ALLOC_NODES 256 struct virt_addr_node { /// first virtural address -- cgit v1.2.3-freya From bfb4f18ddc8b915c9ce5b1e5c085c30b836458db Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:53:15 -0400 Subject: fix yet another terrible bug, someone please kill me --- kernel/memory/virtalloc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index 0cbba33..4ee75bb 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -1,10 +1,12 @@ -#include "lib/kio.h" #include #include #include #include "virtalloc.h" +extern char kernel_start[]; +extern char kernel_end[]; + static struct virt_addr_node *get_node_idx(struct virt_ctx *ctx, int idx) { if (idx < BOOTSTRAP_VIRT_ALLOC_NODES) { @@ -64,6 +66,7 @@ static struct virt_addr_node *get_node(struct virt_ctx *ctx) for (; idx < count; idx++) { struct virt_addr_node *node = get_node_idx(ctx, idx); if (!node->is_used) { + node->is_used = true; ctx->used_node_count++; return node; } @@ -81,7 +84,7 @@ static void free_node(struct virt_ctx *ctx, struct virt_addr_node *node) void virtaddr_init(struct virt_ctx *ctx) { struct virt_addr_node init = { - .start = 0x50000000, + .start = 0x0, .end = 0x1000000000000, // 48bit memory address max .next = NULL, .prev = NULL, @@ -96,6 +99,10 @@ void virtaddr_init(struct virt_ctx *ctx) ctx->alloc_node_count = 0; ctx->used_node_count = 0; ctx->is_allocating = false; + + virtaddr_take(ctx, (void *)kernel_start, + ((uint64_t)kernel_end - (uint64_t)kernel_start) / PAGE_SIZE + + 1); } int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) @@ -211,9 +218,9 @@ int virtaddr_take(struct virt_ctx *ctx, const void *virt, int n_pages) left->prev = node->prev; left->start = node->start; left->end = (uintptr_t)virt; - left->is_used = true; left->is_alloc = false; - node->prev->next = left; + if (node->prev) + node->prev->next = left; node->prev = left; } @@ -224,16 +231,15 @@ int virtaddr_take(struct virt_ctx *ctx, const void *virt, int n_pages) right->next = node->next; right->start = (uintptr_t)virt + n_length; right->end = node->end; - right->is_used = true; right->is_alloc = false; - node->next->prev = right; + if (node->next) + node->next->prev = right; node->next = right; } node->start = (uintptr_t)virt; node->end = node->start + n_length; node->is_alloc = true; - node->is_used = true; return 0; } @@ -257,6 +263,8 @@ long virtaddr_free(struct virt_ctx *ctx, const void *virtaddr) if (node->start == virt) { int length = node->end - node->start; int pages = length / PAGE_SIZE; + // FIXME: ??? + node->is_alloc = false; merge_back(ctx, node); merge_forward(ctx, node); return pages; -- cgit v1.2.3-freya From d7d2d8dcae508660076304f3ff47d85d289881d5 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:56:30 -0400 Subject: add some warnings so i know what the fuck is going wrong, bah --- kernel/main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/main.c b/kernel/main.c index 72a6668..52f832b 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -28,19 +28,26 @@ void load_init(void) struct file *file; const char *init_vector[] = { NULL }; - if (pcb_alloc(&init_pcb)) + if (pcb_alloc(&init_pcb)) { + WARN("failed to alloc init pcb"); return; + } // get root fs fs = fs_get_root_file_system(); - if (fs == NULL) + if (fs == NULL) { + WARN("failed to get root fs"); return; + } // get init bin - if (fs->open(fs, "bin/init", O_RDONLY, &file)) + if (fs->open(fs, "bin/init", O_RDONLY, &file)) { + WARN("cannot find init elf"); return; + } if (user_load(init_pcb, file, init_vector, kernel_mem_ctx)) { + WARN("init elf failed to load! bad bad BAD!!"); file->close(file); return; } -- cgit v1.2.3-freya From 8a7653bcfadc48e400ad7c6b1346a6c6d7f73deb Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 20:19:38 -0400 Subject: ramdisk --- Makefile | 1 + config/grub.cfg | 3 ++- kernel/fs/fs.c | 14 ++++++++++---- kernel/mboot/module.c | 30 ++++++++++++++++++++++++++---- 4 files changed, 39 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/Makefile b/Makefile index ecb859c..3739534 100644 --- a/Makefile +++ b/Makefile @@ -55,5 +55,6 @@ $(BIN)/$(ISO): build config/grub.cfg mkdir -p $(BIN)/iso/boot/grub cp config/grub.cfg $(BIN)/iso/boot/grub cp kernel/bin/kernel $(BIN)/iso/boot + cp user/bin/initrd.tar $(BIN)/iso/boot $(GRUB) -o $(BIN)/$(ISO) bin/iso 2>/dev/null diff --git a/config/grub.cfg b/config/grub.cfg index 62c9792..b4e395d 100644 --- a/config/grub.cfg +++ b/config/grub.cfg @@ -1,8 +1,9 @@ set timeout=1 set default=0 insmod all_video +insmod normal menuentry "kern" { multiboot2 /boot/kernel - boot + module2 /boot/initrd.tar } diff --git a/kernel/fs/fs.c b/kernel/fs/fs.c index 01dea20..ef031f2 100644 --- a/kernel/fs/fs.c +++ b/kernel/fs/fs.c @@ -123,13 +123,16 @@ int fs_find_file_rel(struct file *rel, char *rel_path, struct file *res) static int disk_read_rd(struct disk *disk, size_t offset, size_t len, uint8_t *buffer) { - if (offset + len >= disk->rd.len) { + if (offset >= disk->rd.len) { WARN("attempted to read past length of ramdisk"); return -E_BAD_PARAM; } + if (disk->rd.len - offset < len) + len = disk->rd.len - offset; + memcpy(buffer, disk->rd.start + offset, len); - return 0; + return len; } static int disk_read_ata(struct disk *disk, size_t offset, size_t len, @@ -182,13 +185,16 @@ int disk_read(struct disk *disk, size_t offset, size_t len, void *buffer) static int disk_write_rd(struct disk *disk, size_t offset, size_t len, uint8_t *buffer) { - if (offset + len >= disk->rd.len) { + if (offset >= disk->rd.len) { WARN("attempted to write past length of ramdisk"); return -E_BAD_PARAM; } + if (disk->rd.len - offset < len) + len = disk->rd.len - offset; + memcpy(disk->rd.start + offset, buffer, len); - return 0; + return len; } static int disk_write_ata(struct disk *disk, size_t offset, size_t len, diff --git a/kernel/mboot/module.c b/kernel/mboot/module.c index 79d092e..cb05b45 100644 --- a/kernel/mboot/module.c +++ b/kernel/mboot/module.c @@ -1,3 +1,4 @@ +#include "comus/memory.h" #include #include "mboot.h" @@ -12,13 +13,34 @@ struct multiboot_tag_module { char cmdline[]; }; +static void *mapped_addr = NULL; +size_t initrd_len; + void *mboot_get_initrd(size_t *len) { - void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_MODULE); + struct multiboot_tag_module *mod; + void *tag, *phys; + + // if already loaded, return + if (mapped_addr) { + *len = initrd_len; + return mapped_addr; + } + + // locate + tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_MODULE); if (tag == NULL) return NULL; - struct multiboot_tag_module *mod = (struct multiboot_tag_module *)tag; - *len = mod->mod_end - mod->mod_start; - return (void *)(uintptr_t)mod->mod_start; + mod = (struct multiboot_tag_module *)tag; + phys = (void *) (uintptr_t) mod->mod_start; + initrd_len = mod->mod_end - mod->mod_start; + + // map addr + mapped_addr = kmapaddr(phys, NULL, initrd_len, F_PRESENT | F_WRITEABLE); + if (mapped_addr == NULL) + return NULL; + + *len = initrd_len; + return mapped_addr; } -- cgit v1.2.3-freya From f7a899db24b91005e57bf4d3b5494e59965c7f04 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 21:34:22 -0400 Subject: changes idk --- kernel/fs/tar.c | 1 + kernel/lib/kalloc.c | 4 +++- kernel/mboot/module.c | 2 +- kernel/memory/paging.c | 3 ++- kernel/memory/physalloc.c | 21 ++++++++++++++++----- kernel/memory/virtalloc.c | 6 +++--- 6 files changed, 26 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 86af81f..061dd0c 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include diff --git a/kernel/lib/kalloc.c b/kernel/lib/kalloc.c index 02e9457..8dca46b 100644 --- a/kernel/lib/kalloc.c +++ b/kernel/lib/kalloc.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include @@ -34,7 +35,8 @@ static struct page_header *get_header(void *ptr) static void *alloc_new(size_t size) { - size_t pages = ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; + size_t pages = + ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; void *addr = kalloc_pages(pages); void *mem = (char *)addr + header_len; diff --git a/kernel/mboot/module.c b/kernel/mboot/module.c index cb05b45..bf15eca 100644 --- a/kernel/mboot/module.c +++ b/kernel/mboot/module.c @@ -33,7 +33,7 @@ void *mboot_get_initrd(size_t *len) return NULL; mod = (struct multiboot_tag_module *)tag; - phys = (void *) (uintptr_t) mod->mod_start; + phys = (void *)(uintptr_t)mod->mod_start; initrd_len = mod->mod_end - mod->mod_start; // map addr diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 9dfa236..39f7638 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include @@ -353,7 +354,7 @@ static volatile struct pt *pt_alloc(volatile struct pd *pPD, void *vADDR, } pPT = alloc_phys_page(); - if (pPD == NULL) + if (pPT == NULL) return NULL; vPT = PT_MAP(pPT); diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 8971bcf..4255339 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include #include @@ -62,7 +63,7 @@ static long page_idx(void *page) static inline bool bitmap_get(size_t i) { - return (bitmap[i / 64] >> i % 64) & 1; + return (bitmap[i / 64] >> (i % 64)) & 1; } static inline void bitmap_set(size_t i, bool v) @@ -71,9 +72,9 @@ static inline void bitmap_set(size_t i, bool v) free_memory -= PAGE_SIZE; else free_memory += PAGE_SIZE; - int idx = i / 64; - bitmap[idx] &= ~(1 << i % 64); - bitmap[idx] |= (v << i % 64); + size_t idx = i / 64; + bitmap[idx] &= ~(1 << (i % 64)); + bitmap[idx] |= (v << (i % 64)); } void *alloc_phys_page(void) @@ -105,9 +106,17 @@ void *alloc_phys_pages_exact(size_t pages) free_region_start = i; n_contiguous++; if (n_contiguous == pages) { + void *pADDR; + pADDR = page_at(free_region_start); + + if (pADDR == NULL) { + n_contiguous = 0; + continue; + } + for (size_t j = 0; j < pages; j++) bitmap_set(free_region_start + j, true); - return page_at(free_region_start); + return pADDR; } } else n_contiguous = 0; @@ -118,6 +127,7 @@ void *alloc_phys_pages_exact(size_t pages) struct phys_page_slice alloc_phys_page_withextra(size_t max_pages) { + panic("please dont use this its broken i think?!\n"); if (max_pages == 0) return PHYS_PAGE_SLICE_NULL; @@ -160,6 +170,7 @@ void free_phys_page(void *ptr) void free_phys_pages_slice(struct phys_page_slice slice) { + panic("please dont use this its broken i think?!\n"); free_phys_pages(slice.pagestart, slice.num_pages); } diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index 4ee75bb..da64f3b 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -100,9 +100,9 @@ void virtaddr_init(struct virt_ctx *ctx) ctx->used_node_count = 0; ctx->is_allocating = false; - virtaddr_take(ctx, (void *)kernel_start, - ((uint64_t)kernel_end - (uint64_t)kernel_start) / PAGE_SIZE + - 1); + virtaddr_take(ctx, (void *)0, + ((uint64_t)kernel_end + PAGE_SIZE - 1) / PAGE_SIZE * + PAGE_SIZE); } int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) -- cgit v1.2.3-freya From d5a0abc2fe0ab570ab9e0de9607fec1e951cb933 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 2 May 2025 12:37:40 -0400 Subject: temp badness --- config/grub.cfg | 2 +- kernel/lib/kalloc.c | 44 ++++++++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 19 deletions(-) (limited to 'kernel') diff --git a/config/grub.cfg b/config/grub.cfg index b4e395d..82c5db7 100644 --- a/config/grub.cfg +++ b/config/grub.cfg @@ -5,5 +5,5 @@ insmod normal menuentry "kern" { multiboot2 /boot/kernel - module2 /boot/initrd.tar + # module2 /boot/initrd.tar } diff --git a/kernel/lib/kalloc.c b/kernel/lib/kalloc.c index 8dca46b..f4cd097 100644 --- a/kernel/lib/kalloc.c +++ b/kernel/lib/kalloc.c @@ -35,8 +35,7 @@ static struct page_header *get_header(void *ptr) static void *alloc_new(size_t size) { - size_t pages = - ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; + size_t pages = ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE); void *addr = kalloc_pages(pages); void *mem = (char *)addr + header_len; @@ -91,6 +90,8 @@ static void *alloc_block(size_t size, struct page_header *block) header->prev = block; header->next = block->next; block->next = header; + if (header->next) + header->next->prev = header; header->node_number = block->node_number; void *mem = (char *)header + header_len; @@ -163,7 +164,7 @@ void *krealloc(void *src, size_t dst_len) void kfree(void *ptr) { - struct page_header *header; + struct page_header *header, *neighbor; if (ptr == NULL) return; @@ -176,17 +177,17 @@ void kfree(void *ptr) header->free += header->used; header->used = 0; - struct page_header *neighbor; - // merge left for (neighbor = header->prev; neighbor != NULL; neighbor = neighbor->prev) { if (neighbor->node_number != header->node_number) break; - if (neighbor->used || header->used) - break; neighbor->free += header->free + header_len; neighbor->next = header->next; + if (neighbor->next) + neighbor->next->prev = neighbor; header = neighbor; + if (header->used) + break; } // merge right @@ -197,17 +198,24 @@ void kfree(void *ptr) break; header->free += neighbor->free + header_len; header->next = neighbor->next; - } - - if ((header->next == NULL || - header->next->node_number != header->node_number) && - (header->prev == NULL || - header->prev->node_number != header->node_number) && - header->used == 0) { if (header->next) - header->next->prev = header->prev; - if (header->prev) - header->prev->next = header->next; - kfree_pages(header); + header->next->prev = header; } + + // ignore if node on left + if (header->prev != NULL && + header->prev->node_number == header->node_number) + return; + + // ignore if node on right + if (header->next != NULL && + header->next->node_number == header->node_number) + return; + + // ignore if still used + if (header->used) + return; + + // FIXME: huh?! + // kfree_pages(header); } -- cgit v1.2.3-freya From e10b750a33bb9b8fb9b5f636c5d937cb54104bd9 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 2 May 2025 12:37:55 -0400 Subject: broken? --- kernel/memory/paging.c | 119 +++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 59 deletions(-) (limited to 'kernel') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 39f7638..e21fd34 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1035,71 +1035,72 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, if (phys == NULL) return NULL; - if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, count)) { + if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, + count)) { free_phys_pages(phys, count); return NULL; } return virt; -// size_t pages_needed = count; -// -// struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; -// struct phys_page_slice phys_pages; -// -// if (virtaddr_take(&ctx->virtctx, virt, count)) -// return NULL; -// -// while (pages_needed > 0) { -// phys_pages = alloc_phys_page_withextra(pages_needed); -// if (phys_pages.pagestart == NULL) { -// goto mem_alloc_pages_at_fail; -// } -// -// { -// // allocate the first page and store in it the physical address of the -// // previous chunk of pages -// // TODO: skip this if there are already enough pages from first alloc -// void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, -// F_PRESENT | F_WRITEABLE); -// if (pageone == NULL) { -// panic("kernel out of virtual memory"); -// } -// *((struct phys_page_slice *)pageone) = prev_phys_block; -// prev_phys_block = phys_pages; -// kunmapaddr(pageone); -// } -// -// // index into virtual page array at index [count - pages_needed] -// void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); -// -// assert(pages_needed >= phys_pages.num_pages, "overflow"); -// pages_needed -= phys_pages.num_pages; -// -// if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, -// phys_pages.pagestart, flags, phys_pages.num_pages)) { -// goto mem_alloc_pages_at_fail; -// } -// } -// -// return virt; -// -//mem_alloc_pages_at_fail: -// while (prev_phys_block.pagestart) { -// void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, -// F_PRESENT | F_WRITEABLE); -// if (!virtpage) { -// // memory corruption, most likely a bug -// // could also ERROR here and exit with leak -// panic("unable to free memory from failed mem_alloc_pages_at call"); -// } -// struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; -// prev_phys_block = prev; -// free_phys_pages_slice(prev); -// kunmapaddr(virtpage); -// } -// -// return NULL; + // size_t pages_needed = count; + // + // struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; + // struct phys_page_slice phys_pages; + // + // if (virtaddr_take(&ctx->virtctx, virt, count)) + // return NULL; + // + // while (pages_needed > 0) { + // phys_pages = alloc_phys_page_withextra(pages_needed); + // if (phys_pages.pagestart == NULL) { + // goto mem_alloc_pages_at_fail; + // } + // + // { + // // allocate the first page and store in it the physical address of the + // // previous chunk of pages + // // TODO: skip this if there are already enough pages from first alloc + // void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, + // F_PRESENT | F_WRITEABLE); + // if (pageone == NULL) { + // panic("kernel out of virtual memory"); + // } + // *((struct phys_page_slice *)pageone) = prev_phys_block; + // prev_phys_block = phys_pages; + // kunmapaddr(pageone); + // } + // + // // index into virtual page array at index [count - pages_needed] + // void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); + // + // assert(pages_needed >= phys_pages.num_pages, "overflow"); + // pages_needed -= phys_pages.num_pages; + // + // if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, + // phys_pages.pagestart, flags, phys_pages.num_pages)) { + // goto mem_alloc_pages_at_fail; + // } + // } + // + // return virt; + // + //mem_alloc_pages_at_fail: + // while (prev_phys_block.pagestart) { + // void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, + // F_PRESENT | F_WRITEABLE); + // if (!virtpage) { + // // memory corruption, most likely a bug + // // could also ERROR here and exit with leak + // panic("unable to free memory from failed mem_alloc_pages_at call"); + // } + // struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; + // prev_phys_block = prev; + // free_phys_pages_slice(prev); + // kunmapaddr(virtpage); + // } + // + // return NULL; } void mem_free_pages(mem_ctx_t ctx, const void *virt) -- cgit v1.2.3-freya From ed44d51f7dcaee989d6f36bab8042f438692e7ce Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 2 May 2025 12:38:02 -0400 Subject: off by one --- kernel/memory/physalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 4255339..47522b8 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -27,7 +27,7 @@ static const char *segment_type_str[] = { static int n_pages(const struct memory_segment *m) { - return m->len / PAGE_SIZE; + return (m->len + PAGE_SIZE - 1) / PAGE_SIZE; } static void *page_at(int i) -- cgit v1.2.3-freya From 592c6992c7ea0c2e4cbea79fadb1c845f2fc050e Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Mon, 5 May 2025 09:54:48 -0400 Subject: pc spkr --- Makefile | 1 + kernel/cpu/idt.c | 9 +++--- kernel/drivers.c | 2 +- kernel/drivers/pit.c | 60 +++++++++++++++++++++++++++++-------- kernel/drivers/ps2.c | 15 ++++++++++ kernel/include/comus/drivers/pit.h | 14 +++++++-- kernel/include/comus/drivers/ps2.h | 13 ++++++++ kernel/include/comus/drivers/spkr.h | 29 ++++++++++++++++++ kernel/include/lib/klib.h | 5 ++++ kernel/lib/panic.c | 17 +++++++++-- 10 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 kernel/include/comus/drivers/spkr.h (limited to 'kernel') diff --git a/Makefile b/Makefile index 3739534..2b78eb6 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ GRUB ?= grub-mkrescue QEMUOPTS += -cdrom $(BIN)/$(ISO) \ -no-reboot \ -drive format=raw,file=user/bin/initrd.tar \ + -audiodev pa,id=speaker -machine pcspk-audiodev=speaker \ -serial mon:stdio \ -m 4G \ -name kern diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index 7cbbb65..50e15e0 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -1,3 +1,5 @@ +#include "comus/drivers/spkr.h" +#include "lib/klib.h" #include #include #include @@ -64,10 +66,11 @@ void idt_init(void) uint64_t isr = (uint64_t)isr_stub_table[vector]; // interrupts before 0x20 are for cpu exceptions + uint64_t gate_type = (isr < 0x20) ? GATE_64BIT_TRAP : GATE_64BIT_INT; entry->kernel_cs = 0x08; // offset of 1 into GDT entry->ist = 0; - entry->flags = PRESENT | RING0 | GATE_64BIT_INT; + entry->flags = PRESENT | RING0 | gate_type; entry->isr_low = isr & 0xffff; entry->isr_mid = (isr >> 16) & 0xffff; entry->isr_high = (isr >> 32) & 0xffffffff; @@ -148,9 +151,7 @@ __attribute__((noreturn)) void idt_exception_handler(uint64_t exception, log_backtrace_ex((void *)state->rip, (void *)state->rbp); - while (1) { - halt(); - } + fatal_loop(); } void isr_save(struct cpu_regs *regs) diff --git a/kernel/drivers.c b/kernel/drivers.c index 3d6ec10..572ab98 100644 --- a/kernel/drivers.c +++ b/kernel/drivers.c @@ -10,7 +10,7 @@ void drivers_init(void) { - pit_set_divider(1193); // 1ms + pit_set_freq(CHAN_TIMER, 1000); // 1ms uart_init(); ps2_init(); pci_init(); diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index 53a9263..0c7a207 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -1,29 +1,65 @@ +#include "lib/klib.h" #include #include +#include +#include -#define CHAN_0 0x40 -#define CHAN_1 0x41 -#define CHAN_2 0x42 #define CMD 0x43 +#define SPKR 0x61 + +#define BASE 1193180 volatile uint64_t ticks = 0; -uint16_t pit_read_divider(void) +uint32_t pit_read_freq(uint8_t chan) { - uint16_t count = 0; + uint16_t div = 0; cli(); outb(CMD, 0); // clear bits - count = inb(CHAN_0); // low byte - count |= inb(CHAN_0) << 8; // highbyte + div = inb(chan); // low byte + div |= inb(chan) << 8; // highbyte sti(); - return count; + return div * BASE; } -void pit_set_divider(uint16_t count) +void pit_set_freq(uint8_t chan, uint32_t hz) { - (void)count; + uint16_t div = BASE / hz; cli(); - outb(CHAN_0, count & 0xFF); // low byte - outb(CHAN_0, (count & 0xFF00) >> 8); // high byte + outb(CMD, 0xb6); + outb(chan, div & 0xFF); // low byte + outb(chan, (div & 0xFF00) >> 8); // high byte sti(); } + +void spkr_play_tone(uint32_t hz) +{ + uint8_t reg; + + if (hz == 0) { + spkr_quiet(); + return; + } + + // set spkr freq + pit_set_freq(CHAN_SPKR, hz); + + // enable spkr gate + reg = inb(SPKR); + if (reg != (reg | 0x3)) + outb(SPKR, reg | 0x3); +} + +void spkr_quiet(void) +{ + uint8_t reg; + reg = inb(SPKR) & 0xFC; + outb(SPKR, reg); +} + +void spkr_beep(void) +{ + spkr_play_tone(1000); + kspin_milliseconds(100); + spkr_quiet(); +} diff --git a/kernel/drivers/ps2.c b/kernel/drivers/ps2.c index e260f6b..f605c1d 100644 --- a/kernel/drivers/ps2.c +++ b/kernel/drivers/ps2.c @@ -266,3 +266,18 @@ int ps2_init(void) sti(); return 0; } + +int ps2_set_leds(uint8_t state) +{ + uint8_t result; + + if (!(has_mouse || has_kbd)) + return 1; + + ps2ctrl_out_cmd(0xED); + ps2ctrl_out_data(state); + if ((result = ps2ctrl_in()) != 0xFA) + return 1; + + return 0; +} diff --git a/kernel/include/comus/drivers/pit.h b/kernel/include/comus/drivers/pit.h index 77f0a14..22b8153 100644 --- a/kernel/include/comus/drivers/pit.h +++ b/kernel/include/comus/drivers/pit.h @@ -9,13 +9,23 @@ #ifndef PIT_H_ #define PIT_H_ +#define CHAN_TIMER 0x40 +#define CHAN_SPKR 0x42 + #include // how many time the pit has ticked // not accurate time, good for spinning though extern volatile uint64_t ticks; -uint16_t pit_read_divider(void); -void pit_set_divider(uint16_t count); +/** + * Read timer frequency + */ +uint32_t pit_read_freq(uint8_t chan); + +/** + * Set timer frequency + */ +void pit_set_freq(uint8_t chan, uint32_t hz); #endif diff --git a/kernel/include/comus/drivers/ps2.h b/kernel/include/comus/drivers/ps2.h index 7634e5f..c012ad4 100644 --- a/kernel/include/comus/drivers/ps2.h +++ b/kernel/include/comus/drivers/ps2.h @@ -9,6 +9,8 @@ #ifndef PS2_H_ #define PS2_H_ +#include + /** * Initalize the ps2 controller */ @@ -24,4 +26,15 @@ void ps2kb_recv(void); */ void ps2mouse_recv(void); +/** + * Set ps2 led state + * + * Bits + * ---- + * 0 - Scroll lock + * 1 - Num Lock + * 2 - Caps lock + */ +int ps2_set_leds(uint8_t state); + #endif /* ps2.h */ diff --git a/kernel/include/comus/drivers/spkr.h b/kernel/include/comus/drivers/spkr.h new file mode 100644 index 0000000..f9e427e --- /dev/null +++ b/kernel/include/comus/drivers/spkr.h @@ -0,0 +1,29 @@ +/** + * @file spkr.h + * + * @author Freya Murphy + * + * PC Speaker + */ + +#ifndef SPKR_H_ +#define SPKR_H_ + +#include + +/** + * Play a tone on the pc speaker continuously + */ +void spkr_play_tone(uint32_t hz); + +/** + * Shut up the pc speaker + */ +void spkr_quiet(void); + +/** + * Beep the pc speaker for a short period + */ +void spkr_beep(void); + +#endif /* spkr.h */ diff --git a/kernel/include/lib/klib.h b/kernel/include/lib/klib.h index b4d26ed..f549a09 100644 --- a/kernel/include/lib/klib.h +++ b/kernel/include/lib/klib.h @@ -263,6 +263,11 @@ enum log_level { __attribute__((noreturn, format(printf, 3, 4))) void __panic(unsigned int line, const char *file, const char *format, ...); +/** + * Loop kernel in fatal notifier (beep and blink caps lock key) + */ +__attribute__((noreturn)) void fatal_loop(void); + /** * Fill dst with a stack trace consisting of return addresses in order * from top to bottom diff --git a/kernel/lib/panic.c b/kernel/lib/panic.c index 3a6e029..35ea0b1 100644 --- a/kernel/lib/panic.c +++ b/kernel/lib/panic.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include __attribute__((noreturn)) void __panic(unsigned int line, const char *file, const char *format, ...) @@ -16,6 +18,17 @@ __attribute__((noreturn)) void __panic(unsigned int line, const char *file, log_backtrace(); #endif - while (1) - halt(); + fatal_loop(); +} + +__attribute__((noreturn)) void fatal_loop(void) +{ + while(1) { + spkr_play_tone(1000); + ps2_set_leds(0x4); + kspin_milliseconds(200); + spkr_quiet(); + ps2_set_leds(0x0); + kspin_milliseconds(800); + } } -- cgit v1.2.3-freya From f485b63e72cc5bf29f134c3e033a21d4a52244d3 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:33:57 -0400 Subject: update fs --- kernel/fs/tar.c | 4 ++-- kernel/include/comus/fs.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 061dd0c..8beebc6 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -113,7 +113,7 @@ static int tar_locate(struct file_system *fs, const char *path, return 1; } -int tar_read(struct file *in, char *buf, size_t len) +int tar_read(struct file *in, void *buf, size_t len) { struct tar_file *file = (struct tar_file *)in; size_t max_bytes = file->len - file->offset; @@ -135,7 +135,7 @@ int tar_read(struct file *in, char *buf, size_t len) return bytes; } -int tar_write(struct file *in, const char *buf, size_t len) +int tar_write(struct file *in, const void *buf, size_t len) { (void)in; (void)buf; diff --git a/kernel/include/comus/fs.h b/kernel/include/comus/fs.h index 044330b..b1d0e80 100644 --- a/kernel/include/comus/fs.h +++ b/kernel/include/comus/fs.h @@ -28,7 +28,7 @@ struct disk { /// internal disk device union { struct { - char *start; + uint8_t *start; size_t len; } rd; ide_device_t ide; @@ -137,9 +137,9 @@ struct file { /// file type enum file_type f_type; /// read from the file - int (*read)(struct file *file, char *buffer, size_t nbytes); + int (*read)(struct file *file, void *buffer, size_t nbytes); /// write into the file - int (*write)(struct file *file, const char *buffer, size_t nbytes); + int (*write)(struct file *file, const void *buffer, size_t nbytes); /// seeks the file int (*seek)(struct file *file, long int offset, int whence); /// get directory entry at index -- cgit v1.2.3-freya From 9e0972a754ec218a5bf611aca644738d1c07e9b1 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:34:11 -0400 Subject: remove sym lookup --- kernel/lib/backtrace.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/lib/backtrace.c b/kernel/lib/backtrace.c index 2507be4..2783b74 100644 --- a/kernel/lib/backtrace.c +++ b/kernel/lib/backtrace.c @@ -50,10 +50,9 @@ void log_backtrace_ex(void *ip, void *bp) if (!VALID(frame)) return; kputs("Stack trace:\n"); - kprintf(" %p\t%s\n", ip, mboot_get_elf_sym((uint64_t)ip)); + kprintf(" %p\n", ip); while (VALID(frame)) { - kprintf(" %p\t%s\n", frame->rip, - mboot_get_elf_sym((uint64_t)frame->rip)); + kprintf(" %p\n", frame->rip); frame = frame->rbp; } } -- cgit v1.2.3-freya From 40bfcbb2cf8a39e58ec19b21956caaf4685c9b8b Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:34:48 -0400 Subject: terrible hack to not overwrite mboot data --- kernel/include/comus/mboot.h | 10 ++++++++++ kernel/mboot/mboot.c | 19 +++++++++++++++++++ kernel/mboot/module.c | 16 +++++++++++++--- kernel/memory/physalloc.c | 24 ++++++++++++++++-------- 4 files changed, 58 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/include/comus/mboot.h b/kernel/include/comus/mboot.h index aba3e4e..bed29f1 100644 --- a/kernel/include/comus/mboot.h +++ b/kernel/include/comus/mboot.h @@ -47,4 +47,14 @@ EFI_HANDLE mboot_get_efi_hdl(void); */ void *mboot_get_initrd(size_t *len); +/** + * Returns the physical pointer to the loaded init ram disk with size given by len + */ +void *mboot_get_initrd_phys(size_t *len); + +/** + * Gets the end of the mboot pointer + */ +void *mboot_end(void); + #endif /* mboot.h */ diff --git a/kernel/mboot/mboot.c b/kernel/mboot/mboot.c index e4547e7..8163f04 100644 --- a/kernel/mboot/mboot.c +++ b/kernel/mboot/mboot.c @@ -5,6 +5,8 @@ static volatile void *mboot = NULL; +extern char kernel_end[]; + void mboot_init(long magic, volatile void *ptr) { if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) @@ -12,6 +14,23 @@ void mboot_init(long magic, volatile void *ptr) mboot = ptr; } +void *mboot_end(void) +{ + if (mboot == NULL) + return NULL; + + struct multiboot *info = (struct multiboot *)mboot; + uintptr_t mboot_end, initrd_end; + size_t initrd_len; + + mboot_end = (uintptr_t)info + info->total_size; + initrd_end = (uintptr_t)mboot_get_initrd_phys(&initrd_len); + if (initrd_end) + initrd_end += initrd_len; + + return (void *)MAX(mboot_end, initrd_end); +} + void *locate_mboot_table(uint32_t type) { if (mboot == NULL) diff --git a/kernel/mboot/module.c b/kernel/mboot/module.c index bf15eca..03c5147 100644 --- a/kernel/mboot/module.c +++ b/kernel/mboot/module.c @@ -1,4 +1,4 @@ -#include "comus/memory.h" +#include #include #include "mboot.h" @@ -16,7 +16,7 @@ struct multiboot_tag_module { static void *mapped_addr = NULL; size_t initrd_len; -void *mboot_get_initrd(size_t *len) +void *mboot_get_initrd_phys(size_t *len) { struct multiboot_tag_module *mod; void *tag, *phys; @@ -36,11 +36,21 @@ void *mboot_get_initrd(size_t *len) phys = (void *)(uintptr_t)mod->mod_start; initrd_len = mod->mod_end - mod->mod_start; + *len = initrd_len; + return phys; +} + +void *mboot_get_initrd(size_t *len) +{ + // get phys + void *phys = mboot_get_initrd_phys(len); + if (phys == NULL) + return NULL; + // map addr mapped_addr = kmapaddr(phys, NULL, initrd_len, F_PRESENT | F_WRITEABLE); if (mapped_addr == NULL) return NULL; - *len = initrd_len; return mapped_addr; } diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 47522b8..7551c75 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -1,12 +1,14 @@ -#include "lib/kio.h" #include #include #include +#include +#include #include "physalloc.h" extern char kernel_start[]; extern char kernel_end[]; +static void *kernel_real_end = NULL; // between memory_start and kernel_start will be the bitmap static uintptr_t memory_start = 0; @@ -30,16 +32,17 @@ static int n_pages(const struct memory_segment *m) return (m->len + PAGE_SIZE - 1) / PAGE_SIZE; } -static void *page_at(int i) +static void *page_at(size_t i) { - int cur_page = 0; + size_t cur_page = 0; + const struct memory_segment *m = page_start; for (uint64_t idx = 0; idx < segment_count; idx++) { - const struct memory_segment *m = page_start; - int pages = n_pages(m); + size_t pages = n_pages(m); if (i - cur_page < pages) { return (void *)(m->addr + (PAGE_SIZE * (i - cur_page))); } cur_page += pages; + m++; } return NULL; } @@ -48,8 +51,8 @@ static long page_idx(void *page) { uintptr_t addr = (uintptr_t)page; int cur_page = 0; + const struct memory_segment *m = page_start; for (uint64_t idx = 0; idx < segment_count; idx++) { - const struct memory_segment *m = page_start; if (addr < m->addr) { return -1; } @@ -57,6 +60,7 @@ static long page_idx(void *page) return cur_page + ((addr - m->addr) / PAGE_SIZE); } cur_page += n_pages(m); + m++; } return -1; } @@ -211,7 +215,7 @@ static struct memory_segment clamp_segment(const struct memory_segment *segment) if (memory_start) start = memory_start; else - start = (uintptr_t)kernel_end; + start = (uintptr_t)kernel_real_end; if (segment->addr < start) { addr = start; @@ -243,6 +247,10 @@ void physalloc_init(struct memory_map *map) segment_count = 0; + kernel_real_end = mboot_end(); + if ((char *)kernel_real_end < kernel_end) + kernel_real_end = kernel_end; + for (uint32_t i = 0; i < map->entry_count; i++) { struct memory_segment *segment = &map->entries[i]; @@ -256,7 +264,7 @@ void physalloc_init(struct memory_map *map) long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1; long bitmap_size = bitmap_pages * PAGE_SIZE; - bitmap = (uint64_t *)page_align((uintptr_t)kernel_end); + bitmap = (uint64_t *)page_align((uintptr_t)kernel_real_end); long page_area_size = segment_count * sizeof(struct memory_segment); char *page_area_addr = (char *)bitmap + bitmap_size; -- cgit v1.2.3-freya From b54fdd17a99a7feffc36a3ad067d4293ba3e9577 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:36:04 -0400 Subject: add some memory logging --- kernel/memory/paging.c | 46 ++++++++++++++++++++++++++----------- kernel/user.c | 62 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 76 insertions(+), 32 deletions(-) (limited to 'kernel') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index e21fd34..fc3b256 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1,4 +1,3 @@ -#include "lib/kio.h" #include #include @@ -6,7 +5,6 @@ #include "physalloc.h" #include "paging.h" #include "memory.h" -#include // PAGE MAP LEVEL 4 ENTRY struct pml4e { @@ -259,8 +257,10 @@ static volatile struct pml4 *pml4_alloc(void) volatile struct pml4 *pPML4, *vPML4; pPML4 = alloc_phys_page(); - if (pPML4 == NULL) + if (pPML4 == NULL) { + ERROR("Could not allocate PML4"); return NULL; + } vPML4 = PML4_MAP(pPML4); memsetv(vPML4, 0, sizeof(struct pml4)); @@ -288,8 +288,10 @@ static volatile struct pdpt *pdpt_alloc(volatile struct pml4 *pPML4, } pPDPT = alloc_phys_page(); - if (pPML4 == NULL) + if (pPDPT == NULL) { + ERROR("Could not allocate PDPT"); return NULL; + } vPDPT = PDPT_MAP(pPDPT); memsetv(vPDPT, 0, sizeof(struct pdpt)); @@ -321,8 +323,10 @@ static volatile struct pd *pd_alloc(volatile struct pdpt *pPDPT, void *vADDR, } pPD = alloc_phys_page(); - if (pPDPT == NULL) + if (pPD == NULL) { + ERROR("Could not allocate PD"); return NULL; + } vPD = PD_MAP(pPD); memsetv(vPD, 0, sizeof(struct pd)); @@ -354,8 +358,10 @@ static volatile struct pt *pt_alloc(volatile struct pd *pPD, void *vADDR, } pPT = alloc_phys_page(); - if (pPT == NULL) + if (pPT == NULL) { + ERROR("Could not allocate PT"); return NULL; + } vPT = PT_MAP(pPT); memsetv(vPT, 0, sizeof(struct pt)); @@ -911,11 +917,15 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, // get page aligned (or allocate) vitural address if (virt == NULL) virt = virtaddr_alloc(&ctx->virtctx, pages); - if (virt == NULL) + if (virt == NULL) { + ERROR("Could not alloc vitural address for %zu pages", pages); return NULL; + } - if (virtaddr_take(&ctx->virtctx, virt, pages)) + if (virtaddr_take(&ctx->virtctx, virt, pages)) { + ERROR("Could not take vitural address: %p", virt); return NULL; + } assert((uint64_t)virt % PAGE_SIZE == 0, "mem_mapaddr: vitural address not page aligned"); @@ -923,6 +933,7 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, if (map_pages((volatile struct pml4 *)ctx->pml4, virt, aligned_phys, F_PRESENT | flags, pages)) { virtaddr_free(&ctx->virtctx, virt); + ERROR("Could not map pages"); return NULL; } @@ -1028,21 +1039,30 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, { void *phys = NULL; - if (virtaddr_take(&ctx->virtctx, virt, count)) + if (virtaddr_take(&ctx->virtctx, virt, count)) { + ERROR("Could not take vitural address: %p", virt); return NULL; + } phys = alloc_phys_pages_exact(count); - if (phys == NULL) - return NULL; + if (phys == NULL) { + ERROR("Could not allocate %zu physical pages", count); + goto fail; + } if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, count)) { - free_phys_pages(phys, count); - return NULL; + ERROR("Could not map pages"); + goto fail; } return virt; +fail: + free_phys_pages(phys, count); + virtaddr_free(&ctx->virtctx, virt); + return NULL; + // size_t pages_needed = count; // // struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; diff --git a/kernel/user.c b/kernel/user.c index 9612710..97d8f0f 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include #include @@ -14,7 +15,7 @@ #define USER_STACK_LEN (4 * PAGE_SIZE) #define BLOCK_SIZE (PAGE_SIZE * 1000) -static char *load_buffer = NULL; +static uint8_t *load_buffer = NULL; #define USER_CODE 0x18 #define USER_DATA 0x20 @@ -49,16 +50,22 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) // allocate memory in user process if (mem_alloc_pages_at(pcb->memctx, mem_pages, (void *)hdr.p_vaddr, - F_WRITEABLE | F_UNPRIVILEGED) == NULL) + F_WRITEABLE | F_UNPRIVILEGED) == NULL) { + ERROR("Could not allocate memory for elf segment"); return 1; + } mapADDR = kmapuseraddr(pcb->memctx, (void *)hdr.p_vaddr, mem_bytes); - if (mapADDR == NULL) + if (mapADDR == NULL) { + ERROR("Could load memory for elf segment"); return 1; + } // seek to start of segment - if (file->seek(file, hdr.p_offset, SEEK_SET) < 0) + if (file->seek(file, hdr.p_offset, SEEK_SET) < 0) { + ERROR("Could not load elf segment"); return 1; + } // load data size_t total_read = 0; @@ -66,11 +73,13 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) size_t read = BLOCK_SIZE; if (read > file_bytes - total_read) read = file_bytes - total_read; + TRACE("Reading %zu bytes...", read); if ((read = file->read(file, load_buffer, read)) < 1) { kunmapaddr(mapADDR); + ERROR("Could not load elf segment"); return 1; } - memcpy(mapADDR + total_read, load_buffer, read); + memcpyv(mapADDR + total_read, load_buffer, read); total_read += read; } @@ -89,10 +98,15 @@ static int user_load_segments(struct pcb *pcb, struct file *file) pcb->heap_start = NULL; pcb->heap_len = 0; - if (load_buffer == NULL) - if ((load_buffer = kalloc(BLOCK_SIZE)) == NULL) + if (load_buffer == NULL) { + load_buffer = kalloc(BLOCK_SIZE); + if (load_buffer == NULL) { + ERROR("Could not allocate user load buffer"); return 1; + } + } + TRACE("Loading %u elf segments", pcb->n_elf_segments); for (int i = 0; i < pcb->n_elf_segments; i++) if ((ret = user_load_segment(pcb, file, i))) return ret; @@ -110,12 +124,12 @@ static int validate_elf_hdr(struct pcb *pcb) Elf64_Ehdr *ehdr = &pcb->elf_header; if (strncmp((const char *)ehdr->e_ident, ELFMAG, SELFMAG)) { - WARN("Invalid ELF File."); + ERROR("Invalid ELF File."); return 1; } if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) { - WARN("Unsupported ELF Class."); + ERROR("Unsupported ELF Class."); return 1; } @@ -125,17 +139,17 @@ static int validate_elf_hdr(struct pcb *pcb) } if (ehdr->e_machine != EM_X86_64) { - WARN("Unsupported ELF File target."); + ERROR("Unsupported ELF File target."); return 1; } if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) { - WARN("Unsupported ELF File version."); + ERROR("Unsupported ELF File version."); return 1; } if (ehdr->e_phnum > N_ELF_SEGMENTS) { - WARN("Too many ELF segments."); + ERROR("Too many ELF segments."); return 1; } @@ -151,22 +165,30 @@ static int user_load_elf(struct pcb *pcb, struct file *file) { int ret = 0; - if (file->seek(file, 0, SEEK_SET) < 0) + if (file->seek(file, 0, SEEK_SET) < 0) { + ERROR("Cannot read ELF header."); return 1; - ret = file->read(file, (char *)&pcb->elf_header, sizeof(Elf64_Ehdr)); - if (ret < 0) + } + ret = file->read(file, &pcb->elf_header, sizeof(Elf64_Ehdr)); + if (ret < 0) { + ERROR("Cannot read ELF header."); return 1; + } if (validate_elf_hdr(pcb)) return 1; pcb->n_elf_segments = pcb->elf_header.e_phnum; - if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET) < 0) + if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET) < 0) { + ERROR("Cannot read ELF segemts"); return 1; - ret = file->read(file, (char *)&pcb->elf_segments, + } + ret = file->read(file, &pcb->elf_segments, sizeof(Elf64_Phdr) * pcb->elf_header.e_phnum); - if (ret < 0) + if (ret < 0) { + ERROR("Cannot read ELF segemts"); return 1; + } return 0; } @@ -217,8 +239,10 @@ static int user_setup_stack(struct pcb *pcb, const char **args, /* stack */ if (mem_alloc_pages_at(pcb->memctx, USER_STACK_LEN / PAGE_SIZE, (void *)(USER_STACK_TOP - USER_STACK_LEN), - F_WRITEABLE | F_UNPRIVILEGED) == NULL) + F_WRITEABLE | F_UNPRIVILEGED) == NULL) { + ERROR("Could not allocate user stack"); return 1; + } /* regs */ memset(&pcb->regs, 0, sizeof(struct cpu_regs)); -- cgit v1.2.3-freya From 347cf9e458897814a66725c02832f9f15824fb88 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:36:10 -0400 Subject: virt alloc fixes --- kernel/memory/virtalloc.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) (limited to 'kernel') diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index da64f3b..3d60a9f 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -145,32 +145,31 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) static void merge_back(struct virt_ctx *ctx, struct virt_addr_node *node) { - while (node->prev) { - if (node->is_alloc != node->prev->is_alloc) + struct virt_addr_node *prev; + for (prev = node->prev; prev != NULL; prev = prev->prev) { + if (prev->is_alloc) break; - struct virt_addr_node *temp = node->prev; - node->start = temp->start; - node->prev = temp->prev; - if (temp->prev) - temp->prev->next = node; - free_node(ctx, temp); + node->start = prev->start; + node->prev = prev->prev; + if (node->prev) + node->prev->next = node; + free_node(ctx, prev); } - if (node->prev == NULL) { + if (node->prev == NULL) ctx->start_node = node; - } } static void merge_forward(struct virt_ctx *ctx, struct virt_addr_node *node) { - while (node->next) { - if (node->is_alloc != node->next->is_alloc) + struct virt_addr_node *next; + for (next = node->next; next != NULL; next = next->next) { + if (next->is_alloc) break; - struct virt_addr_node *temp = node->next; - node->end = temp->end; - node->next = temp->next; - if (temp->next) - temp->next->prev = node; - free_node(ctx, temp); + node->end = next->end; + node->next = next->next; + if (node->next) + node->next->prev = node; + free_node(ctx, next); } } @@ -263,7 +262,6 @@ long virtaddr_free(struct virt_ctx *ctx, const void *virtaddr) if (node->start == virt) { int length = node->end - node->start; int pages = length / PAGE_SIZE; - // FIXME: ??? node->is_alloc = false; merge_back(ctx, node); merge_forward(ctx, node); -- cgit v1.2.3-freya From fa745d64c62e150b2391e8d60e0da261d02aac9f Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:36:27 -0400 Subject: kernel alloc should not be doing all of this, make it simpler (and work) --- kernel/lib/kalloc.c | 156 +++++----------------------------------------------- 1 file changed, 14 insertions(+), 142 deletions(-) (limited to 'kernel') diff --git a/kernel/lib/kalloc.c b/kernel/lib/kalloc.c index f4cd097..23b8b73 100644 --- a/kernel/lib/kalloc.c +++ b/kernel/lib/kalloc.c @@ -1,123 +1,38 @@ -#include "lib/kio.h" #include #include #define MAGIC 0xBEEFCAFE struct page_header { - struct page_header *next; - struct page_header *prev; - size_t - node_number; // all headers on the same page alloc have the same node number (so they can be merged) - size_t - free; // free space after the node (if its the last node in the alloc block) - size_t used; // how much space this allocation is using + size_t len; uint64_t magic; }; -static const size_t header_len = sizeof(struct page_header); -static struct page_header *start_header = NULL; -static struct page_header *end_header = NULL; - static struct page_header *get_header(void *ptr) { struct page_header *header = - (struct page_header *)((uintptr_t)ptr - header_len); + (struct page_header *)((uintptr_t)ptr - PAGE_SIZE); - // PERF: do we want to make sure this pointer is paged - // before reading it??? - if (header->magic != MAGIC) { + if (header->magic != MAGIC) return NULL; // invalid pointer - } return header; } -static void *alloc_new(size_t size) +void *kalloc(size_t size) { - size_t pages = ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE); - - void *addr = kalloc_pages(pages); - void *mem = (char *)addr + header_len; - - size_t total = pages * PAGE_SIZE; - size_t free = total - (size + header_len); + struct page_header *header; + size_t pages; - if (addr == NULL) { + pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; + header = kalloc_pages(pages + 1); + if (header == NULL) return NULL; - } - - size_t node; - if (end_header != NULL) { - node = end_header->node_number + 1; - } else { - node = 0; - } - - struct page_header *header = addr; - memsetv(header, 0, sizeof(struct page_header)); - header->magic = MAGIC; - header->used = size; - header->free = free; - header->prev = end_header; - header->next = NULL; - header->node_number = node; - - if (start_header == NULL) { - start_header = header; - } - - if (end_header != NULL) { - end_header->next = header; - } else { - end_header = header; - } - - return mem; -} - -static void *alloc_block(size_t size, struct page_header *block) -{ - struct page_header *header = - (struct page_header *)((char *)block + block->used + header_len); - - size_t free = block->free - (size + header_len); - block->free = 0; header->magic = MAGIC; - header->used = size; - header->free = free; - header->prev = block; - header->next = block->next; - block->next = header; - if (header->next) - header->next->prev = header; - header->node_number = block->node_number; - - void *mem = (char *)header + header_len; - - return mem; -} - -void *kalloc(size_t size) -{ - struct page_header *header = start_header; - - for (; header != NULL; header = header->next) { - size_t free = header->free; - if (free < header_len) - continue; - if (size <= - (free - header_len)) { // we must be able to fit data + header - break; - } - } + header->len = size; - if (header != NULL) { - return alloc_block(size, header); - } else { - return alloc_new(size); - } + return (char *)header + PAGE_SIZE; } void *krealloc(void *src, size_t dst_len) @@ -143,7 +58,7 @@ void *krealloc(void *src, size_t dst_len) if (header == NULL) return NULL; - src_len = header->used; + src_len = header->len; if (src_len == 0) return NULL; @@ -164,7 +79,7 @@ void *krealloc(void *src, size_t dst_len) void kfree(void *ptr) { - struct page_header *header, *neighbor; + struct page_header *header; if (ptr == NULL) return; @@ -174,48 +89,5 @@ void kfree(void *ptr) if (header == NULL) return; - header->free += header->used; - header->used = 0; - - // merge left - for (neighbor = header->prev; neighbor != NULL; neighbor = neighbor->prev) { - if (neighbor->node_number != header->node_number) - break; - neighbor->free += header->free + header_len; - neighbor->next = header->next; - if (neighbor->next) - neighbor->next->prev = neighbor; - header = neighbor; - if (header->used) - break; - } - - // merge right - for (neighbor = header->next; neighbor != NULL; neighbor = neighbor->next) { - if (neighbor->node_number != header->node_number) - break; - if (neighbor->used) - break; - header->free += neighbor->free + header_len; - header->next = neighbor->next; - if (header->next) - header->next->prev = header; - } - - // ignore if node on left - if (header->prev != NULL && - header->prev->node_number == header->node_number) - return; - - // ignore if node on right - if (header->next != NULL && - header->next->node_number == header->node_number) - return; - - // ignore if still used - if (header->used) - return; - - // FIXME: huh?! - // kfree_pages(header); + kfree_pages(header); } -- cgit v1.2.3-freya From a1ed03f222f3e5f5a7a2232ace9785d204228f00 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:36:56 -0400 Subject: make ps2 not do led stuff, it brokie --- kernel/drivers/ps2.c | 2 +- kernel/lib/panic.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/drivers/ps2.c b/kernel/drivers/ps2.c index f605c1d..409ca09 100644 --- a/kernel/drivers/ps2.c +++ b/kernel/drivers/ps2.c @@ -272,7 +272,7 @@ int ps2_set_leds(uint8_t state) uint8_t result; if (!(has_mouse || has_kbd)) - return 1; + return 1; ps2ctrl_out_cmd(0xED); ps2ctrl_out_data(state); diff --git a/kernel/lib/panic.c b/kernel/lib/panic.c index 35ea0b1..99936c1 100644 --- a/kernel/lib/panic.c +++ b/kernel/lib/panic.c @@ -23,12 +23,10 @@ __attribute__((noreturn)) void __panic(unsigned int line, const char *file, __attribute__((noreturn)) void fatal_loop(void) { - while(1) { + while (1) { spkr_play_tone(1000); - ps2_set_leds(0x4); kspin_milliseconds(200); spkr_quiet(); - ps2_set_leds(0x0); kspin_milliseconds(800); } } -- cgit v1.2.3-freya From 50447355b0a0c6d390010c3d209de5e9da2f012f Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 13:21:44 -0400 Subject: set pit into mode3 (fixes uefi) --- kernel/drivers/pit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index 0c7a207..05b6a3a 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -15,7 +15,7 @@ uint32_t pit_read_freq(uint8_t chan) { uint16_t div = 0; cli(); - outb(CMD, 0); // clear bits + outb(CMD, 0x36); // clear bits div = inb(chan); // low byte div |= inb(chan) << 8; // highbyte sti(); @@ -26,7 +26,7 @@ void pit_set_freq(uint8_t chan, uint32_t hz) { uint16_t div = BASE / hz; cli(); - outb(CMD, 0xb6); + outb(CMD, 0x36); outb(chan, div & 0xFF); // low byte outb(chan, (div & 0xFF00) >> 8); // high byte sti(); -- cgit v1.2.3-freya From f14e707144e805611ea01a8f2fd7f1e1beeb65c1 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 13:21:53 -0400 Subject: fixes --- config/grub.cfg | 3 +-- kernel/user.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/config/grub.cfg b/config/grub.cfg index 82c5db7..13c5167 100644 --- a/config/grub.cfg +++ b/config/grub.cfg @@ -1,9 +1,8 @@ set timeout=1 set default=0 insmod all_video -insmod normal menuentry "kern" { multiboot2 /boot/kernel - # module2 /boot/initrd.tar + module2 /boot/initrd.tar } diff --git a/kernel/user.c b/kernel/user.c index 97d8f0f..27b46df 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -79,6 +79,7 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) ERROR("Could not load elf segment"); return 1; } + TRACE("Read %zu bytes", read); memcpyv(mapADDR + total_read, load_buffer, read); total_read += read; } -- cgit v1.2.3-freya From 9405e9870dcac253d66d5008260257e2230320c9 Mon Sep 17 00:00:00 2001 From: Galen Sagarin Date: Tue, 6 May 2025 13:30:06 -0400 Subject: tarfs.c, as well as an incomplete ramfs.c: --- kernel/fs/ramfs.c | 171 ++++++++++++++++ kernel/fs/tar.c | 459 +++++++++++++++++++++++-------------------- kernel/include/comus/ramfs.h | 40 ++++ kernel/include/comus/tar.h | 6 + 4 files changed, 459 insertions(+), 217 deletions(-) create mode 100644 kernel/fs/ramfs.c create mode 100644 kernel/include/comus/ramfs.h create mode 100644 kernel/include/comus/tar.h (limited to 'kernel') diff --git a/kernel/fs/ramfs.c b/kernel/fs/ramfs.c new file mode 100644 index 0000000..0ed4018 --- /dev/null +++ b/kernel/fs/ramfs.c @@ -0,0 +1,171 @@ +#include +#include +//#include +//#include +#include + +#define NOERROR 0 +#define ERROR 1 + +int ramfs_check_exists(const char *name) { + for(int i = 0; i < numberOfFiles; i++) { + if(memcmp(allTheFiles[i].name, name, strlen(allTheFiles[i].name)) == 0) { + // found it + return i; + } + } + // doesn't exist + return -1; +} +int ramfs_create(const char *name) { + if(ramfs_check_exists(name) != -1) { + // already exists + return ERROR; + } + struct file *newFile; + *newFile->name = name; + newFile->size = 0; + newFile->data = kalloc(MAX_FILE_SIZE); + newFile = &allTheFiles[numberOfFiles]; + +} + +int ramfs_delete(const char *name) { + int i = ramfs_check_exists(name); + if(i >= 0) { + kfree(allTheFiles[i].data); + for(int j = i; j < numberOfFiles; j++) { + allTheFiles[j] = allTheFiles[j+1]; + numberOfFiles -= 1; + } + return NOERROR; + + } + return ERROR; +} + +int ramfs_read(const char *name, char *buffer, size_t len) { + int i = ramfs_check_exists(name); + if(i >= 0) { + memcpy(buffer, allTheFiles[i].data, len); + return NOERROR; + } + return ERROR; +} + + +int ramfs_write(const char *name, char *buffer) { + int i = ramfs_check_exists(name); + if(i >= 0) { + memcpy(buffer) + } +} + +// here we return the index of the file as well. +/*int ramfs_find_file(root *r, const char *fullpath, const char *name, file *out, directory *outDirectory) { + directory *location = r->root; + if(ramfs_find_directory(r, fullpath, name, location) == NOERROR) { + for(int i = 0; i < location->file_count; i++) { + if(strcmp(location->files[i]->name, name) == 0) { + outDirectory = location; + out = location->files[i]; + return i; + } + } + + } + return -1; +} +int ramfs_find_directory(root *r, const char *fullpath, const char *name, directory *out) { + directory *location = r->root; + char *path = fullpath; + char *tempPath = strtok(tempPath, "/"); + while(tempPath != NULL) { + bool wasItFound = false; + + for(int i = 0; i < location->directory_count; i++) { + if(strcmp(location->directories[i]->name, tempPath) == 0) { + // yay we found it; + location = location->directories[i]; + wasItFound = true; + break; + + } + } + if(!wasItFound) { + return ERROR; + } + tempPath = strtok(NULL, "/"); + + } + out = location; + return NOERROR; + +} + +int ramfs_create_file(root *r, const char *fullpath, const char *name) { + // trace through the path + // struct ramfs_directory *location = r->root; + directory *location = r->root; + + if(ramfs_find_directory(r, fullpath, name, location) == NOERROR) { + if(location->file_count >= MAX_FILES) { + return ERROR; + } + file *newFile = malloc(sizeof(file)); + strcpy(newFile->name, name); + newFile->size = 0; + newFile->data = malloc(MAX_FILE_SIZE); + location->files[location->file_count] = newFile; + location->file_count += 1; + + return NOERROR; + + } + return ERROR; +} + +int ramfs_delete_file(root *r, const char *fullpath, const char *name) { + directory *location; + if(ramfs_find_directory(r, fullpath, name, location) == NOERROR) { + file *find_file; + int file_index = ramfs_find_file(r, fullpath, name, find_file, location) >= 0; + if(file_index >= 0) { + free(location->files[file_index]->data); + free(location->files[file_index]); + for(int i = file_index + 1; i < location->file_count; i++) { + location->files[i-1] = location->files[i]; + //memcpy(location->files[i-1], location->files[i], location->files[i]->size); + //free(location->files[i]); + } + location->file_count -= 1; + return NOERROR; + } + return ERROR; + + } + return ERROR; +} + +int ramfs_create_directory() { + +} + +int ramfs_delete_directory() { +} + +int ramfs_write() { + +} + + +root *ramfs_init() { + root *r = malloc(sizeof(root)); + r->root = malloc(sizeof(directory)); + strcpy(r->root->name, "/"); + r->root->file_count = 0; + r->root->directory_count = 0; + return r; +} + +*/ diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 8beebc6..b844ed2 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -1,188 +1,222 @@ -#include "lib/kio.h" #include #include - -struct tar_hdr { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char chksum[8]; - char typeflag; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char prefix[155]; - char unused[12]; +#include + +// the placements of these values mimics their placement in standard UStar +struct tar_header { + char name[100]; // 0-99 + char mode[8]; // 100-107 + char ownerUID[8]; // 108-115 + char groupUID[8]; // 116-123 + char fileSize[12]; // 124-135 + char lastMod[12]; // 136-147 + char checksum[8]; // 148-155 + char type_flag; // 156 + char linked_name[100]; // 157-256 + char magic[6]; // 257-262 + char version[2]; // 263-264 + char username[32]; // 265-296 + char groupname[32]; // 297-328 + char majorNum[8]; // 329-336 + char minorNum[8]; // 337-344 + char prefix[155]; // 345-499 + char notUsed[12]; // 500-511 }; - -struct tar_file { - struct file file; - struct file_system *fs; - size_t len; - size_t offset; - size_t sect; -}; - -#define TAR_SECT_SIZE 512 - -#define TMAGIC "ustar" -#define TMAGLEN 6 -#define TVERSION "00" +#define TAR_SIZE 512 +#define TMAGIC "ustar" /* ustar and a null */ +#define TMAGLEN 6 +#define TVERSION "00" /* 00 and no null */ #define TVERSLEN 2 +#define ERROR_TAR 1 +#define NOERROR_TAR 0 -#define REGTYPE '0' -#define DIRTYPE '5' +#define REGTYPE '0' /* regular file */ +#define DIRTYPE '5' /* directory */ -static int read_tar_hdr(struct disk *disk, uint32_t sect, struct tar_hdr *hdr) -{ - if (disk_read(disk, sect * TAR_SECT_SIZE, TAR_SECT_SIZE, hdr) < - TAR_SECT_SIZE) - return 1; - - // check magic - if (memcmp(hdr->magic, TMAGIC, TMAGLEN) != 0) - return 1; - // check version - if (memcmp(hdr->version, TVERSION, TVERSLEN) != 0) - return 1; - - return 0; +struct tar_file { + struct file file; + struct file_system *fs; + size_t len; + size_t offset; + size_t sect; +}; +// read_tar_header reads what is in tar +int read_tar_header(struct disk *disk, uint32_t sect, struct tar_header *hdr) { + + if(disk_read(disk, sect * TAR_SIZE, TAR_SIZE, hdr) < TAR_SIZE) { + return ERROR_TAR; + } + if(memcmp(hdr->magic, TMAGIC, TMAGLEN) != 0 || memcmp(hdr->version, TVERSION, TVERSLEN) != 0) { + return ERROR_TAR; + } + return NOERROR_TAR; + } -static int tar_to_fs_type(char typeflag) -{ - switch (typeflag) { - case REGTYPE: - return F_REG; - case DIRTYPE: - return F_DIR; - default: - return -1; - } +/// @brief +/// @param f +/// @param buffer +/// @param len +/// @return +int tar_read(struct file *f, char *buffer, size_t len) { + struct tar_file *tf = (struct tar_file*) f; + long size = MIN((tf->len - tf->offset), len); + if(tf->file.f_type != F_REG || size < 1) { + return ERROR_TAR; + } + size = disk_read(tf->fs->fs_disk, tf->sect+1 * TAR_SIZE + tf->offset, size, buffer); + tf->offset += size; + return size; } - -static int tar_locate(struct file_system *fs, const char *path, - struct tar_hdr *out_hdr, size_t *out_sect, - size_t *in_sect, bool partial) -{ - struct tar_hdr hdr; - size_t sect = 0; - - if (in_sect != NULL) - sect = *in_sect; - - while (1) { - size_t filesize, sects; - int cmp; - - if (read_tar_hdr(fs->fs_disk, sect, &hdr)) - return 1; - - filesize = strtoull(hdr.size, NULL, 8); - sects = (filesize + TAR_SECT_SIZE - 1) / TAR_SECT_SIZE; - - if (partial) { - size_t len = MIN(strlen(path), strlen(hdr.name)); - cmp = memcmp(hdr.name, path, len); - } else { - cmp = memcmp(hdr.name, path, strlen(path) + 1); - } - - if (cmp) { - // not our file, goto next - sect += sects + 1; - continue; - } - - // we found our file! - *out_hdr = hdr; - *out_sect = sect; - if (in_sect != NULL) - *in_sect = sect + sects + 1; - return 0; - } - - return 1; +//static int read_tar() +// we are assuming that things are formatted correctly. +int find_file(struct file_system *fs, const char *filepath, size_t *sect, size_t *sect_return, struct tar_header *outHeader) { + //char *tempFilePath = filepath; + struct tar_header hdr; + size_t curr_sect; + if(sect == NULL) { + curr_sect = 0; + } else { + curr_sect = *sect; + } + while (1 == 1) { + if(read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { + return ERROR_TAR; + } + if(memcmp(hdr.name, filepath, strlen(filepath) + 1) != 0) { + // didn't find it. + + curr_sect += ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1)/TAR_SIZE) + 1; + continue; + } else { + *outHeader = hdr; + *sect_return = curr_sect; + if(sect != NULL) { + sect += curr_sect; + } + return NOERROR_TAR; + } + + } + return ERROR_TAR; } +int find_file_redux(struct file_system *fs, const char *filepath, size_t *sect, size_t *sect_return, struct tar_header *outHeader) { + struct tar_header hdr; + size_t curr_sect; + if(sect == NULL) { + curr_sect = 0; + } else { + curr_sect = *sect; + } + while (1 == 1) { + if(read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { + return ERROR_TAR; + } + if(memcmp(hdr.name, filepath, MIN(strlen(filepath), strlen(hdr.name))) != 0) { + // didn't find it. + + curr_sect += ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1)/TAR_SIZE) + 1; + continue; + } else { + *outHeader = hdr; + *sect_return = curr_sect; + if(sect != NULL) { + sect += curr_sect + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1)/TAR_SIZE) + 1; + } + return NOERROR_TAR; + + } + + } + return ERROR_TAR; // it should never actually reach here. -int tar_read(struct file *in, void *buf, size_t len) -{ - struct tar_file *file = (struct tar_file *)in; - size_t max_bytes = file->len - file->offset; - long bytes = MIN(max_bytes, len); - - if (file->file.f_type != F_REG) - return 1; - - if (bytes < 1) - return 0; +} - bytes = disk_read(file->fs->fs_disk, - (file->sect + 1) * TAR_SECT_SIZE + file->offset, bytes, - buf); - if (bytes < 0) - return bytes; // return err code - file->offset += bytes; - return bytes; +void tar_close(struct file *f) { + kfree(f); } -int tar_write(struct file *in, const void *buf, size_t len) -{ - (void)in; - (void)buf; - (void)len; +int tar_seek(struct file *f, int offsetAdd, int theSeek) { + struct tar_file *tf = (struct tar_file*) f; + if(theSeek == SEEK_SET) { + tf->offset = offsetAdd; + } else if(theSeek == SEEK_CUR) { + tf->offset = tf->offset + offsetAdd; + } else if(theSeek ==SEEK_END) { + tf->offset = tf->len + offsetAdd; + } else { + return ERROR_TAR; + } + return NOERROR_TAR; + - // cannot write to tar balls - return -1; } -int tar_seek(struct file *in, long int off, int whence) -{ - struct tar_file *file = (struct tar_file *)in; - switch (whence) { - case SEEK_SET: - file->offset = off; - return file->offset; - case SEEK_CUR: - file->offset += off; - return file->offset; - case SEEK_END: - file->offset = file->len + off; - return file->offset; - default: - return -1; - } +int tar_write(struct file *f, const char *buffer, size_t len) { + // tar doesn't do write lol. This is just here so there is something to send to write + (void)f; + (void)buffer; + (void)len; + return ERROR_TAR; } -int tar_ents(struct file *in, struct dirent *ent, size_t entry) +/*int tar_ents(struct file *f, struct dirent *d, size_t dIndex) { + struct tar_header hdr; + struct tar_header dir; + struct tar_file *tf = (struct tar_file*) f; + size_t sect = 0; + size_t sect_off = 0; + size_t curr_index = 0; + if(read_tar_header(tf->fs->fs_disk, sect, &hdr) != 0) { + return ERROR_TAR; + } + while(1 == 1) { + if(find_file_redux(tf->fs, dir.name, §_off, §, &dir) != 0) { + return ERROR_TAR; + } + if(curr_index < dIndex) { + curr_index += 1; + } else if(curr_index > dIndex) { + // something went seriously wrong + return ERROR_TAR; + } else { + d->d_namelen = strlen(hdr.name); + dir.type_flag = DIRTYPE; + d->d_offset = dIndex; + memcpy(d->d_name, hdr.name, d->d_namelen + 1); + return NOERROR_TAR; + } + + + } + + +}*/ + + +int tar_ents(struct file *f, struct dirent *ent, size_t entry) { - struct tar_file *file; - struct tar_hdr dir, hdr; + struct tar_file *tf; + struct tar_header dir, hdr; size_t sect; size_t sect_off = 0; size_t idx = 0; - file = (struct tar_file *)in; + tf = (struct tar_file *)f; sect = 0; - if (file->file.f_type != F_DIR) + if (tf->file.f_type != F_DIR) return -1; - if (read_tar_hdr(file->fs->fs_disk, sect, &dir)) - return 1; + if (read_tar_header(tf->fs->fs_disk, sect, &dir)) { + return ERROR_TAR; + } while (1) { - if (tar_locate(file->fs, dir.name, &hdr, §, §_off, true)) - return 1; + if (find_file_redux(tf->fs, dir.name, §_off, §, &hdr)) + return ERROR_TAR; if (idx != entry) { idx++; @@ -192,77 +226,68 @@ int tar_ents(struct file *in, struct dirent *ent, size_t entry) ent->d_offset = entry; ent->d_namelen = strlen(hdr.name); memcpy(ent->d_name, hdr.name, ent->d_namelen + 1); - return 0; + return NOERROR_TAR; } - return 1; + return ERROR_TAR; } -void tar_close(struct file *file) -{ - kfree(file); +// opens up the tar file at fullpath, and puts it in out. +int tar_open(struct file_system *fs, const char *fullpath, struct file **out) { + struct tar_header hdr; + struct tar_file *newFile; + size_t sect_result; + find_file(fs, fullpath, NULL, §_result, &hdr); + newFile = kalloc(sizeof(struct tar_file)); + //newFile->file = idk; + newFile->file.f_type = F_REG; + newFile->fs = fs; + newFile->file.read = tar_read; + newFile->file.close = tar_close; + newFile->file.write = tar_write; // doesn't actually work; + newFile->file.ents = tar_ents; + newFile->file.seek = tar_seek; + newFile->offset = 0; + newFile->len = strtoull(hdr.fileSize, NULL, 8); + newFile->sect = sect_result; + + *out = (struct file *)newFile; + return NOERROR_TAR; + + + + } -int tar_open(struct file_system *fs, const char *path, int flags, - struct file **out) -{ - struct tar_file *file; - struct tar_hdr hdr; - size_t sect; - - // cannot create or write files - if (flags != O_RDONLY) - return 1; - - if (tar_locate(fs, path, &hdr, §, NULL, false)) - return 1; - - file = kalloc(sizeof(struct tar_file)); - if (file == NULL) - return 1; - - file->file.f_type = tar_to_fs_type(hdr.typeflag); - file->file.read = tar_read; - file->file.write = tar_write; - file->file.seek = tar_seek; - file->file.ents = tar_ents; - file->file.close = tar_close; - file->fs = fs; - file->len = strtoull(hdr.size, NULL, 8); - file->offset = 0; - file->sect = sect; - *out = (struct file *)file; - - return 0; +// gets stats at the file at fullpath, putting them in out. +int tar_stat(struct file_system *fs, const char *fullpath, struct stat *out) { + struct tar_header hdr; + size_t sect_result; + find_file(fs, fullpath, NULL, §_result, &hdr); + out->s_length = strtoull(hdr.fileSize, NULL, 8); + if(hdr.type_flag == REGTYPE) { + out->s_type = F_REG; + } else if(hdr.type_flag == DIRTYPE) { + out->s_type = F_DIR; + } else { + // wth + return ERROR_TAR; + } + return NOERROR_TAR; } -int tar_stat(struct file_system *fs, const char *path, struct stat *stat) -{ - struct tar_hdr hdr; - size_t sect; - - if (tar_locate(fs, path, &hdr, §, NULL, false)) - return 1; - - stat->s_length = strtoull(hdr.size, NULL, 8); - stat->s_type = tar_to_fs_type(hdr.typeflag); - - return 0; +// use tar for the filesystem. +int tar_mount(struct file_system *fs) { + struct tar_header hdr; + // reads into hdr + if(read_tar_header(fs->fs_disk, 0, &hdr) == 0) { + fs->fs_name = "tar"; + fs->open = tar_open; + fs->stat = tar_stat; + fs->fs_present = true; + return NOERROR_TAR; + } + return ERROR_TAR; } -int tar_mount(struct file_system *fs) -{ - struct tar_hdr hdr; - - // if first tar hdr is valid, assume valid tarball - if (read_tar_hdr(fs->fs_disk, 0, &hdr)) - return 1; - - fs->fs_present = true; - fs->fs_name = "tar"; - fs->open = tar_open; - fs->stat = tar_stat; - - INFO("loaded tarfs on disk %d", fs->fs_disk->d_id); - return 0; -} +// no need to unmount, since mount just overrides whatever it was using previously. \ No newline at end of file diff --git a/kernel/include/comus/ramfs.h b/kernel/include/comus/ramfs.h new file mode 100644 index 0000000..33644d6 --- /dev/null +++ b/kernel/include/comus/ramfs.h @@ -0,0 +1,40 @@ +#include +#ifndef RAMFS_H_ +#define RAMFS_H_ +#define MAX_FILES 32 +#define MAX_FILE_SIZE 4096 + +struct file { + char name[32]; + size_t size; + char *data; +} file; + +struct file allTheFiles[MAX_FILES]; +int numberOfFiles = 0; + +#endif +/* +typedef struct ramfs_file { + char name[32]; + int size; + char *data; +} file; + +typedef struct ramfs_directory { + char name[32]; + file *files[MAX_FILES]; + directory *directories[MAX_FILES]; + int file_count; + int directory_count; +} directory; + +typedef struct ramfs_root { + directory *root; +} root; + +//struct file allTheFiles[MAX_FILES]; +int numberOfFiles = 0; + + +#endif*/ \ No newline at end of file diff --git a/kernel/include/comus/tar.h b/kernel/include/comus/tar.h new file mode 100644 index 0000000..b08f668 --- /dev/null +++ b/kernel/include/comus/tar.h @@ -0,0 +1,6 @@ +#include +#ifndef TAR_FS_H_ +#define TAR_FS_H_ + +int tar_mount(struct file_system *fs); +#endif \ No newline at end of file -- cgit v1.2.3-freya From a88f60869c15e21ba300f2632bd6bc2f9bbbfac5 Mon Sep 17 00:00:00 2001 From: Galen Sagarin Date: Tue, 6 May 2025 13:36:16 -0400 Subject: A few bugfixes for tar.c --- kernel/fs/tar.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index b844ed2..9dccdd6 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -59,7 +59,7 @@ int read_tar_header(struct disk *disk, uint32_t sect, struct tar_header *hdr) { /// @param buffer /// @param len /// @return -int tar_read(struct file *f, char *buffer, size_t len) { +int tar_read(struct file *f, void *buffer, size_t len) { struct tar_file *tf = (struct tar_file*) f; long size = MIN((tf->len - tf->offset), len); if(tf->file.f_type != F_REG || size < 1) { @@ -138,7 +138,7 @@ void tar_close(struct file *f) { kfree(f); } -int tar_seek(struct file *f, int offsetAdd, int theSeek) { +int tar_seek(struct file *f, long int offsetAdd, int theSeek) { struct tar_file *tf = (struct tar_file*) f; if(theSeek == SEEK_SET) { tf->offset = offsetAdd; @@ -154,7 +154,7 @@ int tar_seek(struct file *f, int offsetAdd, int theSeek) { } -int tar_write(struct file *f, const char *buffer, size_t len) { +int tar_write(struct file *f, const void *buffer, size_t len) { // tar doesn't do write lol. This is just here so there is something to send to write (void)f; (void)buffer; @@ -233,13 +233,16 @@ int tar_ents(struct file *f, struct dirent *ent, size_t entry) } // opens up the tar file at fullpath, and puts it in out. -int tar_open(struct file_system *fs, const char *fullpath, struct file **out) { +int tar_open(struct file_system *fs, const char *fullpath, int flags, struct file **out) { struct tar_header hdr; struct tar_file *newFile; size_t sect_result; find_file(fs, fullpath, NULL, §_result, &hdr); + if(flags != O_RDONLY) { + return ERROR_TAR; + } newFile = kalloc(sizeof(struct tar_file)); - //newFile->file = idk; + newFile->file.f_type = F_REG; newFile->fs = fs; newFile->file.read = tar_read; -- cgit v1.2.3-freya From b9ba7d2f4da63442b93fa2f9d36978c19b45ba11 Mon Sep 17 00:00:00 2001 From: Galen Sagarin Date: Tue, 6 May 2025 13:41:58 -0400 Subject: Commenting out ramfs things because they aren't working --- kernel/fs/ramfs.c | 2 +- kernel/include/comus/ramfs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/fs/ramfs.c b/kernel/fs/ramfs.c index 0ed4018..e9d5bc2 100644 --- a/kernel/fs/ramfs.c +++ b/kernel/fs/ramfs.c @@ -1,4 +1,4 @@ -#include +/*#include #include //#include //#include diff --git a/kernel/include/comus/ramfs.h b/kernel/include/comus/ramfs.h index 33644d6..d3cd703 100644 --- a/kernel/include/comus/ramfs.h +++ b/kernel/include/comus/ramfs.h @@ -1,4 +1,4 @@ -#include +/*#include #ifndef RAMFS_H_ #define RAMFS_H_ #define MAX_FILES 32 -- cgit v1.2.3-freya From a7e9c12e9b76cff64176dad2313de7c9c85ab372 Mon Sep 17 00:00:00 2001 From: Galen Sagarin Date: Tue, 6 May 2025 13:45:01 -0400 Subject: fixed tar_seek --- kernel/fs/tar.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 9dccdd6..9de94df 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -142,15 +142,16 @@ int tar_seek(struct file *f, long int offsetAdd, int theSeek) { struct tar_file *tf = (struct tar_file*) f; if(theSeek == SEEK_SET) { tf->offset = offsetAdd; + return tf->offset; } else if(theSeek == SEEK_CUR) { tf->offset = tf->offset + offsetAdd; + return tf->offset; } else if(theSeek ==SEEK_END) { tf->offset = tf->len + offsetAdd; + return tf->offset; } else { - return ERROR_TAR; + return -1; } - return NOERROR_TAR; - } -- cgit v1.2.3-freya From 1e590357e26803f103f40ef3424a5c02248e269a Mon Sep 17 00:00:00 2001 From: Galen Sagarin Date: Tue, 6 May 2025 13:50:25 -0400 Subject: Fixed a parentheses issue --- kernel/fs/tar.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 9de94df..569a876 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -55,8 +55,8 @@ int read_tar_header(struct disk *disk, uint32_t sect, struct tar_header *hdr) { } /// @brief -/// @param f -/// @param buffer +/// @param f the file to be read +/// @param buffer the buffer that the content of the file is read into /// @param len /// @return int tar_read(struct file *f, void *buffer, size_t len) { @@ -65,7 +65,7 @@ int tar_read(struct file *f, void *buffer, size_t len) { if(tf->file.f_type != F_REG || size < 1) { return ERROR_TAR; } - size = disk_read(tf->fs->fs_disk, tf->sect+1 * TAR_SIZE + tf->offset, size, buffer); + size = disk_read(tf->fs->fs_disk, (tf->sect+1) * TAR_SIZE + tf->offset, size, buffer); tf->offset += size; return size; } -- cgit v1.2.3-freya From ba44ae06c6aa311d233b6d056a18895b7bf7ab76 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 13:56:35 -0400 Subject: fmt --- kernel/fs/ramfs.c | 16 +-- kernel/fs/tar.c | 385 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 205 insertions(+), 196 deletions(-) (limited to 'kernel') diff --git a/kernel/fs/ramfs.c b/kernel/fs/ramfs.c index e9d5bc2..0c92c96 100644 --- a/kernel/fs/ramfs.c +++ b/kernel/fs/ramfs.c @@ -1,5 +1,5 @@ -/*#include -#include +#include +/*#include //#include //#include #include @@ -36,7 +36,7 @@ int ramfs_delete(const char *name) { kfree(allTheFiles[i].data); for(int j = i; j < numberOfFiles; j++) { allTheFiles[j] = allTheFiles[j+1]; - numberOfFiles -= 1; + numberOfFiles -= 1; } return NOERROR; @@ -62,7 +62,7 @@ int ramfs_write(const char *name, char *buffer) { } // here we return the index of the file as well. -/*int ramfs_find_file(root *r, const char *fullpath, const char *name, file *out, directory *outDirectory) { +*int ramfs_find_file(root *r, const char *fullpath, const char *name, file *out, directory *outDirectory) { directory *location = r->root; if(ramfs_find_directory(r, fullpath, name, location) == NOERROR) { for(int i = 0; i < location->file_count; i++) { @@ -89,14 +89,14 @@ int ramfs_find_directory(root *r, const char *fullpath, const char *name, direct location = location->directories[i]; wasItFound = true; break; - + } } if(!wasItFound) { return ERROR; } tempPath = strtok(NULL, "/"); - + } out = location; return NOERROR; @@ -142,7 +142,7 @@ int ramfs_delete_file(root *r, const char *fullpath, const char *name) { return NOERROR; } return ERROR; - + } return ERROR; } @@ -155,7 +155,7 @@ int ramfs_delete_directory() { } int ramfs_write() { - + } diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 569a876..5f02c34 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -4,163 +4,173 @@ // the placements of these values mimics their placement in standard UStar struct tar_header { - char name[100]; // 0-99 - char mode[8]; // 100-107 - char ownerUID[8]; // 108-115 - char groupUID[8]; // 116-123 - char fileSize[12]; // 124-135 - char lastMod[12]; // 136-147 - char checksum[8]; // 148-155 - char type_flag; // 156 - char linked_name[100]; // 157-256 - char magic[6]; // 257-262 - char version[2]; // 263-264 - char username[32]; // 265-296 - char groupname[32]; // 297-328 - char majorNum[8]; // 329-336 - char minorNum[8]; // 337-344 - char prefix[155]; // 345-499 - char notUsed[12]; // 500-511 + char name[100]; // 0-99 + char mode[8]; // 100-107 + char ownerUID[8]; // 108-115 + char groupUID[8]; // 116-123 + char fileSize[12]; // 124-135 + char lastMod[12]; // 136-147 + char checksum[8]; // 148-155 + char type_flag; // 156 + char linked_name[100]; // 157-256 + char magic[6]; // 257-262 + char version[2]; // 263-264 + char username[32]; // 265-296 + char groupname[32]; // 297-328 + char majorNum[8]; // 329-336 + char minorNum[8]; // 337-344 + char prefix[155]; // 345-499 + char notUsed[12]; // 500-511 }; -#define TAR_SIZE 512 -#define TMAGIC "ustar" /* ustar and a null */ -#define TMAGLEN 6 -#define TVERSION "00" /* 00 and no null */ +#define TAR_SIZE 512 +#define TMAGIC "ustar" /* ustar and a null */ +#define TMAGLEN 6 +#define TVERSION "00" /* 00 and no null */ #define TVERSLEN 2 #define ERROR_TAR 1 #define NOERROR_TAR 0 -#define REGTYPE '0' /* regular file */ -#define DIRTYPE '5' /* directory */ - +#define REGTYPE '0' /* regular file */ +#define DIRTYPE '5' /* directory */ struct tar_file { - struct file file; - struct file_system *fs; - size_t len; - size_t offset; - size_t sect; + struct file file; + struct file_system *fs; + size_t len; + size_t offset; + size_t sect; }; // read_tar_header reads what is in tar -int read_tar_header(struct disk *disk, uint32_t sect, struct tar_header *hdr) { - - if(disk_read(disk, sect * TAR_SIZE, TAR_SIZE, hdr) < TAR_SIZE) { - return ERROR_TAR; - } - if(memcmp(hdr->magic, TMAGIC, TMAGLEN) != 0 || memcmp(hdr->version, TVERSION, TVERSLEN) != 0) { - return ERROR_TAR; - } - return NOERROR_TAR; - +int read_tar_header(struct disk *disk, uint32_t sect, struct tar_header *hdr) +{ + if (disk_read(disk, sect * TAR_SIZE, TAR_SIZE, hdr) < TAR_SIZE) { + return ERROR_TAR; + } + if (memcmp(hdr->magic, TMAGIC, TMAGLEN) != 0 || + memcmp(hdr->version, TVERSION, TVERSLEN) != 0) { + return ERROR_TAR; + } + return NOERROR_TAR; } -/// @brief +/// @brief /// @param f the file to be read /// @param buffer the buffer that the content of the file is read into -/// @param len -/// @return -int tar_read(struct file *f, void *buffer, size_t len) { - struct tar_file *tf = (struct tar_file*) f; - long size = MIN((tf->len - tf->offset), len); - if(tf->file.f_type != F_REG || size < 1) { - return ERROR_TAR; - } - size = disk_read(tf->fs->fs_disk, (tf->sect+1) * TAR_SIZE + tf->offset, size, buffer); - tf->offset += size; - return size; +/// @param len +/// @return +int tar_read(struct file *f, void *buffer, size_t len) +{ + struct tar_file *tf = (struct tar_file *)f; + long size = MIN((tf->len - tf->offset), len); + if (tf->file.f_type != F_REG || size < 1) { + return ERROR_TAR; + } + size = disk_read(tf->fs->fs_disk, (tf->sect + 1) * TAR_SIZE + tf->offset, + size, buffer); + tf->offset += size; + return size; } //static int read_tar() // we are assuming that things are formatted correctly. -int find_file(struct file_system *fs, const char *filepath, size_t *sect, size_t *sect_return, struct tar_header *outHeader) { - //char *tempFilePath = filepath; - struct tar_header hdr; - size_t curr_sect; - if(sect == NULL) { - curr_sect = 0; - } else { - curr_sect = *sect; - } - while (1 == 1) { - if(read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { - return ERROR_TAR; - } - if(memcmp(hdr.name, filepath, strlen(filepath) + 1) != 0) { - // didn't find it. - - curr_sect += ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1)/TAR_SIZE) + 1; - continue; - } else { - *outHeader = hdr; - *sect_return = curr_sect; - if(sect != NULL) { - sect += curr_sect; - } - return NOERROR_TAR; - } +int find_file(struct file_system *fs, const char *filepath, size_t *sect, + size_t *sect_return, struct tar_header *outHeader) +{ + //char *tempFilePath = filepath; + struct tar_header hdr; + size_t curr_sect; + if (sect == NULL) { + curr_sect = 0; + } else { + curr_sect = *sect; + } + while (1 == 1) { + if (read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { + return ERROR_TAR; + } + if (memcmp(hdr.name, filepath, strlen(filepath) + 1) != 0) { + // didn't find it. - } - return ERROR_TAR; + curr_sect += + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1) / TAR_SIZE) + + 1; + continue; + } else { + *outHeader = hdr; + *sect_return = curr_sect; + if (sect != NULL) { + sect += curr_sect; + } + return NOERROR_TAR; + } + } + return ERROR_TAR; } -int find_file_redux(struct file_system *fs, const char *filepath, size_t *sect, size_t *sect_return, struct tar_header *outHeader) { - struct tar_header hdr; - size_t curr_sect; - if(sect == NULL) { - curr_sect = 0; - } else { - curr_sect = *sect; - } - while (1 == 1) { - if(read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { - return ERROR_TAR; - } - if(memcmp(hdr.name, filepath, MIN(strlen(filepath), strlen(hdr.name))) != 0) { - // didn't find it. - - curr_sect += ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1)/TAR_SIZE) + 1; - continue; - } else { - *outHeader = hdr; - *sect_return = curr_sect; - if(sect != NULL) { - sect += curr_sect + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1)/TAR_SIZE) + 1; - } - return NOERROR_TAR; - - } - - } - return ERROR_TAR; // it should never actually reach here. +int find_file_redux(struct file_system *fs, const char *filepath, size_t *sect, + size_t *sect_return, struct tar_header *outHeader) +{ + struct tar_header hdr; + size_t curr_sect; + if (sect == NULL) { + curr_sect = 0; + } else { + curr_sect = *sect; + } + while (1 == 1) { + if (read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { + return ERROR_TAR; + } + if (memcmp(hdr.name, filepath, + MIN(strlen(filepath), strlen(hdr.name))) != 0) { + // didn't find it. + curr_sect += + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1) / TAR_SIZE) + + 1; + continue; + } else { + *outHeader = hdr; + *sect_return = curr_sect; + if (sect != NULL) { + sect += curr_sect + + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1) / + TAR_SIZE) + + 1; + } + return NOERROR_TAR; + } + } + return ERROR_TAR; // it should never actually reach here. } - -void tar_close(struct file *f) { - kfree(f); +void tar_close(struct file *f) +{ + kfree(f); } -int tar_seek(struct file *f, long int offsetAdd, int theSeek) { - struct tar_file *tf = (struct tar_file*) f; - if(theSeek == SEEK_SET) { - tf->offset = offsetAdd; - return tf->offset; - } else if(theSeek == SEEK_CUR) { - tf->offset = tf->offset + offsetAdd; - return tf->offset; - } else if(theSeek ==SEEK_END) { - tf->offset = tf->len + offsetAdd; - return tf->offset; - } else { - return -1; - } - +int tar_seek(struct file *f, long int offsetAdd, int theSeek) +{ + struct tar_file *tf = (struct tar_file *)f; + if (theSeek == SEEK_SET) { + tf->offset = offsetAdd; + return tf->offset; + } else if (theSeek == SEEK_CUR) { + tf->offset = tf->offset + offsetAdd; + return tf->offset; + } else if (theSeek == SEEK_END) { + tf->offset = tf->len + offsetAdd; + return tf->offset; + } else { + return -1; + } } -int tar_write(struct file *f, const void *buffer, size_t len) { - // tar doesn't do write lol. This is just here so there is something to send to write - (void)f; - (void)buffer; - (void)len; - return ERROR_TAR; +int tar_write(struct file *f, const void *buffer, size_t len) +{ + // tar doesn't do write lol. This is just here so there is something to send to write + (void)f; + (void)buffer; + (void)len; + return ERROR_TAR; } /*int tar_ents(struct file *f, struct dirent *d, size_t dIndex) { @@ -193,9 +203,8 @@ int tar_write(struct file *f, const void *buffer, size_t len) { } - -}*/ +}*/ int tar_ents(struct file *f, struct dirent *ent, size_t entry) { @@ -212,8 +221,8 @@ int tar_ents(struct file *f, struct dirent *ent, size_t entry) return -1; if (read_tar_header(tf->fs->fs_disk, sect, &dir)) { - return ERROR_TAR; - } + return ERROR_TAR; + } while (1) { if (find_file_redux(tf->fs, dir.name, §_off, §, &hdr)) @@ -234,64 +243,64 @@ int tar_ents(struct file *f, struct dirent *ent, size_t entry) } // opens up the tar file at fullpath, and puts it in out. -int tar_open(struct file_system *fs, const char *fullpath, int flags, struct file **out) { - struct tar_header hdr; - struct tar_file *newFile; - size_t sect_result; - find_file(fs, fullpath, NULL, §_result, &hdr); - if(flags != O_RDONLY) { - return ERROR_TAR; - } - newFile = kalloc(sizeof(struct tar_file)); - - newFile->file.f_type = F_REG; - newFile->fs = fs; - newFile->file.read = tar_read; - newFile->file.close = tar_close; - newFile->file.write = tar_write; // doesn't actually work; - newFile->file.ents = tar_ents; - newFile->file.seek = tar_seek; - newFile->offset = 0; - newFile->len = strtoull(hdr.fileSize, NULL, 8); - newFile->sect = sect_result; - - *out = (struct file *)newFile; - return NOERROR_TAR; - - - - +int tar_open(struct file_system *fs, const char *fullpath, int flags, + struct file **out) +{ + struct tar_header hdr; + struct tar_file *newFile; + size_t sect_result; + find_file(fs, fullpath, NULL, §_result, &hdr); + if (flags != O_RDONLY) { + return ERROR_TAR; + } + newFile = kalloc(sizeof(struct tar_file)); + + newFile->file.f_type = F_REG; + newFile->fs = fs; + newFile->file.read = tar_read; + newFile->file.close = tar_close; + newFile->file.write = tar_write; // doesn't actually work; + newFile->file.ents = tar_ents; + newFile->file.seek = tar_seek; + newFile->offset = 0; + newFile->len = strtoull(hdr.fileSize, NULL, 8); + newFile->sect = sect_result; + + *out = (struct file *)newFile; + return NOERROR_TAR; } // gets stats at the file at fullpath, putting them in out. -int tar_stat(struct file_system *fs, const char *fullpath, struct stat *out) { - struct tar_header hdr; - size_t sect_result; - find_file(fs, fullpath, NULL, §_result, &hdr); - out->s_length = strtoull(hdr.fileSize, NULL, 8); - if(hdr.type_flag == REGTYPE) { - out->s_type = F_REG; - } else if(hdr.type_flag == DIRTYPE) { - out->s_type = F_DIR; - } else { - // wth - return ERROR_TAR; - } - return NOERROR_TAR; +int tar_stat(struct file_system *fs, const char *fullpath, struct stat *out) +{ + struct tar_header hdr; + size_t sect_result; + find_file(fs, fullpath, NULL, §_result, &hdr); + out->s_length = strtoull(hdr.fileSize, NULL, 8); + if (hdr.type_flag == REGTYPE) { + out->s_type = F_REG; + } else if (hdr.type_flag == DIRTYPE) { + out->s_type = F_DIR; + } else { + // wth + return ERROR_TAR; + } + return NOERROR_TAR; } // use tar for the filesystem. -int tar_mount(struct file_system *fs) { - struct tar_header hdr; - // reads into hdr - if(read_tar_header(fs->fs_disk, 0, &hdr) == 0) { - fs->fs_name = "tar"; - fs->open = tar_open; - fs->stat = tar_stat; - fs->fs_present = true; - return NOERROR_TAR; - } - return ERROR_TAR; +int tar_mount(struct file_system *fs) +{ + struct tar_header hdr; + // reads into hdr + if (read_tar_header(fs->fs_disk, 0, &hdr) == 0) { + fs->fs_name = "tar"; + fs->open = tar_open; + fs->stat = tar_stat; + fs->fs_present = true; + return NOERROR_TAR; + } + return ERROR_TAR; } // no need to unmount, since mount just overrides whatever it was using previously. \ No newline at end of file -- cgit v1.2.3-freya From 633d89e0cbfea56cb5dc9c2d7fb19857cbe6f49d Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 14:06:27 -0400 Subject: increase identity map --- kernel/include/comus/limits.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/include/comus/limits.h b/kernel/include/comus/limits.h index 1ef13b4..a036fcb 100644 --- a/kernel/include/comus/limits.h +++ b/kernel/include/comus/limits.h @@ -7,7 +7,7 @@ */ /// number of pts to identity map the kernel (1pt = 2MB) -#define N_IDENT_PTS 4 // max 512 (1G) +#define N_IDENT_PTS 64 // max 512 (1G) /// max number of processes #define N_PROCS 256 -- cgit v1.2.3-freya From 6cfcabf38e6f4982bfb116ac9cedf2333e29d275 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 14:20:05 -0400 Subject: smooth scrolling for term --- kernel/term.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/term.c b/kernel/term.c index 917f645..88fa072 100644 --- a/kernel/term.c +++ b/kernel/term.c @@ -7,8 +7,10 @@ // terminal data static char buffer[TERM_MAX_WIDTH * TERM_MAX_HEIGHT]; static uint16_t buffer_line = UINT16_MAX; -static uint16_t width = 80; // baseline vga text mode until resized -static uint16_t height = 25; +static uint16_t last_width = 80, + width = 80; // baseline vga text mode until resized +static uint16_t last_height = 25, height = 25; +static uint16_t scrolling = 0; static uint16_t x = 0; static uint16_t y = 0; @@ -140,10 +142,26 @@ void term_redraw(void) for (uint16_t j = 0; j < height; j++) { for (uint16_t i = 0; i < width; i++) { - char c = buffer[BUFIDX(i, j)]; + char c; + + c = buffer[BUFIDX(i, j)]; + + // if screen hasnet changed size + // dont redraw what we dont need to redraw + if (last_width == height && last_width == width) { + char prev; + prev = buffer[BUFIDX(i, (j - scrolling))]; + if (c == prev) + continue; + } + gpu_draw_char(c, i, j); } } + + last_width = width; + last_height = height; + scrolling = 0; } void term_scroll(uint16_t lines) @@ -151,6 +169,8 @@ void term_scroll(uint16_t lines) if (!lines) return; buffer_line += lines; + term_clear_line(y); + scrolling = lines; term_redraw(); } -- cgit v1.2.3-freya From 0fd92cbb351a7ae652ceb047516ad4f00a85ddb6 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 14:21:26 -0400 Subject: set max res for gop framebuffer --- kernel/efi/gop.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/efi/gop.c b/kernel/efi/gop.c index 899bbee..5495980 100644 --- a/kernel/efi/gop.c +++ b/kernel/efi/gop.c @@ -4,6 +4,8 @@ static EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL; +#define MAX_H_RES 1920 + EFI_STATUS efi_load_gop(EFI_SYSTEM_TABLE *ST) { EFI_STATUS status = EFI_SUCCESS; @@ -33,6 +35,8 @@ EFI_STATUS efi_load_gop(EFI_SYSTEM_TABLE *ST) if (info->PixelFormat != PixelBlueGreenRedReserved8BitPerColor && info->PixelFormat != PixelRedGreenBlueReserved8BitPerColor) continue; + if (info->HorizontalResolution > MAX_H_RES) + continue; if (info->HorizontalResolution > width) { width = info->HorizontalResolution; best = i; -- cgit v1.2.3-freya From 128aeb51424414e59dc61c5a6df0c72f87012a52 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 15:03:23 -0400 Subject: start docs --- docs/DRIVERS.md | 47 ++++++++++++++++++++++++ docs/FS.md | 0 docs/HEADERS.md | 0 docs/MEMORY.md | 0 docs/MODULES.md | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ docs/PCB.md | 53 +++++++++++++++++++++++++++ kernel/procs.c | 1 - 7 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 docs/DRIVERS.md create mode 100644 docs/FS.md create mode 100644 docs/HEADERS.md create mode 100644 docs/MEMORY.md create mode 100644 docs/MODULES.md create mode 100644 docs/PCB.md (limited to 'kernel') diff --git a/docs/DRIVERS.md b/docs/DRIVERS.md new file mode 100644 index 0000000..e17e15e --- /dev/null +++ b/docs/DRIVERS.md @@ -0,0 +1,47 @@ +# Drivers + +All drivers and their uses + +## acpi.c + +ACPI (Advanced Configuration and Power Interface) +- allows powering off the system + +## ata.c + +ATA (Advanced Technology Attachment) / IDE (Integrated Drive Electronics) +- ide/ata disk device driver + +## clock.c + +COMS real time clock driver + +## gpu/ + +Contains drivers for each type of gpu +- Bochs (QEMU default gpu device) +- GOP (Graphics Output Protocol), UEFI framebuffer + +## gpu.c + +Functions for abstracting over current loaded gpu + +## pci.c + +PCI (Peripheral Component Interconnect) +- driver to load pci devices (not pcie) + +## pit.c + +PIT (Programmable Interval Timer) +- sends timer interrupts to the pic +- set pc speaker tones + +## ps2.c + +PS2 Controller / Keyboard / Mouse driver +- allows keyboard / mouse input + +## uart.c + +Serial (UART) driver diff --git a/docs/FS.md b/docs/FS.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/HEADERS.md b/docs/HEADERS.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/MEMORY.md b/docs/MEMORY.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/MODULES.md b/docs/MODULES.md new file mode 100644 index 0000000..cf452ff --- /dev/null +++ b/docs/MODULES.md @@ -0,0 +1,109 @@ +# modules + +list of all kernel modules and their functions + +## cpu/ + +Initalizes all cpu components and low level tabels. +- FPU / SSE / AVX +- IDT (Interrupt Descriptor Table) +- PIC (Programmable Interrupt Controller) +- TSS (Task State Segment) + - used for allowing kernel to switch into ring 3 + - used for setting kernel stack on interrupt + +## drivers/ + +Folder `drivers/` contains drivers for the system. See DRIVERS.md. + +File `drivers.c` loads each of the drivers in `drivers/`. + +## efi/ + +Load UEFI components +- UEFI memory map +- GOP (Graphics Output Protocol), UEFI framebuffer + +## entry.S + +Entry point into the kernel along with: +- GDT (Global Descriptor Table) +- Multiboot header see https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html +- Inital kernel stack + - not used once interrupts since interrupt stack will be used +- Inital page tables + - see MEMORY.md + +Symbols: +- `_start` + - generic legacy bios entrypoint in IA-32 mode + +- `_start_efi` + - uefi entrypoint in IA-32e mode + +## font/ + +Loads psf2 font files into kernel .rodata segment + +## fs/ + +See FS.md + +## include/ + +All kernel headers. + +- SEE HEADERS.md + +## input.c + +Abstracts all input from all sources over a single keycode / mouseevent buffer. +- uses ps2 and uart + +## lib/ + +Kernel c library + +Notable files: + +- `backtrace.c` - does stack backtraces and logs them to output + - used during exceptions +- `kspin.c` + - spinlock in kernel space +- `panic.c` + - implements panic functions, along with halt called during exceptions or panic + +## main.c + +Kernel main entrypoint. +- Loads all components of the kernel in order. +- Loads init process +- Dispatches init + +## mboot/ + +Laod information provided by multiboot standard +- `efi.c` - gets `EFI_SYSTEM_TABLE` & `EFI_HANDLE` + - read UEFI standard for more information +- `mmap.c` - load memory map when in legacy boot + - memory map is loaded from `efi/` module when booting from UEFI +- `module.c` + - loads initrd (ramdisk) +- `rsdp.c` + - load root ACPI table, provided for the ACPI driver + +## memory/ + +See MEMORY.md + +## procs.c + +Stores loaded process information and scheduler +- multiple queues for scheduling + - ready - pcb is ready to be executed + - zombie - pcb is a zombie, and waiting to be cleaned up + - syscall - replaced blocked/waiting in baseline + - each syscall has its own queue + - acessed though syscall_queue[SYS_num] + +See PCB.md for pcb information. diff --git a/docs/PCB.md b/docs/PCB.md new file mode 100644 index 0000000..9eaa2a2 --- /dev/null +++ b/docs/PCB.md @@ -0,0 +1,53 @@ +# PCB + +PCB information + +## context + +Contains context infromation for the curernt process. +- memory context (pcb->memctx) + - stores page directory and vitural address allocateor (see MEMORY.md) +- context save area (pcb->regs) + +## medatada + +- `pid` - process idenfitication number +- `parent` ` - parent of the current process + - can be NULL if the init process +- `state` - the current runing state of the process + - `UNUSED` - proces in ptable is not used + - `NEW` - process in ptable has been allocated but has not been initalized + - `READY` - process is ready to be dispatched (and in ready queue) + - `RUNNING` - process is the current running process (and in no queues) + - `BLOCKED` - process is in a syscall queue waiting on their syscall to return + - `ZOMBIE` - process is a zombie and waiting to be cleaned up (in zombie queue) +- `priority` - running process priority + - any number form 0 to SIZET_MAX + - higher priority means longer wait to be scheduled +- `ticks` - number of ticks the process has been running for + - set to zero when process is not running + +## heap + +- `heap_start` is the start of the progams heap +- `heap_len` is the length of the programs heap + +## open files + +- `open_files` is a list of currently opened files indexed by file descriptor + +## elf metadata + +- `elf_header` - the programs elf header (Elf64_Ehdr) +- `elf_segments` - the programs loadable elf segments (Elf64_Phdr[]) +- `n_elf_segments` - the number of elf segmsnts the program has + +## queue linkage + +- `next` - the next pcb in the current queue this pcb is in + +## processs state information + +- `syscall` - the current syscall this process is blocked on +- `wakeup` - the number of ticks until the process can be waked up (used during SYS_sleep) +- `exit_status` - the exit status of the process when a zombie diff --git a/kernel/procs.c b/kernel/procs.c index d471416..6017e3a 100644 --- a/kernel/procs.c +++ b/kernel/procs.c @@ -1,4 +1,3 @@ -#include "lib/kio.h" #include #include #include -- cgit v1.2.3-freya