diff --git a/Makefile b/Makefile index 9852364..0edf561 100644 --- a/Makefile +++ b/Makefile @@ -119,16 +119,26 @@ build/fonts/%.o: fonts/%.cpp | _bd @g++ $(KERNEL_CXXFLAGS) -c $< -o $@ vdir: all - @mkdir -p vdir/EFI/BOOT + @mkdir -p vdir/EFI/BOOT vdir/sys @cp build/BOOTX64.EFI vdir/EFI/BOOT @cp build/Kernel.elf vdir/ + @cp -r resources vdir/sys/ -run: vdir +disk: vdir + @echo "* Building FAT32 disk image (128 MiB)..." + @dd if=/dev/zero of=build/disk.img bs=1M count=128 status=none + @mformat -i build/disk.img -F -T 262144 -h 16 -s 32 :: + @mmd -i build/disk.img ::/EFI ::/EFI/BOOT ::/sys + @mcopy -i build/disk.img -s vdir/EFI/BOOT/BOOTX64.EFI ::/EFI/BOOT/ + @mcopy -i build/disk.img -s vdir/Kernel.elf ::/ + @mcopy -i build/disk.img -s vdir/sys/resources ::/sys/ + +run: disk @echo "Launching QEMU" - @qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -net none -drive file=fat:rw:vdir,index=0,format=vvfat -serial file:serial.log -serial stdio -s -S + @qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -net none -drive file=build/disk.img,index=0,format=raw -serial file:serial.log -s -S clean: @echo "Cleaning old files" @rm -rf build vdir -.PHONY: all vdir run clean _bd +.PHONY: all vdir disk run clean _bd diff --git a/kernel/fs.cpp b/kernel/fs.cpp index a1b1ffd..3d7ec82 100644 --- a/kernel/fs.cpp +++ b/kernel/fs.cpp @@ -372,28 +372,32 @@ static UINT8 lfn_checksum(const UINT8 *SFN) { struct lfn_state { CHAR16 frags[LFN_MAX_FRAGS][LFN_FRAG_SIZE + 1]; UINTN count; + UINT8 checksum; }; static void lfn_reset(struct lfn_state *lfn) { lfn->count = 0; + lfn->checksum = 0; } static void lfn_add(struct lfn_state *lfn, const UINT8 *E) { if (lfn->count >= LFN_MAX_FRAGS) return; + lfn->checksum = E[13]; UINTN pos = 0; - for (SSINT32 i = 0; i < 5 && pos < LFN_FRAG_SIZE; i++) { + BOOLEAN done = FALSE; + for (SSINT32 i = 0; i < 5 && pos < LFN_FRAG_SIZE && !done; i++) { CHAR16 c = *(const UINT16*)(E + 1 + i * 2); - if (c == 0x0000 || c == 0xFFFF) { lfn->frags[lfn->count][pos] = 0; return; } + if (c == 0x0000 || c == 0xFFFF) { done = TRUE; break; } lfn->frags[lfn->count][pos++] = c; } - for (SSINT32 i = 0; i < 6 && pos < LFN_FRAG_SIZE; i++) { + for (SSINT32 i = 0; i < 6 && pos < LFN_FRAG_SIZE && !done; i++) { CHAR16 c = *(const UINT16*)(E + 14 + i * 2); - if (c == 0x0000 || c == 0xFFFF) { lfn->frags[lfn->count][pos] = 0; return; } + if (c == 0x0000 || c == 0xFFFF) { done = TRUE; break; } lfn->frags[lfn->count][pos++] = c; } - for (SSINT32 i = 0; i < 2 && pos < LFN_FRAG_SIZE; i++) { + for (SSINT32 i = 0; i < 2 && pos < LFN_FRAG_SIZE && !done; i++) { CHAR16 c = *(const UINT16*)(E + 28 + i * 2); - if (c == 0x0000 || c == 0xFFFF) { lfn->frags[lfn->count][pos] = 0; return; } + if (c == 0x0000 || c == 0xFFFF) { done = TRUE; break; } lfn->frags[lfn->count][pos++] = c; } lfn->frags[lfn->count][pos] = 0; @@ -445,7 +449,7 @@ static BOOLEAN process_sector(struct fat_fs *fs, UINT8 *Buf, UINT8 Attr = E[11]; - if (Attr == 0x0F) { + if ((Attr & 0x3F) == 0x0F) { if (E[0] & 0x40) lfn_reset(lfn); lfn_add(lfn, E); continue; @@ -454,7 +458,7 @@ static BOOLEAN process_sector(struct fat_fs *fs, UINT8 *Buf, // SFN entry CHAR16 Name[256]; BOOLEAN use_lfn = FALSE; - if (lfn->count > 0 && lfn_checksum(E) == E[13]) { + if (lfn->count > 0 && lfn_checksum(E) == lfn->checksum) { lfn_build(lfn, Name, 256); use_lfn = TRUE; } @@ -626,7 +630,14 @@ struct find_ctx { }; static BOOLEAN name_match(const CHAR16 *a, const CHAR16 *b) { - return wstr_eq((WString)a, (WString)b); + while (*a && *b) { + CHAR16 ca = *a, cb = *b; + if (ca >= L'A' && ca <= L'Z') ca += 32; + if (cb >= L'A' && cb <= L'Z') cb += 32; + if (ca != cb) return FALSE; + a++; b++; + } + return *a == 0 && *b == 0; } static void find_callback(void *ctx, const CHAR16 *Name, UINT8 Attr, diff --git a/kernel/main.cpp b/kernel/main.cpp index 0aa185f..f40d0c1 100644 --- a/kernel/main.cpp +++ b/kernel/main.cpp @@ -196,6 +196,32 @@ extern "C" void kernel_main() { // Compositor task (replaces the old demo tasks) task_create("compositor", layer_compositor_task); + serial_write("Sylva: disk read benchmark...\n"); + void *ttf_buf = NULL; + UINTN ttf_size = 0; + UINT64 t0 = pit_get_ticks(); + EFI_STATUS rd_st = fs_read((WString)L"sys\\resources\\LXGWWenKai-Light.ttf", &ttf_buf, &ttf_size); + UINT64 t1 = pit_get_ticks(); + if (EFI_ERROR(rd_st)) { + serial_write("Sylva: fs_read FAILED: "); + serial_write_hex(rd_st); + serial_write("\n"); + } else { + UINT64 ticks = t1 - t0; + UINT64 ms = ticks * (1000 / PIT_TICK_HZ); + UINT64 kbps = ms ? (ttf_size * 1000ULL) / (ms * 1024ULL) : 0; + serial_write("Sylva: read "); + serial_write_hex(ttf_size); + serial_write(" bytes in "); + serial_write_hex(ms); + serial_write(" ms ("); + serial_write_hex(kbps); + serial_write(" KiB/s)\n"); + kfree(ttf_buf); + } + serial_write("Test done.\n\n"); + + serial_write("Sylva: starting preemptive scheduler\n"); scheduler_run(); // never returns } diff --git a/resources/LXGWWenKai-Light.ttf b/resources/LXGWWenKai-Light.ttf new file mode 100644 index 0000000..d1772b2 Binary files /dev/null and b/resources/LXGWWenKai-Light.ttf differ