From a8050bce47ac5b0d256df328f61b603e60751b37 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Thu, 21 Oct 2021 01:27:05 +0200 Subject: [PATCH] everywhere: Implement pmm_free() --- stage23/entry.s2.c | 14 +++--- stage23/entry.s3.c | 10 +++-- stage23/fs/echfs.h | 6 ++- stage23/fs/echfs.s2.c | 23 +++++----- stage23/fs/ext2.h | 5 ++- stage23/fs/ext2.s2.c | 42 ++++++++++++----- stage23/fs/fat32.h | 6 ++- stage23/fs/fat32.s2.c | 39 ++++++++++------ stage23/fs/file.h | 9 ++-- stage23/fs/file.s2.c | 82 ++++++++++++++++++++-------------- stage23/fs/iso9660.h | 5 ++- stage23/fs/iso9660.s2.c | 25 ++++++++--- stage23/lib/config.c | 14 +++--- stage23/lib/elf.c | 48 +++++++++++++++----- stage23/lib/gterm.c | 19 ++++---- stage23/lib/uri.c | 89 ++++++++++++++++--------------------- stage23/lib/uri.h | 2 +- stage23/mm/pmm.h | 2 + stage23/mm/pmm.s2.c | 9 +++- stage23/protos/chainload.c | 7 ++- stage23/protos/linux.c | 20 +++++---- stage23/protos/multiboot1.c | 20 +++++---- stage23/protos/multiboot2.c | 23 ++++++---- stage23/protos/stivale.c | 16 ++++--- stage23/protos/stivale2.c | 16 ++++--- stage23/pxe/pxe.s2.c | 2 +- stage23/pxe/tftp.h | 2 +- stage23/pxe/tftp.s2.c | 12 ++--- 28 files changed, 346 insertions(+), 221 deletions(-) diff --git a/stage23/entry.s2.c b/stage23/entry.s2.c index dcaf9cae..29d0ae1d 100644 --- a/stage23/entry.s2.c +++ b/stage23/entry.s2.c @@ -34,23 +34,25 @@ extern symbol stage3_addr; extern symbol limine_sys_size; static bool stage3_init(struct volume *part) { - struct file_handle stage3; + struct file_handle *stage3; - if (fopen(&stage3, part, "/limine.sys") - && fopen(&stage3, part, "/boot/limine.sys")) { + if ((stage3 = fopen(part, "/limine.sys")) == NULL + && (stage3 = fopen(part, "/boot/limine.sys")) == NULL) { return false; } stage3_found = true; - if (stage3.size != (size_t)limine_sys_size) { + if (stage3->size != (size_t)limine_sys_size) { print("limine.sys size incorrect.\n"); return false; } - fread(&stage3, stage3_addr, + fread(stage3, stage3_addr, (uintptr_t)stage3_addr - 0x8000, - stage3.size - ((uintptr_t)stage3_addr - 0x8000)); + stage3->size - ((uintptr_t)stage3_addr - 0x8000)); + + fclose(stage3); if (BUILD_ID != stage3_build_id) { print("limine.sys build ID mismatch.\n"); diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c index 5e5f273a..26cae860 100644 --- a/stage23/entry.s3.c +++ b/stage23/entry.s3.c @@ -79,14 +79,16 @@ void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { print(" Using the first volume containing a Limine configuration!\n"); for (size_t i = 0; i < volume_index_i; i++) { - struct file_handle f; + struct file_handle *f; - if (fopen(&f, volume_index[i], "/limine.cfg") - && fopen(&f, volume_index[i], "/boot/limine.cfg") - && fopen(&f, volume_index[i], "/EFI/BOOT/limine.cfg")) { + if ((f = fopen(volume_index[i], "/limine.cfg")) == NULL + && (f = fopen(volume_index[i], "/boot/limine.cfg")) == NULL + && (f = fopen(volume_index[i], "/EFI/BOOT/limine.cfg")) == NULL) { continue; } + fclose(f); + if (volume_index[i]->backing_dev != NULL) { boot_volume = volume_index[i]->backing_dev; } else { diff --git a/stage23/fs/echfs.h b/stage23/fs/echfs.h index 38a684eb..bafce9b2 100644 --- a/stage23/fs/echfs.h +++ b/stage23/fs/echfs.h @@ -28,6 +28,7 @@ struct echfs_file_handle { uint64_t alloc_table_size; uint64_t alloc_table_offset; uint64_t dir_offset; + uint64_t file_block_count; uint64_t *alloc_map; struct echfs_dir_entry dir_entry; }; @@ -35,7 +36,8 @@ struct echfs_file_handle { int echfs_check_signature(struct volume *part); bool echfs_get_guid(struct guid *guid, struct volume *part); -int echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *filename); -int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count); +bool echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *filename); +void echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count); +void echfs_close(struct echfs_file_handle *file); #endif diff --git a/stage23/fs/echfs.s2.c b/stage23/fs/echfs.s2.c index c907b36a..c14546b6 100644 --- a/stage23/fs/echfs.s2.c +++ b/stage23/fs/echfs.s2.c @@ -26,7 +26,7 @@ static bool read_block(struct echfs_file_handle *file, void *buf, uint64_t block return volume_read(file->part, buf, (file->alloc_map[block] * file->block_size) + offset, count); } -int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count) { +void echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count) { for (uint64_t progress = 0; progress < count;) { uint64_t block = (loc + progress) / file->block_size; @@ -38,8 +38,6 @@ int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t read_block(file, buf + progress, block, offset, chunk); progress += chunk; } - - return 0; } int echfs_check_signature(struct volume *part) { @@ -66,7 +64,12 @@ bool echfs_get_guid(struct guid *guid, struct volume *part) { return true; } -int echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *path) { +void echfs_close(struct echfs_file_handle *file) { + pmm_free(file->alloc_map, file->file_block_count * sizeof(uint64_t)); + pmm_free(file, sizeof(struct echfs_file_handle)); +} + +bool echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *path) { ret->part = part; struct echfs_identity_table id_table; @@ -74,7 +77,7 @@ int echfs_open(struct echfs_file_handle *ret, struct volume *part, const char *p if (strncmp(id_table.signature, "_ECH_FS_", 8)) { print("echfs: signature invalid\n"); - return -1; + return false; } ret->block_size = id_table.block_size; @@ -121,16 +124,16 @@ next:; } } - return -1; + return false; found:; // Load the allocation map. - uint64_t file_block_count = DIV_ROUNDUP(ret->dir_entry.size, ret->block_size); + ret->file_block_count = DIV_ROUNDUP(ret->dir_entry.size, ret->block_size); - ret->alloc_map = ext_mem_alloc(file_block_count * sizeof(uint64_t)); + ret->alloc_map = ext_mem_alloc(ret->file_block_count * sizeof(uint64_t)); ret->alloc_map[0] = ret->dir_entry.payload; - for (uint64_t i = 1; i < file_block_count; i++) { + for (uint64_t i = 1; i < ret->file_block_count; i++) { // Read the next block. volume_read(ret->part, &ret->alloc_map[i], @@ -138,5 +141,5 @@ found:; sizeof(uint64_t)); } - return 0; + return true; } diff --git a/stage23/fs/ext2.h b/stage23/fs/ext2.h index e9541a09..baedaa77 100644 --- a/stage23/fs/ext2.h +++ b/stage23/fs/ext2.h @@ -125,7 +125,8 @@ struct ext2_file_handle { int ext2_check_signature(struct volume *part); bool ext2_get_guid(struct guid *guid, struct volume *part); -int ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *path); -int ext2_read(struct ext2_file_handle *file, void *buf, uint64_t loc, uint64_t count); +bool ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *path); +void ext2_read(struct ext2_file_handle *file, void *buf, uint64_t loc, uint64_t count); +void ext2_close(struct ext2_file_handle *file); #endif diff --git a/stage23/fs/ext2.s2.c b/stage23/fs/ext2.s2.c index 8faa5a6d..6a617e6c 100644 --- a/stage23/fs/ext2.s2.c +++ b/stage23/fs/ext2.s2.c @@ -250,6 +250,8 @@ static bool ext2_parse_dirent(struct ext2_dir_entry *dir, struct ext2_file_handl bool escape = false; static char token[256]; + bool ret; + next: memset(token, 0, 256); @@ -277,19 +279,24 @@ next: if (!strcmp(token, name)) { if (escape) { - return true; + ret = true; + goto out; } else { // update the current inode ext2_get_inode(¤t_inode, fd, dir->inode); while ((current_inode.i_mode & FMT_MASK) != S_IFDIR) { if ((current_inode.i_mode & FMT_MASK) == S_IFLNK) { - if (!symlink_to_inode(¤t_inode, fd)) - return false; + if (!symlink_to_inode(¤t_inode, fd)) { + ret = false; + goto out; + } } else { print("ext2: Part of path is not directory nor symlink\n"); - return false; + ret = false; + goto out; } } + pmm_free(alloc_map, current_inode.i_blocks_count * sizeof(uint32_t)); goto next; } } @@ -297,10 +304,14 @@ next: i += dir->rec_len; } - return false; + ret = false; + +out: + pmm_free(alloc_map, current_inode.i_blocks_count * sizeof(uint32_t)); + return ret; } -int ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *path) { +bool ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *path) { ret->part = part; volume_read(ret->part, &ret->sb, 1024, sizeof(struct ext2_superblock)); @@ -317,17 +328,17 @@ int ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *pat struct ext2_dir_entry entry; if (!ext2_parse_dirent(&entry, ret, path)) - return -1; + return false; ext2_get_inode(&ret->inode, ret, entry.inode); while ((ret->inode.i_mode & FMT_MASK) != S_IFREG) { if ((ret->inode.i_mode & FMT_MASK) == S_IFLNK) { if (!symlink_to_inode(&ret->inode, ret)) - return -1; + return false; } else { print("ext2: Entity is not regular file nor symlink\n"); - return -1; + return false; } } @@ -335,11 +346,16 @@ int ext2_open(struct ext2_file_handle *ret, struct volume *part, const char *pat ret->alloc_map = create_alloc_map(ret, &ret->inode); - return 0; + return true; } -int ext2_read(struct ext2_file_handle *file, void *buf, uint64_t loc, uint64_t count) { - return inode_read(buf, loc, count, &file->inode, file, file->alloc_map); +void ext2_close(struct ext2_file_handle *file) { + pmm_free(file->alloc_map, file->inode.i_blocks_count * sizeof(uint32_t)); + pmm_free(file, sizeof(struct ext2_file_handle)); +} + +void ext2_read(struct ext2_file_handle *file, void *buf, uint64_t loc, uint64_t count) { + inode_read(buf, loc, count, &file->inode, file, file->alloc_map); } static struct ext4_extent_header* ext4_find_leaf(struct ext4_extent_header* ext_block, uint32_t read_block, uint64_t block_size, struct volume *part) { @@ -415,6 +431,8 @@ static int inode_read(void *buf, uint64_t loc, uint64_t count, } else { panic("extent for block not found"); } + + pmm_free(leaf, fd->block_size); } else { block_index = alloc_map[block]; } diff --git a/stage23/fs/fat32.h b/stage23/fs/fat32.h index 030c3b5b..92ccecd4 100644 --- a/stage23/fs/fat32.h +++ b/stage23/fs/fat32.h @@ -26,11 +26,13 @@ struct fat32_file_handle { uint32_t size_bytes; uint32_t size_clusters; uint32_t *cluster_chain; + size_t chain_len; }; int fat32_check_signature(struct volume *part); -int fat32_open(struct fat32_file_handle *ret, struct volume *part, const char *path); -int fat32_read(struct fat32_file_handle *file, void *buf, uint64_t loc, uint64_t count); +bool fat32_open(struct fat32_file_handle *ret, struct volume *part, const char *path); +void fat32_read(struct fat32_file_handle *file, void *buf, uint64_t loc, uint64_t count); +void fat32_close(struct fat32_file_handle *file); #endif diff --git a/stage23/fs/fat32.s2.c b/stage23/fs/fat32.s2.c index 03eebaac..e539900a 100644 --- a/stage23/fs/fat32.s2.c +++ b/stage23/fs/fat32.s2.c @@ -249,8 +249,9 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e directory_entries = ext_mem_alloc(dir_chain_len * block_size); - if (!read_cluster_chain(context, directory_cluster_chain, directory_entries, 0, dir_chain_len * block_size)) - return -1; + read_cluster_chain(context, directory_cluster_chain, directory_entries, 0, dir_chain_len * block_size); + + pmm_free(directory_cluster_chain, dir_chain_len * sizeof(uint32_t)); } else { dir_chain_len = DIV_ROUNDUP(context->root_entries * sizeof(struct fat32_directory_entry), block_size); @@ -259,6 +260,8 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e volume_read(context->part, directory_entries, context->root_start * FAT32_SECTOR_SIZE, context->root_entries * sizeof(struct fat32_directory_entry)); } + int ret; + for (size_t i = 0; i < (dir_chain_len * block_size) / sizeof(struct fat32_directory_entry); i++) { if (directory_entries[i].file_name_and_ext[0] == 0x00) { // no more entries here @@ -295,7 +298,8 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e if (!strcmp(current_lfn, name)) { *file = directory_entries[i+1]; - return 0; + ret = 0; + goto out; } } @@ -310,12 +314,17 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e } if (!strncmp(directory_entries[i].file_name_and_ext, fn, 8+3)) { *file = directory_entries[i]; - return 0; + ret = 0; + goto out; } } // file not found - return -1; + ret = -1; + +out: + pmm_free(directory_entries, dir_chain_len * block_size); + return ret; } int fat32_check_signature(struct volume *part) { @@ -323,13 +332,13 @@ int fat32_check_signature(struct volume *part) { return fat32_init_context(&context, part) == 0; } -int fat32_open(struct fat32_file_handle* ret, struct volume *part, const char* path) { +bool fat32_open(struct fat32_file_handle* ret, struct volume *part, const char* path) { struct fat32_context context; int r = fat32_init_context(&context, part); if (r) { print("fat32: context init failure (%d)\n", r); - return r; + return false; } struct fat32_directory_entry _current_directory; @@ -379,7 +388,7 @@ int fat32_open(struct fat32_file_handle* ret, struct volume *part, const char* p } if ((r = fat32_open_in(&context, current_directory, ¤t_file, current_part)) != 0) { - return r; + return false; } if (expect_directory) { @@ -392,13 +401,17 @@ int fat32_open(struct fat32_file_handle* ret, struct volume *part, const char* p ret->first_cluster |= (uint64_t)current_file.cluster_num_high << 16; ret->size_clusters = DIV_ROUNDUP(current_file.file_size_bytes, FAT32_SECTOR_SIZE); ret->size_bytes = current_file.file_size_bytes; - size_t file_chain_len; - ret->cluster_chain = cache_cluster_chain(&context, ret->first_cluster, &file_chain_len); - return 0; + ret->cluster_chain = cache_cluster_chain(&context, ret->first_cluster, &ret->chain_len); + return true; } } } -int fat32_read(struct fat32_file_handle* file, void* buf, uint64_t loc, uint64_t count) { - return !read_cluster_chain(&file->context, file->cluster_chain, buf, loc, count); +void fat32_read(struct fat32_file_handle* file, void* buf, uint64_t loc, uint64_t count) { + read_cluster_chain(&file->context, file->cluster_chain, buf, loc, count); +} + +void fat32_close(struct fat32_file_handle *file) { + pmm_free(file->cluster_chain, file->chain_len * sizeof(uint32_t)); + pmm_free(file, sizeof(struct fat32_file_handle)); } diff --git a/stage23/fs/file.h b/stage23/fs/file.h index 57d3a413..bfd3c0ee 100644 --- a/stage23/fs/file.h +++ b/stage23/fs/file.h @@ -13,16 +13,19 @@ bool fs_get_guid(struct guid *guid, struct volume *part); struct file_handle { bool is_memfile; + bool readall; void *fd; - int (*read)(void *fd, void *buf, uint64_t loc, uint64_t count); + void (*read)(void *fd, void *buf, uint64_t loc, uint64_t count); + void (*close)(void *fd); uint64_t size; #if uefi == 1 EFI_HANDLE efi_part_handle; #endif }; -int fopen(struct file_handle *ret, struct volume *part, const char *filename); -int fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count); +struct file_handle *fopen(struct volume *part, const char *filename); +void fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count); +void fclose(struct file_handle *fd); void *freadall(struct file_handle *fd, uint32_t type); #endif diff --git a/stage23/fs/file.s2.c b/stage23/fs/file.s2.c index a90e9fcb..682a95e6 100644 --- a/stage23/fs/file.s2.c +++ b/stage23/fs/file.s2.c @@ -23,16 +23,18 @@ bool fs_get_guid(struct guid *guid, struct volume *part) { return false; } -int fopen(struct file_handle *ret, struct volume *part, const char *filename) { +struct file_handle *fopen(struct volume *part, const char *filename) { + struct file_handle *ret = ext_mem_alloc(sizeof(struct file_handle)); + ret->is_memfile = false; + ret->readall = false; #if bios == 1 if (part->pxe) { - int r = tftp_open(ret, 0, 69, filename); - if (r) - return r; - - return 0; + if (!tftp_open(ret, 0, 69, filename)) { + goto fail; + } + return ret; } #endif @@ -43,81 +45,95 @@ int fopen(struct file_handle *ret, struct volume *part, const char *filename) { if (iso9660_check_signature(part)) { struct iso9660_file_handle *fd = ext_mem_alloc(sizeof(struct iso9660_file_handle)); - int r = iso9660_open(fd, part, filename); - if (r) - return r; + if (!iso9660_open(fd, part, filename)) { + goto fail; + } ret->fd = (void *)fd; ret->read = (void *)iso9660_read; + ret->close = (void *)iso9660_close; ret->size = fd->size; - return 0; + return ret; } if (echfs_check_signature(part)) { struct echfs_file_handle *fd = ext_mem_alloc(sizeof(struct echfs_file_handle)); - int r = echfs_open(fd, part, filename); - if (r) - return r; + if (!echfs_open(fd, part, filename)) { + goto fail; + } - ret->fd = (void *)fd; + ret->fd = (void *)fd; ret->read = (void *)echfs_read; + ret->close = (void *)echfs_close; ret->size = fd->dir_entry.size; - return 0; + return ret; } if (ext2_check_signature(part)) { struct ext2_file_handle *fd = ext_mem_alloc(sizeof(struct ext2_file_handle)); - int r = ext2_open(fd, part, filename); - if (r) - return r; + if (!ext2_open(fd, part, filename)) { + goto fail; + } - ret->fd = (void *)fd; + ret->fd = (void *)fd; ret->read = (void *)ext2_read; + ret->close = (void *)ext2_close; ret->size = fd->size; - return 0; + return ret; } if (fat32_check_signature(part)) { struct fat32_file_handle *fd = ext_mem_alloc(sizeof(struct fat32_file_handle)); - int r = fat32_open(fd, part, filename); + if (!fat32_open(fd, part, filename)) { + goto fail; + } - if (r) - return r; - - ret->fd = (void *)fd; + ret->fd = (void *)fd; ret->read = (void *)fat32_read; + ret->close = (void *)fat32_close; ret->size = fd->size_bytes; - return 0; + return ret; } - return -1; +fail: + pmm_free(ret, sizeof(struct file_handle)); + return NULL; } -int fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) { +void fclose(struct file_handle *fd) { + if (fd->is_memfile) { + if (fd->readall == false) { + pmm_free(fd->fd, fd->size); + } + } else { + fd->close(fd->fd); + } + pmm_free(fd, sizeof(struct file_handle)); +} + +void fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) { if (fd->is_memfile) { memcpy(buf, fd->fd + loc, count); - return 0; } else { - return fd->read(fd->fd, buf, loc, count); + fd->read(fd->fd, buf, loc, count); } } void *freadall(struct file_handle *fd, uint32_t type) { if (fd->is_memfile) { memmap_alloc_range((uint64_t)(size_t)fd->fd, ALIGN_UP(fd->size, 4096), type, false, true, false, false); + fd->readall = true; return fd->fd; } else { void *ret = ext_mem_alloc_type(fd->size, type); - if (fd->read(fd->fd, ret, 0, fd->size)) { - panic("freadall error"); - } + fd->read(fd->fd, ret, 0, fd->size); return ret; } } diff --git a/stage23/fs/iso9660.h b/stage23/fs/iso9660.h index 2819f325..8f13eccc 100644 --- a/stage23/fs/iso9660.h +++ b/stage23/fs/iso9660.h @@ -19,7 +19,8 @@ struct iso9660_file_handle { }; int iso9660_check_signature(struct volume *vol); -int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path); -int iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count); +bool iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path); +void iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count); +void iso9660_close(struct iso9660_file_handle *file); #endif diff --git a/stage23/fs/iso9660.s2.c b/stage23/fs/iso9660.s2.c index 904597db..f8cedce2 100644 --- a/stage23/fs/iso9660.s2.c +++ b/stage23/fs/iso9660.s2.c @@ -76,7 +76,8 @@ struct iso9660_contexts_node { struct iso9660_context context; struct iso9660_contexts_node *next; }; -struct iso9660_contexts_node *contexts = NULL; + +static struct iso9660_contexts_node *contexts = NULL; static void iso9660_find_PVD(struct iso9660_volume_descriptor *desc, struct volume *vol) { uint32_t lba = ISO9660_FIRST_VOLUME_DESCRIPTOR; @@ -207,7 +208,7 @@ int iso9660_check_signature(struct volume *vol) { return !strcmp(buf, "CD001"); } -int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path) { +bool iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path) { ret->context = iso9660_get_context(vol); while (*path == '/') @@ -216,6 +217,8 @@ int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char struct iso9660_directory_entry *current = ret->context->root; uint32_t current_size = ret->context->root_size; + bool first = true; + uint32_t next_sector = 0; uint32_t next_size = 0; @@ -228,7 +231,7 @@ int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char struct iso9660_directory_entry *entry = iso9660_find(current, current_size, filename); if (!entry) - return 1; // Not found :( + return false; // Not found :( next_sector = entry->extent.little; next_size = entry->extent_size.little; @@ -236,17 +239,27 @@ int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char if (*path++ == '\0') break; // Found :) + if (!first) { + pmm_free(current, current_size); + } + current_size = next_size; current = ext_mem_alloc(current_size); + + first = false; + volume_read(vol, current, next_sector * ISO9660_SECTOR_SIZE, current_size); } ret->LBA = next_sector; ret->size = next_size; - return 0; + return true; } -int iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count) { +void iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count) { volume_read(file->context->vol, buf, file->LBA * ISO9660_SECTOR_SIZE + loc, count); - return 0; +} + +void iso9660_close(struct iso9660_file_handle *file) { + pmm_free(file, sizeof(struct iso9660_file_handle)); } diff --git a/stage23/lib/config.c b/stage23/lib/config.c index dc549373..080a77ba 100644 --- a/stage23/lib/config.c +++ b/stage23/lib/config.c @@ -17,18 +17,20 @@ bool config_ready = false; static char *config_addr; int init_config_disk(struct volume *part) { - struct file_handle f; + struct file_handle *f; - if (fopen(&f, part, "/limine.cfg") - && fopen(&f, part, "/boot/limine.cfg") - && fopen(&f, part, "/EFI/BOOT/limine.cfg")) { + if ((f = fopen(part, "/limine.cfg")) == NULL + && (f = fopen(part, "/boot/limine.cfg")) == NULL + && (f = fopen(part, "/EFI/BOOT/limine.cfg")) == NULL) { return -1; } - size_t config_size = f.size + 1; + size_t config_size = f->size + 1; config_addr = ext_mem_alloc(config_size); - fread(&f, config_addr, 0, f.size); + fread(f, config_addr, 0, f->size); + + fclose(f); return init_config(config_size); } diff --git a/stage23/lib/elf.c b/stage23/lib/elf.c index c99f633b..360b40c2 100644 --- a/stage23/lib/elf.c +++ b/stage23/lib/elf.c @@ -229,22 +229,34 @@ int elf64_load_section(uint8_t *elf, void *buffer, const char *name, size_t limi char *names = ext_mem_alloc(shstrtab.sh_size); memcpy(names, elf + (shstrtab.sh_offset), shstrtab.sh_size); + int ret; + for (uint16_t i = 0; i < hdr.sh_num; i++) { struct elf64_shdr section; memcpy(§ion, elf + (hdr.shoff + i * sizeof(struct elf64_shdr)), sizeof(struct elf64_shdr)); if (!strcmp(&names[section.sh_name], name)) { - if (section.sh_size > limit) - return 3; - if (section.sh_size < limit) - return 4; + if (section.sh_size > limit) { + ret = 3; + goto out; + } + if (section.sh_size < limit) { + ret = 4; + goto out; + } memcpy(buffer, elf + (section.sh_offset), section.sh_size); - return elf64_apply_relocations(elf, &hdr, buffer, section.sh_addr, section.sh_size, slide); + ret = elf64_apply_relocations(elf, &hdr, buffer, section.sh_addr, section.sh_size, slide); + goto out; } } - return 2; + ret = 2; + +out: + pmm_free(names, shstrtab.sh_size); + + return ret; } /// SAFETY: The caller must ensure that the provided `elf` is a valid 64-bit @@ -311,22 +323,34 @@ int elf32_load_section(uint8_t *elf, void *buffer, const char *name, size_t limi char *names = ext_mem_alloc(shstrtab.sh_size); memcpy(names, elf + (shstrtab.sh_offset), shstrtab.sh_size); + int ret; + for (uint16_t i = 0; i < hdr.sh_num; i++) { struct elf32_shdr section; memcpy(§ion, elf + (hdr.shoff + i * sizeof(struct elf32_shdr)), sizeof(struct elf32_shdr)); if (!strcmp(&names[section.sh_name], name)) { - if (section.sh_size > limit) - return 3; - if (section.sh_size < limit) - return 4; + if (section.sh_size > limit) { + ret = 3; + goto out; + } + if (section.sh_size < limit) { + ret = 4; + goto out; + } memcpy(buffer, elf + (section.sh_offset), section.sh_size); - return 0; + ret = 0; + goto out; } } - return 2; + ret = 2; + +out: + pmm_free(names, shstrtab.sh_size); + + return ret; } static uint64_t elf64_max_align(uint8_t *elf) { diff --git a/stage23/lib/gterm.c b/stage23/lib/gterm.c index 5b96c404..ecc3bde3 100644 --- a/stage23/lib/gterm.c +++ b/stage23/lib/gterm.c @@ -671,12 +671,13 @@ bool gterm_init(size_t *_rows, size_t *_cols, size_t width, size_t height) { char *background_path = config_get_value(NULL, 0, "BACKGROUND_PATH"); if (background_path != NULL) { - struct file_handle *bg_file = ext_mem_alloc(sizeof(struct file_handle)); - if (uri_open(bg_file, background_path)) { + struct file_handle *bg_file; + if ((bg_file = uri_open(background_path)) != NULL) { background = ext_mem_alloc(sizeof(struct image)); if (open_image(background, bg_file)) { background = NULL; } + fclose(bg_file); } } @@ -741,16 +742,16 @@ bool gterm_init(size_t *_rows, size_t *_cols, size_t width, size_t height) { if (menu_font == NULL) menu_font = config_get_value(NULL, 0, "TERMINAL_FONT"); if (menu_font != NULL) { - struct file_handle f; - if (!uri_open(&f, menu_font)) { + struct file_handle *f; + if ((f = uri_open(menu_font)) == NULL) { print("menu: Could not open font file.\n"); } else { - if (fread(&f, vga_font_bits, 0, font_bytes) == 0) { - if (menu_font_size != NULL) { - vga_font_width = tmp_font_width; - vga_font_height = tmp_font_height; - } + fread(f, vga_font_bits, 0, font_bytes); + if (menu_font_size != NULL) { + vga_font_width = tmp_font_width; + vga_font_height = tmp_font_height; } + fclose(f); } } diff --git a/stage23/lib/uri.c b/stage23/lib/uri.c index c7eb1519..4d9c2b33 100644 --- a/stage23/lib/uri.c +++ b/stage23/lib/uri.c @@ -86,63 +86,54 @@ static bool parse_bios_partition(char *loc, int *drive, int *partition) { return true; } -static bool uri_hdd_dispatch(struct file_handle *fd, char *loc, char *path) { +static struct file_handle *uri_hdd_dispatch(char *loc, char *path) { int drive, partition; if (!parse_bios_partition(loc, &drive, &partition)) - return false; + return NULL; struct volume *volume = volume_get_by_coord(false, drive, partition); if (volume == NULL) - return false; + return NULL; - if (fopen(fd, volume, path)) - return false; - - return true; + return fopen(volume, path); } -static bool uri_odd_dispatch(struct file_handle *fd, char *loc, char *path) { +static struct file_handle *uri_odd_dispatch(char *loc, char *path) { int drive, partition; if (!parse_bios_partition(loc, &drive, &partition)) - return false; + return NULL; struct volume *volume = volume_get_by_coord(true, drive, partition); if (volume == NULL) - return false; + return NULL; - if (fopen(fd, volume, path)) - return false; - - return true; + return fopen(volume, path); } -static bool uri_guid_dispatch(struct file_handle *fd, char *guid_str, char *path) { +static struct file_handle *uri_guid_dispatch(char *guid_str, char *path) { struct guid guid; if (!string_to_guid_be(&guid, guid_str)) - return false; + return NULL; struct volume *volume = volume_get_by_guid(&guid); if (volume == NULL) { if (!string_to_guid_mixed(&guid, guid_str)) - return false; + return NULL; volume = volume_get_by_guid(&guid); if (volume == NULL) - return false; + return NULL; } - if (fopen(fd, volume, path)) - return false; - - return true; + return fopen(volume, path); } #if bios == 1 -static bool uri_tftp_dispatch(struct file_handle *fd, char *root, char *path) { +static struct file_handle *uri_tftp_dispatch(char *root, char *path) { uint32_t ip; if (!strcmp(root, "")) { ip = 0; @@ -152,18 +143,19 @@ static bool uri_tftp_dispatch(struct file_handle *fd, char *root, char *path) { } } - if (tftp_open(fd, ip, 69, path)) { - return false; + struct file_handle *ret = ext_mem_alloc(sizeof(struct file_handle)); + if (!tftp_open(ret, ip, 69, path)) { + return NULL; } - return true; + return ret; } #endif -static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path) { +static struct file_handle *uri_boot_dispatch(char *s_part, char *path) { #if bios == 1 if (boot_volume->pxe) - return uri_tftp_dispatch(fd, s_part, path); + return uri_tftp_dispatch(s_part, path); #endif int partition; @@ -181,16 +173,13 @@ static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path) struct volume *volume = volume_get_by_coord(boot_volume->is_optical, boot_volume->index, partition); if (volume == NULL) - return false; + return NULL; - if (fopen(fd, volume, path)) - return false; - - return true; + return fopen(volume, path); } -bool uri_open(struct file_handle *fd, char *uri) { - bool ret; +struct file_handle *uri_open(char *uri) { + struct file_handle *ret; char *resource, *root, *path; uri_resolve(uri, &resource, &root, &path); @@ -208,33 +197,33 @@ bool uri_open(struct file_handle *fd, char *uri) { if (!strcmp(resource, "bios")) { panic("bios:// resource is no longer supported. Check CONFIG.md for hdd:// and odd://"); } else if (!strcmp(resource, "hdd")) { - ret = uri_hdd_dispatch(fd, root, path); + ret = uri_hdd_dispatch(root, path); } else if (!strcmp(resource, "odd")) { - ret = uri_odd_dispatch(fd, root, path); + ret = uri_odd_dispatch(root, path); } else if (!strcmp(resource, "boot")) { - ret = uri_boot_dispatch(fd, root, path); + ret = uri_boot_dispatch(root, path); } else if (!strcmp(resource, "guid")) { - ret = uri_guid_dispatch(fd, root, path); + ret = uri_guid_dispatch(root, path); } else if (!strcmp(resource, "uuid")) { - ret = uri_guid_dispatch(fd, root, path); + ret = uri_guid_dispatch(root, path); #if bios == 1 } else if (!strcmp(resource, "tftp")) { - ret = uri_tftp_dispatch(fd, root, path); + ret = uri_tftp_dispatch(root, path); #endif } else { panic("Resource `%s` not valid.", resource); } - if (compressed && ret) { - struct file_handle compressed_fd = {0}; - fread(fd, &compressed_fd.size, fd->size - 4, sizeof(uint32_t)); - compressed_fd.fd = ext_mem_alloc(compressed_fd.size); - void *src = ext_mem_alloc(fd->size); - fread(fd, src, 0, fd->size); - if (tinf_gzip_uncompress(compressed_fd.fd, src, fd->size)) + if (compressed && ret != NULL) { + struct file_handle *compressed_fd = ext_mem_alloc(sizeof(struct file_handle)); + fread(ret, &compressed_fd->size, ret->size - 4, sizeof(uint32_t)); + compressed_fd->fd = ext_mem_alloc(compressed_fd->size); + void *src = freadall(ret, MEMMAP_BOOTLOADER_RECLAIMABLE); + if (tinf_gzip_uncompress(compressed_fd->fd, src, ret->size)) panic("tinf error"); - compressed_fd.is_memfile = true; - *fd = compressed_fd; + fclose(ret); + compressed_fd->is_memfile = true; + ret = compressed_fd; } return ret; diff --git a/stage23/lib/uri.h b/stage23/lib/uri.h index 1fb65f43..a883a53a 100644 --- a/stage23/lib/uri.h +++ b/stage23/lib/uri.h @@ -5,6 +5,6 @@ #include bool uri_resolve(char *uri, char **resource, char **root, char **path); -bool uri_open(struct file_handle *fd, char *uri); +struct file_handle *uri_open(char *uri); #endif diff --git a/stage23/mm/pmm.h b/stage23/mm/pmm.h index 5f6bcfa4..fce753e6 100644 --- a/stage23/mm/pmm.h +++ b/stage23/mm/pmm.h @@ -49,6 +49,8 @@ void *ext_mem_alloc_type(size_t count, uint32_t type); void *conv_mem_alloc(size_t count); +void pmm_free(void *ptr, size_t length); + #if uefi == 1 void pmm_reclaim_uefi_mem(void); void pmm_release_uefi_mem(void); diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c index 7dc7341f..984d68f6 100644 --- a/stage23/mm/pmm.s2.c +++ b/stage23/mm/pmm.s2.c @@ -563,6 +563,13 @@ struct e820_entry_t *get_raw_memmap(size_t *entry_count) { } #endif +void pmm_free(void *ptr, size_t count) { + count = ALIGN_UP(count, 4096); + if (allocations_disallowed) + panic("Memory allocations disallowed"); + memmap_alloc_range((uintptr_t)ptr, count, MEMMAP_USABLE, false, false, false, false); +} + void *ext_mem_alloc(size_t count) { return ext_mem_alloc_type(count, MEMMAP_BOOTLOADER_RECLAIMABLE); } @@ -612,7 +619,7 @@ void *ext_mem_alloc_type(size_t count, uint32_t type) { } -/// Compute and returns the amount of upper and lower memory till +/// Compute and returns the amount of upper and lower memory till /// the first hole. struct meminfo mmap_get_info(size_t mmap_count, struct e820_entry_t *mmap) { struct meminfo info = {0}; diff --git a/stage23/protos/chainload.c b/stage23/protos/chainload.c index f773488c..9f8876b1 100644 --- a/stage23/protos/chainload.c +++ b/stage23/protos/chainload.c @@ -116,8 +116,8 @@ void chainload(char *config) { if (image_path == NULL) panic("chainload: IMAGE_PATH not specified"); - struct file_handle *image = ext_mem_alloc(sizeof(struct file_handle)); - if (!uri_open(image, image_path)) + struct file_handle *image; + if ((image = uri_open(image_path)) == NULL) panic("chainload: Failed to open image with path `%s`. Is the path correct?", image_path); EFI_HANDLE efi_part_handle = image->efi_part_handle; @@ -130,6 +130,9 @@ void chainload(char *config) { panic("chainload: Allocation failure"); memcpy(ptr, _ptr, image_size); + pmm_free(_ptr, image->size); + fclose(image); + term_deinit(); size_t req_width = 0, req_height = 0, req_bpp = 0; diff --git a/stage23/protos/linux.c b/stage23/protos/linux.c index b578a9d5..4ddcc2f8 100644 --- a/stage23/protos/linux.c +++ b/stage23/protos/linux.c @@ -346,13 +346,13 @@ struct boot_params { // End of Linux code void linux_load(char *config, char *cmdline) { - struct file_handle *kernel = ext_mem_alloc(sizeof(struct file_handle)); + struct file_handle *kernel; char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); if (kernel_path == NULL) panic("linux: KERNEL_PATH not specified"); - if (!uri_open(kernel, kernel_path)) + if ((kernel = uri_open(kernel_path)) == NULL) panic("linux: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); uint32_t signature; @@ -441,11 +441,13 @@ void linux_load(char *config, char *cmdline) { if (module_path == NULL) break; - struct file_handle module; - if (!uri_open(&module, module_path)) + struct file_handle *module; + if ((module = uri_open(module_path)) == NULL) panic("linux: Failed to open module with path `%s`. Is the path correct?", module_path); - size_of_all_modules += module.size; + size_of_all_modules += module->size; + + fclose(module); } modules_mem_base -= size_of_all_modules; @@ -464,15 +466,15 @@ void linux_load(char *config, char *cmdline) { if (module_path == NULL) break; - struct file_handle module; - if (!uri_open(&module, module_path)) + struct file_handle *module; + if ((module = uri_open(module_path)) == NULL) panic("linux: Could not open `%s`", module_path); print("linux: Loading module `%s`...\n", module_path); - fread(&module, (void *)_modules_mem_base, 0, module.size); + fread(module, (void *)_modules_mem_base, 0, module->size); - _modules_mem_base += module.size; + _modules_mem_base += module->size; } if (size_of_all_modules != 0) { diff --git a/stage23/protos/multiboot1.c b/stage23/protos/multiboot1.c index 71eac9aa..727e02aa 100644 --- a/stage23/protos/multiboot1.c +++ b/stage23/protos/multiboot1.c @@ -24,7 +24,7 @@ __attribute__((noreturn)) void multiboot1_spinup_32( struct multiboot1_info multiboot1_info = {0}; void multiboot1_load(char *config, char *cmdline) { - struct file_handle *kernel_file = ext_mem_alloc(sizeof(*kernel_file)); + struct file_handle *kernel_file; char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); if (kernel_path == NULL) @@ -32,11 +32,13 @@ void multiboot1_load(char *config, char *cmdline) { print("multiboot1: Loading kernel `%s`...\n", kernel_path); - if (!uri_open(kernel_file, kernel_path)) + if ((kernel_file = uri_open(kernel_path)) == NULL) panic("multiboot1: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); uint8_t *kernel = freadall(kernel_file, MEMMAP_KERNEL_AND_MODULES); + fclose(kernel_file); + struct multiboot1_header header = {0}; size_t header_offset = 0; @@ -134,8 +136,8 @@ void multiboot1_load(char *config, char *cmdline) { print("multiboot1: Loading module `%s`...\n", module_path); - struct file_handle f; - if (!uri_open(&f, module_path)) + struct file_handle *f; + if ((f = uri_open(module_path)) == NULL) panic("multiboot1: Failed to open module with path `%s`. Is the path correct?", module_path); char *module_cmdline = config_get_value(config, i, "MODULE_STRING"); @@ -143,16 +145,18 @@ void multiboot1_load(char *config, char *cmdline) { strcpy(lowmem_modstr, module_cmdline); void *module_addr = (void *)(uintptr_t)ALIGN_UP(kernel_top, 4096); - memmap_alloc_range((uintptr_t)module_addr, f.size, MEMMAP_KERNEL_AND_MODULES, + memmap_alloc_range((uintptr_t)module_addr, f->size, MEMMAP_KERNEL_AND_MODULES, true, true, false, false); - kernel_top = (uintptr_t)module_addr + f.size; - fread(&f, module_addr, 0, f.size); + kernel_top = (uintptr_t)module_addr + f->size; + fread(f, module_addr, 0, f->size); m->begin = (uint32_t)(size_t)module_addr; - m->end = m->begin + f.size; + m->end = m->begin + f->size; m->cmdline = (uint32_t)(size_t)lowmem_modstr; m->pad = 0; + fclose(f); + if (verbose) { print("multiboot1: Requested module %u:\n", i); print(" Path: %s\n", module_path); diff --git a/stage23/protos/multiboot2.c b/stage23/protos/multiboot2.c index 25f1e41f..09236623 100644 --- a/stage23/protos/multiboot2.c +++ b/stage23/protos/multiboot2.c @@ -79,7 +79,7 @@ static size_t get_multiboot2_info_size( #define append_tag(P, TAG) ({ (P) += ALIGN_UP((TAG)->size, MULTIBOOT_TAG_ALIGN); }) void multiboot2_load(char *config, char* cmdline) { - struct file_handle *kernel_file = ext_mem_alloc(sizeof(struct file_handle)); + struct file_handle *kernel_file; char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); if (kernel_path == NULL) @@ -87,10 +87,13 @@ void multiboot2_load(char *config, char* cmdline) { print("multiboot2: Loading kernel `%s`...\n", kernel_path); - if (!uri_open(kernel_file, kernel_path)) + if ((kernel_file = uri_open(kernel_path)) == NULL) panic("multiboot2: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); uint8_t *kernel = freadall(kernel_file, MEMMAP_KERNEL_AND_MODULES); + + fclose(kernel_file); + struct multiboot_header *header = load_multiboot2_header(kernel); struct multiboot_header_tag_address *addresstag = NULL; @@ -301,8 +304,8 @@ void multiboot2_load(char *config, char* cmdline) { print("multiboot2: Loading module `%s`...\n", module_path); - struct file_handle f; - if (!uri_open(&f, module_path)) + struct file_handle *f; + if ((f = uri_open(module_path)) == NULL) panic("multiboot2: Failed to open module with path `%s`. Is the path correct?", module_path); char *module_cmdline = config_get_value(config, i, "MODULE_STRING"); @@ -314,20 +317,22 @@ void multiboot2_load(char *config, char* cmdline) { module_cmdline = ""; } - memmap_alloc_range((uintptr_t)module_addr, f.size, MEMMAP_KERNEL_AND_MODULES, + memmap_alloc_range((uintptr_t)module_addr, f->size, MEMMAP_KERNEL_AND_MODULES, true, true, false, false); - kernel_top = (uintptr_t)module_addr + f.size; - fread(&f, module_addr, 0, f.size); + kernel_top = (uintptr_t)module_addr + f->size; + fread(f, module_addr, 0, f->size); struct multiboot_tag_module *module_tag = (struct multiboot_tag_module *)(mb2_info + info_idx); module_tag->type = MULTIBOOT_TAG_TYPE_MODULE; module_tag->size = sizeof(struct multiboot_tag_module) + strlen(module_cmdline) + 1; module_tag->mod_start = (uint32_t)(size_t)module_addr; - module_tag->mod_end = module_tag->mod_start + f.size; + module_tag->mod_end = module_tag->mod_start + f->size; strcpy(module_tag->cmdline, module_cmdline); // Copy over the command line + fclose(f); + if (verbose) { print("multiboot2: Requested module %u:\n", i); print(" Path: %s\n", module_path); @@ -496,7 +501,7 @@ void multiboot2_load(char *config, char* cmdline) { ////////////////////////////////////////////// { // NOTE: The multiboot2 specification does not say anything about if both - // smbios 32 and 64 bit entry points are present, then we pass both of them + smbios + // smbios 32 and 64 bit entry points are present, then we pass both of them + smbios // support for grub2 is unimplemented. So, we are going to assume they expect us to // pass both of them if avaliable. Oh well... if (smbios_entry_32 != NULL) { diff --git a/stage23/protos/stivale.c b/stage23/protos/stivale.c index 5a7b0cf2..3dabb5d8 100644 --- a/stage23/protos/stivale.c +++ b/stage23/protos/stivale.c @@ -66,7 +66,7 @@ void stivale_load(char *config, char *cmdline) { stivale_struct.flags |= (1 << 1); // we give colour information stivale_struct.flags |= (1 << 2); // we give SMBIOS information - struct file_handle *kernel_file = ext_mem_alloc(sizeof(struct file_handle)); + struct file_handle *kernel_file; char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); if (kernel_path == NULL) @@ -74,7 +74,7 @@ void stivale_load(char *config, char *cmdline) { print("stivale: Loading kernel `%s`...\n", kernel_path); - if (!uri_open(kernel_file, kernel_path)) + if ((kernel_file = uri_open(kernel_path)) == NULL) panic("stivale: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); char *kaslr_s = config_get_value(config, 0, "KASLR"); @@ -92,6 +92,8 @@ void stivale_load(char *config, char *cmdline) { int bits = elf_bits(kernel); bool loaded_by_anchor = false; + fclose(kernel_file); + if (bits == -1) { struct stivale_anchor *anchor; if (!stivale_load_by_anchor((void **)&anchor, "STIVALE1 ANCHOR", kernel, kernel_file->size)) { @@ -210,17 +212,19 @@ void stivale_load(char *config, char *cmdline) { print("stivale: Loading module `%s`...\n", module_path); - struct file_handle f; - if (!uri_open(&f, module_path)) + struct file_handle *f; + if ((f = uri_open(module_path)) == NULL) panic("stivale: Failed to open module with path `%s`. Is the path correct?", module_path); - m->begin = REPORTED_ADDR((uint64_t)(size_t)freadall(&f, STIVALE_MMAP_KERNEL_AND_MODULES)); - m->end = m->begin + f.size; + m->begin = REPORTED_ADDR((uint64_t)(size_t)freadall(f, STIVALE_MMAP_KERNEL_AND_MODULES)); + m->end = m->begin + f->size; m->next = 0; *prev_mod_ptr = REPORTED_ADDR((uint64_t)(size_t)m); prev_mod_ptr = &m->next; + fclose(f); + if (verbose) { print("stivale: Requested module %u:\n", i); print(" Path: %s\n", module_path); diff --git a/stage23/protos/stivale2.c b/stage23/protos/stivale2.c index 5254273b..ed678c7e 100644 --- a/stage23/protos/stivale2.c +++ b/stage23/protos/stivale2.c @@ -62,7 +62,7 @@ void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t); #endif void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table) { - struct file_handle *kernel_file = ext_mem_alloc(sizeof(struct file_handle)); + struct file_handle *kernel_file; char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); if (kernel_path == NULL) @@ -70,7 +70,7 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table print("stivale2: Loading kernel `%s`...\n", kernel_path); - if (!uri_open(kernel_file, kernel_path)) + if ((kernel_file = uri_open(kernel_path)) == NULL) panic("stivale2: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); char *kaslr_s = config_get_value(config, 0, "KASLR"); @@ -91,6 +91,8 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table int bits = elf_bits(kernel); bool loaded_by_anchor = false; + fclose(kernel_file); + if (bits == -1) { struct stivale2_anchor *anchor; if (!stivale_load_by_anchor((void **)&anchor, "STIVALE2 ANCHOR", kernel, kernel_file->size)) { @@ -294,12 +296,14 @@ failed_to_load_header_section: print("stivale2: Loading module `%s`...\n", module_path); - struct file_handle f; - if (!uri_open(&f, module_path)) + struct file_handle *f; + if ((f = uri_open(module_path)) == NULL) panic("stivale2: Failed to open module with path `%s`. Is the path correct?", module_path); - m->begin = REPORTED_ADDR((uint64_t)(size_t)freadall(&f, STIVALE2_MMAP_KERNEL_AND_MODULES)); - m->end = m->begin + f.size; + m->begin = REPORTED_ADDR((uint64_t)(size_t)freadall(f, STIVALE2_MMAP_KERNEL_AND_MODULES)); + m->end = m->begin + f->size; + + fclose(f); if (verbose) { print("stivale2: Requested module %u:\n", i); diff --git a/stage23/pxe/pxe.s2.c b/stage23/pxe/pxe.s2.c index a49ff5c7..2516e225 100644 --- a/stage23/pxe/pxe.s2.c +++ b/stage23/pxe/pxe.s2.c @@ -50,7 +50,7 @@ void pxe_init(void) { panic("!pxe signature corrupted"); } set_pxe_fp(bangpxe->rm_entry); - printv("pxe: Successfully initialized"); + printv("pxe: Successfully initialized\n"); } #endif diff --git a/stage23/pxe/tftp.h b/stage23/pxe/tftp.h index 60febf66..169f2819 100644 --- a/stage23/pxe/tftp.h +++ b/stage23/pxe/tftp.h @@ -38,7 +38,7 @@ struct pxenv_get_file_size { #define TFTP_CLOSE 0x21 //server_ip and server_port can be 0 for default -int tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_port, const char *name); +bool tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_port, const char *name); uint32_t get_boot_server_info(void); diff --git a/stage23/pxe/tftp.s2.c b/stage23/pxe/tftp.s2.c index 510b4e5a..cfe27b3c 100644 --- a/stage23/pxe/tftp.s2.c +++ b/stage23/pxe/tftp.s2.c @@ -16,7 +16,7 @@ uint32_t get_boot_server_info(void) { return ph->sip; } -int tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_port, const char *name) { +bool tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_port, const char *name) { int ret = 0; if (!server_ip) { @@ -26,7 +26,7 @@ int tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_po struct PXENV_UNDI_GET_INFORMATION undi_info = { 0 }; ret = pxe_call(UNDI_GET_INFORMATION, ((uint16_t)rm_seg(&undi_info)), (uint16_t)rm_off(&undi_info)); if (ret) { - return -1; + return false; } //TODO figure out a more proper way to do this. @@ -39,7 +39,7 @@ int tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_po strcpy((char*)fsize.name, name); ret = pxe_call(TFTP_GET_FILE_SIZE, ((uint16_t)rm_seg(&fsize)), (uint16_t)rm_off(&fsize)); if (ret) { - return -1; + return false; } handle->size = fsize.file_size; @@ -56,7 +56,7 @@ int tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_po ret = pxe_call(TFTP_OPEN, ((uint16_t)rm_seg(&open)), (uint16_t)rm_off(&open)); if (ret) { print("tftp: Failed to open file %x or bad packet size", open.status); - return -1; + return false; } mtu = open.packet_size; @@ -94,7 +94,9 @@ int tftp_open(struct file_handle *handle, uint32_t server_ip, uint16_t server_po panic("tftp: Close failure"); } - return 0; + pmm_free(buf, mtu); + + return true; } #endif