simple tar initfs
This commit is contained in:
parent
9a4c59ecfd
commit
125707d5bc
5 changed files with 162 additions and 10 deletions
|
@ -1,6 +1,7 @@
|
|||
timeout: 0
|
||||
quiet: yes
|
||||
quiet: yes
|
||||
|
||||
/Calcite
|
||||
protocol: limine
|
||||
path: boot():/calcite/kernel.elf
|
||||
protocol: limine
|
||||
path: boot():/calcite/kernel.elf
|
||||
module_path: boot():/calcite/initfs.tar
|
||||
|
|
26
kernel/include/initfs.h
Normal file
26
kernel/include/initfs.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Calcite, kernel/include/initfs.h
|
||||
* Copyright 2025 Benji Dial
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void set_initfs(const uint8_t *start, uint64_t length);
|
||||
|
||||
//if the file does not exist, *start_out is set to a null pointer.
|
||||
void look_up_initfs_file(
|
||||
const char *path, const uint8_t **start_out, uint64_t *length_out);
|
|
@ -15,6 +15,7 @@
|
|||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <initfs.h>
|
||||
#include <limine.h>
|
||||
#include <paging.h>
|
||||
|
||||
|
@ -44,6 +45,12 @@ static volatile struct limine_memmap_request memmap_request = {
|
|||
.response = 0
|
||||
};
|
||||
|
||||
static volatile struct limine_module_request module_request = {
|
||||
.id = LIMINE_MODULE_REQUEST,
|
||||
.revision = 0,
|
||||
.response = 0
|
||||
};
|
||||
|
||||
[[noreturn]] static void die() {
|
||||
while (1)
|
||||
__asm__ ("hlt");
|
||||
|
@ -70,6 +77,9 @@ static int fb_width;
|
|||
static int fb_height;
|
||||
static int fb_pitch;
|
||||
|
||||
static uint8_t *initfs_start;
|
||||
static uint64_t initfs_length;
|
||||
|
||||
[[noreturn]] static void with_kernel_page_tables();
|
||||
|
||||
[[noreturn]] void kernel_entry() {
|
||||
|
@ -78,7 +88,9 @@ static int fb_pitch;
|
|||
|
||||
if (fb_request.response == 0 || hhdm_request.response == 0 ||
|
||||
ka_request.response == 0 || memmap_request.response == 0 ||
|
||||
fb_request.response->framebuffer_count == 0)
|
||||
module_request.response == 0 ||
|
||||
fb_request.response->framebuffer_count == 0 ||
|
||||
module_request.response->module_count == 0)
|
||||
die();
|
||||
|
||||
struct limine_framebuffer *fb = fb_request.response->framebuffers[0];
|
||||
|
@ -88,6 +100,8 @@ static int fb_pitch;
|
|||
fb->blue_mask_shift != 0 || fb->blue_mask_size != 8)
|
||||
die();
|
||||
|
||||
struct limine_file *initfs = module_request.response->modules[0];
|
||||
|
||||
//set up page tables. we will mark the regions with bootloader structures as
|
||||
//usable, so we need to be careful not to allocate any physical pages until
|
||||
//after we are done using bootloader structures. we map the kernel into our
|
||||
|
@ -131,6 +145,18 @@ static int fb_pitch;
|
|||
fb_height = fb->height;
|
||||
fb_pitch = fb->pitch;
|
||||
|
||||
//remap initfs module and store information.
|
||||
|
||||
uint64_t initfs_physical_start =
|
||||
(uint64_t)initfs->address - hhdm_request.response->offset;
|
||||
|
||||
initfs_length = initfs->size;
|
||||
uint64_t initfs_length_rounded = ((initfs_length - 1) / 4096 + 1) * 4096;
|
||||
|
||||
initfs_start = find_free_kernel_region(initfs_length_rounded);
|
||||
map_kernel_region(
|
||||
initfs_physical_start, initfs_start, initfs_length_rounded, 0, 0);
|
||||
|
||||
//switch to kernel page tables!
|
||||
|
||||
switch_to_kernel_page_tables(&with_kernel_page_tables);
|
||||
|
@ -139,7 +165,22 @@ static int fb_pitch;
|
|||
|
||||
[[noreturn]] static void with_kernel_page_tables() {
|
||||
|
||||
//display our test pattern
|
||||
//test initfs
|
||||
|
||||
set_initfs(initfs_start, initfs_length);
|
||||
|
||||
const uint8_t *hello_start;
|
||||
uint64_t hello_length;
|
||||
look_up_initfs_file("resx/hello.txt", &hello_start, &hello_length);
|
||||
|
||||
if (hello_length != 7)
|
||||
die();
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
if (hello_start[i] != "Hello!\n"[i])
|
||||
die();
|
||||
|
||||
//test framebuffer
|
||||
|
||||
for (int y = 0; y < fb_height; ++y)
|
||||
for (int x = 0; x < fb_width; ++x) {
|
||||
|
|
74
kernel/src/initfs.c
Normal file
74
kernel/src/initfs.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* Calcite, kernel/src/initfs.c
|
||||
* Copyright 2025 Benji Dial
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <initfs.h>
|
||||
|
||||
static const uint8_t *initfs_start;
|
||||
static uint64_t initfs_length;
|
||||
|
||||
void set_initfs(const uint8_t *start, uint64_t length) {
|
||||
initfs_start = start;
|
||||
initfs_length = length;
|
||||
}
|
||||
|
||||
static uint64_t decode_octal(const char *from) {
|
||||
uint64_t value = 0;
|
||||
while (*from != '\0') {
|
||||
value = value * 8 + *from - '0';
|
||||
++from;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void look_up_initfs_file(
|
||||
const char *path, const uint8_t **start_out, uint64_t *length_out) {
|
||||
|
||||
int path_len = 0;
|
||||
while (path[path_len] != '\0')
|
||||
++path_len;
|
||||
|
||||
uint64_t offset = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (offset + 512 > initfs_length) {
|
||||
*start_out = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t length =
|
||||
decode_octal((const char *)(initfs_start + offset + 0x7c));
|
||||
|
||||
int found_it = 1;
|
||||
|
||||
for (int i = 0; i < path_len; ++i)
|
||||
if (initfs_start[offset + i] != path[i]) {
|
||||
found_it = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found_it) {
|
||||
*start_out = initfs_start + offset + 512;
|
||||
*length_out = length;
|
||||
return;
|
||||
}
|
||||
|
||||
offset += 512 + ((length - 1) / 512 + 1) * 512;
|
||||
|
||||
}
|
||||
|
||||
}
|
20
makefile
20
makefile
|
@ -1,5 +1,6 @@
|
|||
CC_EXTRA_FLAGS = -O3 -Wall -Wextra
|
||||
CC_FLAGS = -std=c23 -mno-sse -ffreestanding ${CC_EXTRA_FLAGS}
|
||||
COMMON_CC_EXTRA_FLAGS = -O3 -Wall -Wextra
|
||||
COMMON_CC_FLAGS = -std=c23 ${CC_EXTRA_FLAGS}
|
||||
KERNEL_CC_FLAGS = -mno-sse -ffreestanding ${COMMON_CC_FLAGS}
|
||||
|
||||
.PHONY: default
|
||||
default: build/disk.iso
|
||||
|
@ -14,7 +15,7 @@ clean:
|
|||
|
||||
# kernel
|
||||
|
||||
KERNEL_SOURCES = entry.c paging.asm paging.c
|
||||
KERNEL_SOURCES = entry.c initfs.c paging.asm paging.c
|
||||
|
||||
build/kernel/%.asm.o: kernel/src/%.asm
|
||||
@mkdir -p ${@D}
|
||||
|
@ -22,14 +23,22 @@ build/kernel/%.asm.o: kernel/src/%.asm
|
|||
|
||||
build/kernel/%.c.o: kernel/src/%.c
|
||||
@mkdir -p ${@D}
|
||||
cc -c ${CC_FLAGS} -I dependencies/limine -I kernel/include $^ -o $@
|
||||
cc -c ${KERNEL_CC_FLAGS} -I dependencies/limine -I kernel/include $^ -o $@
|
||||
|
||||
build/kernel/kernel.elf: ${KERNEL_SOURCES:%=build/kernel/%.o}
|
||||
ld -T kernel/link.ld $^ -o $@
|
||||
|
||||
# initfs
|
||||
|
||||
build/initfs.tar:
|
||||
rm -rf build/initfs
|
||||
mkdir -p build/initfs/resx
|
||||
echo Hello! > build/initfs/resx/hello.txt
|
||||
cd build/initfs; tar cf ../initfs.tar *
|
||||
|
||||
# disk
|
||||
|
||||
build/disk.iso: build/kernel/kernel.elf
|
||||
build/disk.iso: build/kernel/kernel.elf build/initfs.tar
|
||||
rm -rf build/disk
|
||||
cp -r disk build/disk
|
||||
cp dependencies/limine/limine-uefi-cd.bin build/disk/limine/
|
||||
|
@ -39,6 +48,7 @@ build/disk.iso: build/kernel/kernel.elf
|
|||
cp dependencies/limine/BOOTX64.EFI build/disk/EFI/BOOT/
|
||||
mkdir build/disk/calcite
|
||||
cp build/kernel/kernel.elf build/disk/calcite/
|
||||
cp build/initfs.tar build/disk/calcite/
|
||||
xorriso \
|
||||
-as mkisofs -R -r -J -b limine/limine-bios-cd.bin -no-emul-boot \
|
||||
-boot-load-size 4 -boot-info-table -hfsplus -apm-block-size 2048 \
|
||||
|
|
Loading…
Add table
Reference in a new issue