Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
bootloader_emu
busybox
busybox.tar.bz2
counted_disk
demo_uki.img
demo.img
dependencies.make
Expand Down
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
MAKEFLAGS += --no-builtin-rules
.SILENT:
UNIT_TESTS := loader fat32 io_buf
.PHONY: all clean distclean test unit_tests qemu_test uki_test kexec_test emu_test $(UNIT_TESTS:%=run_test_%)
.PHONY: all clean distclean test unit_tests qemu_test uki_test kexec_test boot_count_test emu_test $(UNIT_TESTS:%=run_test_%)

CC := gcc
CC_X86 := x86_64-linux-gnu-gcc
Expand All @@ -24,7 +24,7 @@ OBJDUMP_FLAGS_M16 := -m i8086 -M intel

all: disk uki.efi kexec.cpio bootloader_emu kernel

test: unit_tests emu_test qemu_test uki_test kexec_test
test: unit_tests emu_test qemu_test uki_test kexec_test boot_count_test

unit_tests: $(UNIT_TESTS:%=run_test_%)

Expand Down Expand Up @@ -63,6 +63,12 @@ kexec_test: kernel kexec.cpio
grep -F 'kexec_core: Starting new kernel' < serial.log > /dev/null
grep -F 'hello from the initrd' < serial.log > /dev/null

boot_count_test: counted_disk
echo 'running $< in qemu'
./run_vm.sh -n '$<' | tee serial.log
grep -F 'Failed to load kernel' < serial.log > /dev/null
grep -F 'hello from the initrd' < serial.log > /dev/null

debug: disk bootloader.elf
echo 'running $< in qemu in debug mode'
./debug.sh $^
Expand Down Expand Up @@ -114,6 +120,10 @@ disk: make_disk.sh mbr.bin bootloader.bin kernel initrd.cpio
echo 'creating $@'
./$^ $@

counted_disk: make_counted_disk.sh mbr.bin bootloader.bin kernel initrd.cpio
echo 'creating $@'
./$^ $@

demo: demo.img demo_uki.img

demo.img: make_demo.sh mbr.bin bootloader.bin kernel busybox
Expand Down
75 changes: 71 additions & 4 deletions fat32.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,10 @@ static struct fat32_dir_entry * next_entry(struct fat32_dir_entry **entries, uin
return (void *) 0;
}

int16 for_each_dir_entry(void (*callback)(const char *entry_name, uint32 entry_cluster, uint32 entry_size))
int16 for_each_dir_entry(void (*callback)(const char *entry_name, int32 entry_index, uint32 entry_cluster, uint32 entry_size))
{
int16 error;
struct fat32_dir_entry *entries_start;
struct fat32_dir_entry *entries;
uint32 entries_len;
struct fat32_dir_entry *entry;
Expand All @@ -323,17 +324,83 @@ int16 for_each_dir_entry(void (*callback)(const char *entry_name, uint32 entry_c
error = load_dir();
if (error != 0) return error;

entries = dir_cache.buf;
entries_len = dir_cache.num_entries;
entries_start = dir_cache.buf;
entries = entries_start;
entries_len = dir_cache.num_entries;

while ((entry = next_entry(&entries, &entries_len, &entry_name)) != (void *) 0) {
entry_cluster = (((uint32) entry->cluster_high) << 0x10) + entry->cluster_low;
callback(entry_name, entry_cluster, entry->size);
callback(entry_name, (int32)(entry - entries_start), entry_cluster, entry->size);
}

return 0;
}

struct dir_entry_handle make_handle(int32 entry_index)
{
struct dir_entry_handle h;
h.dir_cluster = fs.current_dir;
h.entry_index = entry_index;
return h;
}

int16 open_handle(struct dir_entry_handle h)
{
int16 error;
struct fat32_dir_entry *entry;

fs.current_dir = h.dir_cluster;

error = load_dir();
if (error != 0) return error;

if (h.entry_index < 0 || (uint32) h.entry_index >= dir_cache.num_entries) {
print_str("Handle entry_index out of range\r\n");
return -1;
}

entry = &dir_cache.buf[h.entry_index];

open_cluster((((uint32) entry->cluster_high) << 0x10) + entry->cluster_low, entry->size);
file.entry_index = h.entry_index;

return 0;
}

int16 get_file_name(char *name_out, uint16 name_out_len)
{
int16 error;
struct fat32_dir_entry *entries_start;
struct fat32_dir_entry *entries;
uint32 entries_len;
struct fat32_dir_entry *entry;
char *entry_name;
uint16 i;

if (file.entry_index < 0) {
print_str("No file opened\r\n");
return -1;
}

error = load_dir();
if (error != 0) return error;

entries_start = dir_cache.buf;
entries = entries_start;
entries_len = dir_cache.num_entries;

while ((entry = next_entry(&entries, &entries_len, &entry_name)) != (void *) 0) {
if ((int32)(entry - entries_start) == file.entry_index) {
for (i = 0; i + 1 < name_out_len && entry_name[i] != 0x00; ++i) name_out[i] = entry_name[i];
name_out[i] = 0x00;
return 0;
}
}

print_str("Entry index not found in directory\r\n");
return -1;
}

void open_cluster(uint32 cluster, uint32 size)
{
file.size = size;
Expand Down
10 changes: 9 additions & 1 deletion fat32.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

#include "prefix.h"

struct dir_entry_handle {
uint32 dir_cluster;
int32 entry_index;
};

int16 PREFIX(load_fat32)(void);
int16 PREFIX(open)(const char *file);
void PREFIX(open_cluster)(uint32 cluster, uint32 size);
Expand All @@ -10,7 +15,10 @@ int16 PREFIX(chdir)(const char *dir);
int16 PREFIX(unlink)(void);
int16 PREFIX(link)(const char *name);
int16 PREFIX(rename)(const char *name);
int16 PREFIX(for_each_dir_entry)(void (*callback)(const char *entry_name, uint32 entry_cluster, uint32 entry_size));
int16 PREFIX(for_each_dir_entry)(void (*callback)(const char *entry_name, int32 entry_index, uint32 entry_cluster, uint32 entry_size));
struct dir_entry_handle PREFIX(make_handle)(int32 entry_index);
int16 PREFIX(open_handle)(struct dir_entry_handle h);
int16 PREFIX(get_file_name)(char *name_out, uint16 name_out_len);
void PREFIX(reset_seek)(void);
int16 PREFIX(seek)(uint32 sectors);
uint32 PREFIX(read)(uint8 *buf, uint32 sectors);
Expand Down
2 changes: 2 additions & 0 deletions hello.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include <stdio.h>
#include <sys/reboot.h>

int main()
{
puts("hello from the initrd");
reboot(RB_POWER_OFF);
return 0;
}
Loading
Loading