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
|
timeout: 0
|
||||||
quiet: yes
|
quiet: yes
|
||||||
|
|
||||||
/Calcite
|
/Calcite
|
||||||
protocol: limine
|
protocol: limine
|
||||||
path: boot():/calcite/kernel.elf
|
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/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <initfs.h>
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include <paging.h>
|
#include <paging.h>
|
||||||
|
|
||||||
|
@ -44,6 +45,12 @@ static volatile struct limine_memmap_request memmap_request = {
|
||||||
.response = 0
|
.response = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static volatile struct limine_module_request module_request = {
|
||||||
|
.id = LIMINE_MODULE_REQUEST,
|
||||||
|
.revision = 0,
|
||||||
|
.response = 0
|
||||||
|
};
|
||||||
|
|
||||||
[[noreturn]] static void die() {
|
[[noreturn]] static void die() {
|
||||||
while (1)
|
while (1)
|
||||||
__asm__ ("hlt");
|
__asm__ ("hlt");
|
||||||
|
@ -70,6 +77,9 @@ static int fb_width;
|
||||||
static int fb_height;
|
static int fb_height;
|
||||||
static int fb_pitch;
|
static int fb_pitch;
|
||||||
|
|
||||||
|
static uint8_t *initfs_start;
|
||||||
|
static uint64_t initfs_length;
|
||||||
|
|
||||||
[[noreturn]] static void with_kernel_page_tables();
|
[[noreturn]] static void with_kernel_page_tables();
|
||||||
|
|
||||||
[[noreturn]] void kernel_entry() {
|
[[noreturn]] void kernel_entry() {
|
||||||
|
@ -78,7 +88,9 @@ static int fb_pitch;
|
||||||
|
|
||||||
if (fb_request.response == 0 || hhdm_request.response == 0 ||
|
if (fb_request.response == 0 || hhdm_request.response == 0 ||
|
||||||
ka_request.response == 0 || memmap_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();
|
die();
|
||||||
|
|
||||||
struct limine_framebuffer *fb = fb_request.response->framebuffers[0];
|
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)
|
fb->blue_mask_shift != 0 || fb->blue_mask_size != 8)
|
||||||
die();
|
die();
|
||||||
|
|
||||||
|
struct limine_file *initfs = module_request.response->modules[0];
|
||||||
|
|
||||||
//set up page tables. we will mark the regions with bootloader structures as
|
//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
|
//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
|
//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_height = fb->height;
|
||||||
fb_pitch = fb->pitch;
|
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!
|
||||||
|
|
||||||
switch_to_kernel_page_tables(&with_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() {
|
[[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 y = 0; y < fb_height; ++y)
|
||||||
for (int x = 0; x < fb_width; ++x) {
|
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
|
COMMON_CC_EXTRA_FLAGS = -O3 -Wall -Wextra
|
||||||
CC_FLAGS = -std=c23 -mno-sse -ffreestanding ${CC_EXTRA_FLAGS}
|
COMMON_CC_FLAGS = -std=c23 ${CC_EXTRA_FLAGS}
|
||||||
|
KERNEL_CC_FLAGS = -mno-sse -ffreestanding ${COMMON_CC_FLAGS}
|
||||||
|
|
||||||
.PHONY: default
|
.PHONY: default
|
||||||
default: build/disk.iso
|
default: build/disk.iso
|
||||||
|
@ -14,7 +15,7 @@ clean:
|
||||||
|
|
||||||
# kernel
|
# 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
|
build/kernel/%.asm.o: kernel/src/%.asm
|
||||||
@mkdir -p ${@D}
|
@mkdir -p ${@D}
|
||||||
|
@ -22,14 +23,22 @@ build/kernel/%.asm.o: kernel/src/%.asm
|
||||||
|
|
||||||
build/kernel/%.c.o: kernel/src/%.c
|
build/kernel/%.c.o: kernel/src/%.c
|
||||||
@mkdir -p ${@D}
|
@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}
|
build/kernel/kernel.elf: ${KERNEL_SOURCES:%=build/kernel/%.o}
|
||||||
ld -T kernel/link.ld $^ -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
|
# disk
|
||||||
|
|
||||||
build/disk.iso: build/kernel/kernel.elf
|
build/disk.iso: build/kernel/kernel.elf build/initfs.tar
|
||||||
rm -rf build/disk
|
rm -rf build/disk
|
||||||
cp -r disk build/disk
|
cp -r disk build/disk
|
||||||
cp dependencies/limine/limine-uefi-cd.bin build/disk/limine/
|
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/
|
cp dependencies/limine/BOOTX64.EFI build/disk/EFI/BOOT/
|
||||||
mkdir build/disk/calcite
|
mkdir build/disk/calcite
|
||||||
cp build/kernel/kernel.elf build/disk/calcite/
|
cp build/kernel/kernel.elf build/disk/calcite/
|
||||||
|
cp build/initfs.tar build/disk/calcite/
|
||||||
xorriso \
|
xorriso \
|
||||||
-as mkisofs -R -r -J -b limine/limine-bios-cd.bin -no-emul-boot \
|
-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 \
|
-boot-load-size 4 -boot-info-table -hfsplus -apm-block-size 2048 \
|
||||||
|
|
Loading…
Add table
Reference in a new issue