284 Commits
Author SHA1 Message Date
josh 4a39341a83 Turn off local APIC timer 2022-12-14 23:56:11 -05:00
josh 42ab6f396d Processing multiple RTC interrupts 2022-12-14 23:51:35 -05:00
josh 58d685a15b Program I/O APIC; got one RTC interrupt 2022-12-14 23:43:26 -05:00
josh d49f9e32cd dev checkpoint 2022-12-14 19:40:22 -05:00
josh b1a8f8d348 Handle local APIC exceptions 2022-12-07 23:24:01 -05:00
josh 9b52ae58e8 Get local APIC timer ready to run 2022-12-07 23:13:51 -05:00
josh 5799f94efe Configure local APIC interrupt vectors 2022-12-06 22:06:57 -05:00
josh 400a7b22db Enable local APIC interrupts 2022-12-06 21:22:56 -05:00
josh 2bba0dfca4 Add hulk.mtrr module 2022-11-08 21:49:41 -05:00
josh edba40b2c6 Implement frame buffer double-buffering
This slowed down drawing to video in QEMU/VirtualBox but greatly sped up
doing so on real hardware (no longer reading from video memory).
Despite the speed-up, it is still quite slow though.
2022-11-08 06:19:03 -05:00
josh 55604468c8 Allocate framebuffer buffer1 in HELLO 2022-11-07 21:27:52 -05:00
josh 71c30fa932 Reclaim bootloader page table pages 2022-11-06 21:59:42 -05:00
josh b3fb599b25 Move EFER initialization to initialize_cpu() 2022-11-05 22:49:57 -04:00
josh d357aada75 Map HULK regions separately 2022-11-05 22:45:35 -04:00
josh 1fef8ada29 Define acpi structs as static 2022-11-05 22:26:21 -04:00
josh 5231930543 Clean up ApicRegister 2022-11-05 22:22:09 -04:00
josh 95b9e4558a Move hulk.writef buffer variables to stack
Previously ldc2 was emitting AVX/SSE instructions to initialize these
buffers.
2022-11-05 22:06:18 -04:00
josh 354555d7f1 Disable AVX and SSE instruction generation for HULK 2022-11-05 22:03:13 -04:00
josh 1b69810e8f Turn on OSXSAVE 2022-11-05 21:17:30 -04:00
josh 64190b04cb Add initialize_cpu() 2022-11-05 20:27:48 -04:00
josh d7b12c7896 Run qemu with maximum supported host CPU features 2022-11-05 20:15:30 -04:00
josh 11f922da33 Add write_cr0() 2022-11-05 19:58:10 -04:00
josh 59e084c234 Add cpuid1() and output bit enums 2022-11-04 19:28:34 -04:00
josh f21ee0d149 Add enums for a few CPU register bits 2022-11-04 00:08:40 -04:00
josh 2a7c783bba Add write_cr4() 2022-11-03 23:31:55 -04:00
josh 1f2a2bea48 Add xgetbv()/xsetbv() 2022-11-03 22:45:35 -04:00
josh 8eedf4e267 Switch klog buffer to ubyte array to move it to bss section 2022-11-03 16:34:03 -04:00
josh ae49c29c75 Fail build if thread-local data is found 2022-11-03 16:17:42 -04:00
josh 4d88810fc1 Move hulk.writef hex character strings out of data section 2022-11-03 16:03:12 -04:00
josh ba9cf30e67 Clean up linker script symbols 2022-11-03 15:41:14 -04:00
josh b9675019e7 Rename BOOTX64.EFI -> HOS.EFI 2022-11-03 13:54:42 -04:00
josh aa9809e0ed README: add building instructions 2022-11-03 13:34:21 -04:00
josh 07202b902b README: fix headings 2022-11-03 13:30:09 -04:00
josh 08501e86bb README: Add HOS System Requirements 2022-11-03 13:29:05 -04:00
josh 10a2d63e08 Add instructions to run HOS from GRUB 2022-11-03 13:27:24 -04:00
josh 8aa01ba122 Build HELLO page tables from unused memory instead of scratch buffer 2022-11-02 22:49:42 -04:00
josh 0b326e2e36 Move PAGE_SIZE from hulk.hippo to hulk.pagetable 2022-11-01 22:23:26 -04:00
josh e49c27cbbc Increase scratch space to 10MB 2022-10-30 21:29:19 -04:00
josh 49677c8499 PageTableEntry improvements
- fix alias this
- add properties for dirty/accessed
- add opIndex for direct indexing
2022-10-29 22:07:38 -04:00
josh 1e1c389caf Turn on EFER NXE bit to allow no-execute pages 2022-10-27 23:42:18 -04:00
josh 7b531e36ea Fix HELLO check that HULK bss and stack region could be found 2022-10-26 23:26:25 -04:00
josh 7540d4302e Add a couple more page table flags 2022-10-26 23:18:08 -04:00
josh ba7c2996d5 Add MSR_EFER and rdmsr() 2022-10-26 22:45:09 -04:00
josh 707d42bec4 Remove PageTable.opIndex and .opIndexAssign, use .entry 2022-10-26 21:58:22 -04:00
josh 476ae7d6fd Move hos.* modules to hulk.* 2022-10-26 00:16:07 -04:00
josh 4a431f7d93 Use hulk.pagetable from hello 2022-10-26 00:05:49 -04:00
josh 555ec9b627 Split PageTable struct out from hulk.hurl to hulk.pagetable 2022-10-25 23:30:17 -04:00
josh c11361d40f Build new page tables in HULK 2022-10-19 23:59:11 -04:00
josh c8a81b1101 Add PAGE_SIZE constant 2022-10-18 21:53:38 -04:00
josh 41531cf4d2 Rename Hurl to hurl for consistency 2022-10-18 20:59:13 -04:00
josh edbe33bcfa Add ApicRegisters structure 2022-10-18 20:48:46 -04:00
josh 747e824dae Fix calcuation of reserved HULK binary pages 2022-10-18 16:23:13 -04:00
josh b1be5b888f Add apic module that does not do anything yet 2022-10-18 12:56:02 -04:00
josh dba58b2277 acpi: show APIC address found 2022-10-18 12:55:41 -04:00
josh 72b83b0c3c Hurl.debug_lookup(): show page table entry index 2022-10-18 12:54:27 -04:00
josh 90711adada Actually calling Hurl.initialize() helps a lot 2022-10-18 12:51:08 -04:00
josh 4f98c469b7 Add Hurl.debug_lookup() 2022-10-18 11:18:19 -04:00
josh 7d2b535df5 Add hulk.acpi module 2022-10-18 00:48:56 -04:00
josh 2f1a12be81 Add Hurl.map_range() 2022-10-18 00:48:40 -04:00
josh 5ca95a5662 memcpy*() should take const src ptr 2022-10-18 00:47:46 -04:00
josh 7471a846ec Locate the ACPI XSDT 2022-10-17 21:48:43 -04:00
josh 2ee920fdd2 Reset console position on OSOD 2022-10-14 17:10:32 -04:00
josh d24eafbd63 Tweak VirtualBox instructions 2022-10-14 16:05:35 -04:00
josh 6f94bc3ddd Add VirtualBox instructions and task to create a VMDK 2022-10-14 15:57:26 -04:00
josh 777820d471 Tell rscons the map files are side-effect files 2022-10-14 15:28:38 -04:00
josh b3ca9af48a Disable PIC 2022-09-06 22:35:41 -04:00
josh 43d945b5e8 Enable interrupts and halt CPU 2022-09-04 23:03:20 -04:00
josh bc7fd3f2fc Add idt module and set up IDT 2022-09-04 22:25:46 -04:00
josh b72c69ef1c Clear interrupts on HULK startup just in case 2022-09-01 15:50:59 -04:00
josh 66bd51ffb0 Add hulk.gdt module and create our own GDT 2022-09-01 15:43:00 -04:00
josh 16143a727a Avoid using SSE instructions in writef functions 2022-08-23 22:48:52 -04:00
josh 63e6fd4bb5 Add run-vb task 2022-08-20 19:57:10 -04:00
josh b4a4638a82 Create HOS.img with a GPT partition table and EFI partition 2022-08-20 19:01:25 -04:00
josh 93763917c1 Rename hos.img -> HOS.img 2022-08-18 23:03:16 -04:00
josh 743cf9ffef Update to rscons 3.1.0 2022-08-11 15:08:49 -04:00
josh b9f051017c Rename max_physical_address -> physical_address_limit 2022-05-03 19:46:46 -04:00
josh 59890868c1 Fix efibootmgr command to install HOS to physical machine 2022-05-03 16:18:47 -04:00
josh 6b715c9051 Add README.md with installation instructions 2022-05-01 16:17:11 -04:00
josh 89f7d2120f Add Hurl struct with map() method 2022-05-01 09:26:33 -04:00
josh 7515ebdf1c Fix hippo.allocate_page() 2022-05-01 09:20:41 -04:00
josh b0e59b3e26 Add hippo.allocate_page() 2022-04-26 21:45:17 -04:00
josh 153a8d43f1 Add hulk.linker_addresses module 2022-04-26 19:37:05 -04:00
josh bf9a005dbc Launch qemu with a USB XHCI controller and USB tablet device 2022-04-13 21:55:06 -04:00
josh 53e2e52bbe Scan for PCI devices 2022-04-13 21:54:28 -04:00
josh 12067b8e1a Remove src-old 2022-04-13 17:12:16 -04:00
josh 8278c4211b Add HIPPO module and starting tracking free physical pages 2022-03-29 22:24:14 -04:00
josh 3bdc5bccdd Pass page table address range to HULK on boot 2022-03-28 21:22:10 -04:00
josh f904ec2b48 Convert hello.console to use a namespacing struct 2022-03-28 15:18:31 -04:00
josh bcec23ef89 Update hello.scratch to use namespacing struct 2022-03-28 15:17:07 -04:00
josh d86745d91d Move bootinfo into HULK header 2022-03-27 16:14:54 -04:00
josh cf5956dcd3 Rename Header to HulkHeader 2022-03-27 09:45:09 -04:00
josh 8498de6b62 Add HURL; relocate kernel virtual regions 2022-03-26 10:41:53 -04:00
josh f761d0a445 Jump to HULK from assembly 2022-03-26 00:36:23 -04:00
josh f29bd9d00c Allocate HULK stack region from HELLO, translate memory region types 2022-03-26 00:29:19 -04:00
josh f236a64b21 HELLO: Be more welcoming 2022-03-25 13:17:22 -04:00
josh 1225e98276 Pass HULK physical memory info to kernel from HELLO 2022-03-25 13:16:36 -04:00
josh cb31e36e90 Clean up console 2022-03-25 12:37:18 -04:00
josh 0568a813f2 HELLO: Zero out HULK bss section 2022-03-25 11:53:01 -04:00
josh 37d5621e41 HULK console: clear last row when shifting rows up 2022-03-25 10:51:52 -04:00
josh 98e992aad0 Convert fb, console, klog to "static instance" namespacing structs 2022-03-25 10:48:32 -04:00
josh 06242a0c9f Add console, klog, and writef modules.
They are not complete, but adding to checkpoint progress.
2022-03-24 17:52:39 -04:00
josh e214a9c3de Fix call to fb.blend_alpha_bitmap() 2022-03-24 09:52:26 -04:00
josh c259ae4cee Add Framebuffer.copy_rows_up() 2022-03-23 22:12:38 -04:00
josh b4d8707243 Rename blending blit methods to blend 2022-03-22 22:32:45 -04:00
josh 6b7b14d954 Add Framebuffer.character() 2022-03-22 22:11:12 -04:00
josh 9e7c3ee676 Add Framebuffer.rect(), .hline(), .vline() 2022-03-22 21:55:25 -04:00
josh 2d7bf5197f Drawing text working using Framebuffer.blit_alpha_bitmap() 2022-03-22 20:01:08 -04:00
josh 7562be585f Add Framebuffer.blit_alpha_bitmap() 2022-03-22 20:00:32 -04:00
josh 3d04eec427 Compile HULK with large code model 2022-03-22 19:29:30 -04:00
josh 5c97acba5f Update fontgen to output D instead of C 2022-03-22 13:01:20 -04:00
josh c3ead56582 Add Framebuffer object 2022-03-21 16:32:11 -04:00
josh 15559b0a56 Add HULK header; map virtual memory for HULK bss section 2022-03-21 16:31:01 -04:00
josh c58284761a Comment hulk.hulk module a bit 2022-03-20 23:05:10 -04:00
josh bd99e429a9 Comment hulk.bootinfo a bit 2022-03-20 22:58:25 -04:00
josh d0acf5a718 Comment hello.hello module a bit better 2022-03-20 22:38:42 -04:00
josh b40151055c Rework scratch module and use qualified names for function calls 2022-03-20 22:21:10 -04:00
josh 1e00d7a9e9 Rename hello.output to hello.console 2022-03-20 22:12:46 -04:00
josh 79b34477ed Reorganize D modules a bit 2022-03-19 22:39:12 -04:00
josh 163ef9f79e Increase scratch buffer size 2022-03-19 22:08:35 -04:00
josh 3c549f0838 Write size file for HULK/HELLO 2022-03-19 22:07:37 -04:00
josh d8c85ad045 Map all memory regions and graphics framebuffer 2022-03-19 21:54:30 -04:00
josh 7c5af33ace Fix receiving correct argument to hulk_start() 2022-03-19 20:02:49 -04:00
josh 6f3521c576 Make sure to rebuild HELLO properly when HULK changes 2022-03-19 00:27:10 -04:00
josh 5a5d60abae Fix HULK virtual start address to be addressable 2022-03-19 00:04:59 -04:00
josh 9182a83ef2 HELLO: Make sure scratch area is page-aligned 2022-03-18 23:43:05 -04:00
josh 195b7496f4 HELLO: Include EfiLoaderCode and EfiLoaderData memory regions in memory map 2022-03-18 23:33:42 -04:00
josh b1042fd649 Jump to HULK
Unfortunately, crashes... :(
2022-03-18 23:16:07 -04:00
josh 6beb7da4cd Map HULK virtual address space 2022-03-18 23:04:09 -04:00
josh f27851def9 Bundle HULK in HELLO 2022-03-18 22:43:37 -04:00
josh 18f1bfc88f Build HELLO after HULK 2022-03-18 22:02:07 -04:00
josh cd6983e2cd Generate HULK binary 2022-03-18 22:01:27 -04:00
josh 8df1646c61 Add initial HULK source and linker script 2022-03-18 21:55:38 -04:00
josh 3e25ab6ae4 HELLO: Zero out page tables after allocating, before using 2022-03-18 21:21:00 -04:00
josh 05cc2da2e3 HULK: Add virtual start address 2022-03-18 21:19:06 -04:00
josh a54536660b HELLO: Create page tables to identity map available RAM prior to jumping to kernel 2022-03-18 21:15:58 -04:00
josh 9e3d9b18ea Add write_cr3() 2022-03-18 16:40:46 -04:00
josh ef01239468 HELLO: Add scratch module 2022-03-18 16:03:50 -04:00
josh 372b7265f1 Add src/common/hos/cpu.d 2022-03-18 10:51:35 -04:00
josh 1bc8722098 Add hos.memory module in src/common 2022-03-18 00:07:10 -04:00
josh cd2f3f9a84 Rename kernel to hulk 2022-03-17 16:57:18 -04:00
josh 08a35e40d4 Rename HEL -> HELLO 2022-03-16 16:11:26 -04:00
josh a855702214 Fix checking for EFI_INVALID_PARAMETER 2022-03-16 14:37:46 -04:00
josh 706f2c1c5d HEL: Call ExitBootServices 2022-03-16 01:12:07 -04:00
josh 704fd15f7b Get memory map; remove heap 2022-03-15 23:58:37 -04:00
josh f054bab5cc Set bootinfo framebuffer fields 2022-03-15 23:03:28 -04:00
josh 3fa8e4a24b Set maximum resolution for running in qemu 2022-03-15 22:52:56 -04:00
josh a38f95a7b8 Set graphics mode 2022-03-14 22:26:55 -04:00
josh dd57a31d38 HEL: Add heap module; locate GOP handle 2022-03-14 21:43:40 -04:00
josh 406f17c1db HEL: format hex, decimal, and CHAR16 strings in output module 2022-03-14 15:09:02 -04:00
josh 0be1b113aa Add output module for console output routines 2022-03-14 13:53:02 -04:00
josh d782b59768 Write map file 2022-03-14 01:35:28 -04:00
josh c3a6139f83 Run image from temporary copy to avoid modified disk image file 2022-03-14 00:57:24 -04:00
josh 3d3a433800 Update to rscons 3.0.2 2022-03-14 00:51:54 -04:00
josh 54451bcf5b Add initial HOS EFI Loader sources 2022-03-13 23:16:37 -04:00
josh 1fc2dd34e5 Update build system for 64-bit, EFI, and D 2022-03-13 22:46:59 -04:00
josh cb6bd3914c Remove HOS v0.16 sources 2022-02-28 15:10:25 -05:00
josh 56c3be9207 Update to rscons 3.0.0 2022-02-28 13:40:08 -05:00
josh c6ae200a54 Update to rscons 2.3.0
Move cross compiler to i686-elf-gcc directory.
Automatically build cross compiler using rscons subsidiary script.
2021-12-08 11:33:03 -05:00
josh 6b1de7c9d4 Explicitly check page boundaries when adding bootloader-provided memory regions 2021-08-16 17:35:11 -04:00
josh ebfeca47b5 Use size_t rather than uint32_t 2021-08-16 14:01:39 -04:00
josh 43f4a1f4b1 Show kernel size/address 2021-08-16 13:59:39 -04:00
josh 0f73efbdc3 add mm module to manage free physical page regions 2020-10-26 20:17:08 -04:00
josh a084ab296c define _hos_mem_start and _hos_mem_end symbols 2020-10-25 17:08:07 -04:00
josh aa28284187 build kernel .size file on build 2020-10-25 17:06:56 -04:00
josh 87c135b010 set up a GDT to stop using the one GRUB set up 2020-10-25 16:49:09 -04:00
josh 3d30025d3b write a map file when linking 2020-10-25 16:48:42 -04:00
josh 556b0f0c4d add gdt.h 2020-10-23 00:48:40 -04:00
josh bffd652c16 walk multiboot2 memory map 2020-10-23 00:47:19 -04:00
josh cbd427b14b add 64-bit formatting support 2020-10-23 00:46:40 -04:00
josh fa4ff5facf load some multiboot2 info after the framebuffer is initialized 2020-10-22 22:03:43 -04:00
josh db16e69d5d add klog module to print kernel messages 2020-10-20 21:44:21 -04:00
josh 1d3b0a5621 make fb_clear() public 2020-10-20 20:24:48 -04:00
josh d03a34ab3e fb: store fb.pitch in words, not bytes 2020-10-20 20:07:51 -04:00
josh 494ef6de81 add fb_width(), fb_height() 2020-10-20 20:06:54 -04:00
josh 784009ba6c hos_printf: handle field width, zero-padding, and left-justifiying conversion specifiers 2020-10-20 19:56:30 -04:00
josh 9bddf11ee4 stream: use char instead of uint8_t 2020-10-20 19:47:15 -04:00
josh 313b86fdc7 provide an implementation for memcpy() 2020-10-20 19:31:26 -04:00
josh 75491dd36b add hos_printf and stream modules 2020-10-20 19:30:23 -04:00
josh c8db9fe905 add string.h 2020-10-20 17:55:31 -04:00
josh d0cbaba4d1 add memcpy(), memmove(), memset() 2020-10-20 17:47:40 -04:00
josh 1f22d0c900 add a few multiboot2 info structures 2020-10-20 17:34:08 -04:00
josh a474368435 increase kernel font size a little 2020-10-20 17:28:43 -04:00
josh fb88595dec add fb_clear(), just clear to solid bluish color for now 2020-10-20 17:28:16 -04:00
josh 70b4db9dbb fix fb_text_render_char() to use given color 2020-10-20 17:23:51 -04:00
josh 9fde638b6e build with -O2 2020-10-20 15:09:00 -04:00
josh b4b77dd52c add mem.h and memset32() 2020-10-20 15:08:12 -04:00
josh 79951bd0f1 add cross/clean.sh 2020-10-20 14:15:28 -04:00
josh 41152cb4ca add fb_fill() 2020-10-20 14:01:14 -04:00
josh dba3d28bbf draw a character 2020-10-20 13:34:02 -04:00
josh 610f30fae9 generate a built-in kernel font 2020-10-20 00:34:53 -04:00
josh e22b90b768 configure GRUB to boot HOS automatically after 1s 2020-10-20 00:17:05 -04:00
josh 08fc9a5445 rename target run-bios -> run 2020-10-20 00:11:12 -04:00
josh a66df19edc add fb_ready() 2020-10-20 00:09:09 -04:00
josh 5bc844649b set desired framebuffer size to 1600x900x32 2020-10-19 23:57:54 -04:00
josh 0d390465f6 simplify boot.S 2020-10-19 23:42:02 -04:00
josh 04d29fdb71 add mbinfo module to parse multiboot2 boot info 2020-10-19 23:34:42 -04:00
josh e9f426894c rename kernel_main.c -> hos_main.c 2020-10-19 22:40:55 -04:00
josh c8810e4701 rename _start -> hos_start 2020-10-19 22:26:12 -04:00
josh b202eca0cc define startup stack in linker script, not assembly 2020-10-19 22:23:39 -04:00
josh 05de14800b remove hard tabs! 2020-10-19 22:12:34 -04:00
josh 8ae84716d6 rename kernel_main() to hos_main() 2020-10-19 22:12:17 -04:00
josh bb495eceec add "fb" module for framebuffer control 2020-10-19 22:09:33 -04:00
josh 67b90a482f add "clean" target 2020-10-19 21:59:54 -04:00
josh 85e5b76aa3 Move multiboot2 header from assembly to C. 2020-10-19 21:44:27 -04:00
josh 412925a790 switch from multiboot to multiboot2 2020-10-18 14:25:06 -04:00
josh 21afa93c4b fill in framebuffer with more exciting pattern - working in qemu BIOS but lost graphics in qemu EFI 2020-10-18 13:47:35 -04:00
josh d08d54ecbf make run tasks depend on all 2020-10-18 13:29:56 -04:00
josh 06644a02f9 draw pixels to screen to verify framebuffer access and multiboot info 2020-10-18 13:25:26 -04:00
josh 8f9881889b build both BIOS and EFI images 2020-10-18 13:16:02 -04:00
josh a91ea8d620 update Makefile to wrap rscons and add run target 2020-10-15 20:05:58 -04:00
josh a9a2f6dcaf fix GRUB config to add a HOS menu entry 2020-10-15 20:01:40 -04:00
josh 9befd553eb always disassemble kernel when building 2020-10-15 19:47:20 -04:00
josh 6053745ee9 build kernel as 32-bit ELF for now so GRUB can recognize it as multiboot 2020-10-15 19:46:53 -04:00
josh 0adc6e395c Add more modern build script for kernel and disk image based on osdev Bare Bones template
GRUB is not identifying the kernel as multiboot compatible. Possibly
because I am using x86_64 instead of i686. Need to investigate further.
2020-10-14 21:20:41 -04:00
josh bbf212d5a2 add configure script 2020-10-13 19:53:14 -04:00
josh 94ed9078df update rscons 2020-10-13 19:20:19 -04:00
josh e97e76da7b add cross compiler build script and configure script 2020-10-06 20:06:19 -04:00
josh 1f5e3507ba change nasm output format to elf32 2020-10-02 10:21:10 -04:00
josh a9a6f6f4d4 avoid make jobserver warnings 2020-10-02 10:17:32 -04:00
josh 2d009273a1 add readme.txt 2017-07-26 13:51:58 -04:00
josh 2b936758ff add .gitignore 2017-07-26 13:42:21 -04:00
josh 509009d134 get HOS building again on Ubuntu 17.04 with GCC 6 2017-07-26 13:41:23 -04:00
josh 0aaf5db5ad Import backup from 2006-01-02 2017-07-25 22:23:52 -04:00
josh 89d962e33a Import backup from 2005-12-31 2017-07-25 22:23:52 -04:00
josh 712337c485 Import backup from 2005-12-30 2017-07-25 22:23:52 -04:00
josh 761e3f0483 Import backup from 2005-12-26 2017-07-25 22:23:51 -04:00
josh 98abfc2af0 Import backup from 2005-12-19 2017-07-25 22:23:51 -04:00
josh 677551fba5 Import backup from 2005-11-03 2017-07-25 22:23:51 -04:00
josh 7daa1c5336 Import backup from 2005-11-01 2017-07-25 22:23:51 -04:00
josh 79ca453f66 Import backup from 2005-09-13 2017-07-25 22:23:51 -04:00
josh 0521733e20 Import backup from 2005-09-11 2017-07-25 22:23:51 -04:00
josh 396c5f3452 Import backup from 2005-09-01 2017-07-25 22:23:51 -04:00
josh 9e03bfc8b6 Import backup from 2005-08-30 2017-07-25 22:23:51 -04:00
josh 2b67ff6f49 Import backup from 2005-08-29 2017-07-25 22:23:51 -04:00
josh daa29212d0 Import backup from 2005-08-27 2017-07-25 22:23:50 -04:00
josh 83a5b032f8 Import backup from 2005-08-25 2017-07-25 22:23:50 -04:00
josh 345ef6c9f3 Import backup from 2005-08-18 2017-07-25 22:23:50 -04:00
josh e1682a2fe7 Import backup from 2005-08-17 2017-07-25 22:23:50 -04:00
josh 2cefd9441c Import backup from 2005-06-21 2017-07-25 22:23:50 -04:00
josh da90bcc164 Import backup from 2005-06-20 2017-07-25 22:23:50 -04:00
josh 4689c11cc8 Import backup from 2005-06-13 2017-07-25 22:23:50 -04:00
josh 692cf2fc08 Import backup from 2005-06-02 2017-07-25 22:23:50 -04:00
josh b0132c866e Import backup from 2005-05-12 2017-07-25 22:23:50 -04:00
josh 14792ef954 Import backup from 2005-03-21 2017-07-25 22:23:50 -04:00
josh bb8ff09e3f Import backup from 2005-03-11 2017-07-25 22:23:50 -04:00
josh dfeabc39aa Import backup from 2005-02-23 2017-07-25 22:23:50 -04:00
josh 14148e4d80 Import backup from 2005-02-15 2017-07-25 22:23:49 -04:00
josh 80774c48fe Import backup from 2005-02-07 2017-07-25 22:23:49 -04:00
josh 862b36b37b Import backup from 2005-02-01 2017-07-25 22:23:49 -04:00
josh 4638656aaf Import backup from 2005-01-31 2017-07-25 22:23:49 -04:00
josh 3381041a8f Import backup from 2005-01-26 2017-07-25 22:23:49 -04:00
josh f09ed66826 Import backup from 2005-01-18 2017-07-25 22:23:49 -04:00
josh ba5906c7a3 Import backup from 2005-01-14 2017-07-25 22:23:49 -04:00
josh 05183a3949 Import backup from 2005-01-05 2017-07-25 22:23:49 -04:00
josh d8580a9393 Import backup from 2005-01-04 2017-07-25 22:23:49 -04:00
josh 50285aa33b Import backup from 2005-01-01 2017-07-25 22:23:49 -04:00
josh ee63a84c0e Import backup from 2004-12-31 2017-07-25 22:23:49 -04:00
josh 76a243d894 Import backup from 2004-12-30 2017-07-25 22:23:49 -04:00
josh 6bad3f2b96 Import backup from 2004-12-29 2017-07-25 22:23:49 -04:00
josh 51948ce081 Import backup from 2004-12-24 2017-07-25 22:23:49 -04:00
josh b40a68f581 Import backup from 2004-12-23 2017-07-25 22:23:49 -04:00
josh 55b7429d4e Import backup from 2004-12-22 2017-07-25 22:23:49 -04:00
josh 7b805f2495 Import backup from 2004-12-21 2017-07-25 22:23:48 -04:00
josh 2445034e43 Import backup from 2004-12-20 2017-07-25 22:23:48 -04:00
josh 3c531f3b7b Import backup from 2004-12-17 2017-07-25 22:23:48 -04:00
josh 11cc0c87f3 Import backup from 2004-12-16 2017-07-25 22:23:48 -04:00
josh bad7f79ed1 Import backup from 2004-09-21 2017-07-25 22:23:48 -04:00
josh 78272f6bc3 Import backup from 2004-08-20 2017-07-25 22:23:48 -04:00
josh 396d5015d2 Import backup from 2004-08-19 2017-07-25 22:23:48 -04:00
josh 1bf14ddefa Import backup from 2004-08-17 2017-07-25 22:23:48 -04:00
josh c0dd3b529e Import backup from 2004-08-16 2017-07-25 22:23:48 -04:00
josh 8a8f56decb Import backup from 2004-08-15 2017-07-25 22:23:48 -04:00
josh b9c77827bd Import backup from 2004-08-06 2017-07-25 22:23:48 -04:00
josh cd02211b21 Import backup from 2004-08-03 2017-07-25 22:23:48 -04:00
josh a50c2a1233 Import backup from 2004-08-02 2017-07-25 22:23:48 -04:00
josh 07e8a0f4cf Import backup from 2004-07-31 2017-07-25 22:23:48 -04:00
josh 6d23c76e84 Import backup from 2004-07-29 2017-07-25 22:23:48 -04:00
josh 11da8cb162 Import backup from 2004-07-25 2017-07-25 22:23:48 -04:00
josh 1063a68a21 Import backup from 2004-07-20 2017-07-25 22:23:47 -04:00
josh 286b5e9ae1 Import backup from 2004-07-17 2017-07-25 22:23:47 -04:00
josh d4aadbea38 Import backup from 2004-07-15 2017-07-25 22:23:47 -04:00
josh dfb71cc759 Import backup from 2004-07-12 2017-07-25 22:23:47 -04:00
josh 872d562d6a Import backup from 2004-07-10 2017-07-25 22:23:47 -04:00
josh 0729754659 Import backup from 2004-07-09 2017-07-25 22:23:47 -04:00
99 changed files with 3912 additions and 7927 deletions

No files matched your search

-43
View File
@@ -1,43 +0,0 @@
# configuration file generated by Bochs
config_interface: textconfig
display_library: x
megs: 32
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000
vgaromimage: /usr/share/bochs/VGABIOS-lgpl-latest
boot: floppy
floppya: 1_44="/dev/fd0", status=inserted
# no floppyb
ata0: enabled=0
ata1: enabled=0
ata2: enabled=0
ata3: enabled=0
parport1: enabled=1, file=""
com1: enabled=1, dev=""
usb1: enabled=1, ioaddr=0xff80, irq=10
# no sb16
floppy_bootsig_check: disabled=0
vga_update_interval: 30000
keyboard_serial_delay: 20000
keyboard_paste_delay: 100000
floppy_command_delay: 50000
ips: 500000
text_snapshot_check: 0
mouse: enabled=0
private_colormap: enabled=0
i440fxsupport: enabled=0
clock: sync=none, time0=local
# no ne2k
newharddrivesupport: enabled=1
# no loader
log: -
logprefix: %t%e%d
debugger_log: -
panic: action=fatal
error: action=report
info: action=report
debug: action=ignore
pass: action=fatal
keyboard_mapping: enabled=0, map=
keyboard_type: mf
user_shortcut: keys=none
# no cmosimage
+3
View File
@@ -0,0 +1,3 @@
.rscons*
/x86_64-elf-gcc/
/build/
+3
View File
@@ -0,0 +1,3 @@
[submodule "uefi-d"]
path = uefi-d
url = git://github.com/kubasz/uefi-d
-117
View File
@@ -1,117 +0,0 @@
#####################################################################
# Author: Josh Holtrop / Benjamen R. Meyer #
# Date: 02/15/04 Modified: 06/07/04 #
# Purpose: To build Josh Holtrop's OS (HOS) using GNU make #
# Note: This makefile is for use on Linux & other Unix-like systems #
#####################################################################
##############
# Variables: #
##############
# Information for creating a floppy image
# Note: FLOPPY_FS and FLOPPY_FAT_SIZE are related fields.
# FLOPPY_FAT_SIZE should be either 12 or 16,
# depending on if FLOPPY_FS is FAT12 or FAT16, respectively.
MKDOSFS_PROG=mkdosfs
FLOPPY_IMAGE=floppy.img
FLOPPY_BLOCK_COUNT=1440
FLOPPY_FS=FAT12
FLOPPY_FAT_SIZE=12
FLOPPY_MOUNT=./floppy_image
# Floppy images are good for programs like VMware and Bochs Pentium Emulator. ;-)
# Program for copying
COPY_BIN=cp
##########################################
# Build the IPL (Boot Loader) and Kernel #
##########################################
all:
# A word of warning to users :-> And a little helpful information ;-)
@echo "Installation must be done as root."
@echo "Type 'make install' to install to a floppy in drive '/dev/fd0'"
@echo "Type 'make install_img' to create a floppy image and install to it."
make -C boot
make -C kernel
#################################################
# Clean up the source directory of any binaries #
#################################################
clean:
make -C boot clean
make -C kernel clean
###########################################
# The following is for the floppy drive #
# Note: This must be done on *nix as root #
###########################################
##########################
# Make install to floppy #
##########################
install: Install_IPL File_Copy
############################################
# Write the Stage 1 IPL to the boot sector #
############################################
Install_IPL:
$(MKDOSFS_PROG) /dev/fd0
dd if=boot/stage1.bin of=/dev/fd0
#################################
# Copy the files onto the drive #
#################################
File_Copy:
- mkdir floppy_mount
@echo "Mounting floppy to ./floppy_mount..."
mount /dev/fd0 ./floppy_mount
@echo "Copying stage 2 bootloader to the floppy..."
$(COPY_BIN) boot/stage2.bin ./floppy_mount
@echo "Copying kernel to the floppy..."
$(COPY_BIN) kernel/kernel.bin ./floppy_mount
@echo "Unmounting floppy..."
umount ./floppy_mount
- rm -rf floppy_mount
############################################
# The following is for the floppy image. #
# Note: This must be done on *nix as root. #
############################################
######################################
# Create and Format the floppy image #
######################################
install_img:
$(MKDOSFS_PROG) -C -F $(FLOPPY_FAT_SIZE) -r 112 $(FLOPPY_IMAGE) $(FLOPPY_BLOCK_COUNT)
############################################
# Write the Stage 1 IPL to the boot sector #
############################################
@echo "Writing boot sector to image..."
dd if=boot/stage1.bin of=$(FLOPPY_IMAGE) seek=0
#################################
# Copy the files onto the image #
#################################
- mkdir $(FLOPPY_MOUNT)
@echo "Mounting floppy image..."
mount $(FLOPPY_IMAGE) $(FLOPPY_MOUNT) -o loop
@echo "Copying stage 2 bootloader to the floppy image..."
$(COPY_BIN) boot/stage2.bin $(FLOPPY_MOUNT)
@echo "Copying kernel to the floppy image..."
$(COPY_BIN) kernel/kernel.bin $(FLOPPY_MOUNT)
@echo "Unmounting floppy image..."
mount $(FLOPPY_IMAGE) $(FLOPPY_MOUNT) -o loop
+71
View File
@@ -0,0 +1,71 @@
# HOS System Requirements
HOS requires:
* A 64-bit CPU.
* A UEFI system.
* 128MB of RAM.
# Building HOS
From the top level of the repository, run:
./rscons
If you get errors about missing packages, install the packages and then re-run
the build command.
# Running HOS
## Physical Machine
To install HOS to an EFI partition, follow these steps:
1. Copy build/hello/HOS.EFI to EFI partition EFI/HOS.EFI. For example, from Linux:
sudo cp build/hello/HOS.EFI /boot/efi/EFI/HOS.EFI
2. Register EFI loader for HOS (one time only) with command:
efibootmgr -c -d /dev/nvme1n1 -p 2 -l '\EFI\HOS.EFI' -L HOS
(Update the -d device parameter and -p partition parameter as appropriate)
3. Set boot order to desired boot order. Exact order will be system dependent. Example:
efibootmgr -o 2,0,6,5
At this point you should be able to boot HOS from your EFI boot selection menu.
If you use GRUB, you can optionally create a GRUB boot entry to load HOS.EFI
with an entry like this:
menuentry 'HOS' {
insmod part_gpt
insmod chain
set root='(hd0,gpt1)'
chainloader /EFI/HOS.EFI
}
Just update the root setting for the correction location to your system's EFI
partition.
## VirtualBox
To create a VM in VirtualBox:
1. Build HOS ("./rscons").
2. In VirtualBox, select Machine -> New.
3. Set name to HOS.
4. Set Type to Other.
5. Set Version to Other/Unknown (64-bit).
6. Click Next.
7. Set memory size to 512 MB.
8. Click Next.
9. Select Do not add a virtual hard disk.
10. Click Create.
11. From the HOS repository, create a VirtualBox VMDK image with "./rscons mk-vmdk".
12. Move the HOS.vmdk file generated to the HOS VirtualBox folder.
13. In VirtualBox Manager, open HOS VM settings.
14. Under System, check the Enable EFI checkbox.
15. Under Storage, add a hard disk and browse to select the HOS.vmdk file.
16. To run HOS, either start the VM through VirtualBox or with "./rscons run-vb".
+201
View File
@@ -0,0 +1,201 @@
require "tmpdir"
project_name "HOS"
path_prepend "x86_64-elf-gcc/bin"
configure do
rscons "x86_64-elf-gcc.rb", "-b", "#{build_dir}/x86_64-elf-gcc"
check_d_compiler "ldc2", use: "ldc2"
check_c_compiler "x86_64-w64-mingw32-gcc", use: "x86_64-w64-mingw32-gcc"
check_c_compiler "x86_64-elf-gcc", use: "x86_64-elf-gcc"
check_c_compiler
check_program "mformat", on_fail: "Install the mtools package"
check_program "parted"
check_cfg package: "freetype2", on_fail: "Install libfreetype-dev", use: "freetype"
sh %w[git submodule update --init]
end
# Kernel default font size.
KFONT_SIZE = 18
# One kilobyte.
KB = 1024
# One megabyte.
MB = 1024 * 1024
class HulkBinObj < Builder
def run(options)
FileUtils.mkdir_p(File.dirname(@target))
File.write(@target, <<EOF)
.section ".rodata"
.balign 4096
.global _hulk_bin_start
_hulk_bin_start:
.incbin "#{@sources.first}"
.balign 4096
.global _hulk_bin_end
_hulk_bin_end:
EOF
unless @cache.up_to_date?(@target, nil, @sources, @env)
print_run_message("Creating HULK binary object <target>#{@target}<reset>", nil)
@cache.register_build(@target, nil, @sources, @env)
end
true
end
end
# Create a GPT disk image with an EFI partition containing the EFI image.
class Image < Builder
def run(options)
unless @cache.up_to_date?(@target, nil, @sources, @env)
print_run_message("Creating disk image <target>#{@target}<reset>", nil)
efi_image_size = File.stat(@sources.first).size
efi_image_size_mb = (efi_image_size + MB - 1) / MB
partition_size_mb = efi_image_size_mb + 1
empty_mb = "\0".b * MB
File.binwrite(@target, empty_mb * partition_size_mb)
system(*%W[mformat -i #{@target} ::])
system(*%W[mmd -i #{@target} ::/EFI])
system(*%W[mmd -i #{@target} ::/EFI/BOOT])
system(*%W[mcopy -i #{@target} #{@sources.first} ::/EFI/BOOT/BOOTX64.EFI])
partition_contents = File.binread(@target)
disk_image = empty_mb + partition_contents + empty_mb
File.binwrite(@target, disk_image)
system(*%W[parted --script #{@target} mklabel gpt mkpart HOS fat32 1MiB #{partition_size_mb + 1}MiB])
@cache.register_build(@target, nil, @sources, @env)
end
true
end
end
class CheckThreadLocal < Builder
def run(options)
map_file = File.binread(@sources.first)
if map_file =~ /\.(tdata|tbss)\b/
$stderr.puts "Error: found thread-local data in #{@sources.first}"
false
else
true
end
end
end
class FontGen < Builder
def run(options)
if @command
finalize_command
else
fontgen = @vars["fontgen"]
@sources += [fontgen]
command = %W[#{fontgen} #{@sources.first} #{KFONT_SIZE} #{@target}]
standard_command("FontGen <target>#{@target}<reset>", command, {})
end
end
end
fontgen_env = env "fontgen", use: "freetype" do |env|
env.Program("^/fontgen", glob("src/fontgen/**/*.c"))
end
hulk_env = env "hulk", use: %w[ldc2 x86_64-elf-gcc] do |env|
env.add_builder(FontGen)
env.add_builder(CheckThreadLocal)
env.FontGen("^/src/hulk/kfont.d", "font/Hack-Regular.ttf",
"fontgen" => fontgen_env.expand("^/fontgen"))
env["sources"] = glob("src/hulk/**/*.d")
env["sources"] << "^/src/hulk/kfont.d"
cpu_attrs = %w[
-avx
-avx2
-avx512bf16
-avx512bitalg
-avx512bw
-avx512cd
-avx512dq
-avx512er
-avx512f
-avx512ifma
-avx512pf
-avx512vbmi
-avx512vbmi2
-avx512vl
-avx512vnni
-avx512vp2intersect
-avx512vpopcntdq
-sse
-sse-unaligned-mem
-sse2
-sse3
-sse4.1
-sse4.2
-sse4a
-ssse3
]
env["DFLAGS"] += %W[-mtriple=x86_64-unknown-elf -mattr=#{cpu_attrs.join(",")} --betterC -release -O3 --wi --enable-cross-module-inlining -code-model=large]
env["D_IMPORT_PATH"] += %w[src]
env["D_IMPORT_PATH"] << env.expand("^/src")
env["LD"] = "x86_64-elf-gcc"
env["LDFLAGS"] += %w[-nostdlib -Tsrc/hulk/hulk.ld -Wl,-Map,${_TARGET}.map]
env["LDCMD"] = %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}]
env["OBJDUMP"] = "x86_64-elf-objdump"
env["OBJCOPY"] = "x86_64-elf-objcopy"
env.Program("^/hulk.elf", "${sources}")
env.produces("^/hulk.elf", "^/hulk.elf.map")
env.CheckThreadLocal(:hulk_map_check, "^/hulk.elf.map")
env.depends("^/hulk.elf", "src/hulk/hulk.ld")
env["SIZE"] = "x86_64-elf-size"
env.Size("^/hulk.size", "^/hulk.elf")
env.Disassemble("^/hulk.txt", "^/hulk.elf")
env.Command("^/hulk.bin", "^/hulk.elf",
"CMD" => %W[${OBJCOPY} -O binary ${_SOURCES} ${_TARGET}],
"CMD_DESC" => "Convert ELF to binary:")
env.add_build_hook do |builder|
if builder.target.end_with?(".o")
env.Disassemble("#{builder.target}.txt", builder.target)
end
end
end
hello_env = env "hello", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env|
env.add_builder(Image)
env.add_builder(CheckThreadLocal)
env.add_builder(HulkBinObj)
env["sources"] = glob("src/hello/**/*.d")
env["sources"] += glob("uefi-d/source/**/*.d")
env.HulkBinObj("^/hulk_bin.S", hulk_env.expand("^/hulk.bin"))
env.Object("^/hulk_bin.o", "^/hulk_bin.S")
env.depends("^/hulk_bin.o", hulk_env.expand("^/hulk.bin"))
env["sources"] << "^/hulk_bin.o"
env["DFLAGS"] += %w[-mtriple=x86_64-unknown-windows-coff --betterC -release -O3 --wi --enable-cross-module-inlining]
env["D_IMPORT_PATH"] += %w[src uefi-d/source]
env["LD"] = "x86_64-w64-mingw32-gcc"
env["LDFLAGS"] += %w[-nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -Wl,-Map,${_TARGET}.map]
env["LDCMD"] = %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}]
env["OBJDUMP"] = "x86_64-w64-mingw32-objdump"
env.Program("^/HOS.EFI", "${sources}")
env.produces("^/HOS.EFI", "^/HOS.EFI.map")
env.CheckThreadLocal(:hos_map_check, "^/HOS.EFI.map")
env["SIZE"] = "x86_64-w64-mingw32-size"
env.Size("^/HOS.size", "^/HOS.EFI")
env.Disassemble("^/HOS.txt", "^/HOS.EFI")
env.Image("^/HOS.img", "^/HOS.EFI")
end
task "run", desc: "Run HOS in QEMU" do
Dir.mktmpdir do |tmpdir|
img = hello_env.expand("^/HOS.img")
FileUtils.cp(img, tmpdir)
sh %W[qemu-system-x86_64 -cpu max -bios OVMF.fd -drive file=#{tmpdir}/HOS.img,format=raw -device qemu-xhci -device usb-tablet]
end
end
# See README.md for how to set up VirtualBox for HOS.
task "mk-vmdk", desc: "Create VirtualBox VMDK virtual drive for HOS" do
sh %W[VBoxManage internalcommands createrawvmdk -filename HOS.vmdk -rawdisk #{File.expand_path(hello_env.expand("^/HOS.img"))}]
end
# See README.md for how to set up VirtualBox for HOS.
task "run-vb", desc: "Run HOS in VirtualBox" do
sh %W[VBoxManage startvm HOS]
end
-32
View File
@@ -1,32 +0,0 @@
#####################################################################
# Author: Josh Holtrop / Benjamen R. Meyer #
# Date: 02/15/04 #
# Purpose: To build Josh Holtrop's OS (HOS) using GNU make #
# Note: This makefile is for use on Linux & other Unix-like systems #
#####################################################################
# Assembler information:
NASM_BIN=nasm
#################
# Build the IPL #
#################
all: stage1 stage2
################
# IPL: Stage 1 #
################
stage1: stage1.asm
$(NASM_BIN) stage1.asm -o stage1.bin
################
# IPL: Stage 2 #
################
stage2: stage2.asm
$(NASM_BIN) stage2.asm -o stage2.bin
#########
# Clean #
#########
clean:
- rm *.bin *~
-26
View File
@@ -1,26 +0,0 @@
%define VERSION "0.03" ;HOS bootloader version
%define BOOT_FAT_SEG 0x07E0 ;right after boot sector
%define BOOT_ROOT_SEG 0x0900 ;right after FAT
%define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR
%define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG
%define BOOT_STAGE2_ADD 0xB000 ;address of stage2 to jump to, org at
%define BOOT_KERNEL_ADD 0x106000 ;final pmode kernel destination - physical
%define BOOT_RD_ADD 0x200000 ;2mb for ram disk
%define BOOT_DATA_SEG 0x9000 ;data gathered by stage2 loader goes here
%define BOOT_HASRD 0x0000 ;1
%define BOOT_VESA 0x0002 ;2 - 0 for console, otherwise VESA mode
%define BOOT_VESA_OEM 0x0004 ;258 - null-terminated OEM identification string
%define BOOT_VESA_VBE 0x0106 ;512 - copy of VESA VBEInfoBlock
%define BOOT_VESA_INFO 0x0306 ;256 - copy of VESA ModeInfoBlock for selected mode
%define BOOT_MEMENTRIES 0x040A ;4 - dword = number of memmap entries
%define BOOT_MEMMAP 0x2000 ;? - memory map information
%define BOOT_DRIVE 0x7C24 ;1 - boot drive
-235
View File
@@ -1,235 +0,0 @@
;stage1.asm
;This is the stage1 section of the HOS bootloader
;It is 512 bytes to be put on the first sector of a floppy
;Author: Josh Holtrop
;Date: 03/11/04
;Modified: 05/21/04
%include "bootdef.inc"
[bits 16]
org 0x7c00
jmp short start
; --------------------------------------------------
; data portion of the "DOS BOOT RECORD"
; ----------------------------------------------------------------------
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
brOEM DB 'MSDOS5.0' ; 0003h - OEM ID - Windows 95B
brBPS DW 512 ; 000Bh - Bytes per sector
brSPC DB 1 ; 000Dh - Sector per cluster
brSc_b4_fat DW 1 ; 000Eh - Reserved sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0E0H ; 0011h - Root directory entries
brSectorCount DW 2880 ; 0013h - Sectors in volume, < 32MB
brMedia DB 240 ; 0015h - Media descriptor
brSPF DW 9 ; 0016h - Sectors per FAT
brSc_p_trk DW 18 ; 0018h - Sectors per head/track
brHPC DW 2 ; 001Ah - Heads per cylinder
brSc_b4_prt DD 0 ; 001Ch - Hidden sectors
brSectors DD 0 ; 0020h - Total number of sectors
brDrive DB 0 ; 0024h - Physical drive no.
DB 0 ; 0025h - Reserved (FAT32)
DB 29H ; 0026h - Extended boot record sig (FAT32)
brSerialNum DD 404418EAH ; 0027h - Volume serial number
brLabel DB 'Holtrops OS' ; 002Bh - Volume label
brFSID DB 'FAT12 ' ; 0036h - File System ID
;------------------------------------------------------------------------
start:
jmp 0:jmphere ;ensure that cs=0 and ip=0x7c00...
jmphere:
;dl=drive number, save it!
xor ax, ax
mov ds, ax
mov [brDrive], dl
cli
mov ss, ax
mov sp, 0x7Bfe ;right under boot sector
sti
mov ax, 0xb800
mov ds, ax
mov es, ax
xor di, di
mov ax, 0x0700
mov cx, 2000
cls:
stosw
loop cls
enable_a20:
in al, 0x64
test al, 2
jnz enable_a20
mov al, 0xD1
out 0x64, al
ea20_2: in al, 0x64
and ax, byte 2
jnz ea20_2
mov al, 0xDF
out 0x60, al
unreal:
xor ax, ax
mov es, ax
mov ds, ax
lgdt [gdtr] ;load gdt
cli
push es
push ds ;save segment values
mov ebx, cr0
inc bl
mov cr0, ebx ;pmode!
mov ax, KERNEL_DATA
mov es, ax
mov ds, ax ;load segment limits
dec bl
mov cr0, ebx ;back to real mode!
pop ds
pop es ;segments back, with 4gb limits!
sti
;now lets read in the FAT and root directory so we can search for the stage2 file...
mov ax, 0x0209 ;FAT1
mov cx, 0x0002
xor dh, dh
mov dl, [brDrive]
mov bx, BOOT_FAT_SEG
mov es, bx
xor bx, bx
int 0x13
mov ax, 0x020E ;root directory
mov cx, 0x0002 ;cyl/sect
mov dh, 0x01 ;head
mov dl, [brDrive] ;drive
mov bx, BOOT_ROOT_SEG
mov es, bx
xor bx, bx
int 0x13
;k now read root directory
mov bx, BOOT_ROOT_SEG
mov ds, bx
xor si, si ;k now ds:si points to beginning of root directory
mov es, si
mov cx, 224 ;max root entries
loop_compare:
mov di, stage2
push cx
push si ;save pointer to root dir entry
mov cx, 11
loop_name:
cmpsb
loopz loop_name
jnz goon ;cx didn't get to zero, bad file
pop si
pop cx
jmp found_file ;good file, ds:si points to start of root directory entry
goon:
pop si
pop cx
add si, 32
loop loop_compare
error:
jmp $ ;halt! no kernel file found!
found_file: ;ds:si points to root dir entry
xor ax, ax
mov gs, ax
mov ax, BOOT_STAGE2_SEG
mov es, ax
mov ax, [ds:si+26]
mov bx, BOOT_FAT_SEG
mov ds, bx ;ds points to beginning of FAT
xor di, di
readstage2_loop:
cmp ax, 0xff7
jg readstage2_done
inc di
push ax
call getCHSfromCluster
mov ax, 0x0201
mov dl, [gs:BOOT_DRIVE]
xor bx, bx
int 0x13
mov bx, es
add bx, 0x0020
mov es, bx
pop ax ;current logical cluster #
mov cx, ax ;cx=logical cluster
mov dx, 3
mul dx
shr ax, 1 ;ax=logical cluster * 3 / 2
mov si, ax
test cl, 1 ;is bit0 set?
jnz odd_cluster
even_cluster:
lodsw
and ax, 0x0fff
jmp got_cluster
odd_cluster:
lodsw
shr ax, 4
got_cluster:
jmp readstage2_loop
readstage2_done:
jmp 0:BOOT_STAGE2_ADD
;------------------------------------------------------
getCHSfromCluster:
;input: ax=lba of sector on floppy (0-2879)
add ax, 31 ;convert logical cluster# to lba#
xor dx, dx ;lba->chs
mov bx, 18
div bx
inc dx
mov cl, dl ;sector# (1-18)
xor dx, dx
mov bx, 2
div bx
mov ch, al ;cylinder# (0-79)
mov dh, dl ;head# (0-1)
ret
;-------------------------------------------------------
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
dd 0
dd 0
KERNEL_DATA equ $-gdt
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf ;cf
db 0x00
gdt_end:
stage2: db "STAGE2 BIN"
times 510-($-$$) db 0
db 0x55, 0xaa
-978
View File
@@ -1,978 +0,0 @@
;stage2.asm
;This is the stage2 section of the HOS bootloader
;It is to be copied into the normal FAT12 filesystem to be loaded by stage1
;Author: Josh Holtrop
;Date: 03/11/04
;Modified: 05/21/04
%include "bootdef.inc"
%define VESA_MODEINFO_SEG 0x0120
%define VESA_MODELIST_SEG 0x0140
%define GOOD_MODELIST_SEG 0x0160
[bits 16]
org BOOT_STAGE2_ADD
;k now read root directory
mov bx, BOOT_ROOT_SEG
mov ds, bx
xor si, si ;k now ds:si points to beginning of root directory
mov es, si
mov cx, 224 ;max root entries
loop_compare:
mov di, kernel
push cx
push si ;save pointer to root dir entry
mov cx, 11
loop_name:
cmpsb
loopz loop_name
jnz goon ;cx didn't get to zero, bad file
pop si
pop cx
jmp found_file ;good file, ds:si points to start of root directory entry
goon:
pop si
add si, 32
pop cx
loop loop_compare
error:
jmp $ ;halt! no kernel file found!
found_file: ;ds:si points to root dir entry of kernel file
xor ax, ax
mov gs, ax
mov ax, [ds:si+26]
mov bx, BOOT_FAT_SEG
mov ds, bx ;ds points to beginning of FAT
mov edi, BOOT_KERNEL_ADD
readkernel_loop:
cmp ax, 0xff7
jg readkernel_done
push ax
call getCHSfromCluster
mov ax, 0x0201
mov dl, [gs:BOOT_DRIVE]
mov bx, BOOT_KERNEL_SEG
mov es, bx
xor bx, bx
int 0x13
mov cx, 256
xor ax, ax
mov es, ax
mov esi, BOOT_KERNEL_SEG*16
copykernel_loop:
mov ax, [es:esi]
mov [es:edi], ax
inc esi
inc esi
inc edi
inc edi
loop copykernel_loop
pop ax ;current logical cluster #
mov cx, ax ;cx=logical cluster
mov dx, 3
mul dx
shr ax, 1 ;ax=logical cluster * 3 / 2
mov si, ax
test cl, 1 ;is bit0 set?
jnz odd_cluster
even_cluster:
lodsw
and ax, 0x0fff
jmp got_cluster
odd_cluster:
lodsw
shr ax, 4
got_cluster:
jmp readkernel_loop
;------------------------------------------------------
readkernel_done: ;-------------put more real mode init stuff here!
;----ask to load RD from floppy
mov ax, 0xb800
mov es, ax
xor ax, ax
mov ds, ax
xor di, di
mov cx, 2000
mov ax, 0x0700
cls_loop:
stosw
loop cls_loop
mov dx, 0x3d4 ;move cursor off screen...
mov al, 0x0e
out dx, al
inc dx
mov al, 0xff
out dx, al
dec dx
mov al, 0x0f
out dx, al
inc dx
out dx, al
xor di, di
mov si, txt_welcome
mov ah, 0x1f
call puts
mov di, 160
mov si, txt_rd1
mov ah, 7
call puts
mov si, txt_rd2
mov di, 160*2
call puts
mov di, 160*3
mov si, txt_input
call puts
get_rd:
xor ax, ax
int 0x16
cmp al, '1'
jz got_rd
cmp al, '2'
jnz get_rd
got_rd:
stosb
sub al, '1'
push ds
mov bx, BOOT_DATA_SEG ;segment for data to send kernel
mov ds, bx
mov [ds:BOOT_HASRD], al
pop ds ;ds=0
cmp al, 0 ;dont load rd
jnz yes_rd
jmp no_rd
yes_rd:
mov cx, 80
mov edi, 0xb8000+160*4
filler_loop: ;draw a red bar
mov word [ds:edi], 0x0400+177
inc edi
inc edi
loop filler_loop
mov cx, 80 ;80 cylinders to read
xor si, si ;start at cylinder 0
mov edi, BOOT_RD_ADD ;ram disk address
read_cylinder:
push cx
mov bx, 0x0100 ;read sectors from head 0
mov es, bx
xor bx, bx ;es:bx = data buffer for read
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si ;what cyl. we are on is now in cx
mov ch, cl ;ch = cyl. number
mov cl, 1 ;cl = sector number 1-63
xor dx, dx ;dh = head number
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13
mov bx, 0x0100 ;now read sectors from head 1
mov es, bx
mov bx, 9216 ;es:bx = data buffer for read
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si ;what cyl. we are on is now in cx
mov ch, cl ;ch = cyl. number
mov cl, 1 ;cl = sector number 1-63
mov dh, 1 ;dh = head number
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13
mov ebx, 0xb8000
add bx, si
shl bl, 1
mov word [ds:ebx+160*4], 0x0200+219
push si
mov esi, 0x1000
mov cx, 0x2400
copydisk_loop:
mov ax, [ds:esi]
inc esi
inc esi
mov [ds:edi], ax
inc edi
inc edi
loop copydisk_loop
pop si ;what cylinder# we are on...
inc si
pop cx
loop read_cylinder
;------------------------------------------------------
no_rd:
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_MEMMAP ;store memmap info in es:di for kernel
xor edx, edx
mov ax, 0x0100
mov ds, ax
xor ebx, ebx
getmemmap_loop:
push es
push di
push edx
mov ax, 0x0100 ;get memory map
mov es, ax
xor di, di
mov eax, 0x0000E820
mov ecx, 0x00000014
;mov ebx, 0x00000000
mov edx, 0x534D4150 ;'SMAP'
int 0x15
jc getmemmap_carry
cmp eax, 0x534D4150 ;eax should be 'SMAP' on return...
jnz getmemmap_error
cmp ebx, 0
jz getmemmap_done
pop edx ;now, copy memmap entry to es:di on the stack
pop di
pop es
xor si, si
mov cx, 20
getmemmap_copymem_loop:
lodsb
stosb
loop getmemmap_copymem_loop
inc edx
jmp getmemmap_loop
getmemmap_error:
mov ax, 0xb800
mov es, ax
mov di, 160*24
xor ax, ax
mov ds, ax
mov si, txt_memerror
mov ah, 0x04
call puts
hlt
jmp $
getmemmap_carry:
dec edx
getmemmap_done:
pop edx
pop di
pop es
xor si, si
mov cx, 20
getmemmap_done_copymem_loop:
lodsb
stosb
loop getmemmap_done_copymem_loop
inc edx
mov di, BOOT_MEMENTRIES
mov [es:di], edx ;save # of memmap entries for kernel
;on to vesa info...
xor ax, ax
mov gs, ax
mov ds, ax
mov ax, 0xb800
mov es, ax
mov di, 160
mov cx, 2000-80
mov ax, 0x0700
cls_vesa_loop:
stosw
loop cls_vesa_loop
mov si, txt_vesa
mov di, 160*1
mov ah, 7
call puts
push di
mov ax, 0x0100
mov es, ax
xor di, di
mov dword [es:di], "2EBV"
mov ax, 0x4F00
int 0x10
pop di
cmp ax, 0x004F
jz vesa_good
mov si, txt_novesa
mov ax, 0xb800
mov es, ax
mov ah, 7
call puts
mov ax, BOOT_DATA_SEG
mov ds, ax
mov word [ds:BOOT_VESA], 0
jmp vesa_done
vesa_good:
mov ax, 0xb800
mov es, ax
mov ax, 0x0100
mov ds, ax
xor si, si
mov bx, [4]
mov al, bh
call puthex
mov al, '.'
stosb
mov al, 7
stosb
mov al, bl
call puthex
add di, 4
cmp bh, 2
jge vesa_good2
xor ax, ax
mov ds, ax
mov si, txt_vesaold
mov ah, 7
call puts
mov ax, BOOT_DATA_SEG
mov ds, ax
mov word [ds:BOOT_VESA], 0
jmp vesa_done
vesa_good2:
mov ebx, [6] ;something like 0x00000E60
mov edx, [14]
mov si, bx
shr ebx, 16
mov ds, bx ;ds:si points to null-terminated OEM identification string
mov ah, 2
push si
call puts
pop si
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_VESA_OEM
vesa_copyoem:
lodsb
stosb
or al, al
jnz vesa_copyoem
mov ax, 0x0100
mov ds, ax
xor si, si
mov di, BOOT_VESA_VBE
mov cx, 512
vesa_copyvbe:
lodsb
stosb
loop vesa_copyvbe
mov si, dx
shr edx, 16
mov ds, dx ;ds:si points to video mode list
mov ax, VESA_MODELIST_SEG
mov es, ax
xor di, di
vesa_copymodes:
lodsw
stosw
cmp ax, 0xffff
jnz vesa_copymodes
mov ax, GOOD_MODELIST_SEG
mov es, ax
xor di, di
mov cx, 256
mov ax, 0xffff
clear_good_mode_list_loop:
stosw
loop clear_good_mode_list_loop
mov ax, VESA_MODELIST_SEG
mov ds, ax
xor si, si ;ds:si points to video mode list where we can edit it :)
mov ax, GOOD_MODELIST_SEG
mov es, ax
xor di, di
xor dx, dx ;dx=what good mode # we are on
vesa_readmodeinfo_loop:
lodsw
cmp ax, 0xffff
jz vesa_endofmodes
push ax ;save mode#
call checkmode
cmp ax, 0
jz vesa_readmodeinfo_good
pop ax
jmp vesa_readmodeinfo_loop
vesa_readmodeinfo_good:
pop ax ;restore mode#
stosw
call vesa_showmodeinfo
inc dx
jmp vesa_readmodeinfo_loop
vesa_endofmodes: ;here we have a list of good modes at GOOD_MODELIST_SEG:0
xor ax, ax
mov ds, ax
mov si, txt_consolemode
mov ax, 0xb800
mov es, ax
mov di, 160*2
mov ah, 7
call puts
mov di, 160*3
mov cx, dx
mov al, 'b'
vesa_displaylabels:
stosb
push ax
mov al, 7
stosb
mov al, '.'
stosb
mov al, 7
stosb
pop ax
inc al
add di, 160-4
loop vesa_displaylabels ;done drawing screen of VESA choices, now ask for one
;valid options are 'a' through (al-1)
mov bl, al
xor ax, ax
mov ds, ax
mov di, 160*24
mov si, txt_input
mov ah, 14
call puts
vesa_getchoice:
xor ax, ax
int 0x16
cmp al, 'a'
jl vesa_getchoice
cmp al, bl
jge vesa_getchoice
stosb
push ax
mov al, 14
stosb
pop ax
xor ah, ah
sub ax, 'a'
cmp ax, 0
jz vesa_consolemode_only
mov cx, ax ;cx holds good mode# (1=first good vesa mode)
dec cx
mov ax, GOOD_MODELIST_SEG
mov ds, ax
shl cx, 1
mov si, cx ;ds:si points to word containing selected mode#
lodsw
mov cx, ax
mov dx, ax ;cx and dx hold mode#
mov ax, VESA_MODEINFO_SEG
mov es, ax
xor di, di
mov ax, 0x4F01
int 0x10
call checkvesa
mov ax, VESA_MODEINFO_SEG
mov ds, ax
xor si, si
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_VESA_INFO
mov cx, 256
vesa_copymodeinfo_loop:
lodsb
stosb
loop vesa_copymodeinfo_loop ;store ModeInfoBlock for current
mov [es:BOOT_VESA], dx ;store mode# for kernel
; mov ax, 0xb800
; mov es, ax
; xor di, di
; mov al, dh
; call puthex2
; mov al, dl
; call puthex2
mov bx, dx
or bx, 0x4000 ;set "use LFB" bit of mode#
mov ax, 0x4F02
int 0x10 ;switch to graphics mode!!!
call checkvesa
jmp vesa_done
vesa_consolemode_only:
mov ax, BOOT_DATA_SEG
mov es, ax
mov word [es:BOOT_VESA], 0
jmp vesa_done
;------------------------------------------------------
vesa_showmodeinfo:
pusha
push es
push ds
mov ax, VESA_MODEINFO_SEG
mov ds, ax
xor si, si
mov ax, 0xb800
mov es, ax
mov cx, dx
mov ax, 160
mul dx ;ax=160*mod#
add ax, 160*3+6 ;offset first line of modes and room on left for label
mov di, ax
mov ax, [ds:18]
call console_putDec
add di, 10
mov al, 'x'
call console_putChar
inc di
inc di
mov ax, [ds:20]
call console_putDec
add di, 10
mov al, 'x'
call console_putChar
inc di
inc di
xor ah, ah
mov al, [ds:25]
call console_putDec
add di, 8
mov al, [ds:0]
test al, 0x80
jz vesa_showmodeinfo_done
mov al, 'L'
call console_putChar
mov al, 'F'
call console_putChar
mov al, 'B'
call console_putChar
inc di
inc di
mov ebx, [ds:40]
mov eax, ebx
shr eax, 24
call puthex2
mov eax, ebx
shr eax, 16
call puthex2
mov al, bh
call puthex2
mov al, bl
call puthex2
vesa_showmodeinfo_done:
pop ds
pop es
popa
ret
;------------------------------------------------------
checkmode:
push bx
push cx
push dx
push es
push ds
push di
push si
mov cx, ax ;cx=modenumber
mov ax, VESA_MODEINFO_SEG
mov es, ax
xor di, di
mov ax, 0x4F01
int 0x10
call checkvesa
xor di, di ;es:di -> ModeInfoBlock struc
mov ax, [es:di] ;ModeAttributes
test al, 1 ;mode supported
jz vesa_modenogood
test al, 8 ;color mode
jz vesa_modenogood
test al, 0x10 ;graphics mode
jz vesa_modenogood
test al, 0x80 ;Linear Frame Buffer supported
jz vesa_modenogood
mov al, [es:di+25] ;BitsPerPixel
cmp al, 16
jz vesa_bppok
cmp al, 24
jz vesa_bppok
cmp al, 32
jnz vesa_modenogood
vesa_bppok:
mov ax, [es:di+18] ;XResolution
mov bx, [es:di+20] ;YResolution
cmp ax, 640 ;640x480
jnz res_goon1
cmp bx, 480
jnz vesa_modenogood
jmp vesa_modegood
res_goon1:
cmp ax, 800
jnz res_goon2
cmp bx, 600
jnz vesa_modenogood
jmp vesa_modegood
res_goon2:
cmp ax, 1024
jnz res_goon3
cmp bx, 768
jnz vesa_modenogood
jmp vesa_modegood
res_goon3:
cmp ax, 1280
jnz res_goon4
cmp bx, 1024
jz vesa_modegood
cmp bx, 960
jz vesa_modegood
jmp vesa_modenogood
res_goon4:
cmp ax, 1600
jnz vesa_modenogood
cmp bx, 1200
jnz vesa_modenogood
vesa_modegood:
pop si
pop di
pop ds
pop es
pop dx
pop cx
pop bx
xor ax, ax
ret
vesa_modenogood:
pop si
pop di
pop ds
pop es
pop dx
pop cx
pop bx
mov ax, 0xffff
ret
;------------------------------------------------------
vesa_done:
; xor ax, ax ;wait for keypress...
; int 0x16
jmp go_pm
;------------------------------------------------------
puts:
lodsb
or al, al
jz puts_done
stosb
mov al, ah
stosb
jmp puts
puts_done:
ret
;------------------------------------------------------
checkvesa:
cmp ax, 0x004F
jnz vesaerror
ret
vesaerror:
mov ax, 0xb800
mov es, ax
xor ax, ax
mov ds, ax
mov si, txt_vesaerror
mov di, 160*24
mov ah, 4
call puts
cli
hlt
;-------Function console_putDec
;input:
; AX = number to display
;output:
; number written in decimal to es:di
console_putDec:
pusha
xor dx, dx
xor bh, bh ;no characters written yet
mov cx, 10000
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon1
call console_putChar
mov bh, 1
.goon1:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 1000
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon11
call console_putChar
mov bh, 1
jmp .goon2
.goon11:
cmp bh, 0
je .goon2
call console_putChar
.goon2:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 100
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon21
call console_putChar
mov bh, 1
jmp .goon3
.goon21:
cmp bh, 0
je .goon3
call console_putChar
.goon3:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 10
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon31
call console_putChar
mov bh, 1
jmp .goon4
.goon31:
cmp bh, 0
je .goon4
call console_putChar
.goon4: ;here dx contains last remainder
mov ax, dx
add ax, '0'
call console_putChar
popa
ret
;------------------------------------------------------
console_putChar:
stosb
mov al, 7
stosb
ret
;------------------------------------------------------
puthex:
;es:di points to video memory
;al holds hex value
push ax
mov ah, al
shr ax, 4
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex_goon1
add al, 'A'-'9'-1
puthex_goon1:
cmp al, '0'
jz puthex_skipzero
stosb
mov al, 7
stosb
puthex_skipzero:
pop ax
push ax
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex_goon2
add al, 'A'-'9'-1
puthex_goon2:
stosb
mov al, 7
stosb
pop ax
ret
;------------------------------------------------------
puthex2:
;es:di points to video memory, always displays 2 characters!
;al holds hex value
push ax
mov ah, al
shr ax, 4
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex2_goon1
add al, 'A'-'9'-1
puthex2_goon1:
stosb
mov al, 7
stosb
pop ax
push ax
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex2_goon2
add al, 'A'-'9'-1
puthex2_goon2:
stosb
mov al, 7
stosb
pop ax
ret
;------------------------------------------------------
txt_welcome: db " HOS bootloader v", VERSION, "! ", 0
txt_rd1: db "1. Do not load an initial ram disk", 0
txt_rd2: db "2. Load initial ram disk from boot media", 0
txt_input: db "Enter your selection: ", 0
txt_vesa: db "VESA version: ", 0
txt_vesaerror: db "VESA function call error! Halting system!", 0
txt_novesa: db "VESA not found. Starting in console mode...", 0
txt_vesaold: db "VESA version 2.0 required. Starting in console mode...", 0
txt_consolemode: db "a. Console mode only.", 0
txt_memerror: db "Extended Memory Map information unavailable! Halting system...", 0
;------------------------------------------------------
getCHSfromCluster:
;input: ax=lba of sector on floppy (0-2879)
add ax, 31 ;convert logical cluster# to lba#
xor dx, dx ;lba->chs
mov bx, 18
div bx
inc dx
mov cl, dl ;sector# (1-18)
xor dx, dx
mov bx, 2
div bx
mov ch, al ;cylinder# (0-79)
mov dh, dl ;head# (0-1)
ret
;-------------------------------------------------------
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
dd 0
dd 0
KERNEL_CODE equ $-gdt
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x00 ;base 31:24
KERNEL_DATA equ $-gdt
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf
db 0x00
gdt_end:
;-------------------------------------------------------
gdtr32:
dw gdt_end32-gdt32-1
dd gdt32
gdt32:
dd 0
dd 0
;a base of 0x4000_0000, when added to 0xC000_0000 will produce 0x0000_0000 physical before paging in effect
KERNEL_CODE32 equ $-gdt32
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x40 ;base 31:24
KERNEL_DATA32 equ $-gdt32
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf
db 0x40
gdt_end32:
;------------------------------------------------------
go_pm:
xor ax, ax
mov ds, ax
lgdt [gdtr]
cli
mov eax, cr0
inc eax
mov cr0, eax
jmp KERNEL_CODE:pmode
bits 32
pmode:
lgdt [gdtr32]
jmp KERNEL_CODE32:pmode_offsetted+0xC0000000
pmode_offsetted:
mov ax, KERNEL_DATA32
mov es, ax
mov ds, ax
mov fs, ax
mov gs, ax
jmp KERNEL_CODE:BOOT_KERNEL_ADD+0xC0000000
kernel: db "KERNEL BIN", 0
Binary file not shown.
-76
View File
@@ -1,76 +0,0 @@
#####################################################################
# Author: Josh Holtrop / Benjamen R. Meyer #
# Date: 02/15/04 Modified: 06/16/04 #
# Purpose: To build Josh Holtrop's OS (HOS) using GNU make #
# Note: This makefile is for use on Linux & other Unix-like systems #
#####################################################################
##############
# Variables: #
##############
# Format of kernel object files:
# Do not change unless you know what you are doing
KERNEL_FORMAT=aout
# Assembler information:
NASM_BIN=nasm
NASM_FLAGS=-f $(KERNEL_FORMAT)
# C++ Compile Information:
CPP=g++
CPP_FLAGS=-fleading-underscore -fno-builtin -nostdlib -nostdinc++ -nostartfiles -fno-rtti -fno-exceptions -nodefaultlibs -I. -Wall
# Linker Information:
LD=ld
LD_FLAGS=-nodefaultlibs -nostdlib --no-demangle -T link.ld
###############################
# Linking the kernel together #
###############################
all: Asm_Kernel Asm_Functions C_Kernel
$(LD) $(LD_FLAGS) -o kernel.bin -Map ./lst/LDout.doc ks.o kernel.o asmfuncs.o fdc.o keyboard.o kio.o mm.o mouse.o stdfont.o video.o vmm.o rtc.o pic.o io.o cstring.o string.o cmos.o hos_defines.o vfs.o devfs.o Mount.o
##########################
# Assembly Kernel Loader #
##########################
Asm_Kernel: kernel.asm
$(NASM_BIN) $(NASM_FLAGS) -o ks.o -l ./lst/kernel.lst kernel.asm
#################################
# Assembly Functions for Kernel #
#################################
Asm_Functions: asmfuncs.asm
$(NASM_BIN) $(NASM_FLAGS) -o asmfuncs.o -l ./lst/asmfuncs.lst asmfuncs.asm
############
# C Kernel #
############
C_Kernel:
$(CPP) $(CPP_FLAGS) -c kernel.cpp -o kernel.o
$(CPP) $(CPP_FLAGS) -c kio.cpp -o kio.o
$(CPP) $(CPP_FLAGS) -c sys/rtc.cpp -o rtc.o
$(CPP) $(CPP_FLAGS) -c sys/pic.cpp -o pic.o
$(CPP) $(CPP_FLAGS) -c sys/io.cpp -o io.o
$(CPP) $(CPP_FLAGS) -c sys/cmos.cpp -o cmos.o
$(CPP) $(CPP_FLAGS) -c lang/cstring.cpp -o cstring.o
$(CPP) $(CPP_FLAGS) -c lang/string.cpp -o string.o
$(CPP) $(CPP_FLAGS) -c video/stdfont.cpp -o stdfont.o
$(CPP) $(CPP_FLAGS) -c video/video.cpp -o video.o
$(CPP) $(CPP_FLAGS) -c block/fdc.cpp -o fdc.o
$(CPP) $(CPP_FLAGS) -c char/keyboard.cpp -o keyboard.o
$(CPP) $(CPP_FLAGS) -c char/mouse.cpp -o mouse.o
$(CPP) $(CPP_FLAGS) -c mm/mm.cpp -o mm.o
$(CPP) $(CPP_FLAGS) -c mm/vmm.cpp -o vmm.o
$(CPP) $(CPP_FLAGS) -c hos_defines.cpp -o hos_defines.o
$(CPP) $(CPP_FLAGS) -c fs/vfs.cpp -o vfs.o
$(CPP) $(CPP_FLAGS) -c fs/devfs.cpp -o devfs.o
$(CPP) $(CPP_FLAGS) -c fs/Mount.cpp -o Mount.o
#################################################
# Clean up the source directory of any binaries #
#################################################
clean:
- rm *.s *.o *.bin *~ block/*~ char/*~ fs/*~ lang/*~ mm/*~ sys/*~ video/*~
-510
View File
@@ -1,510 +0,0 @@
; asmfuncs.asm
; Josh Holtrop
; Created: 10/23/03
; Modified: 02/26/04
[extern _putc]
[extern _console_memory]
[extern _cursorPosition]
[extern _video_drawConsole]
[extern _videoMode]
%macro jzfar 1
jnz %%skip
jmp %1
%%skip:
%endmacro
;stores the parameter to the CR0 register
;extern dword write_cr0(dword cr0);
[global _write_cr0]
_write_cr0:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr0, eax
pop ebp
ret
;returns the value in the CR0 register
;extern dword read_cr0();
[global _read_cr0]
_read_cr0:
mov eax, cr0;
ret
;stores the parameter to the CR3 register
;extern dword write_cr3(dword cr3);
[global _write_cr3]
_write_cr3:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr3, eax
pop ebp
ret
;returns the value in the CR2 register
;extern dword read_cr2();
[global _read_cr2]
_read_cr2:
mov eax, cr2;
ret
;returns the value in the CR3 register
;extern dword read_cr3();
[global _read_cr3]
_read_cr3:
mov eax, cr3;
ret
;compares one string to another
;returns 0 if the strings are different
;extern dword strcmp(char *str1, char *str2);
[global _strcmp]
_strcmp:
push ebp
mov ebp, esp
push esi
push edi
mov esi, [ebp+8]
mov edi, [ebp+12]
strcmp_loop1:
lodsb
mov ah, [edi]
inc edi
cmp ah, al
jnz strcmp_ne
or al, al
jz strcmp_e
jmp strcmp_loop1
strcmp_e:
mov eax, 1
jmp short strcmp_done
strcmp_ne:
xor eax, eax
strcmp_done:
pop edi
pop esi
pop ebp
ret
;copies a string from the source to the destination parameter
;extern void strcpy(char *dest, char *src);
[global _strcpy]
_strcpy:
push ebp
mov ebp, esp
push esi
push edi
mov edi, [ebp+8]
mov esi, [ebp+12]
strcpyloop:
lodsb
stosb
or al, al
jnz strcpyloop
pop edi
pop esi
pop ebp
ret
;copies memory of n bytes from src to destination
;void memcpy(void *dest, void *src, dword n);
[global _memcpy]
_memcpy:
push ebp
mov ebp, esp
push esi
push edi
push ecx
mov edi, [ebp+8]
mov esi, [ebp+12]
mov ecx, [ebp+16]
cld
rep movsb
pop ecx
pop edi
pop esi
pop ebp
ret
;copies memory of n dwords (n*4 bytes) from src to destination
;void memcpyd(void *dest, void *src, dword n);
[global _memcpyd]
_memcpyd:
push ebp
mov ebp, esp
push esi
push edi
push ecx
mov edi, [ebp+8]
mov esi, [ebp+12]
mov ecx, [ebp+16]
cld
rep movsd
pop ecx
pop edi
pop esi
pop ebp
ret
;sets num bytes at buffer to the value of c
;void *memset(void *buffer, int c, int num);
[global _memset]
_memset:
push ebp
mov ebp, esp
push edi
push ecx
mov edi, [ebp+8]
push edi ;save for return address
mov eax, [ebp+12]
mov ecx, [ebp+16]
rep stosb
pop eax
pop ecx
pop edi
pop ebp
ret
;sets num words at buffer to the value of c
;void *memsetw(void *buffer, int c, int num);
[global _memsetw]
_memsetw:
push ebp
mov ebp, esp
push edi
push ecx
mov edi, [ebp+8]
push edi ;save for return address
mov eax, [ebp+12]
mov ecx, [ebp+16]
rep stosw
pop eax
pop ecx
pop edi
pop ebp
ret
;sets num dwords at buffer to the value of c
;void *memsetd(void *buffer, int c, int num);
[global _memsetd]
_memsetd:
push ebp
mov ebp, esp
push edi
push ecx
mov edi, [ebp+8]
push edi ;save for return address
mov eax, [ebp+12]
mov ecx, [ebp+16]
rep stosd
pop eax
pop ecx
pop edi
pop ebp
ret
;returns the number of characters in a string
;extern dword strlen(char *str);
[global _strlen]
_strlen:
push ebp
mov ebp, esp
push esi
push ebx
mov esi, [ebp+8]
xor ebx, ebx
strlenloop:
lodsb
or al, al
jz strlendone
inc ebx
jmp strlenloop
strlendone:
mov eax, ebx
pop ebx
pop esi
pop ebp
ret
;this function invalidates the page directory/table entry that
; would be used to access the memory address given in the parameter
;extern void invlpg_(dword addr);
[global _invlpg_]
_invlpg_:
mov eax, [esp+4]
invlpg [eax]
ret
;
;void writeCursorPosition(word pos)
;
[global _writeCursorPosition]
_writeCursorPosition:
push ebp
mov ebp, esp
push eax
push ebx
push edx
mov eax, [ebp+8] ;cursor position in ax
mov bl, al
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
mov al, ah
out dx, al
dec dx
mov al, 0x0F
out dx, al
inc dx
mov al, bl
out dx, al
pop edx
pop ebx
pop eax
pop ebp
ret
;
;word getCursorPosition()
;
[global _getCursorPosition]
_getCursorPosition:
push ebx
push edx
xor eax, eax
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
in al, dx
mov bl, al
dec dx
mov al, 0x0F
out dx, al
inc dx
in al, dx
mov ah, bl
pop edx
pop ebx
ret
;
;int puts(char *str)
;
[global _puts]
_puts:
push ebp
mov ebp, esp
push esi
push eax
mov esi, [ebp+8] ;esi = to string
puts_loop:
lodsb
cmp al, 0
jz puts_done
push eax
call _putc
add esp, 4
jmp puts_loop
puts_done:
pop eax
pop esi
pop ebp
ret
[global _putDecu]
_putDecu:
push ebp
mov ebp, esp
sub esp, 24
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L2:
mov edx, DWORD [ebp+8]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
cmp eax, DWORD [ebp-4]
jae L4
jmp L3
L4:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L2
L3:
nop
L5:
cmp DWORD [ebp-4], 1
ja L7
jmp L6
L7:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L5
L6:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
[global _putDec]
_putDec:
push ebp
mov ebp, esp
sub esp, 24
cmp DWORD [ebp+8], 0
jns L9
sub esp, 12
push 45
call _putc
add esp, 16
neg DWORD [ebp+8]
L9:
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L10:
mov eax, DWORD [ebp+8]
cmp eax, DWORD [ebp-4]
jae L12
jmp L11
L12:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L10
L11:
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
L13:
cmp DWORD [ebp-4], 1
ja L15
jmp L14
L15:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L13
L14:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
-36
View File
@@ -1,36 +0,0 @@
// asmfuncs.h
// Author: Josh Holtrop
// Created: 02/26/04
// Modified: 05/21/04
#ifndef __HOS_ASMFUNCS__
#define __HOS_ASMFUNCS__ __HOS_ASMFUNCS__
#include "hos_defines.h"
extern "C" {
dword write_cr0(dword cr0);
dword read_cr0();
dword write_cr3(dword cr3);
dword read_cr2();
dword read_cr3();
void writeCursorPosition(dword pos);
dword getCursorPosition();
int puts(char *str);
int putDec(int number);
int putDecu(dword number);
void strcpy(char *dest, const char *src);
void memcpy(void *dest, const void *src, dword n);
void memcpyd(void *dest, const void *src, dword n);
void *memset(void *buffer, int c, int num);
void *memsetw(void *buffer, int c, int num);
void *memsetd(void *buffer, int c, int num);
dword strlen(const char *str);
void invlpg_(dword addr);
}
#endif
-9
View File
@@ -1,9 +0,0 @@
//fdc.c
//Author: Josh Holtrop
//Created: 10/30/03
//Modified: 02/26/04
#include "fdc.h"
-23
View File
@@ -1,23 +0,0 @@
//fdc.h
//Author: Josh Holtrop
//Date: 10/30/03
//Modified: 02/26/04
#ifndef __HOS_FDC__
#define __HOS_FDC__ __HOS_FDC__
#include "sys/io.h"
#define FDC_DOR 0x3f2
#define FDC_MSR 0x3f4
//inline void fdc_sendDOR(byte dor);
static inline void fdc_sendDOR(byte dor)
{
outportb(FDC_DOR, dor);
}
#endif
-22
View File
@@ -1,22 +0,0 @@
// loop.c
// Author: Josh Holtrop
// Date: 03/16/04
// Provides a loop-back device for mounting files on existing volumes as new volumes
#include "hos_defines.h"
#include "loop.h"
#include "fs/vfs.h"
int loop_readSector(LoopDevice *ld, dword sector, byte *buffer)
{
return vfs_readFileBlock(ld->vol, ld->filePath, sector * LOOP_SECTOR_SIZE, buffer, LOOP_SECTOR_SIZE);
}
int loop_writeSector(LoopDevice *ld, dword sector, byte *buffer)
{
return vfs_writeFileBlock(ld->vol, ld->filePath, sector * LOOP_SECTOR_SIZE, buffer, LOOP_SECTOR_SIZE);
}
-22
View File
@@ -1,22 +0,0 @@
// loop.h
// Author: Josh Holtrop
// Date: 03/16/04
// Provides a loop-back device for mounting files on existing volumes as new volumes
#ifndef __HOS_LOOP__
#define __HOS_LOOP__ __HOS_LOOP__
#include "hos_includes.h"
typedef struct
{
Volume *vol;
char filePath[256];
} LoopDevice;
int loop_readSector(LoopDevice *ld, dword sector, byte *buffer);
int loop_writeSector(LoopDevice *ld, dword sector, byte *buffer);
#endif
-7
View File
@@ -1,7 +0,0 @@
// rd.c
// Author: Josh Holtrop
// Date: 03/11/04
#include "rd.h"
-12
View File
@@ -1,12 +0,0 @@
// rd.h
// Author: Josh Holtrop
// Date: 03/11/04
#ifndef __HOS_RD__
#define __HOS_RD__ __HOS_RD__
#endif
-252
View File
@@ -1,252 +0,0 @@
// keyboard.c
// Author: Josh Holtrop
// Created: 04/17/03
// Modified: 03/02/04
#include "hos_defines.h"
#include "keyboard.h"
#include "sys/io.h"
#include "sys/pic.h"
#include "functions.h"
#include "kio.h"
#define KBD_BUFFER_LENGTH 64
extern "C" {
byte kbdFlags = 0; //holds current keyboard flags - caps/num/scroll/shift/ctrl/alt
byte kbdAscii = 0; //holds ASCII value of a key pressed
byte kbdScan = 0; //holds the keyboard scan code of a key pressed
dword kbdBuffer[KBD_BUFFER_LENGTH]; //a buffer for all keypresses
int kbdBufferStart = 0; //position of next key in buffer
int kbdBufferLen = 0; //number of keys left in the buffer
byte kbdExt = 0; //# of extended key codes left to input
byte kbdExt2 = 0; //# of 2nd-set-extended key codes left to input
byte ackReason = 0; //used to record the reason why we would get an acknowledge byte (0xFA)
//these arrays convert a keyboard scan code to an ASCII character value
//nul esc bksp tab lctl lsft rsft lalt caps F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 numScrlNumPad------- unknown---- F11 F12 unknown....
const byte SCAN2ASCII[129] = "\000\0331234567890-=\010\011qwertyuiop[]\n\001asdfghjkl;'`\001\\zxcvbnm,./\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001-\001\001\001+\001\001\001\001\001\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
const byte SCAN2ASCIISHIFT[129] = "\000\033!@#$%^&*()_+\010\011QWERTYUIOP{}\n\001ASDFGHJKL:\"~\001|ZXCVBNM<>?\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001789-456+1230.\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
//====FUNCTIONS:
// The Keyboard Interrupt Service Routine
void isr_keyboard()
{
kbdScan = inportb(0x60);
//printf("\nKEYBOARD INTERRUPT: 0x%x", kbdScan);
byte inState = inportb(0x61);
outportb(0x61, inState|0x80);
outportb(0x61, inState);
//printf("IRQ 1: %x\n", kbdScan);
if (kbdScan == 0xFA) //250 //ACKnowledge
{
//printf("KBD_ACK 0x%x!\n", ackReason);
if (ackReason == 0xED) //reset LEDs
{
outportb(0x60, (kbdFlags & 0x07));
}
ackReason = 0;
}
if (kbdScan == 224) //extended key
{
kbdExt = 1;
pic_eoi();
return;
}
if (kbdScan == 225) //2nd-set-extended key
{
kbdExt2 = 2;
pic_eoi();
return;
}
//====handle control keys::
kbdAscii = 2;
switch (kbdScan) //control keys
{
case KBD_SCAN_LSHIFT:
kbdFlags |= KBD_SHIFT;
kbdAscii = 1;
break;
case KBD_SCAN_RSHIFT:
kbdFlags |= KBD_SHIFT;
kbdAscii = 1;
break;
case KBD_SCAN_LCTRL:
kbdFlags |= KBD_CTRL;
kbdAscii = 1;
break;
case KBD_SCAN_LALT:
kbdFlags |= KBD_ALT;
kbdAscii = 1;
break;
case KBD_SCAN_LSHIFT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_SHIFT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_RSHIFT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_SHIFT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_LCTRL + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_CTRL ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_LALT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_ALT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_CAPS+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_CAPS;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
case KBD_SCAN_SCROLL+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_SCROLL;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
case KBD_SCAN_NUM+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_NUM;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
}
if (kbdAscii == 1)
{
if (kbdExt > 0)
kbdExt--;
pic_eoi();
return;
}
//====determine ASCII value of key::
if (kbdExt > 0) //extended key, kbdScan holds extended key
{
kbdExt--;
kbdAscii = 1;
switch (kbdScan)
{
case KBD_SCANE_ENTER:
kbdAscii = '\n'; break;
case 53: // '/' character (divide on numpad)
kbdAscii = '/'; break;
}
}
else if (kbdExt2 > 0) //extended key 2
{
kbdExt2--;
// if (kbdScan == 69) // (pause|break)
// kbdAscii = 2; //flag ascii value of 1 means control character (pausebreak)
// else
kbdAscii = 2; //flag ascii value of 2 means ignore key (or unknown value)
}
else //not an extended key
{
// if letter key
if (((kbdScan >= 16) && (kbdScan <= 25)) || ((kbdScan >= 30) && (kbdScan <= 38)) || ((kbdScan >= 44) && (kbdScan <= 50)))
{
// if caps and shift are different (either one pressed, not both)
if (((kbdFlags & KBD_SHIFT) != 0) & ((kbdFlags & KBD_CAPS) != 0))
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
else if (((kbdFlags & KBD_SHIFT) == 0) & ((kbdFlags & KBD_CAPS) == 0))
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
}
// if numpad key
else if ((kbdScan >= 71) && (kbdScan <= 83))
{
// if numlock on
if (kbdFlags & KBD_NUM)
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
}
// other key
else
{
if ((kbdFlags & KBD_SHIFT) != 0)
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
}
}
//====do something with key::
// printf("kbdScan == %d\nkbdAscii == %d\nkbdFlags == %d\n", kbdScan, kbdAscii, kbdFlags);
if ((kbdScan == 83) && (kbdFlags & KBD_CTRL) && (kbdFlags & KBD_ALT))
{
printf("Initiating reboot.");
restart();
}
if (kbdAscii == 2) //unknown key / ignore key
{
pic_eoi();
return;
}
if (kbdScan < KBD_SCAN_RELEASED) //a key was pressed, save it
{
if (kbdBufferLen >= KBD_BUFFER_LENGTH) //no key slots available
{
pic_eoi();
return;
}
else
{
kbdBuffer[(kbdBufferStart+kbdBufferLen++)%KBD_BUFFER_LENGTH] = (dword) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii);
// printf("S:%d\tL:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, kbdBuffer[kbdBufferStart]);
}
}
pic_eoi();
}
//Gets a key from the buffer, returns 0 if no keys available, returns immediately
dword kbdGetKey()
{
if (kbdBufferLen == 0) //buffer empty
return 0;
dword retVal = kbdBuffer[kbdBufferStart];
kbdBufferStart++;
kbdBufferLen--;
if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
}
//Gets a key from the buffer, if no keys available, waits for one to be entered
dword kbdWaitKey()
{
for (;;)
{
if (kbdBufferLen != 0) //buffer empty
break;
}
dword retVal = kbdBuffer[kbdBufferStart];
kbdBufferStart++;
kbdBufferLen--;
if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
}
//Resets the keyboard LEDs to reflect the current state of the num lock, caps lock, and scroll lock bits
void kbd_resetLEDs()
{
outportb(0x60, 0xED);
ackReason = 0xED;
}
}
-53
View File
@@ -1,53 +0,0 @@
// keyboard.h
// Author: Josh Holtrop
// Created: 04/17/03
// Modified: 03/02/04
#include "hos_defines.h"
#ifndef __HOS_KEYBOARD__
#define __HOS_KEYBOARD__ __HOS_KEYBOARD__
#define KBD_SCROLL 0x01
#define KBD_NUM 0x02
#define KBD_CAPS 0x04
#define KBD_SHIFT 0x10
#define KBD_CTRL 0x20
#define KBD_ALT 0x40
#define KBD_SCAN_RELEASED 128
#define KBD_SCAN_LCTRL 29
#define KBD_SCAN_LSHIFT 42
#define KBD_SCAN_RSHIFT 54
#define KBD_SCAN_LALT 56
#define KBD_SCAN_SCROLL 70
#define KBD_SCAN_CAPS 58
#define KBD_SCAN_NUM 69
#define KBD_SCANE_PRINTSCREEN 55
#define KBD_SCANE_INS 82
#define KBD_SCANE_HOME 71
#define KBD_SCANE_PGUP 73
#define KBD_SCANE_DEL 83
#define KBD_SCANE_END 79
#define KBD_SCANE_PGDN 81
#define KBD_SCANE_ENTER 28
#define KBD_SCANE_NULL 42
//====PROTOTYPES:
extern "C" {
void isr_keyboard();
void kbd_resetLEDs();
dword kbdGetKey();
dword kbdWaitKey();
}
#endif
-76
View File
@@ -1,76 +0,0 @@
// mouse.c
// Author: Josh Holtrop
// Date: 10/03/03
// Modified: 05/21/04
#include "mouse.h"
#include "hos_defines.h"
#include "video/video.h"
#include "sys/io.h"
#define MOUSE_BUFFER_LENGTH 16
extern "C" {
int mouse_x;
int mouse_y;
int mouse_bytesRead;
byte mouse_inbuffer[MOUSE_BUFFER_LENGTH];
//This method initializes the ps/2 mouse
void mouse_init()
{
outportb(0x64, 0x20); //tell keyboard controller we are going to read keyboard controller command byte
byte temp = inportb(0x60); //read keyboard controller command byte
outportb(0x64, 0x60); //tell keyboard controller we are going to write keyboard controller command byte
outportb(0x60, 0x03 | (temp&0x40)); //write keyboard controller command byte: enable mouse/keyboard ints, include original XLATE bit from temp (bit6)
outportb(0x64, 0xA8); //enable mouse port
outportb(0x64, 0xD4); //send command to mouse, not kbd
outportb(0x60, 0xF4); //enable data reporting
mouse_x = video_getWidth() >> 1;
mouse_y = video_getHeight() >> 1;
mouse_bytesRead = 0;
//outportb(0x64, 0xD4);
//outportb(0x60, 0xE7); //scaling 2:1
}
//This method is called when a mouse interrupt occurs
void isr_mouse()
{
byte inb = inportb(0x60); //read mouse byte
if ((inb == 0xFA) && (mouse_bytesRead < 1)) //ACK
return;
mouse_inbuffer[mouse_bytesRead] = inb;
mouse_bytesRead++;
if (mouse_bytesRead == 3) //complete packet received
{
mouse_bytesRead = 0;
int adjx = (char) mouse_inbuffer[1];
int adjy = (char) mouse_inbuffer[2];
mouse_x += adjx;
mouse_y -= adjy; //-= because screen y coordinates are opposite mouse y coordinates
if (mouse_x < 0)
mouse_x = 0;
if (mouse_x >= video_getWidth())
mouse_x = video_getWidth() - 1;
if (mouse_y < 0)
mouse_y = 0;
if (mouse_y >= video_getHeight())
mouse_y = video_getHeight() - 1;
if (mouse_inbuffer[0] & 0x01) //left button
video_pset(mouse_x, mouse_y, 0x00FF9900);
else
video_pset(mouse_x, mouse_y, 0x00FFFFFF);
}
}
}
-17
View File
@@ -1,17 +0,0 @@
// mouse.h
// Author: Josh Holtrop
// Date: 10/03/03
// Modified: 03/02/04
#ifndef __HOS_MOUSE__
#define __HOS_MOUSE__ __HOS_MOUSE__
extern "C" {
void mouse_init();
void isr_mouse();
}
#endif
-28
View File
@@ -1,28 +0,0 @@
// Mount.cpp
// Author: Josh Holtrop
// Date: 06/16/04
// Modified: 06/16/04
#include "lang/string.h"
#include "Mount.h"
Mount::Mount()
{
}
Mount::Mount(string dev, string mount)
{
mountPoint = mount;
device = dev;
}
bool Mount::operator==(const Mount & second) const
{
/* Match *either* device or mountPoint to signal an invalid mount attempt */
return (device == second.device || mountPoint == second.mountPoint);
}
-28
View File
@@ -1,28 +0,0 @@
// Mount.h
// Author: Josh Holtrop
// Date: 06/16/04
// Modified: 06/16/04
#ifndef __HOS_MOUNT__
#define __HOS_MOUNT__ __HOS_MOUNT__
#include "hos_defines.h"
class Mount
{
public:
string mountPoint;
string device;
dword major;
dword minor;
Mount();
Mount(string dev, string mount);
bool operator==(const Mount & second) const;
};
#endif
-25
View File
@@ -1,25 +0,0 @@
// devfs.cpp
// device filesystem for HOS
// Author: Josh Holtrop
// Date: 06/03/04
// Modified: 06/16/04
#include "devfs.h"
#include "kio.h"
#include "lang/string.h"
#include "vfs.h"
void devfs_init(string mountPoint)
{
vfs_mount("devfs ", mountPoint);
vfs_mount("testdev ", "/mnt/win");
vfs_mount("/dev/hda6", "/scratch");
vfs_mount("/dev/rd0 ", "/");
vfs_mount("/dev/sda1", "/mnt/usb");
vfs_mount("sysfs ", "/sys");
vfs_mount("sysfs ", "/tmp");
vfs_mount("otherfs ", "/sys");
}
-17
View File
@@ -1,17 +0,0 @@
// devfs.h
// device filesystem for HOS
// Author: Josh Holtrop
// Date: 06/03/04
// Modified: 06/08/04
#ifndef __HOS_DEVFS__
#define __HOS_DEVFS__ __HOS_DEVFS__
#include "lang/string.h"
void devfs_init(string mountPoint);
#endif
-113
View File
@@ -1,113 +0,0 @@
// vfat.c
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 03/22/04
#include "vfat.h"
#include "hos_defines.h"
#include "fs/vfs.h"
#include "mm/vmm.h"
#include "lang/cstring.h"
//From Microsoft's FAT32 File System Specification
DSKSZTOSECPERCLUS DskTableFAT16 [] =
{
{ 8400, 0}, /* disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error */
{ 32680, 2}, /* disks up to 16 MB, 1k cluster */
{ 262144, 4}, /* disks up to 128 MB, 2k cluster */
{ 524288, 8}, /* disks up to 256 MB, 4k cluster */
{ 1048576, 16}, /* disks up to 512 MB, 8k cluster */
/* The entries after this point are not used unless FAT16 is forced */
// { 2097152, 32}, /* disks up to 1 GB, 16k cluster */
// { 4194304, 64}, /* disks up to 2 GB, 32k cluster */
{ 0xFFFFFFFF, 0} /* any disk greater than 2GB, 0 value for SecPerClusVal trips an error */
};
//From Microsoft's FAT32 File System Specification
DSKSZTOSECPERCLUS DskTableFAT32 [] =
{
{ 66600, 0}, /* disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error */
{ 532480, 1}, /* disks up to 260 MB, .5k cluster */
{ 16777216, 8}, /* disks up to 8 GB, 4k cluster */
{ 33554432, 16}, /* disks up to 16 GB, 8k cluster */
{ 67108864, 32}, /* disks up to 32 GB, 16k cluster */
{ 0xFFFFFFFF, 64}/* disks greater than 32GB, 32k cluster */
};
int vfat_identify(vfat_bpb *bpb)
{
int rootDirSectors = ((bpb->rootEntries * 32) + (bpb->bytesPerSector - 1)) / bpb->bytesPerSector;
int totalSectors = bpb->totalSectors16 ? bpb->totalSectors16 : bpb->totalSectors32;
int fatSectors = bpb->sectorsPerFAT16 ? bpb->sectorsPerFAT16 : bpb->sectorsPerFAT32;
int dataSectors = totalSectors - (bpb->reservedSectors + bpb->numFATs * fatSectors + rootDirSectors);
int clusters = dataSectors / bpb->sectorsPerCluster;
if (clusters < 4085)
return 12;
if (clusters < 65525)
return 16;
return 32;
}
int vfat_format(Volume *vol)
{
}
FILE *vfat_open(char *fileName, dword attributes, Volume *vol)
{
while (*fileName == '/')
++fileName;
if (strlen(fileName) < 1)
return 0;
vfat_bpb *bpb = vfat_getBootSector(vol);
if (!bpb) return 0;
byte *fat = vfat_loadFAT(vol, bpb);
if (!fat)
{
free(bpb);
return 0;
}
int segs = string_split(fileName); //number of sections of path (1=file is in root directory)
int me = vfat_identify(bpb);
if (me != 32)
{
if (segs == 1) //we are looking for the file in the root directory
{
vfat_getEntryInRoot(vol, bpb, fileName, 0);
}
}
else
{
}
}
byte *vfat_loadFAT(Volume *vol, vfat_bpb *bpb)
{
int fatSize = bpb->sectorsPerFAT16 ? bpb->sectorsPerFAT16 : bpb->sectorsPerFAT32;
byte *fat = malloc(fatSize << 9); //512 bytes per sector
if (!fat) return 0;
if (vfs_readSectorn(vol, bpb->reservedSectors, fat, fatSize))
{
free(fat);
return 0;
}
return fat;
}
vfat_bpb *vfat_getBootSector(Volume *vol)
{
vfat_bpb *bs;
if (!(bs = malloc(512)))
return 0;
vfs_readSector(vol, 0, bs);
return bs;
}
int vfat_close(FILE *fp)
{
return free(fp);
}
-134
View File
@@ -1,134 +0,0 @@
// vfat.h
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 03/22/04
#ifndef __HOS_VFAT__
#define __HOS_VFAT__ __HOS_VFAT__
#include "hos_defines.h"
#include "fs/vfs.h"
#define VFAT_FAT12_EOCL 0x0FF8 // end-of-cluster chain reached if FatValue >= EOCL
#define VFAT_FAT16_EOCL 0xFFF8
#define VFAT_FAT32_EOCL 0x0FFFFFF8
#define VFAT_FAT12_EOC 0x0FFF // end-of-cluster chain value
#define VFAT_FAT16_EOC 0xFFFF
#define VFAT_FAT32_EOC 0x0FFFFFFF
#define VFAT_FAT12_BAD 0x0FF7 // bad cluster mark
#define VFAT_FAT16_BAD 0xFFF7
#define VFAT_FAT32_BAD 0x0FFFFFF7
#define VFAT_DIRENTRY_FREE 0xE5
#define VFAT_DIRENTRY_FREE_LAST 0x00
typedef struct
{
byte jmpBoot[3]; // {0xEB, 0x??, 0x90} or {0xE9, 0x??, 0x??}
char OEMName[8]; // any 8-char string (def. "MSWIN4.1")
word bytesPerSector; // 512 (default), 1024, 2048, 4096
byte sectorsPerCluster; // 1 (default), 2, 4, 8, 16, 32, 64, 128
word reservedSectors; // 1 (fat12/16), 32 (fat32)
byte numFATs; // 2
word rootEntries; // number of 32-byte root directory entries (224 for 1440k floppy) - 0 for fat32
word totalSectors16; // total number of sectors in volume (2880 for floppy) - 0 for fat32
byte media; // >= 0xF0 valid, 0xF8 (default non-removable), 0xF0 (default removable), must match lsb of FAT[0]
word sectorsPerFAT16; // number of sectors in FAT (9 for floppy)
word sectorsPerTrack; // (18 for floppy)
word numHeads; // number of heads (2 for floppy)
dword hiddenSectors; // 0
dword totalSectors32; // 0, non-zero for fat32 volumes
/* FAT32 specific members */
dword sectorsPerFAT32; // number of sectors in a fat for fat32 volumes
word extFlags; // bits 0-3 active fat, bit 7 {0 = mirror all FATs, 1 = only use 1 FAT}
word fsVersion; // fat32 version (0:0)
dword rootCluster; // first cluster of root directory (default 2)
word fsInfo; // sector number of FSINFO block (default 1)
word bootCopy; // sector of backup boot record (default 6)
} __attribute__ ((packed)) vfat_bpb;
typedef struct
{
dword leadSignature; // 0x41615252
byte reserved1[480];
dword structSignature; // 0x61417272
dword lastFree; // last known free cluster (0xFFFFFFFF == unknown)
dword nextFree; // start looking for free clusters here (0xFFFFFFFF == unknown)
byte reserved2[12];
dword trailSignature; // 0xAA550000
} __attribute__ ((packed)) vfat_fsinfo;
typedef struct
{
char fileName[8]; // file name, 8 char. max, pad w/ spaces
char fileExt[3]; // file extension, 3 char. max, pad w/ spaces
byte attributes; // file attributes, read-only, etc.
byte reserved; // 0
byte timeTenths; // 0-199
word time; // time of creation
word date; // date of creation
word adate; // last accessed date
word clusterHigh; // 0 for fat12/16
word wtime; // last write time
word wdate; // last write date
word clusterLow; // LSW of first cluster of file data
dword fileSize;
} __attribute__ ((packed)) vfat_dirEntry;
typedef struct
{
byte order;
word name0_4[5]; // filename - first 5 characters (unicode)
byte attributes; // must be VFAT_LONG_NAME
byte type; // 0 = part of long name
byte checksum; // checksum of short entry at end of long entry set
word name5_10[6]; // filename - next 6 characters (unicode)
word clusterLow; // 0
word name11_12[2]; // filename - next 2 characters
} __attribute__ ((packed)) vfat_lfnEntry;
#define VFAT_READ_ONLY 0x01
#define VFAT_HIDDEN 0x02
#define VFAT_SYSTEM 0x04
#define VFAT_VOLUME 0x08
#define VFAT_DIRECTORY 0x10
#define VFAT_ARCHIVE 0x20
#define VFAT_LONG_NAME 0x0F // VFAT_READ_ONLY | VFAT_HIDDEN | VFAT_SYSTEM | VFAT_VOLUME
#define VFAT_ATTR_MASK 0x3F // VFAT_READ_ONLY | VFAT_HIDDEN | VFAT_SYSTEM | VFAT_VOLUME | VFAT_DIRECTORY | VFAT_ARCHIVE
#define VFAT_ORDER_MASK 0x40
/*
* Illegal file name characters:
* Values less than 0x20 except for 0x05. 0x05 signifies that the actual filename character is 0xE5
* 0x22 ("), 0x2A (*)
* 0x2E (.), 0x2F (/), 0x3A (:)
* 0x3C (<), 0x3E (>), 0x3F (?), 0x5C (\), 0x7C (|)
* The following are illegal in 8.3 but legal in LFN:
* 0x2B (+), 0x2C (,), 0x3B (;), 0x3D (=), 0x5B ([), 0x5D (])
*/
//From Microsoft's FAT32 File System Specification
typedef struct
{
dword diskSize;
byte sectorsPerCluster;
} DSKSZTOSECPERCLUS;
// sector[510] == 0x55
// sector[511] == 0xAA
int vfat_identify(vfat_bpb *bpb);
int vfat_format(Volume *vol);
FILE *vfat_open(char *fileName, dword attributes, Volume *vol);
vfat_bpb *vfat_getBootSector(Volume *vol);
int vfat_close(FILE *fp);
byte *vfat_loadFAT(Volume *vol, vfat_bpb *bpb)
#endif
-55
View File
@@ -1,55 +0,0 @@
// vfs.cpp
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 04/16/04
#include "hos_defines.h"
#include "vfs.h"
//#include "fs/vfat.h"
//#include "block/rd.h"
//#include "block/loop.h"
#include "lang/LinkedList.h"
#include "lang/string.h"
#include "devfs.h"
#include "kio.h"
#include "Mount.h"
LinkedList<Mount> *mounts;
void vfs_init()
{
mounts = new LinkedList<Mount>;
}
void list()
{
LinkedList<Mount>::iterator it = mounts->begin();
while (it != mounts->end())
{
printf("%s\t%s\n", (*it).device.data(), (*it).mountPoint.data());
++it;
}
}
int vfs_mount(string device, string mountPoint)
{
Mount mount(device, mountPoint);
LinkedList<Mount>::iterator it = mounts->begin();
int i = 0;
while (it != mounts->end() && (*it).mountPoint <= mount.mountPoint)
{
if (*it == mount)
return 1; //device already mounted or mount point already taken
i++;
++it;
}
mounts->insert(i, mount);
return 0;
}
-19
View File
@@ -1,19 +0,0 @@
// vfs.h
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 06/16/04
#ifndef __HOS_VFS__
#define __HOS_VFS__ __HOS_VFS__
#include "hos_defines.h"
#include "lang/string.h"
void vfs_init();
int vfs_mount(string device, string mountPoint);
void list();
#endif
-94
View File
@@ -1,94 +0,0 @@
//functions.h
//05/07/03 Josh Holtrop
//for HOS
//Modified: 02/26/04
#ifndef __HOS_FUNCTIONS__
#define __HOS_FUNCTIONS__ __HOS_FUNCTIONS__
#include "hos_defines.h"
#include "sys/io.h"
extern dword _code;
extern dword _bss;
extern dword _end;
//Enables (SeTs) Interrupt Flag on the processor
static inline void enable_ints()
{
asm("sti");
}
//Disables (CLears) Interrupt Flag on the processor
static inline void disable_ints()
{
asm("cli");
}
//Restarts the computer
static inline void restart()
{
enable_ints();
byte temp;
do
{
temp = inportb(0x64);
if (temp & 1)
inportb(0x60);
} while(temp & 2);
outportb (0x64, 0xfe);
for (;;) {}
}
//Halts (freezes) the computer
static inline void halt()
{
asm("cli");
asm("hlt");
while (1);
}
//Initializes 8253 Programmable Interrupt Timer
static inline void timer_init()
{
//set timer : 2e9c = 100hz
outportb(0x43, 0x34);
outportb(0x40, 0x9c); //lsb
outportb(0x40, 0x2e); //msb
}
//Returns the size of the kernel (code & data)
// - this does include the bss section
// - this should be 4kb aligned per the linker script
// - this is the amount of RAM the kernel code, data, & bss take
static inline dword kernel_size_used()
{
return (dword)(&_end)-(dword)(&_code);
}
//Returns the size of the kernel (code & data)
// - this does not include the bss section
// - this should be 4kb aligned per the linker script
// - this should be the size of kernel.bin
static inline dword kernel_size()
{
return (dword)(&_bss)-(dword)(&_code);
}
//converts a binary-coded-decimal byte to its decimal equivalent
static inline byte bcd2byte(byte bcd)
{
return (10 * ((bcd & 0xF0) >> 4)) + (bcd & 0x0F);
}
//converts a binary-coded-decimal byte to its decimal equivalent
static inline byte byte2bcd(byte bite)
{
return ((bite / 10) << 4) | (bite % 10);
}
#endif
-71
View File
@@ -1,71 +0,0 @@
;gdt.inc
;Author: Josh Holtrop
;Date: 10/30/03
;Modified: 03/02/04
gdtr:
dw gdt_end-gdt-1
dd GDT_V
gdt:
dd 0
dd 0
KERNEL_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
KERNEL_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
USER_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xFA ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
USER_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xF2 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
gVESA_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
VESA_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
VIDEO_TEXT equ $-gdt
dw 0x7FFF ;limit 15:0
dw 0x8000 ;base 15:0
db 0x0B ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
VIDEO_GRAPHICS equ $-gdt
dw 0xFFFF ;limit 15:0
dw 0x0000 ;base 15:0
db 0x0A ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
gdt_end:
-27
View File
@@ -1,27 +0,0 @@
#include "mm/vmm.h"
//overload the operator "new"
void * operator new (dword size)
{
return malloc(size);
}
//overload the operator "new[]"
void * operator new[] (dword size)
{
return malloc(size);
}
//overload the operator "delete"
void operator delete (void *p)
{
free(p);
}
//overload the operator "delete[]"
void operator delete[] (void *p)
{
free(p);
}
-48
View File
@@ -1,48 +0,0 @@
//hos_defines.h
//03/17/03 Josh Holtrop
//Modified: 03/02/04
#ifndef __HOS_HOS_DEFINES__
#define __HOS_HOS_DEFINES__ __HOS_HOS_DEFINES__
#define FREERAM_START 0x368000 // 0x368000 is first available byte (this is right after the initrd @ 2mb, 1440kb.
#define MAX_RAM 0x40000000 //1gb maximum RAM supported
#define PID_KERNEL 0x02 //kernel's PID
#define PID_VMM 0x03
#define PID_USER 0x10000 //user processes' start PID
//these defines are the memory locations of values saved by the stage 2 bootloader
#define BOOT_MEMMAP_ENTRIES 0xC009040A
#define BOOT_FIRST_MEMMAP 0xC0092000
#define BOOT_VIDEO_MODE 0xC0090002
#define BOOT_VIDEO_MODE_INFO_BLOCK 0xC0090306
#define BOOT_HASRD 0xC0090000
#define NULL 0
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
typedef struct {
dword lowdword;
dword highdword;
} __attribute__((packed)) qword;
//overload the operator "new"
void * operator new (dword size);
//overload the operator "new[]"
void * operator new[] (dword size);
//overload the operator "delete"
void operator delete (void *p);
//overload the operator "delete[]"
void operator delete[] (void *p);
#endif
-117
View File
@@ -1,117 +0,0 @@
;idt.inc
;Author: Josh Holtrop
;Date: 10/30/03
;Modified: 03/02/04
idtr:
dw 50*8-1 ;size of idt
dd IDT_V ;address of idt
%macro isr_label 1
isr_%1:
push eax
mov eax, %1
jmp isr_main
%endmacro
isr_label 0
isr_label 1
isr_label 2
isr_label 3
isr_label 4
isr_label 5
isr_label 6
isr_label 7
isr_label 8
isr_label 9
isr_label 10
isr_label 11
isr_label 12
isr_label 13
isr_label 14
isr_label 15
isr_label 16
isr_label 17
isr_label 18
isr_label 19
isr_label 20
isr_label 21
isr_label 22
isr_label 23
isr_label 24
isr_label 25
isr_label 26
isr_label 27
isr_label 28
isr_label 29
isr_label 30
isr_label 31
isr_label 32
isr_label 33
isr_label 34
isr_label 35
isr_label 36
isr_label 37
isr_label 38
isr_label 39
isr_label 40
isr_label 41
isr_label 42
isr_label 43
isr_label 44
isr_label 45
isr_label 46
isr_label 47
isr_label 48
isr_label 49
isr_main:
cmp eax, 0x30
jz isr_syscall
pusha
push ds
push es
push eax
call _isr
add esp, 4
pop es
pop ds
popa
pop eax
iret
isr_syscall:
pop eax ;syscall function number
pusha
push ds
push es
sc1:
cmp eax, 1 ;syscall 1 - putc
jnz sc2
push ebx
call _putc
add esp, 4
jmp scdone
sc2:
scdone:
pop es
pop ds
popa
iret
-102
View File
@@ -1,102 +0,0 @@
;kernel.asm
;Author: Josh Holtrop
;Date: 10/30/03
;Modified: 10/30/03
%define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space
%define GDT_V GDT_P+0xC0000000
%define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space
%define IDT_V IDT_P+0xC0000000
%define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD)
%define PDBR_V PDBR_P+0xC0000000
%define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb
%define LOPT_V LOPT_P+0xC0000000
%define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address
%define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel
[global _start]
[extern _isr]
[extern _k_init]
[extern _putc]
bits 32
;This is where the kernel begins execution
;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0.
;We must enable paging with the first 4mb mapped 1:1 virtual:physical
; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical.
;Then we can start using our "real" gdt, then unmap the lower 4mb.
_start:
cli ;if they weren't already off
xor eax, eax
mov edi, PDBR_V
mov ecx, 1024 ;clear the PDBR
rep stosd
mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov edi, LOPT_V
mov ecx, 1024
mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags)
fill_lopt_loop: ;fill the page table
stosd
add eax, 4096 ;increment next phsyical address by 4kb
loop fill_lopt_loop
mov eax, PDBR_P
mov cr3, eax ;store the Page Directory Base Address
mov eax, cr0
or eax, 0x80000000 ;set page enable bit
mov cr0, eax ;now paging is active!
mov edi, GDT_V
mov esi, gdt
mov ecx, gdt_end-gdt
copy_gdt:
lodsb
stosb
loop copy_gdt
mov edi, IDT_V ;destination
mov esi, isr_0 ;address of isr0
mov edx, isr_1-isr_0 ;distance between isr labels
mov ecx, 50 ;number of isrlabels
fill_idt:
mov ebx, esi
mov ax, si
stosw ;0 offset 15:0
mov ax, KERNEL_CODE
stosw ;2 selector 15:0
mov ax, 0x8E00
stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0]
shr esi, 16
mov ax, si
stosw ;6 offset 31:16
mov esi, ebx
add esi, edx
loop fill_idt
mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
lgdt [gdtr] ;load gdt
jmp KERNEL_CODE:newgdtcontinue
newgdtcontinue:
mov ax, KERNEL_DATA
mov es, ax
mov ds, ax
mov gs, ax
mov fs, ax
mov ss, ax
mov esp, 0xc0200000 ;stack just under 3gb+2mb, moves downward
lidt [idtr] ;load idt
call _k_init
haltit:
hlt ;halt processor when k_init is done
jmp haltit ;shouldn't get here...
%include "gdt.inc"
%include "idt.inc"
-129
View File
@@ -1,129 +0,0 @@
// kernel.c
// Author: Josh Holtrop
// Date: 08/13/03
// Holtrop's Operating System - Version 0.13
// Modified: 03/08/04
#include "hos_defines.h" //#DEFINE's for kernel
#include "functions.h" //general functions
#include "asmfuncs.h" //assembly functions
#include "kio.h" //kernel input/output functions
#include "mm/mm.h" //physical memory management functions
#include "mm/vmm.h" //virtual memory management & paging functions
#include "char/keyboard.h" //generic keyboard driver & functions
#include "char/mouse.h" //generic ps/2 mouse driver & functions
#include "block/fdc.h" //Floppy Disk Controller functions
#include "sys/cmos.h" //CMOS interface functions
#include "sys/io.h" //port i/o functions
#include "sys/pic.h" //Programmable Interrupt Controller functions
#include "sys/rtc.h" //Real Time Clock functions
#include "video/video.h" //video functions
#include "fs/vfs.h" //Virtual File System layer
#include "fs/devfs.h" //Device filesystem
extern "C" {
void isr(dword num);
void k_init();
dword timer = 0;
//Main kernel initialization method
void k_init()
{
// ===== Initialization
fdc_sendDOR(0x0C); //turn off floppy motor!!
mm_init();
vmm_init();
video_init();
kio_init();
kio_console_cls();
pic_remap(0x20, 0x28);
timer_init();
mouse_init();
pic_mask1(0); //unmask IRQ's 0-7
pic_mask2(0); //unmask IRQ's 8-15
enable_ints();
kbd_resetLEDs(); //after enabling interrupts!!
if (video_Mode())
{
int w = video_getWidth(), h = video_getHeight();
int p = w * h - 1;
for (; p >= 0; p--)
video_pseti(p, 0x00000075);
int x = w >> 1, y = h >> 1, sz = h >> 1;
for (p = 0; p <= sz; p += 24)
{
video_line(x + p, y, x, y + sz - p, 0x0000FF00);
video_line(x + p, y, x, y - sz + p, 0x0000FF00);
video_line(x - p, y, x, y + sz - p, 0x0000FF00);
video_line(x - p, y, x, y - sz + p, 0x0000FF00);
}
kio_drawConsole();
}
printf("HOS 0.14 - Kernel File Size: %uKb Mem Used: %uKb\n", kernel_size()>>10, kernel_size_used()>>10);
printf("Memory available to OS: %u MB (%u bytes)\n", mm_getTotalMegs(), mm_getTotalMem());
printf("Free memory: %u bytes (%u pages)\n", mm_freemem(), mm_freemem()>>12);
printf("Built on %s at %s\n", __DATE__, __TIME__);
printf("%b/%b/%b %b:%b:%b\n", rtc_readMonth(), rtc_readDay(), rtc_readYear(), rtc_readHour(), rtc_readMinute(), rtc_readSecond());
vfs_init();
devfs_init("/dev");
list();
printf("Done.\n");
dword key = 0;
for (;;)
{
key = kbdWaitKey();
if ((key & 0xFF) > 2) //key is not a control key
putc(key);
}
}
// main Interrupt Service Routine - handles all interrupts unless caught by kernel.asm
void isr(dword num)
{
switch(num)
{
case 14:
printf("Page fault, CR2 = 0x%x\n", read_cr2());
{
enable_ints();
for (;;) ; //infinetly loop so that my KVM will still work :) 06/10/04
}
// halt();
break;
case 0x20: // IRQ0 - timer interrupt
timer++;
(*(byte *)(0xc00b8000))++;
if (!(timer % 100))
{
dword curPos = kio_getCursorPosition();
kio_writeCursorPosition(72);
printf("%b:%b:%b\n", rtc_readHour(), rtc_readMinute(), rtc_readSecond());
kio_writeCursorPosition(curPos);
}
pic_eoi();
break;
case 0x21: // IRQ1 - keyboard interrupt
isr_keyboard(); //isr_keybard() takes care of calling eoi()
break;
case 0x2C: // IRQ12 - PS/2 mouse
isr_mouse();
pic_eoi2();
break;
default:
printf("Interrupt %d (0x%x) Unhandled!!\n", num, num);
halt();
break;
}
}
}
-227
View File
@@ -1,227 +0,0 @@
// kio.c
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 04/06/04
#include "hos_defines.h"
#include "kio.h"
#include "asmfuncs.h"
#include "video/video.h"
dword graphical;
dword cursorPosition; //Caches the current cursor position
word console_memory[2000]; //holds a copy of the console's memory
// This is the main output routine, it uses a format string and a variable
// number of arguments to print formatted text
extern "C" {
void kio_init()
{
graphical = video_Mode();
cursorPosition = 0;
writeCursorPosition(0);
}
void printf(char *fmt, ...)
{
dword *params = ((dword *)(&fmt)) + 1; //points to the first paramater
int i;
int special = 0;
for (i = 0; ; i++)
{
if (special)
{
special = 0;
switch (fmt[i])
{
case 0:
return;
case '%':
putc('%');
break;
case 's': case 'S':
puts((char *)*params);
params++;
break;
case 'c': case 'C':
putc(*params);
params++;
break;
case 'd': case 'D': case 'i': case 'I':
putDec(*params);
params++;
break;
case 'u': case 'U':
putDecu(*params);
params++;
break;
case 'x': case 'X':
putHex(*params);
params++;
break;
case 'b': case 'B':
kio_putBCD(*params);
params++;
break;
}
}
else
{
switch (fmt[i])
{
case '%':
special = 1;
break;
case 0:
return;
default:
putc(fmt[i]);
}
}
}
}
// This function draws a single character
void putc(dword chr)
{
char charac = (char)chr;
word *vidmem = (word *)0xC00B8000;
if (charac == '\n')
{
if (cursorPosition % 80)
cursorPosition = cursorPosition + 80 - (cursorPosition % 80);
else
cursorPosition += 80;
}
else if (charac == '\t')
{
if (cursorPosition % 8)
cursorPosition = cursorPosition + 8 - (cursorPosition % 8);
else
cursorPosition += 8;
}
else
{
if (graphical)
{
console_memory[cursorPosition] = charac | 0x0700;
kio_drawConsoleChar(cursorPosition);
}
else
{
console_memory[cursorPosition] = charac | 0x0700;
vidmem[cursorPosition] = charac | 0x0700;
}
cursorPosition++;
}
if (cursorPosition >= 2000)
{
kio_console_scroll();
cursorPosition = 2000-80;
}
if (!graphical)
writeCursorPosition(cursorPosition);
}
// This function displays a number in hexadecimal
void putHex(dword number)
{
int hitNum = 0;
int i;
for (i = 7; i >= 0; i--)
{
dword val = (number >> (i*4)) & 0xF;
if ((val != 0) || (i == 0))
hitNum = 1;
if (hitNum)
{
val = val + '0';
if (val > '9')
val = val + ('A' - '9' - 1);
putc(val);
}
}
}
void kio_putBCD(dword bcd)
{
putc(((bcd & 0xF0) >> 4) + '0');
putc((bcd & 0xF) + '0');
}
void kio_console_scroll()
{
memcpyd(console_memory, console_memory + 80, 960);
memsetw(console_memory + 1920, 0x0720, 80);
if (graphical)
kio_drawConsole();
else
memcpyd((void *)0xC00B8000, console_memory, 1000);
}
void kio_console_cls()
{
memsetw(console_memory, 0x0720, 2000);
if (graphical)
kio_drawConsole();
else
memcpyd((void *)0xC00B8000, console_memory, 1000);
writeCursorPosition(0);
}
// This function draws a simple "console" window in graphical mode to display text
void kio_drawConsole()
{
video_rectf(8, 8, 491, 261, 0);
video_rect(7, 7, 492, 262, 0x00777777);
int x, y;
x = 250, y = 135;
int s = 100, p = 0;
for (p = 0; p <= s; p += 16)
{
video_line(x + p, y, x, y + s - p, 0x00008800);
video_line(x + p, y, x, y - s + p, 0x00008800);
video_line(x - p, y, x, y + s - p, 0x00008800);
video_line(x - p, y, x, y - s + p, 0x00008800);
}
for (x = 0; x < 80; x++)
{
for (y = 0; y < 25; y++)
{
video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0, 0x00FFFFFF, 0, 0);
}
}
}
// This function draws a "console" character to the graphical video screen
void kio_drawConsoleChar(dword position)
{
int x = position % 80;
int y = position / 80;
video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0, 0x00FFFFFF, 1, 0);
}
dword kio_getCursorPosition()
{
return cursorPosition;
}
void kio_writeCursorPosition(dword position)
{
cursorPosition = position;
if (!graphical)
writeCursorPosition(position);
}
}
-29
View File
@@ -1,29 +0,0 @@
// kio.h
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 05/21/04
#ifndef __HOS_KIO__
#define __HOS_KIO__ __HOS_KIO__
#include "hos_defines.h"
extern "C" {
void kio_init();
void printf(char *fmt, ...);
void putc(dword chr);
void putHex(dword number);
void kio_drawConsole();
void kio_drawConsoleChar(dword position);
void kio_console_scroll();
void kio_console_cls();
void kio_putBCD(dword bcd);
dword kio_getCursorPosition();
void kio_writeCursorPosition(dword position);
}
#endif
-210
View File
@@ -1,210 +0,0 @@
// LinkedList.h
// implements a LinkedList container for HOS
// Author: Josh Holtrop
// Date: 05/22/04
// Modified: 06/09/04
#ifndef __HOS_LINKEDLIST__
#define __HOS_LINKEDLIST__ __HOS_LINKEDLIST__
template <typename Element>
class LinkedList
{
private:
class LinkedNode
{
public:
LinkedNode()
{
prev = next = 0;
}
LinkedNode(Element dataElement)
{
data = dataElement;
prev = next = 0;
}
Element data;
LinkedNode *next;
LinkedNode *prev;
};
LinkedNode *firstNode;
LinkedNode *lastNode;
int count;
public:
class iterator
{
private:
LinkedNode *theNode;
public:
iterator(LinkedNode & node)
{
theNode = &node;
}
iterator(LinkedNode *node)
{
theNode = node;
}
Element & operator*()
{
return theNode->data;
}
void operator++() //prefix
{
theNode = theNode->next;
}
void operator++(int dum) //postfix
{
theNode = theNode->next;
}
bool operator==(const iterator & second) const
{ return theNode == second.theNode; }
bool operator!=(const iterator & second) const
{ return theNode != second.theNode; }
};
class reverse_iterator
{
private:
LinkedNode *theNode;
public:
reverse_iterator(LinkedNode & node)
{
theNode = &node;
}
reverse_iterator(LinkedNode *node)
{
theNode = node;
}
Element & operator*()
{
return theNode->data;
}
void operator++() //prefix
{
theNode = theNode->prev;
}
void operator++(int dum) //postfix
{
theNode = theNode->prev;
}
bool operator==(const reverse_iterator & second) const
{ return theNode == second.theNode; }
bool operator!=(const reverse_iterator & second) const
{ return theNode != second.theNode; }
};
/* Basic constructor */
LinkedList();
/* How many elements in the list */
int size() { return count; }
/* Return some iterators for traversing the list */
iterator begin() { return iterator(firstNode->next); }
iterator end() { return iterator(lastNode->next); }
reverse_iterator rbegin() { return reverse_iterator(lastNode); }
reverse_iterator rend() { return reverse_iterator(firstNode); }
/* Insert an element, its position will be index */
LinkedList & insert(int index, Element e);
/* Append an element to the end of the list */
LinkedList & push_back(Element e);
/* Remove an element at position index */
LinkedList & remove(int index);
/* Pop an element from the end of the list */
LinkedList & pop_back();
/* Direct access to an element in the list */
Element & operator[](int index);
};
template <typename T>
LinkedList<T>::LinkedList()
{
firstNode = lastNode = new LinkedNode(); //head node
count = 0;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::insert(int index, Element e)
{
if (index == count)
push_back(e);
else if (index >= 0 && index < count)
{
LinkedNode *nptr = firstNode;
for (int i = 0; i <= index; i++)
nptr = nptr->next;
LinkedNode *newptr = new LinkedNode(e);
newptr->next = nptr;
newptr->prev = nptr->prev;
newptr->prev->next = newptr;
nptr->prev = newptr;
count++;
}
return *this;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::push_back(Element e)
{
lastNode->next = new LinkedNode(e);
lastNode->next->prev = lastNode;
lastNode = lastNode->next;
count++;
return *this;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::remove(int index)
{
if (index == count-1)
pop_back();
else if (index >= 0 && index < count)
{
LinkedNode *nptr = firstNode;
for (int i = 0; i <= index; i++)
nptr = nptr->next;
nptr->prev->next = nptr->next;
nptr->next->prev = nptr->prev;
delete nptr;
count--;
}
return *this;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::pop_back()
{
if (count)
{
lastNode = lastNode->prev;
delete lastNode->next;
lastNode->next = 0;
count--;
}
return *this;
}
template <typename Element>
Element & LinkedList<Element>::operator[](int index)
{
if (index >= 0 && index < count)
{
LinkedNode *nptr = firstNode;
for (int i = 0; i <= index; i++)
nptr = nptr->next;
return nptr->data;
}
return firstNode->data;
}
#endif
-91
View File
@@ -1,91 +0,0 @@
// cstring.c
// Author: Josh Holtrop
// Created: 02/26/04
// Modified: 06/01/04
// Implements c string functions
#include "string.h"
#include "asmfuncs.h"
char *strcat(char *dest, const char *src)
{
strcpy(dest+strlen(dest), src);
return dest;
}
//Splits a string into multiple strings by turning all characters
// equal to delim into null values (string termination character)
//Returns the number of strings after the split, 1 if no delim chars
int string_split(char *str, char delim)
{
if (strlen(str) < 1)
return 0; //empty string
int count = 1;
for (; *str; str++)
{
if (*str == delim)
{
count++;
*str = 0;
}
}
return count;
}
//Advances a char pointer to the byte after the current string's
// null-terminating character
//Useful after calling string_split()
//Returns a pointer to the following string
char *string_advance(char *str)
{
for (; *str; str++);
return str+1;
}
void rtrim(char *str)
{
str += strlen(str); //now points to the null character at the end of the string
str--;
for (;;)
{
if ((*str == ' ') || (*str == '\t') || (*str == '\n'))
*str-- = 0;
else
break;
}
}
char *ucase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'a') && (*str <= 'z'))
*str = (*str) - 32;
str++;
}
return ret;
}
char *lcase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'A') && (*str <= 'Z'))
*str = (*str) + 32;
str++;
}
return ret;
}
-19
View File
@@ -1,19 +0,0 @@
// cstring.h
// Author: Josh Holtrop
// Created: 02/26/04
// Modified: 06/01/04
// Implements c string functions
#ifndef __HOS_CSTRING__
#define __HOS_CSTRING__ __HOS_CSTRING__
char *strcat(char *dest, const char *src);
int string_split(char *str, char delim);
char *string_advance(char *str);
void rtrim(char *str);
char *ucase(char *str);
char *lcase(char *str);
#endif
-279
View File
@@ -1,279 +0,0 @@
// string.cpp
// implements c++ string object for HOS
// Author: Josh Holtrop
// Date: 06/01/04
// Modified: 06/07/04
#include "string.h" //string class declaration
#include "asmfuncs.h" //memcpy(void *dest, void *src, int n), strlen(char *str)
string::string()
{
myLength = 0;
myChars = new char; //myChars must be a valid pointer at all times
*myChars = 0;
}
string::~string()
{
delete[] myChars;
}
string::string(const string & orig)
{
myLength = orig.myLength;
myChars = new char[myLength + 1];
memcpy(myChars, orig.myChars, myLength + 1);
}
string::string(const char *cstring)
{
myLength = strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, cstring, myLength + 1);
}
string & string::operator=(const string & orig)
{
if (this != &orig)
{
delete[] myChars;
myLength = orig.myLength;
myChars = new char[myLength + 1];
memcpy(myChars, orig.myChars, myLength + 1);
}
return *this;
}
string & string::operator=(const char *cstring)
{
if (myChars != cstring)
{
delete[] myChars;
myLength = strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, cstring, myLength + 1);
}
return *this;
}
char * string::data() const { return myChars; }
int string::size() const { return myLength; }
string & string::operator+=(const string & str)
{
char *newStr = new char[myLength + str.myLength + 1];
memcpy(newStr, myChars, myLength);
memcpy(newStr + myLength, str.myChars, str.myLength + 1);
delete[] myChars;
myChars = newStr;
myLength += str.myLength;
return *this;
}
string & string::operator+=(const char *cstring)
{
char *newStr = new char[myLength + strlen(cstring) + 1];
memcpy(newStr, myChars, myLength);
memcpy(newStr + myLength, cstring, strlen(cstring) + 1);
delete[] myChars;
myChars = newStr;
myLength += strlen(cstring);
return *this;
}
string & string::operator-=(const string & str)
{
char *newStr = new char[myLength + str.myLength + 1];
memcpy(newStr, str.myChars, str.myLength);
memcpy(newStr + str.myLength, myChars, myLength + 1);
delete[] myChars;
myChars = newStr;
myLength += str.myLength;
return *this;
}
string & string::operator-=(const char *cstring)
{
char *newStr = new char[myLength + strlen(cstring) + 1];
memcpy(newStr, cstring, strlen(cstring));
memcpy(newStr + strlen(cstring), myChars, myLength + 1);
delete[] myChars;
myChars = newStr;
myLength += strlen(cstring);
return *this;
}
string & string::operator+=(char chr)
{
myLength++;
char *newStr = new char[myLength + 1];
memcpy(newStr, myChars, myLength);
newStr[myLength - 1] = chr;
newStr[myLength] = 0;
delete[] myChars;
myChars = newStr;
return *this;
}
string & string::operator-=(char chr)
{
myLength++;
char *newStr = new char[myLength + 1];
memcpy(newStr + 1, myChars, myLength);
*newStr = chr;
delete[] myChars;
myChars = newStr;
return *this;
}
string::string(const string & str1, const string & str2)
{
myLength = str1.myLength + str2.myLength;
myChars = new char[myLength + 1];
memcpy(myChars, str1.myChars, str1.myLength);
memcpy(myChars + str1.myLength, str2.myChars, str2.myLength + 1);
}
string::string(const string & str1, const char *cstring)
{
myLength = str1.myLength + strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, str1.myChars, str1.myLength);
memcpy(myChars + str1.myLength, cstring, strlen(cstring) + 1);
}
string::string(const char *cstring, const string & str)
{
myLength = str.myLength + strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, cstring, strlen(cstring));
memcpy(myChars + strlen(cstring), str.myChars, str.myLength + 1);
}
string::string(const string & str1, char chr)
{
myLength = str1.myLength + 1;
myChars = new char[myLength + 1];
memcpy(myChars, str1.myChars, myLength);
myChars[myLength - 1] = chr;
myChars[myLength] = 0;
}
string::string(char chr, const string & str1)
{
myLength = str1.myLength + 1;
myChars = new char[myLength + 1];
memcpy(myChars + 1, str1.myChars, myLength + 1);
*myChars = chr;
}
const char & string::operator[](unsigned int index) const
{
if (index < myLength)
return myChars[index];
return *myChars; //if index is invalid, return a pointer to the trailing 0
}
char & string::operator[](unsigned int index)
{
if (index < myLength)
return myChars[index];
return *myChars; //if index is invalid, return a pointer to the trailing 0
}
bool string::operator==(const string & second) const
{
if (myLength != second.myLength)
return false;
for (unsigned int i = 0; i < myLength; i++)
{
if (myChars[i] != second.myChars[i])
return false;
}
return true;
}
bool string::operator==(const char *cstring) const
{
if (myLength != strlen(cstring))
return false;
for (unsigned int i = 0; i < myLength; i++)
{
if (myChars[i] != cstring[i])
return false;
}
return true;
}
bool string::operator!=(const string & second) const
{ return !operator==(second); }
bool string::operator!=(const char *cstring) const
{ return !operator==(cstring); }
bool string::operator<(const string & second) const
{
char *c1 = myChars, *c2 = second.myChars;
while (*c1 == *c2 && *c1)
{
c1++;
c2++;
}
return *c1 < *c2;
}
bool string::operator>(const string & second) const
{
char *c1 = myChars, *c2 = second.myChars;
while (*c1 == *c2 && *c1)
{
c1++;
c2++;
}
return *c1 > *c2;
}
bool string::operator<(const char *cstring) const
{
char *c1 = myChars;
while (*c1 == *cstring && *c1)
{
c1++;
cstring++;
}
return *c1 < *cstring;
}
bool string::operator>(const char *cstring) const
{
char *c1 = myChars;
while (*c1 == *cstring && *c1)
{
c1++;
cstring++;
}
return *c1 > *cstring;
}
bool string::operator<=(const string & second) const
{ return !operator>(second); }
bool string::operator>=(const string & second) const
{ return !operator<(second); }
bool string::operator<=(const char *cstring) const
{ return operator<(cstring) || operator==(cstring); }
bool string::operator>=(const char *cstring) const
{ return operator>(cstring) || operator==(cstring); }
-145
View File
@@ -1,145 +0,0 @@
// string.h
// implements c++ string object for HOS
// Author: Josh Holtrop
// Date: 06/01/04
// Modified: 06/09/04
#ifndef __HOS_STRING__
#define __HOS_STRING__ __HOS_STRING__
class string
{
private:
/* myChars is a pointer to a character array
* It will always be a valid pointer, not null.
* The constructor is responsible for initializing
* it to point to a 1-char array with myChars[0] == 0 */
char * myChars;
/* myLength holds how many characters are in the
* string, not including the trailing null value
* (ASCII 0 character) */
unsigned int myLength;
public:
/* Basic constructors */
string();
~string();
/* Copy constructor */
string(const string & orig);
/* Construct strings from c-style strings:
* Allows declarations like string s = "data"; */
string(const char *cstring);
/* Assignment operators */
string & operator=(const string & orig);
string & operator=(const char *cstring);
/* Boolean comparison operators */
bool operator==(const string & second) const;
bool operator==(const char *cstring) const;
bool operator!=(const string & second) const;
bool operator!=(const char *cstring) const;
bool operator<(const string & second) const;
bool operator>(const string & second) const;
bool operator<(const char *cstring) const;
bool operator>(const char *cstring) const;
bool operator<=(const string & second) const;
bool operator>=(const string & second) const;
bool operator<=(const char *cstring) const;
bool operator>=(const char *cstring) const;
/* Construct strings made up of combinations of other
* strings, c-style strings, and characters */
string(const string & str1, const string & str2);
string(const string & str1, const char *cstring);
string(const char *cstring, const string & str);
string(const string & str1, char chr);
string(char chr, const string & str1);
/* Append and prepend operators */
string & operator+=(const string & str);
string & operator+=(const char *cstring);
string & operator-=(const string & str);
string & operator-=(const char *cstring);
string & operator+=(char chr);
string & operator-=(char chr);
/* Direct character-access operators */
const char & operator[](unsigned int index) const;
char & operator[](unsigned int index);
/* Returns handle to actual character-array for programs
* that need raw data instead of a string object */
char * data() const;
/* Returns the size of the string. This is myLength
* and is the number of characters in the string
* not counting the trailing null (ASCII 0) character */
int size() const;
};
static inline bool operator==(char *cstring, const string & str)
{ return str == cstring; }
static inline bool operator!=(char *cstring, const string & str)
{ return str != cstring; }
static inline bool operator<(const char *cstring, const string & str)
{ return str > cstring; }
static inline bool operator>(const char *cstring, const string & str)
{ return str < cstring; }
static inline bool operator<=(const char *cstring, const string & str)
{ return str >= cstring; }
static inline bool operator>=(const char *cstring, const string & str)
{ return str <= cstring; }
static inline string & operator+=(const char *cstring, string & str)
{ return str -= cstring; }
static inline string & operator-=(const char *cstring, string & str)
{ return str += cstring; }
static inline string & operator+=(char chr, string & str)
{ return str -= chr; }
static inline string & operator-=(char chr, string & str)
{ return str += chr; }
static inline string operator+(const string & str1, const string & str2)
{ return string(str1, str2); }
static inline string operator+(const string & str1, const char *cstring)
{ return string(str1, cstring); }
static inline string operator-(const string & str1, const string & str2)
{ return string(str2, str1); }
static inline string operator-(const string & str1, const char *cstring)
{ return string(cstring, str1); }
static inline string operator+(const string & str1, char chr)
{ return string(str1, chr); }
static inline string operator-(const string & str1, char chr)
{ return string(chr, str1); }
static inline string operator+(char chr, const string & str1)
{ return string(chr, str1); }
static inline string operator-(char chr, const string & str1)
{ return string(str1, chr); }
#endif
-26
View File
@@ -1,26 +0,0 @@
OUTPUT_FORMAT("binary")
ENTRY(_start)
SECTIONS
{
.text 0xC0106000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data : {
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}
.rodata : {
rodata = .; _rodata = .; __rodata = .;
*(.rodata)
. = ALIGN(4096);
}
.bss : {
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}
-22
View File
@@ -1,22 +0,0 @@
OUTPUT_FORMAT("pe-i386")
ENTRY(_start)
SECTIONS
{
.text 0xC0106000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data : {
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}
-422
View File
@@ -1,422 +0,0 @@
Memory Configuration
Name Origin Length Attributes
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
.text 0x00000000c0106000 0x5000
0x00000000c0106000 code = .
0x00000000c0106000 _code = .
0x00000000c0106000 __code = .
*(.text)
.text 0x00000000c0106000 0x384 ks.o
0x00000000c0106000 _start
.text 0x00000000c0106384 0x55b kernel.o
0x00000000c0106384 _k_init
0x00000000c0106694 _isr
*fill* 0x00000000c01068df 0x1 00
.text 0x00000000c01068e0 0x308 asmfuncs.o
0x00000000c01068fe _read_cr3
0x00000000c0106902 _strcmp
0x00000000c0106a11 _puts
0x00000000c0106998 _memsetd
0x00000000c01069c6 _invlpg_
0x00000000c0106a30 _putDecu
0x00000000c0106954 _memcpyd
0x00000000c010693d _memcpy
0x00000000c010696b _memset
0x00000000c01068fa _read_cr2
0x00000000c01069ce _writeCursorPosition
0x00000000c0106981 _memsetw
0x00000000c0106af8 _putDec
0x00000000c0106928 _strcpy
0x00000000c01069ae _strlen
0x00000000c01069f4 _getCursorPosition
0x00000000c01068e0 _write_cr0
0x00000000c01068ef _write_cr3
0x00000000c01068eb _read_cr0
.text 0x00000000c0106be8 0x69a keyboard.o
0x00000000c010711c _kbdGetKey
0x00000000c01071b2 _kbd_resetLEDs
0x00000000c0106be8 _isr_keyboard
0x00000000c010716e _kbdWaitKey
*fill* 0x00000000c0107282 0x2 00
.text 0x00000000c0107284 0x665 kio.o
0x00000000c0107834 _kio_drawConsoleChar
0x00000000c01073ee _putc
0x00000000c010763a _kio_console_cls
0x00000000c010752a _putHex
0x00000000c01078c2 _kio_writeCursorPosition
0x00000000c01075d6 _kio_console_scroll
0x00000000c0107694 _kio_drawConsole
0x00000000c01078b8 _kio_getCursorPosition
0x00000000c0107284 _kio_init
0x00000000c01072ae _printf
0x00000000c010759e _kio_putBCD
*fill* 0x00000000c01078e9 0x3 00
.text 0x00000000c01078ec 0x350 mm.o
0x00000000c01078ec __Z7mm_initv
0x00000000c0107ace __Z8mm_pfreej
0x00000000c0107a90 __Z9mm_pfreenjj
0x00000000c0107c28 __Z14mm_getTotalMemv
0x00000000c0107b18 __Z9mm_pallocv
0x00000000c0107bc0 __Z10mm_freememv
0x00000000c0107c32 __Z15mm_getTotalMegsv
.text 0x00000000c0107c3c 0x201 mouse.o
0x00000000c0107c3c _mouse_init
0x00000000c0107ce6 _isr_mouse
*fill* 0x00000000c0107e3d 0x3 00
.text 0x00000000c0107e40 0x8f stdfont.o
0x00000000c0107ea0 __Z17stdfont_getBitmapj
0x00000000c0107e40 __Z20stdfont_getFontWidthj
0x00000000c0107e70 __Z21stdfont_getFontHeightj
*fill* 0x00000000c0107ecf 0x1 00
.text 0x00000000c0107ed0 0x669 video.o
0x00000000c01083b0 __Z13video_psetp32ij
0x00000000c01081c4 __Z10video_vertiiij
0x00000000c01083cc __Z15video_psetpnullij
0x00000000c01080a8 __Z11video_horiziiij
0x00000000c01083e2 __Z15video_getHeightv
0x00000000c0108402 __Z20video_getPhysBasePtrv
0x00000000c0107ed0 __Z10video_initv
0x00000000c010827c __Z10video_rectiiiij
0x00000000c0108416 __Z10video_lineiiiij
0x00000000c01083d2 __Z14video_getWidthv
0x00000000c01083f2 __Z21video_getBitsPerPixelv
0x00000000c01081a8 __Z11video_psetiij
0x00000000c010831c __Z13video_psetp16ij
0x00000000c01082d4 __Z11video_rectfiiiij
0x00000000c0108150 __Z10video_psetiij
0x00000000c0108362 __Z13video_psetp24ij
0x00000000c0107fc2 __Z16video_renderChariiiijij
0x00000000c010840c __Z10video_Modev
*fill* 0x00000000c0108539 0x3 00
.text 0x00000000c010853c 0x8b8 vmm.o
0x00000000c0108ae2 __Z21vmm_addHeapEntryBlockv
0x00000000c0108ba4 __Z20vmm_getLastHeapEntryv
0x00000000c0108904 __Z21vmm_coalesceHeapEntryP9HeapEntry
0x00000000c0108d12 __Z7reallocPvj
0x00000000c0108cd6 __Z22vmm_getHeapEntryByBasej
0x00000000c0108856 __Z16vmm_getFreeChunkj
0x00000000c0108c8c __Z4freePv
0x00000000c01089ce __Z12vmm_moreCorej
0x00000000c01087e2 __Z6mallocj
0x00000000c0108c54 __Z19vmm_heapEntriesLeftv
0x00000000c010853c __Z8vmm_initv
0x00000000c0108da6 __Z6callocjj
0x00000000c0108bd4 __Z25vmm_getFirstHoleHeapEntryj
0x00000000c01085e4 __Z12vmm_heb_initP14HeapEntryBlock
0x00000000c0108ac6 __Z17vmm_nextHeapEntryv
0x00000000c0108660 __Z8vmm_map1jj
0x00000000c0108738 __Z8vmm_mapnjjj
0x00000000c01087b4 __Z10vmm_unmapnjj
0x00000000c0108772 __Z10vmm_unmap1j
0x00000000c0108c1a __Z27vmm_getFirstUnusedHeapEntryv
.text 0x00000000c0108df4 0x269 rtc.o
0x00000000c0108e1e __Z13rtc_readMonthv
0x00000000c0108ff4 __Z11rtc_setHourh
0x00000000c0108df4 __Z11rtc_readDayv
0x00000000c0108f24 __Z12rtc_setMonthh
0x00000000c0108fc0 __Z13rtc_setMinuteh
0x00000000c0108ef0 __Z10rtc_setDayh
0x00000000c0108ec6 __Z12rtc_readHourv
0x00000000c0108e48 __Z12rtc_readYearv
0x00000000c0108e72 __Z14rtc_readSecondv
0x00000000c0108f58 __Z11rtc_setYearh
0x00000000c0108e9c __Z14rtc_readMinutev
0x00000000c0108f8c __Z13rtc_setSecondh
*fill* 0x00000000c010905d 0x3 00
.text 0x00000000c0109060 0x121 pic.o
0x00000000c0109060 __Z9pic_remapii
*fill* 0x00000000c0109181 0x3 00
.text 0x00000000c0109184 0x15d cstring.o
0x00000000c01091ac __Z12string_splitPcc
0x00000000c0109184 __Z6strcatPcPKc
0x00000000c010920a __Z14string_advancePc
0x00000000c0109266 __Z5ucasePc
0x00000000c0109224 __Z5rtrimPc
0x00000000c01092a4 __Z5lcasePc
*fill* 0x00000000c01092e1 0x3 00
.text 0x00000000c01092e4 0xed9 string.o
0x00000000c01099f2 __ZN6stringC1ERKS_S1_
0x00000000c01097c6 __ZN6stringmIEPKc
0x00000000c0109474 __ZN6stringC1EPKc
0x00000000c0109d6c __ZN6stringC2EcRKS_
0x00000000c0109aec __ZN6stringC1ERKS_PKc
0x00000000c0109384 __ZN6stringC2ERKS_
0x00000000c01094c8 __ZN6stringaSERKS_
0x00000000c0109420 __ZN6stringC2EPKc
0x00000000c010a132 __ZNK6stringleEPKc
0x00000000c010a0ee __ZNK6stringleERKS_
0x00000000c01092e4 __ZN6stringC2Ev
0x00000000c0109668 __ZN6stringpLEPKc
0x00000000c010997c __ZN6stringC2ERKS_S1_
0x00000000c0109e5a __ZN6stringixEj
0x00000000c0109c84 __ZN6stringC2ERKS_c
0x00000000c01095b0 __ZNK6string4dataEv
0x00000000c0109cf8 __ZN6stringC1ERKS_c
0x00000000c0109dcc __ZN6stringC1EcRKS_
0x00000000c010a096 __ZNK6stringgtEPKc
0x00000000c0109e2c __ZNK6stringixEj
0x00000000c0109364 __ZN6stringD1Ev
0x00000000c0109ff2 __ZNK6stringgtERKS_
0x00000000c0109b70 __ZN6stringC2EPKcRKS_
0x00000000c0109724 __ZN6stringmIERKS_
0x00000000c0109ef0 __ZNK6stringeqEPKc
0x00000000c0109344 __ZN6stringD2Ev
0x00000000c0109f62 __ZNK6stringneERKS_
0x00000000c01095ba __ZNK6string4sizeEv
0x00000000c010a178 __ZNK6stringgeEPKc
0x00000000c0109a68 __ZN6stringC2ERKS_PKc
0x00000000c010a110 __ZNK6stringgeERKS_
0x00000000c010990c __ZN6stringmIEc
0x00000000c01093d2 __ZN6stringC1ERKS_
0x00000000c0109fa6 __ZNK6stringltERKS_
0x00000000c0109f84 __ZNK6stringneEPKc
0x00000000c0109bfa __ZN6stringC1EPKcRKS_
0x00000000c0109e88 __ZNK6stringeqERKS_
0x00000000c010a03e __ZNK6stringltEPKc
0x00000000c0109888 __ZN6stringpLEc
0x00000000c01095c6 __ZN6stringpLERKS_
0x00000000c0109538 __ZN6stringaSEPKc
0x00000000c0109314 __ZN6stringC1Ev
*fill* 0x00000000c010a1bd 0x3 00
.text 0x00000000c010a1c0 0xe5 cmos.o
0x00000000c010a218 __Z11cmos_gethd0v
0x00000000c010a1c0 __Z11cmos_getfd0v
0x00000000c010a1ec __Z11cmos_getfd1v
0x00000000c010a244 __Z11cmos_gethd1v
*fill* 0x00000000c010a2a5 0x3 00
.text 0x00000000c010a2a8 0x58 hos_defines.o
0x00000000c010a2d4 __ZdlPv
0x00000000c010a2be __Znaj
0x00000000c010a2a8 __Znwj
0x00000000c010a2ea __ZdaPv
.text 0x00000000c010a300 0x24d vfs.o
0x00000000c010a32e __Z4listv
0x00000000c010a3d0 __Z9vfs_mount6stringS_
0x00000000c010a300 __Z8vfs_initv
*fill* 0x00000000c010a54d 0x3 00
.text 0x00000000c010a550 0x2b7 devfs.o
0x00000000c010a550 __Z10devfs_init6string
*fill* 0x00000000c010a807 0x1 00
.text 0x00000000c010a808 0x145 Mount.o
0x00000000c010a858 __ZN5MountC2E6stringS0_
0x00000000c010a8ac __ZN5MountC1E6stringS0_
0x00000000c010a900 __ZNK5MounteqERKS_
0x00000000c010a830 __ZN5MountC1Ev
0x00000000c010a808 __ZN5MountC2Ev
0x00000000c010b000 . = ALIGN (0x1000)
*fill* 0x00000000c010a94d 0x80b2310000006b3 00
.gnu.linkonce.t._ZN10LinkedListI5MountEC1Ev
0x00000000c010b000 0x43
.gnu.linkonce.t._ZN10LinkedListI5MountEC1Ev
0x00000000c010b000 0x43 vfs.o
0x00000000c010b000 __ZN10LinkedListI5MountEC1Ev
.gnu.linkonce.t._ZN10LinkedListI5MountE5beginEv
0x00000000c010b044 0x27
.gnu.linkonce.t._ZN10LinkedListI5MountE5beginEv
0x00000000c010b044 0x27 vfs.o
0x00000000c010b044 __ZN10LinkedListI5MountE5beginEv
.gnu.linkonce.t._ZN10LinkedListI5MountE3endEv
0x00000000c010b06c 0x28
.gnu.linkonce.t._ZN10LinkedListI5MountE3endEv
0x00000000c010b06c 0x28 vfs.o
0x00000000c010b06c __ZN10LinkedListI5MountE3endEv
.gnu.linkonce.t._ZNK10LinkedListI5MountE8iteratorneERKS2_
0x00000000c010b094 0x17
.gnu.linkonce.t._ZNK10LinkedListI5MountE8iteratorneERKS2_
0x00000000c010b094 0x17 vfs.o
0x00000000c010b094 __ZNK10LinkedListI5MountE8iteratorneERKS2_
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratordeEv
0x00000000c010b0ac 0xa
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratordeEv
0x00000000c010b0ac 0xa vfs.o
0x00000000c010b0ac __ZN10LinkedListI5MountE8iteratordeEv
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorppEv
0x00000000c010b0b6 0x12
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorppEv
0x00000000c010b0b6 0x12 vfs.o
0x00000000c010b0b6 __ZN10LinkedListI5MountE8iteratorppEv
.gnu.linkonce.t._ZN10LinkedListI5MountE6insertEiS0_
0x00000000c010b0c8 0x101
.gnu.linkonce.t._ZN10LinkedListI5MountE6insertEiS0_
0x00000000c010b0c8 0x101 vfs.o
0x00000000c010b0c8 __ZN10LinkedListI5MountE6insertEiS0_
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1Ev
0x00000000c010b1ca 0x2a
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1Ev
0x00000000c010b1ca 0x2a vfs.o
0x00000000c010b1ca __ZN10LinkedListI5MountE10LinkedNodeC1Ev
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorC1EPNS1_10LinkedNodeE
0x00000000c010b1f4 0xd
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorC1EPNS1_10LinkedNodeE
0x00000000c010b1f4 0xd vfs.o
0x00000000c010b1f4 __ZN10LinkedListI5MountE8iteratorC1EPNS1_10LinkedNodeE
.gnu.linkonce.t._ZN10LinkedListI5MountE9push_backES0_
0x00000000c010b202 0x82
.gnu.linkonce.t._ZN10LinkedListI5MountE9push_backES0_
0x00000000c010b202 0x82 vfs.o
0x00000000c010b202 __ZN10LinkedListI5MountE9push_backES0_
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1ES0_
0x00000000c010b284 0x40
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1ES0_
0x00000000c010b284 0x40 vfs.o
0x00000000c010b284 __ZN10LinkedListI5MountE10LinkedNodeC1ES0_
.gnu.linkonce.t._ZN5MountaSERKS_
0x00000000c010b2c4 0x4d
.gnu.linkonce.t._ZN5MountaSERKS_
0x00000000c010b2c4 0x4d vfs.o
0x00000000c010b2c4 __ZN5MountaSERKS_
.gnu.linkonce.t._ZN5MountC1ERKS_
0x00000000c010b312 0x4a
.gnu.linkonce.t._ZN5MountC1ERKS_
0x00000000c010b312 0x4a vfs.o
0x00000000c010b312 __ZN5MountC1ERKS_
.gnu.linkonce.t._ZN5MountD1Ev
0x00000000c010b35c 0x28
.gnu.linkonce.t._ZN5MountD1Ev
0x00000000c010b35c 0x28 vfs.o
0x00000000c010b35c __ZN5MountD1Ev
.data 0x00000000c010b388 0xc78
0x00000000c010b388 data = .
0x00000000c010b388 _data = .
0x00000000c010b388 __data = .
*(.data)
.data 0x00000000c010b388 0x18 stdfont.o
0x00000000c010b388 _fonts
.data 0x00000000c010b3a0 0x10 video.o
0x00000000c010b3a0 _vid_ptr16
0x00000000c010b3ac _video_psetp
0x00000000c010b3a8 _vid_ptr32
0x00000000c010b3a4 _vid_ptr24
.data 0x00000000c010b3b0 0x4 vmm.o
0x00000000c010b3b0 _firstHeapEntry
0x00000000c010c000 . = ALIGN (0x1000)
*fill* 0x00000000c010b3b4 0x8116e3800000c4c 00
.rodata 0x00000000c010c000 0x2000
0x00000000c010c000 rodata = .
0x00000000c010c000 _rodata = .
0x00000000c010c000 __rodata = .
*(.rodata)
.rodata 0x00000000c010c000 0x141 kernel.o
*fill* 0x00000000c010c141 0x1f 00
.rodata 0x00000000c010c160 0x141 keyboard.o
*fill* 0x00000000c010c2a1 0x3 00
.rodata 0x00000000c010c2a4 0x1e4 kio.o
*fill* 0x00000000c010c488 0x18 00
.rodata 0x00000000c010c4a0 0x1200 stdfont.o
.rodata 0x00000000c010d6a0 0x7 vfs.o
.rodata 0x00000000c010d6a7 0x6d devfs.o
0x00000000c010e000 . = ALIGN (0x1000)
*fill* 0x00000000c010d714 0x8116e9c000008ec 00
.bss 0x00000000c010e000 0x22000
0x00000000c010e000 bss = .
0x00000000c010e000 _bss = .
0x00000000c010e000 __bss = .
*(.bss)
.bss 0x00000000c010e000 0x4 kernel.o
0x00000000c010e000 _timer
*fill* 0x00000000c010e004 0x4 00
*fill* 0x00000000c010e008 0x18 00
.bss 0x00000000c010e020 0x12b keyboard.o
0x00000000c010e040 _kbdBuffer
0x00000000c010e148 _kbdExt
0x00000000c010e021 _kbdAscii
0x00000000c010e149 _kbdExt2
0x00000000c010e14a _ackReason
0x00000000c010e140 _kbdBufferStart
0x00000000c010e022 _kbdScan
0x00000000c010e144 _kbdBufferLen
0x00000000c010e020 _kbdFlags
*fill* 0x00000000c010e14b 0x15 00
.bss 0x00000000c010e160 0xfc0 kio.o
0x00000000c010e180 _console_memory
0x00000000c010e160 _graphical
0x00000000c010e164 _cursorPosition
.bss 0x00000000c010f120 0x20020 mm.o
0x00000000c010f124 _mm_megabytes
0x00000000c010f140 _page_bitmap
0x00000000c010f120 _mm_totalmem
.bss 0x00000000c012f140 0x1c mouse.o
0x00000000c012f144 _mouse_y
0x00000000c012f148 _mouse_bytesRead
0x00000000c012f140 _mouse_x
0x00000000c012f14c _mouse_inbuffer
*fill* 0x00000000c012f15c 0x4 00
.bss 0x00000000c012f160 0x104 video.o
0x00000000c012f160 _video_mode
0x00000000c012f260 _videoMode
.bss 0x00000000c012f264 0x4 vfs.o
0x00000000c012f264 _mounts
0x00000000c0130000 . = ALIGN (0x1000)
*fill* 0x00000000c012f268 0x8116ff000000d98 00
0x00000000c0130000 end = .
0x00000000c0130000 _end = .
0x00000000c0130000 __end = .
LOAD ks.o
LOAD kernel.o
LOAD asmfuncs.o
LOAD fdc.o
LOAD keyboard.o
LOAD kio.o
LOAD mm.o
LOAD mouse.o
LOAD stdfont.o
LOAD video.o
LOAD vmm.o
LOAD rtc.o
LOAD pic.o
LOAD io.o
LOAD cstring.o
LOAD string.o
LOAD cmos.o
LOAD hos_defines.o
LOAD vfs.o
LOAD devfs.o
LOAD Mount.o
OUTPUT(kernel.bin binary)
.note.GNU-stack
0x0000000000000000 0x0
.comment 0x0000000000000000 0x3c9
.comment 0x0000000000000000 0x33 kernel.o
.comment 0x0000000000000033 0x33 fdc.o
.comment 0x0000000000000066 0x33 keyboard.o
.comment 0x0000000000000099 0x33 kio.o
.comment 0x00000000000000cc 0x33 mm.o
.comment 0x00000000000000ff 0x33 mouse.o
.comment 0x0000000000000132 0x33 stdfont.o
.comment 0x0000000000000165 0x33 video.o
.comment 0x0000000000000198 0x33 vmm.o
.comment 0x00000000000001cb 0x33 rtc.o
.comment 0x00000000000001fe 0x33 pic.o
.comment 0x0000000000000231 0x33 io.o
.comment 0x0000000000000264 0x33 cstring.o
.comment 0x0000000000000297 0x33 string.o
.comment 0x00000000000002ca 0x33 cmos.o
.comment 0x00000000000002fd 0x33 hos_defines.o
.comment 0x0000000000000330 0x33 vfs.o
.comment 0x0000000000000363 0x33 devfs.o
.comment 0x0000000000000396 0x33 Mount.o
-510
View File
@@ -1,510 +0,0 @@
1 ; asmfuncs.asm
2 ; Josh Holtrop
3 ; Created: 10/23/03
4 ; Modified: 02/26/04
5
6 [extern _putc]
7 [extern _console_memory]
8 [extern _cursorPosition]
9 [extern _video_drawConsole]
10 [extern _videoMode]
11
12 %macro jzfar 1
13 jnz %%skip
14 jmp %1
15 %%skip:
16
17 %endmacro
18
19 ;stores the parameter to the CR0 register
20 ;extern dword write_cr0(dword cr0);
21 [global _write_cr0]
22 _write_cr0:
23 00000000 55 push ebp
24 00000001 89E5 mov ebp, esp
25 00000003 8B4508 mov eax, [ebp+8]
26 00000006 0F22C0 mov cr0, eax
27 00000009 5D pop ebp
28 0000000A C3 ret
29
30 ;returns the value in the CR0 register
31 ;extern dword read_cr0();
32 [global _read_cr0]
33 _read_cr0:
34 0000000B 0F20C0 mov eax, cr0;
35 0000000E C3 ret
36
37 ;stores the parameter to the CR3 register
38 ;extern dword write_cr3(dword cr3);
39 [global _write_cr3]
40 _write_cr3:
41 0000000F 55 push ebp
42 00000010 89E5 mov ebp, esp
43 00000012 8B4508 mov eax, [ebp+8]
44 00000015 0F22D8 mov cr3, eax
45 00000018 5D pop ebp
46 00000019 C3 ret
47
48
49 ;returns the value in the CR2 register
50 ;extern dword read_cr2();
51 [global _read_cr2]
52 _read_cr2:
53 0000001A 0F20D0 mov eax, cr2;
54 0000001D C3 ret
55
56
57
58 ;returns the value in the CR3 register
59 ;extern dword read_cr3();
60 [global _read_cr3]
61 _read_cr3:
62 0000001E 0F20D8 mov eax, cr3;
63 00000021 C3 ret
64
65
66 ;compares one string to another
67 ;returns 0 if the strings are different
68 ;extern dword strcmp(char *str1, char *str2);
69 [global _strcmp]
70 _strcmp:
71 00000022 55 push ebp
72 00000023 89E5 mov ebp, esp
73 00000025 56 push esi
74 00000026 57 push edi
75
76 00000027 8B7508 mov esi, [ebp+8]
77 0000002A 8B7D0C mov edi, [ebp+12]
78 strcmp_loop1:
79 0000002D AC lodsb
80 0000002E 8A27 mov ah, [edi]
81 00000030 47 inc edi
82 00000031 38C4 cmp ah, al
83 00000033 750D jnz strcmp_ne
84 00000035 08C0 or al, al
85 00000037 7402 jz strcmp_e
86 00000039 EBF2 jmp strcmp_loop1
87 strcmp_e:
88 0000003B B801000000 mov eax, 1
89 00000040 EB02 jmp short strcmp_done
90 strcmp_ne:
91 00000042 31C0 xor eax, eax
92 strcmp_done:
93
94 00000044 5F pop edi
95 00000045 5E pop esi
96 00000046 5D pop ebp
97 00000047 C3 ret
98
99 ;copies a string from the source to the destination parameter
100 ;extern void strcpy(char *dest, char *src);
101 [global _strcpy]
102 _strcpy:
103 00000048 55 push ebp
104 00000049 89E5 mov ebp, esp
105 0000004B 56 push esi
106 0000004C 57 push edi
107 0000004D 8B7D08 mov edi, [ebp+8]
108 00000050 8B750C mov esi, [ebp+12]
109 strcpyloop:
110 00000053 AC lodsb
111 00000054 AA stosb
112 00000055 08C0 or al, al
113 00000057 75FA jnz strcpyloop
114 00000059 5F pop edi
115 0000005A 5E pop esi
116 0000005B 5D pop ebp
117 0000005C C3 ret
118
119 ;copies memory of n bytes from src to destination
120 ;void memcpy(void *dest, void *src, dword n);
121 [global _memcpy]
122 _memcpy:
123 0000005D 55 push ebp
124 0000005E 89E5 mov ebp, esp
125 00000060 56 push esi
126 00000061 57 push edi
127 00000062 51 push ecx
128 00000063 8B7D08 mov edi, [ebp+8]
129 00000066 8B750C mov esi, [ebp+12]
130 00000069 8B4D10 mov ecx, [ebp+16]
131
132 0000006C FC cld
133 0000006D F3A4 rep movsb
134
135 0000006F 59 pop ecx
136 00000070 5F pop edi
137 00000071 5E pop esi
138 00000072 5D pop ebp
139 00000073 C3 ret
140
141
142 ;copies memory of n dwords (n*4 bytes) from src to destination
143 ;void memcpyd(void *dest, void *src, dword n);
144 [global _memcpyd]
145 _memcpyd:
146 00000074 55 push ebp
147 00000075 89E5 mov ebp, esp
148 00000077 56 push esi
149 00000078 57 push edi
150 00000079 51 push ecx
151 0000007A 8B7D08 mov edi, [ebp+8]
152 0000007D 8B750C mov esi, [ebp+12]
153 00000080 8B4D10 mov ecx, [ebp+16]
154
155 00000083 FC cld
156 00000084 F3A5 rep movsd
157
158 00000086 59 pop ecx
159 00000087 5F pop edi
160 00000088 5E pop esi
161 00000089 5D pop ebp
162 0000008A C3 ret
163
164
165 ;sets num bytes at buffer to the value of c
166 ;void *memset(void *buffer, int c, int num);
167 [global _memset]
168 _memset:
169 0000008B 55 push ebp
170 0000008C 89E5 mov ebp, esp
171 0000008E 57 push edi
172 0000008F 51 push ecx
173 00000090 8B7D08 mov edi, [ebp+8]
174 00000093 57 push edi ;save for return address
175 00000094 8B450C mov eax, [ebp+12]
176 00000097 8B4D10 mov ecx, [ebp+16]
177
178 0000009A F3AA rep stosb
179
180 0000009C 58 pop eax
181 0000009D 59 pop ecx
182 0000009E 5F pop edi
183 0000009F 5D pop ebp
184 000000A0 C3 ret
185
186
187 ;sets num words at buffer to the value of c
188 ;void *memsetw(void *buffer, int c, int num);
189 [global _memsetw]
190 _memsetw:
191 000000A1 55 push ebp
192 000000A2 89E5 mov ebp, esp
193 000000A4 57 push edi
194 000000A5 51 push ecx
195 000000A6 8B7D08 mov edi, [ebp+8]
196 000000A9 57 push edi ;save for return address
197 000000AA 8B450C mov eax, [ebp+12]
198 000000AD 8B4D10 mov ecx, [ebp+16]
199
200 000000B0 F366AB rep stosw
201
202 000000B3 58 pop eax
203 000000B4 59 pop ecx
204 000000B5 5F pop edi
205 000000B6 5D pop ebp
206 000000B7 C3 ret
207
208
209 ;sets num dwords at buffer to the value of c
210 ;void *memsetd(void *buffer, int c, int num);
211 [global _memsetd]
212 _memsetd:
213 000000B8 55 push ebp
214 000000B9 89E5 mov ebp, esp
215 000000BB 57 push edi
216 000000BC 51 push ecx
217 000000BD 8B7D08 mov edi, [ebp+8]
218 000000C0 57 push edi ;save for return address
219 000000C1 8B450C mov eax, [ebp+12]
220 000000C4 8B4D10 mov ecx, [ebp+16]
221
222 000000C7 F3AB rep stosd
223
224 000000C9 58 pop eax
225 000000CA 59 pop ecx
226 000000CB 5F pop edi
227 000000CC 5D pop ebp
228 000000CD C3 ret
229
230
231 ;returns the number of characters in a string
232 ;extern dword strlen(char *str);
233 [global _strlen]
234 _strlen:
235 000000CE 55 push ebp
236 000000CF 89E5 mov ebp, esp
237 000000D1 56 push esi
238 000000D2 53 push ebx
239 000000D3 8B7508 mov esi, [ebp+8]
240 000000D6 31DB xor ebx, ebx
241 strlenloop:
242 000000D8 AC lodsb
243 000000D9 08C0 or al, al
244 000000DB 7403 jz strlendone
245 000000DD 43 inc ebx
246 000000DE EBF8 jmp strlenloop
247 strlendone:
248 000000E0 89D8 mov eax, ebx
249 000000E2 5B pop ebx
250 000000E3 5E pop esi
251 000000E4 5D pop ebp
252 000000E5 C3 ret
253
254 ;this function invalidates the page directory/table entry that
255 ; would be used to access the memory address given in the parameter
256 ;extern void invlpg_(dword addr);
257 [global _invlpg_]
258 _invlpg_:
259 000000E6 8B442404 mov eax, [esp+4]
260 000000EA 0F0138 invlpg [eax]
261 000000ED C3 ret
262
263
264 ;
265 ;void writeCursorPosition(word pos)
266 ;
267 [global _writeCursorPosition]
268 _writeCursorPosition:
269 000000EE 55 push ebp
270 000000EF 89E5 mov ebp, esp
271
272 000000F1 50 push eax
273 000000F2 53 push ebx
274 000000F3 52 push edx
275
276 000000F4 8B4508 mov eax, [ebp+8] ;cursor position in ax
277
278 000000F7 88C3 mov bl, al
279 000000F9 66BAD403 mov dx, 0x03D4
280 000000FD B00E mov al, 0x0E
281 000000FF EE out dx, al
282
283 00000100 6642 inc dx
284 00000102 88E0 mov al, ah
285 00000104 EE out dx, al
286
287 00000105 664A dec dx
288 00000107 B00F mov al, 0x0F
289 00000109 EE out dx, al
290
291 0000010A 6642 inc dx
292 0000010C 88D8 mov al, bl
293 0000010E EE out dx, al
294
295 0000010F 5A pop edx
296 00000110 5B pop ebx
297 00000111 58 pop eax
298 00000112 5D pop ebp
299
300 00000113 C3 ret
301
302
303 ;
304 ;word getCursorPosition()
305 ;
306 [global _getCursorPosition]
307 _getCursorPosition:
308 00000114 53 push ebx
309 00000115 52 push edx
310
311 00000116 31C0 xor eax, eax
312 00000118 66BAD403 mov dx, 0x03D4
313 0000011C B00E mov al, 0x0E
314 0000011E EE out dx, al
315
316 0000011F 6642 inc dx
317 00000121 EC in al, dx
318 00000122 88C3 mov bl, al
319
320 00000124 664A dec dx
321 00000126 B00F mov al, 0x0F
322 00000128 EE out dx, al
323
324 00000129 6642 inc dx
325 0000012B EC in al, dx
326 0000012C 88DC mov ah, bl
327
328 0000012E 5A pop edx
329 0000012F 5B pop ebx
330
331 00000130 C3 ret
332
333
334 ;
335 ;int puts(char *str)
336 ;
337 [global _puts]
338 _puts:
339 00000131 55 push ebp
340 00000132 89E5 mov ebp, esp
341 00000134 56 push esi
342 00000135 50 push eax
343 00000136 8B7508 mov esi, [ebp+8] ;esi = to string
344 puts_loop:
345 00000139 AC lodsb
346 0000013A 3C00 cmp al, 0
347 0000013C 740E jz puts_done
348 0000013E 50 push eax
349 0000013F E8(00000000) call _putc
350 00000144 81C404000000 add esp, 4
351 0000014A EBED jmp puts_loop
352
353 puts_done:
354 0000014C 58 pop eax
355 0000014D 5E pop esi
356 0000014E 5D pop ebp
357 0000014F C3 ret
358
359
360
361
362 [global _putDecu]
363 _putDecu:
364 00000150 55 push ebp
365 00000151 89E5 mov ebp, esp
366 00000153 81EC18000000 sub esp, 24
367 00000159 C745FC01000000 mov DWORD [ebp-4], 1
368 00000160 C645FB00 mov BYTE [ebp-5], 0
369 L2:
370 00000164 8B5508 mov edx, DWORD [ebp+8]
371 00000167 B8CDCCCCCC mov eax, -858993459
372 0000016C F7E2 mul edx
373 0000016E 89D0 mov eax, edx
374 00000170 C1E803 shr eax, 3
375 00000173 3B45FC cmp eax, DWORD [ebp-4]
376 00000176 7305 jae L4
377 00000178 E912000000 jmp L3
378 L4:
379 0000017D 8B45FC mov eax, DWORD [ebp-4]
380 00000180 89C2 mov edx, eax
381 00000182 C1E202 sal edx, 2
382 00000185 01C2 add edx, eax
383 00000187 8D0412 lea eax, [edx+edx]
384 0000018A 8945FC mov DWORD [ebp-4], eax
385 0000018D EBD5 jmp L2
386 L3:
387 0000018F 90 nop
388 L5:
389 00000190 817DFC01000000 cmp DWORD [ebp-4], 1
390 00000197 7705 ja L7
391 00000199 E959000000 jmp L6
392 L7:
393 0000019E 8B5508 mov edx, DWORD [ebp+8]
394 000001A1 89D0 mov eax, edx
395 000001A3 BA00000000 mov edx, 0
396 000001A8 F775FC div DWORD [ebp-4]
397 000001AB 8945F4 mov DWORD [ebp-12], eax
398 000001AE 8A45F4 mov al, BYTE [ebp-12]
399 000001B1 8845FB mov BYTE [ebp-5], al
400 000001B4 B800000000 mov eax, 0
401 000001B9 8A45FB mov al, BYTE [ebp-5]
402 000001BC 0FAF45FC imul eax, DWORD [ebp-4]
403 000001C0 294508 sub DWORD [ebp+8], eax
404 000001C3 8B55FC mov edx, DWORD [ebp-4]
405 000001C6 B8CDCCCCCC mov eax, -858993459
406 000001CB F7E2 mul edx
407 000001CD 89D0 mov eax, edx
408 000001CF C1E803 shr eax, 3
409 000001D2 8945FC mov DWORD [ebp-4], eax
410 000001D5 8D45FB lea eax, [ebp-5]
411 000001D8 800030 add BYTE [eax], 48
412 000001DB 81EC0C000000 sub esp, 12
413 000001E1 B800000000 mov eax, 0
414 000001E6 8A45FB mov al, BYTE [ebp-5]
415 000001E9 50 push eax
416 000001EA E8(00000000) call _putc
417 000001EF 81C410000000 add esp, 16
418 000001F5 EB99 jmp L5
419 L6:
420 000001F7 81EC0C000000 sub esp, 12
421 000001FD 8A4508 mov al, BYTE [ebp+8]
422 00000200 0530000000 add eax, 48
423 00000205 25FF000000 and eax, 255
424 0000020A 50 push eax
425 0000020B E8(00000000) call _putc
426 00000210 81C410000000 add esp, 16
427 00000216 C9 leave
428 00000217 C3 ret
429
430
431
432
433 [global _putDec]
434 _putDec:
435 00000218 55 push ebp
436 00000219 89E5 mov ebp, esp
437 0000021B 81EC18000000 sub esp, 24
438 00000221 817D0800000000 cmp DWORD [ebp+8], 0
439 00000228 7919 jns L9
440 0000022A 81EC0C000000 sub esp, 12
441 00000230 682D000000 push 45
442 00000235 E8(00000000) call _putc
443 0000023A 81C410000000 add esp, 16
444 00000240 F75D08 neg DWORD [ebp+8]
445 L9:
446 00000243 C745FC01000000 mov DWORD [ebp-4], 1
447 0000024A C645FB00 mov BYTE [ebp-5], 0
448 L10:
449 0000024E 8B4508 mov eax, DWORD [ebp+8]
450 00000251 3B45FC cmp eax, DWORD [ebp-4]
451 00000254 7305 jae L12
452 00000256 E912000000 jmp L11
453 L12:
454 0000025B 8B45FC mov eax, DWORD [ebp-4]
455 0000025E 89C2 mov edx, eax
456 00000260 C1E202 sal edx, 2
457 00000263 01C2 add edx, eax
458 00000265 8D0412 lea eax, [edx+edx]
459 00000268 8945FC mov DWORD [ebp-4], eax
460 0000026B EBE1 jmp L10
461 L11:
462 0000026D 8B55FC mov edx, DWORD [ebp-4]
463 00000270 B8CDCCCCCC mov eax, -858993459
464 00000275 F7E2 mul edx
465 00000277 89D0 mov eax, edx
466 00000279 C1E803 shr eax, 3
467 0000027C 8945FC mov DWORD [ebp-4], eax
468 L13:
469 0000027F 817DFC01000000 cmp DWORD [ebp-4], 1
470 00000286 7705 ja L15
471 00000288 E959000000 jmp L14
472 L15:
473 0000028D 8B5508 mov edx, DWORD [ebp+8]
474 00000290 89D0 mov eax, edx
475 00000292 BA00000000 mov edx, 0
476 00000297 F775FC div DWORD [ebp-4]
477 0000029A 8945F4 mov DWORD [ebp-12], eax
478 0000029D 8A45F4 mov al, BYTE [ebp-12]
479 000002A0 8845FB mov BYTE [ebp-5], al
480 000002A3 B800000000 mov eax, 0
481 000002A8 8A45FB mov al, BYTE [ebp-5]
482 000002AB 0FAF45FC imul eax, DWORD [ebp-4]
483 000002AF 294508 sub DWORD [ebp+8], eax
484 000002B2 8B55FC mov edx, DWORD [ebp-4]
485 000002B5 B8CDCCCCCC mov eax, -858993459
486 000002BA F7E2 mul edx
487 000002BC 89D0 mov eax, edx
488 000002BE C1E803 shr eax, 3
489 000002C1 8945FC mov DWORD [ebp-4], eax
490 000002C4 8D45FB lea eax, [ebp-5]
491 000002C7 800030 add BYTE [eax], 48
492 000002CA 81EC0C000000 sub esp, 12
493 000002D0 B800000000 mov eax, 0
494 000002D5 8A45FB mov al, BYTE [ebp-5]
495 000002D8 50 push eax
496 000002D9 E8(00000000) call _putc
497 000002DE 81C410000000 add esp, 16
498 000002E4 EB99 jmp L13
499 L14:
500 000002E6 81EC0C000000 sub esp, 12
501 000002EC 8A4508 mov al, BYTE [ebp+8]
502 000002EF 0530000000 add eax, 48
503 000002F4 25FF000000 and eax, 255
504 000002F9 50 push eax
505 000002FA E8(00000000) call _putc
506 000002FF 81C410000000 add esp, 16
507 00000305 C9 leave
508 00000306 C3 ret
509
510
-492
View File
@@ -1,492 +0,0 @@
1 ;kernel.asm
2 ;Author: Josh Holtrop
3 ;Date: 10/30/03
4 ;Modified: 10/30/03
5
6 %define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space
7 %define GDT_V GDT_P+0xC0000000
8 %define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space
9 %define IDT_V IDT_P+0xC0000000
10 %define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD)
11 %define PDBR_V PDBR_P+0xC0000000
12 %define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb
13 %define LOPT_V LOPT_P+0xC0000000
14 %define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address
15 %define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel
16
17 [global _start]
18 [extern _isr]
19 [extern _k_init]
20 [extern _putc]
21
22 bits 32
23
24 ;This is where the kernel begins execution
25 ;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0.
26 ;We must enable paging with the first 4mb mapped 1:1 virtual:physical
27 ; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical.
28 ;Then we can start using our "real" gdt, then unmap the lower 4mb.
29 _start:
30 00000000 FA cli ;if they weren't already off
31
32 00000001 31C0 xor eax, eax
33 00000003 BF004010C0 mov edi, PDBR_V
34 00000008 B900040000 mov ecx, 1024 ;clear the PDBR
35 0000000D F3AB rep stosd
36 0000000F C705004010C0035010- mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
37 00000018 00
38 00000019 C705004C10C0035010- mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
39 00000022 00
40
41 00000023 BF005010C0 mov edi, LOPT_V
42 00000028 B900040000 mov ecx, 1024
43 0000002D B803000000 mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags)
44 fill_lopt_loop: ;fill the page table
45 00000032 AB stosd
46 00000033 0500100000 add eax, 4096 ;increment next phsyical address by 4kb
47 00000038 E2F8 loop fill_lopt_loop
48
49 0000003A B800401000 mov eax, PDBR_P
50 0000003F 0F22D8 mov cr3, eax ;store the Page Directory Base Address
51 00000042 0F20C0 mov eax, cr0
52 00000045 0D00000080 or eax, 0x80000000 ;set page enable bit
53 0000004A 0F22C0 mov cr0, eax ;now paging is active!
54
55
56 0000004D BF000010C0 mov edi, GDT_V
57 00000052 BE[D4000000] mov esi, gdt
58 00000057 B948000000 mov ecx, gdt_end-gdt
59 copy_gdt:
60 0000005C AC lodsb
61 0000005D AA stosb
62 0000005E E2FC loop copy_gdt
63
64 00000060 BF002010C0 mov edi, IDT_V ;destination
65 00000065 BE[22010000] mov esi, isr_0 ;address of isr0
66 0000006A BA0B000000 mov edx, isr_1-isr_0 ;distance between isr labels
67 0000006F B932000000 mov ecx, 50 ;number of isrlabels
68 fill_idt:
69 00000074 89F3 mov ebx, esi
70 00000076 6689F0 mov ax, si
71 00000079 66AB stosw ;0 offset 15:0
72 0000007B 66B80800 mov ax, KERNEL_CODE
73 0000007F 66AB stosw ;2 selector 15:0
74 00000081 66B8008E mov ax, 0x8E00
75 00000085 66AB stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0]
76 00000087 C1EE10 shr esi, 16
77 0000008A 6689F0 mov ax, si
78 0000008D 66AB stosw ;6 offset 31:16
79 0000008F 89DE mov esi, ebx
80 00000091 01D6 add esi, edx
81 00000093 E2DF loop fill_idt
82 00000095 66C705842110C000EE mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
83
84 0000009E 0F0115[CE000000] lgdt [gdtr] ;load gdt
85 000000A5 EA[AC000000]0800 jmp KERNEL_CODE:newgdtcontinue
86 newgdtcontinue:
87 000000AC 66B81000 mov ax, KERNEL_DATA
88 000000B0 8EC0 mov es, ax
89 000000B2 8ED8 mov ds, ax
90 000000B4 8EE8 mov gs, ax
91 000000B6 8EE0 mov fs, ax
92 000000B8 8ED0 mov ss, ax
93 000000BA BC000020C0 mov esp, 0xc0200000 ;stack just under 3gb+2mb, moves downward
94 000000BF 0F011D[1C010000] lidt [idtr] ;load idt
95
96 000000C6 E8(00000000) call _k_init
97 haltit:
98 000000CB F4 hlt ;halt processor when k_init is done
99 000000CC EBFD jmp haltit ;shouldn't get here...
100
101 %include "gdt.inc"
102 <1> ;gdt.inc
103 <1> ;Author: Josh Holtrop
104 <1> ;Date: 10/30/03
105 <1> ;Modified: 03/02/04
106 <1>
107 <1> gdtr:
108 000000CE 4700 <1> dw gdt_end-gdt-1
109 000000D0 000010C0 <1> dd GDT_V
110 <1> gdt:
111 000000D4 00000000 <1> dd 0
112 000000D8 00000000 <1> dd 0
113 <1> KERNEL_CODE equ $-gdt
114 000000DC FFFF <1> dw 0xffff ;limit 15:0
115 000000DE 0000 <1> dw 0x0000 ;base 15:0
116 000000E0 00 <1> db 0x00 ;base 23:16
117 000000E1 9A <1> db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
118 000000E2 CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
119 000000E3 00 <1> db 0x00 ;base 31:24
120 <1> KERNEL_DATA equ $-gdt
121 000000E4 FFFF <1> dw 0xffff ;limit 15:0
122 000000E6 0000 <1> dw 0x0000 ;base 15:0
123 000000E8 00 <1> db 0x00 ;base 23:16
124 000000E9 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
125 000000EA CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
126 000000EB 00 <1> db 0x00 ;base 31:24
127 <1> USER_CODE equ $-gdt
128 000000EC FFFF <1> dw 0xffff ;limit 15:0
129 000000EE 0000 <1> dw 0x0000 ;base 15:0
130 000000F0 00 <1> db 0x00 ;base 23:16
131 000000F1 FA <1> db 0xFA ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
132 000000F2 CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
133 000000F3 00 <1> db 0x00 ;base 31:24
134 <1> USER_DATA equ $-gdt
135 000000F4 FFFF <1> dw 0xffff ;limit 15:0
136 000000F6 0000 <1> dw 0x0000 ;base 15:0
137 000000F8 00 <1> db 0x00 ;base 23:16
138 000000F9 F2 <1> db 0xF2 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
139 000000FA CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
140 000000FB 00 <1> db 0x00 ;base 31:24
141 <1> gVESA_CODE equ $-gdt
142 000000FC FFFF <1> dw 0xffff ;limit 15:0
143 000000FE 0000 <1> dw 0x0000 ;base 15:0
144 00000100 00 <1> db 0x00 ;base 23:16
145 00000101 9A <1> db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
146 00000102 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
147 00000103 00 <1> db 0x00 ;base 31:24
148 <1> VESA_DATA equ $-gdt
149 00000104 FFFF <1> dw 0xffff ;limit 15:0
150 00000106 0000 <1> dw 0x0000 ;base 15:0
151 00000108 00 <1> db 0x00 ;base 23:16
152 00000109 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
153 0000010A 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
154 0000010B 00 <1> db 0x00 ;base 31:24
155 <1> VIDEO_TEXT equ $-gdt
156 0000010C FF7F <1> dw 0x7FFF ;limit 15:0
157 0000010E 0080 <1> dw 0x8000 ;base 15:0
158 00000110 0B <1> db 0x0B ;base 23:16
159 00000111 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
160 00000112 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
161 00000113 00 <1> db 0x00 ;base 31:24
162 <1> VIDEO_GRAPHICS equ $-gdt
163 00000114 FFFF <1> dw 0xFFFF ;limit 15:0
164 00000116 0000 <1> dw 0x0000 ;base 15:0
165 00000118 0A <1> db 0x0A ;base 23:16
166 00000119 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
167 0000011A 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
168 0000011B 00 <1> db 0x00 ;base 31:24
169 <1> gdt_end:
170 <1>
171 <1>
172 <1>
173 %include "idt.inc"
174 <1> ;idt.inc
175 <1> ;Author: Josh Holtrop
176 <1> ;Date: 10/30/03
177 <1> ;Modified: 03/02/04
178 <1>
179 <1> idtr:
180 0000011C 8F01 <1> dw 50*8-1 ;size of idt
181 0000011E 002010C0 <1> dd IDT_V ;address of idt
182 <1>
183 <1>
184 <1> %macro isr_label 1
185 <1> isr_%1:
186 <1> push eax
187 <1> mov eax, %1
188 <1> jmp isr_main
189 <1> %endmacro
190 <1>
191 <1> isr_label 0
192 <2> isr_%1:
193 00000122 50 <2> push eax
194 00000123 B800000000 <2> mov eax, %1
195 00000128 E91B020000 <2> jmp isr_main
196 <1> isr_label 1
197 <2> isr_%1:
198 0000012D 50 <2> push eax
199 0000012E B801000000 <2> mov eax, %1
200 00000133 E910020000 <2> jmp isr_main
201 <1> isr_label 2
202 <2> isr_%1:
203 00000138 50 <2> push eax
204 00000139 B802000000 <2> mov eax, %1
205 0000013E E905020000 <2> jmp isr_main
206 <1> isr_label 3
207 <2> isr_%1:
208 00000143 50 <2> push eax
209 00000144 B803000000 <2> mov eax, %1
210 00000149 E9FA010000 <2> jmp isr_main
211 <1> isr_label 4
212 <2> isr_%1:
213 0000014E 50 <2> push eax
214 0000014F B804000000 <2> mov eax, %1
215 00000154 E9EF010000 <2> jmp isr_main
216 <1> isr_label 5
217 <2> isr_%1:
218 00000159 50 <2> push eax
219 0000015A B805000000 <2> mov eax, %1
220 0000015F E9E4010000 <2> jmp isr_main
221 <1> isr_label 6
222 <2> isr_%1:
223 00000164 50 <2> push eax
224 00000165 B806000000 <2> mov eax, %1
225 0000016A E9D9010000 <2> jmp isr_main
226 <1> isr_label 7
227 <2> isr_%1:
228 0000016F 50 <2> push eax
229 00000170 B807000000 <2> mov eax, %1
230 00000175 E9CE010000 <2> jmp isr_main
231 <1> isr_label 8
232 <2> isr_%1:
233 0000017A 50 <2> push eax
234 0000017B B808000000 <2> mov eax, %1
235 00000180 E9C3010000 <2> jmp isr_main
236 <1> isr_label 9
237 <2> isr_%1:
238 00000185 50 <2> push eax
239 00000186 B809000000 <2> mov eax, %1
240 0000018B E9B8010000 <2> jmp isr_main
241 <1> isr_label 10
242 <2> isr_%1:
243 00000190 50 <2> push eax
244 00000191 B80A000000 <2> mov eax, %1
245 00000196 E9AD010000 <2> jmp isr_main
246 <1> isr_label 11
247 <2> isr_%1:
248 0000019B 50 <2> push eax
249 0000019C B80B000000 <2> mov eax, %1
250 000001A1 E9A2010000 <2> jmp isr_main
251 <1> isr_label 12
252 <2> isr_%1:
253 000001A6 50 <2> push eax
254 000001A7 B80C000000 <2> mov eax, %1
255 000001AC E997010000 <2> jmp isr_main
256 <1> isr_label 13
257 <2> isr_%1:
258 000001B1 50 <2> push eax
259 000001B2 B80D000000 <2> mov eax, %1
260 000001B7 E98C010000 <2> jmp isr_main
261 <1> isr_label 14
262 <2> isr_%1:
263 000001BC 50 <2> push eax
264 000001BD B80E000000 <2> mov eax, %1
265 000001C2 E981010000 <2> jmp isr_main
266 <1> isr_label 15
267 <2> isr_%1:
268 000001C7 50 <2> push eax
269 000001C8 B80F000000 <2> mov eax, %1
270 000001CD E976010000 <2> jmp isr_main
271 <1> isr_label 16
272 <2> isr_%1:
273 000001D2 50 <2> push eax
274 000001D3 B810000000 <2> mov eax, %1
275 000001D8 E96B010000 <2> jmp isr_main
276 <1> isr_label 17
277 <2> isr_%1:
278 000001DD 50 <2> push eax
279 000001DE B811000000 <2> mov eax, %1
280 000001E3 E960010000 <2> jmp isr_main
281 <1> isr_label 18
282 <2> isr_%1:
283 000001E8 50 <2> push eax
284 000001E9 B812000000 <2> mov eax, %1
285 000001EE E955010000 <2> jmp isr_main
286 <1> isr_label 19
287 <2> isr_%1:
288 000001F3 50 <2> push eax
289 000001F4 B813000000 <2> mov eax, %1
290 000001F9 E94A010000 <2> jmp isr_main
291 <1> isr_label 20
292 <2> isr_%1:
293 000001FE 50 <2> push eax
294 000001FF B814000000 <2> mov eax, %1
295 00000204 E93F010000 <2> jmp isr_main
296 <1> isr_label 21
297 <2> isr_%1:
298 00000209 50 <2> push eax
299 0000020A B815000000 <2> mov eax, %1
300 0000020F E934010000 <2> jmp isr_main
301 <1> isr_label 22
302 <2> isr_%1:
303 00000214 50 <2> push eax
304 00000215 B816000000 <2> mov eax, %1
305 0000021A E929010000 <2> jmp isr_main
306 <1> isr_label 23
307 <2> isr_%1:
308 0000021F 50 <2> push eax
309 00000220 B817000000 <2> mov eax, %1
310 00000225 E91E010000 <2> jmp isr_main
311 <1> isr_label 24
312 <2> isr_%1:
313 0000022A 50 <2> push eax
314 0000022B B818000000 <2> mov eax, %1
315 00000230 E913010000 <2> jmp isr_main
316 <1> isr_label 25
317 <2> isr_%1:
318 00000235 50 <2> push eax
319 00000236 B819000000 <2> mov eax, %1
320 0000023B E908010000 <2> jmp isr_main
321 <1> isr_label 26
322 <2> isr_%1:
323 00000240 50 <2> push eax
324 00000241 B81A000000 <2> mov eax, %1
325 00000246 E9FD000000 <2> jmp isr_main
326 <1> isr_label 27
327 <2> isr_%1:
328 0000024B 50 <2> push eax
329 0000024C B81B000000 <2> mov eax, %1
330 00000251 E9F2000000 <2> jmp isr_main
331 <1> isr_label 28
332 <2> isr_%1:
333 00000256 50 <2> push eax
334 00000257 B81C000000 <2> mov eax, %1
335 0000025C E9E7000000 <2> jmp isr_main
336 <1> isr_label 29
337 <2> isr_%1:
338 00000261 50 <2> push eax
339 00000262 B81D000000 <2> mov eax, %1
340 00000267 E9DC000000 <2> jmp isr_main
341 <1> isr_label 30
342 <2> isr_%1:
343 0000026C 50 <2> push eax
344 0000026D B81E000000 <2> mov eax, %1
345 00000272 E9D1000000 <2> jmp isr_main
346 <1> isr_label 31
347 <2> isr_%1:
348 00000277 50 <2> push eax
349 00000278 B81F000000 <2> mov eax, %1
350 0000027D E9C6000000 <2> jmp isr_main
351 <1> isr_label 32
352 <2> isr_%1:
353 00000282 50 <2> push eax
354 00000283 B820000000 <2> mov eax, %1
355 00000288 E9BB000000 <2> jmp isr_main
356 <1> isr_label 33
357 <2> isr_%1:
358 0000028D 50 <2> push eax
359 0000028E B821000000 <2> mov eax, %1
360 00000293 E9B0000000 <2> jmp isr_main
361 <1> isr_label 34
362 <2> isr_%1:
363 00000298 50 <2> push eax
364 00000299 B822000000 <2> mov eax, %1
365 0000029E E9A5000000 <2> jmp isr_main
366 <1> isr_label 35
367 <2> isr_%1:
368 000002A3 50 <2> push eax
369 000002A4 B823000000 <2> mov eax, %1
370 000002A9 E99A000000 <2> jmp isr_main
371 <1> isr_label 36
372 <2> isr_%1:
373 000002AE 50 <2> push eax
374 000002AF B824000000 <2> mov eax, %1
375 000002B4 E98F000000 <2> jmp isr_main
376 <1> isr_label 37
377 <2> isr_%1:
378 000002B9 50 <2> push eax
379 000002BA B825000000 <2> mov eax, %1
380 000002BF E984000000 <2> jmp isr_main
381 <1> isr_label 38
382 <2> isr_%1:
383 000002C4 50 <2> push eax
384 000002C5 B826000000 <2> mov eax, %1
385 000002CA E979000000 <2> jmp isr_main
386 <1> isr_label 39
387 <2> isr_%1:
388 000002CF 50 <2> push eax
389 000002D0 B827000000 <2> mov eax, %1
390 000002D5 E96E000000 <2> jmp isr_main
391 <1> isr_label 40
392 <2> isr_%1:
393 000002DA 50 <2> push eax
394 000002DB B828000000 <2> mov eax, %1
395 000002E0 E963000000 <2> jmp isr_main
396 <1> isr_label 41
397 <2> isr_%1:
398 000002E5 50 <2> push eax
399 000002E6 B829000000 <2> mov eax, %1
400 000002EB E958000000 <2> jmp isr_main
401 <1> isr_label 42
402 <2> isr_%1:
403 000002F0 50 <2> push eax
404 000002F1 B82A000000 <2> mov eax, %1
405 000002F6 E94D000000 <2> jmp isr_main
406 <1> isr_label 43
407 <2> isr_%1:
408 000002FB 50 <2> push eax
409 000002FC B82B000000 <2> mov eax, %1
410 00000301 E942000000 <2> jmp isr_main
411 <1> isr_label 44
412 <2> isr_%1:
413 00000306 50 <2> push eax
414 00000307 B82C000000 <2> mov eax, %1
415 0000030C E937000000 <2> jmp isr_main
416 <1> isr_label 45
417 <2> isr_%1:
418 00000311 50 <2> push eax
419 00000312 B82D000000 <2> mov eax, %1
420 00000317 E92C000000 <2> jmp isr_main
421 <1> isr_label 46
422 <2> isr_%1:
423 0000031C 50 <2> push eax
424 0000031D B82E000000 <2> mov eax, %1
425 00000322 E921000000 <2> jmp isr_main
426 <1> isr_label 47
427 <2> isr_%1:
428 00000327 50 <2> push eax
429 00000328 B82F000000 <2> mov eax, %1
430 0000032D E916000000 <2> jmp isr_main
431 <1> isr_label 48
432 <2> isr_%1:
433 00000332 50 <2> push eax
434 00000333 B830000000 <2> mov eax, %1
435 00000338 E90B000000 <2> jmp isr_main
436 <1> isr_label 49
437 <2> isr_%1:
438 0000033D 50 <2> push eax
439 0000033E B831000000 <2> mov eax, %1
440 00000343 E900000000 <2> jmp isr_main
441 <1>
442 <1> isr_main:
443 00000348 3D30000000 <1> cmp eax, 0x30
444 0000034D 7414 <1> jz isr_syscall
445 <1>
446 0000034F 60 <1> pusha
447 00000350 1E <1> push ds
448 00000351 06 <1> push es
449 <1>
450 00000352 50 <1> push eax
451 <1>
452 00000353 E8(00000000) <1> call _isr
453 <1>
454 00000358 81C404000000 <1> add esp, 4
455 <1>
456 0000035E 07 <1> pop es
457 0000035F 1F <1> pop ds
458 00000360 61 <1> popa
459 00000361 58 <1> pop eax
460 <1>
461 00000362 CF <1> iret
462 <1>
463 <1>
464 <1> isr_syscall:
465 00000363 58 <1> pop eax ;syscall function number
466 00000364 60 <1> pusha
467 00000365 1E <1> push ds
468 00000366 06 <1> push es
469 <1>
470 <1> sc1:
471 00000367 3D01000000 <1> cmp eax, 1 ;syscall 1 - putc
472 0000036C 7511 <1> jnz sc2
473 0000036E 53 <1> push ebx
474 0000036F E8(00000000) <1> call _putc
475 00000374 81C404000000 <1> add esp, 4
476 0000037A E900000000 <1> jmp scdone
477 <1> sc2:
478 <1>
479 <1> scdone:
480 0000037F 07 <1> pop es
481 00000380 1F <1> pop ds
482 00000381 61 <1> popa
483 00000382 CF <1> iret
484 <1>
485 <1>
486 <1>
487 <1>
488 <1>
489 <1>
490 <1>
491
492
-132
View File
@@ -1,132 +0,0 @@
// mm.c
// Author: Josh Holtrop
// Created: 09/01/03
// Modified: 03/08/04
#include "hos_defines.h"
#include "mm.h"
//The total amount of physical memory available (bytes, 1 bit per page)
#define BITMAP_SIZE 0x20000
dword mm_totalmem = 0;
dword mm_megabytes = 0;
byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
//0x20000*(8 bits/byte)=0x100000 pages in 4gb total
//This function initializes the memory manager's linked list, filling it with the
// memory areas returned by bios interrupt 0x8E20
void mm_init()
{
dword memmap_entries = *(dword *)BOOT_MEMMAP_ENTRIES;
memmap_entry *maps = (memmap_entry *) BOOT_FIRST_MEMMAP;
dword a;
for (a = 0; a < BITMAP_SIZE; a++)
{
page_bitmap[a] = 0xFF; //all pages used
}
for (a = 0; a < memmap_entries; a++)
{
if (maps[a].attributes == 1) // (1) mem free to OS
{
mm_totalmem += maps[a].limit.lowdword;
if ((maps[a].base.lowdword + maps[a].limit.lowdword) >= (FREERAM_START+4096)) //goes past where we start freeram
{
if (maps[a].base.lowdword < FREERAM_START)
{
mm_pfreen(FREERAM_START, (maps[a].limit.lowdword - (FREERAM_START - maps[a].base.lowdword)) >> 12);
}
else
{
mm_pfreen(maps[a].base.lowdword, maps[a].limit.lowdword >> 12); //set the appropriate bits as "free" in the page bitmap
}
}
}
}
if (mm_totalmem % 0x100000)
mm_megabytes = (mm_totalmem >> 20) + 1;
else
mm_megabytes = mm_totalmem >> 20;
}
// This function frees a certain number of pages starting at the address
// specified in base for a length of pages pages
void mm_pfreen(dword base, dword pages)
{
dword a;
dword max = base + (pages << 12);
for (a = base; a < max; a += 4096)
{
mm_pfree(a);
}
}
// This function frees a single page
void mm_pfree(dword base)
{
// dword pageNumber = base >> 12; // >>12 == /4096
dword byteNumber = base >> 15; //pageNumber >> 3; //pageNumber/8
dword bitNumber = (base >> 12) % 8; //pageNumber % 8;
page_bitmap[byteNumber] = page_bitmap[byteNumber] & ((0x01 << bitNumber) ^ 0xFF);
}
// This function allocates a single page, returning its physical address
void *mm_palloc()
{
dword bite;
for (bite = 0; bite < BITMAP_SIZE; bite++)
{
if (page_bitmap[bite] != 0xFF) //there is an available page within this 8-page region
{
int bit;
for (bit = 0; bit < 8; bit++)
{
if (!(page_bitmap[bite] & (1 << bit))) //this bite/bit combination is available
{
page_bitmap[bite] = page_bitmap[bite] | (1 << bit); //set page as used
return (void *)((bite << 15) | (bit << 12));
}
}
}
}
return 0; //no free page
}
// This function reports the number of bytes of free physical memory
dword mm_freemem()
{
dword a;
dword pages = 0;
for (a = 0; a < BITMAP_SIZE; a++)
{
int bit;
for (bit = 0; bit < 8; bit++)
{
if (!(page_bitmap[a] & (1 << bit)))
pages++;
}
}
return pages << 12;
}
dword mm_getTotalMem()
{
return mm_totalmem;
}
dword mm_getTotalMegs()
{
return mm_megabytes;
}
-28
View File
@@ -1,28 +0,0 @@
// mm.c
// Author: Josh Holtrop
// Created: 09/01/03
// Modified: 03/08/04
#ifndef __HOS_MM__
#define __HOS_MM__ __HOS_MM__
#include "hos_defines.h"
typedef struct {
qword base;
qword limit;
dword attributes;
} __attribute__((packed)) memmap_entry;
void mm_init();
void mm_pfreen(dword base, dword pages);
void mm_pfree(dword base);
void *mm_palloc();
dword mm_freemem();
dword mm_getTotalMem();
dword mm_getTotalMegs();
#endif
-380
View File
@@ -1,380 +0,0 @@
// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 03/02/04
#include "hos_defines.h"
#include "vmm.h"
#include "asmfuncs.h"
#include "mm/mm.h"
HeapEntry *firstHeapEntry = (HeapEntry *)0xD0000000; //this is where heap memory starts
// This is the initialization procedure for the Virtual Memory Manager
// It sets up the final page directory/page table setup and maps video memory, if present
void vmm_init()
{
unsigned int *pageTables = (unsigned int *)0xC0104000; //this is the location of the page directory
pageTables[0x3FF] = 0x104000|0x03; //the last page directory entry points to the page directory itself
pageTables[0] = 0;
invlpg_(0);
unsigned int firstHeapEntryBlock = (unsigned int)mm_palloc();
vmm_map1((unsigned int)firstHeapEntry, firstHeapEntryBlock);
HeapEntryBlock *heb = (HeapEntryBlock *)firstHeapEntry;
vmm_heb_init(heb);
heb->entry[0].base = (unsigned int)firstHeapEntry; //start of kernel's heap memory
heb->entry[0].size = 4096; //the first HeapEntryBlock is 1 page long
heb->entry[0].attributes = VMM_HE_HEB; //this is a HeapEntryBlock
heb->entry[1].base = (unsigned int)firstHeapEntry+4096; //this is the start of the rest of the kernel's heap memory
heb->entry[1].size = 0x10000000-4096; //the rest of the kernel's heap memory: 256mb - 4kb
heb->entry[1].attributes = VMM_HE_HOLE; //this is a hole - an unmapped section of heap memory
}
// This function initialzes a Heap Entry Block to unused entries linked together
void vmm_heb_init(HeapEntryBlock *heb)
{
int a;
for (a = 0; a < 256; a++)
{
heb->entry[a].base = 0;
heb->entry[a].size = 0;
heb->entry[a].attributes = VMM_HE_UNUSED;
heb->entry[a].link = (unsigned int)&(heb->entry[a+1]);
}
heb->entry[255].link = 0;
}
// This function maps a virtual address to a physical address using the page directory / page table
void vmm_map1(unsigned int virt, unsigned int physical)
{
unsigned int pde = virt >> 22;
unsigned int pte = (virt & 0x003FF000) >> 12;
unsigned int *pageTables = (unsigned int *)0xC0104000; //this is the location of the page directory
if (!(pageTables[pde] & 0x01)) //the page directory entry does not exist, we must allocate a page for it
{
unsigned int *newpagetable = (dword *)mm_palloc();
pageTables[pde] = ((unsigned int)newpagetable) | 0x03;
invlpg_(virt);
unsigned int *newpteptr = (unsigned int *)(0xFFC00000 | (pde << 12)); //points to first unsigned int of newly allocated page table
int a;
for (a = 0; a < 1024; a++)
{
newpteptr[a] = 0;
}
}
unsigned int *pteptr = (unsigned int *)(0xFFC00000 | (pde << 12) | (pte << 2));
*pteptr = physical | 0x03;
invlpg_(virt);
}
// This function maps a variable number of pages in a row
void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n)
{
for (; n > 0; n--)
{
vmm_map1(virt, physical);
virt += 4096;
physical += 4096;
}
}
// This function removes the virtual address's entry in the page directory / page table
void vmm_unmap1(unsigned int virt)
{
unsigned int *pteptr = (unsigned int *)(0xFFC00000 | ((virt & 0xFFC00000) >> 10) | ((virt & 0x003FF000) >> 10));
*pteptr = 0;
invlpg_(virt);
}
// This function removes multiple pages' entries
void vmm_unmapn(unsigned int virt, unsigned int n)
{
for (; n > 0; n--)
{
vmm_unmap1(virt);
virt += 4096;
}
}
// Virtual Memory allocator function
void *malloc(unsigned int bytes)
{
if (bytes % VMM_MALLOC_GRANULARITY)
bytes = bytes + VMM_MALLOC_GRANULARITY - (bytes % VMM_MALLOC_GRANULARITY);
void *attempt = vmm_getFreeChunk(bytes);
if (attempt)
return attempt;
if(vmm_moreCore(bytes))
return NULL; //we could not get any more heap memory
return vmm_getFreeChunk(bytes);
}
// This function returns a pointer if a free chunk of memory exists
void *vmm_getFreeChunk(unsigned int bytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_FREE)
{
if (he->size > bytes)
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_USED;
he->base += bytes;
he->size -= bytes;
return (void *)(nhe->base);
}
if (he->size == bytes)
{
he->attributes = VMM_HE_USED;
return (void *)(he->base);
}
}
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function coalesces any two adjacent heap entries into one entry
void vmm_coalesceHeapEntry(HeapEntry *he)
{
if (!(he->attributes == VMM_HE_FREE || he->attributes == VMM_HE_HOLE))
return;
if (he->size == 0)
{
he->attributes = VMM_HE_UNUSED;
return;
}
HeapEntry *hec = firstHeapEntry;
for (;;)
{
if (hec->attributes == he->attributes)
{
if ((hec->base + hec->size) == he->base) //hec ends where he begins
{
he->base = hec->base;
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
if ((he->base + he->size) == hec->base) //he ends where hec begins
{
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
}
hec = (HeapEntry *)hec->link;
if (!hec)
break;
}
}
// This function retrieves more physical memory for the heap
int vmm_moreCore(unsigned int bytes)
{
unsigned int pages = (bytes >> 12) + 1;
bytes = pages << 12;
HeapEntry *he = vmm_getFirstHoleHeapEntry(bytes);
unsigned int virt = he->base;
for (; pages > 0; pages--)
{
unsigned int phys = (unsigned int)mm_palloc();
if (!phys)
return 1;
vmm_map1(virt, phys);
virt += 4096;
}
if (he->size == bytes)
{
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
}
else
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_FREE;
he->base += bytes;
he->size -= bytes;
vmm_coalesceHeapEntry(nhe);
}
return 0;
}
// This function returns the next available heap entry, creates more entries if we are running low
HeapEntry *vmm_nextHeapEntry()
{
if (vmm_heapEntriesLeft() < 10)
vmm_addHeapEntryBlock();
return vmm_getFirstUnusedHeapEntry();
}
// This function creates a new block (page) of heap entries (256)
void vmm_addHeapEntryBlock()
{
HeapEntry *he = vmm_getFirstHoleHeapEntry(4096);
HeapEntry *newBlock = vmm_getFirstUnusedHeapEntry();
unsigned int heb = (unsigned int)mm_palloc();
vmm_map1(he->base, heb);
vmm_heb_init((HeapEntryBlock *)he->base);
HeapEntry *lhe = vmm_getLastHeapEntry();
if (he->size == 4096)
{
he->attributes = VMM_HE_HEB;
lhe->link = (unsigned int)he->base;
}
else
{
newBlock->base = he->base;
newBlock->size = 4096;
newBlock->attributes = VMM_HE_HEB;
he->base += 4096;
he->size -= 4096;
lhe->link = (unsigned int)newBlock->base;
}
return;
}
// This function returns the last heap entry in the linked list, useful for setting
// its link field to point to the first entry of a newly allocated list
HeapEntry *vmm_getLastHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->link == 0)
return he;
he = (HeapEntry *)he->link;
}
}
// This function returns the first heap entry corresponding to a memory "hole"
HeapEntry *vmm_getFirstHoleHeapEntry(unsigned int minBytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if ((he->attributes == VMM_HE_HOLE) && (he->size >= minBytes))
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the first heap entry that is not being used
HeapEntry *vmm_getFirstUnusedHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the number of heap entries available for use
unsigned int vmm_heapEntriesLeft()
{
HeapEntry *he = firstHeapEntry;
unsigned int entries = 0;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
entries++;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return entries;
}
// This function "frees" an area of memory previously allocated with malloc()
int free(void *ptr)
{
HeapEntry *he = vmm_getHeapEntryByBase((unsigned int)ptr);
if (!he)
return 1; //a heap entry starting at the given address was not found
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
return 0;
}
// This function scans the heap entry linked list for an entry that begins at the given address
HeapEntry *vmm_getHeapEntryByBase(unsigned int base)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->base == base)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return NULL;
}
// This function re-allocates memory already allocated, preserving the old contents
// (as long as newSize is greater than oldSize)
void *realloc(void *orig, unsigned int newSize)
{
void *newMem;
if ((newMem = malloc(newSize)))
{
HeapEntry *he = vmm_getHeapEntryByBase((unsigned int) orig);
if (!he)
return NULL; //old chunk not found / nonexistent
memcpy(newMem, orig, (he->size < newSize ? he->size : newSize));
free(orig);
return newMem;
}
else
return NULL; //could not get mem for new chunk
}
// This function allocates and zeros memory for the given number of objects,
// given the size of each object
void *calloc(unsigned int number, unsigned int size)
{
void *mem = malloc(number * size);
if (!mem)
return NULL; //could not get memory
memset(mem, 0, number * size);
return mem;
}
-56
View File
@@ -1,56 +0,0 @@
// vmm.h
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 03/02/04
#include "hos_defines.h"
#ifndef __HOS_VMM__
#define __HOS_VMM__ __HOS_VMM__
#define VMM_HE_UNUSED 0 //available entry
#define VMM_HE_FREE 1 //free section of memory
#define VMM_HE_USED 2 //used section of memory
#define VMM_HE_HOLE 3 //a "hole" (unmapped) section of virtual memory
#define VMM_HE_HEB 4 //HeapEntryBlock
#define VMM_MALLOC_GRANULARITY 4 //granularity for all memory requests
typedef struct {
unsigned int base; //virtual base address
unsigned int size; //size in bytes
unsigned int attributes; //free/used/hole
unsigned int link; //link to next HeapEntry
} __attribute__((packed)) HeapEntry;
typedef struct {
HeapEntry entry[256]; //256 HeapEntry objects = 4kb (1 page)
} __attribute__((packed)) HeapEntryBlock;
void vmm_init();
void *malloc(unsigned int bytes);
int free(void *ptr);
void vmm_map1(unsigned int virt, unsigned int physical);
void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n);
void vmm_unmap1(unsigned int virt);
void vmm_unmapn(unsigned int virt, unsigned int n);
void vmm_heb_init(HeapEntryBlock *heb);
void *vmm_getFreeChunk(unsigned int bytes);
HeapEntry *vmm_nextHeapEntry();
unsigned int vmm_heapEntriesLeft();
HeapEntry *vmm_getLastHeapEntry();
HeapEntry *vmm_getFirstUnusedHeapEntry();
HeapEntry *vmm_getFirstHoleHeapEntry(unsigned int minBytes);
void vmm_addHeapEntryBlock();
int vmm_moreCore(unsigned int bytes);
void vmm_coalesceHeapEntry(HeapEntry *he);
HeapEntry *vmm_getHeapEntryByBase(unsigned int base);
void *realloc(void *orig, unsigned int newSize);
void *calloc(unsigned int number, unsigned int size);
#endif
-1
View File
@@ -1 +0,0 @@
grep -R -n -i %1 *
-2
View File
@@ -1,2 +0,0 @@
#!/bin/sh
grep -R -n -i $1 *
-42
View File
@@ -1,42 +0,0 @@
// cmos.c
// Author: Josh Holtrop
// Created: 02/26/04
// Implements various CMOS function calls
#include "hos_defines.h"
#include "cmos.h"
#include "sys/io.h"
//Returns the cmos type of floppy disk drive 0 (0 = not present)
unsigned char cmos_getfd0()
{
outportb(0x70, 0x10);
return (inportb(0x71) >> 4);
}
//Returns the cmos type of floppy disk drive 1 (0 = not present)
unsigned char cmos_getfd1()
{
outportb(0x70, 0x10);
return (inportb(0x71) & 0x0F);
}
//Returns the cmos type of hard disk drive 0 (0 = not present)
unsigned char cmos_gethd0()
{
outportb(0x70, 0x12);
return (inportb(0x71) >> 4);
}
//Returns the cmos type of hard disk drive 1 (0 = not present)
unsigned char cmos_gethd1()
{
outportb(0x70, 0x12);
return (inportb(0x71) & 0x0F);
}
-18
View File
@@ -1,18 +0,0 @@
// cmos.h
// Author: Josh Holtrop
// Created: 02/26/04
// Implements various CMOS function calls
#include "hos_defines.h"
#ifndef __HOS_CMOS__
#define __HOS_CMOS__ __HOS_CMOS__
unsigned char cmos_getfd0();
unsigned char cmos_getfd1();
unsigned char cmos_gethd0();
unsigned char cmos_gethd1();
#endif
-8
View File
@@ -1,8 +0,0 @@
// io.c
// Author: Josh Holtrop
// Created: 02/26/04
// Implements basic port input/output functions
#include "io.h"
-40
View File
@@ -1,40 +0,0 @@
// io.h
// Author: Josh Holtrop
// Created: 02/26/04
// Implements basic port input/output functions
#ifndef __HOS_IO__
#define __HOS_IO__ __HOS_IO__
#include "hos_defines.h"
//void outportb(unsigned int port, unsigned char value);
//inline void outportw(unsigned int port, unsigned int value);
//inline unsigned char inportb(unsigned short port);
//Writes a byte out to a port
static inline void outportb(unsigned int port, unsigned char value) // Output a byte to a port
{
asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
}
//Writes a word out to a port
static inline void outportw(unsigned int port, unsigned int value) // Output a word to a port
{
asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value));
}
//Reads a byte from a port
static inline unsigned char inportb(unsigned short port)
{
unsigned char ret_val;
asm volatile("inb %w1,%b0"
: "=a"(ret_val)
: "d"(port));
return ret_val;
}
#endif
-30
View File
@@ -1,30 +0,0 @@
// pic.c
// Author: Josh Holtrop
// Created: 02/26/04
#include "hos_defines.h"
#include "pic.h"
#include "sys/io.h"
//Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address
void pic_remap(int pic1, int pic2)
{
byte a1, a2;
a1 = inportb(PIC1_DATA); //0x21
a2 = inportb(PIC2_DATA); //0xA1
outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); //0x20, 0x10+0x01 00010001b
outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); //0xA0, 0x10+0x01 00010001b
outportb(PIC1_DATA, pic1); //0x21, pic1
outportb(PIC2_DATA, pic2); //0xA1, pic2
outportb(PIC1_DATA, 4); //0x21, 0x04 00000100b
outportb(PIC2_DATA, 2); //0xA1, 0x02 00000010b
outportb(PIC1_DATA, ICW4_8086); //0x21, 0x01 00000001b
outportb(PIC2_DATA, ICW4_8086); //0xA1, 0x01 00000001b
outportb(PIC1_DATA, a1); //0x21
outportb(PIC2_DATA, a2); //0xA1
}
-65
View File
@@ -1,65 +0,0 @@
// pic.h
// Author: Josh Holtrop
// Created: 02/26/04
#ifndef __HOS_PIC__
#define __HOS_PIC__ __HOS_PIC__
#include "hos_defines.h"
#include "sys/io.h"
#define PIC1 0x20
#define PIC2 0xA0
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)
#define PIC_EOI 0x20
#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
void pic_remap(int pic1, int pic2);
//inline void pic_mask1(byte mask);
//inline void pic_mask2(byte mask);
//inline void pic_eoi();
//inline void pic_eoi2();
//Masks interrupts on first Programmable Interrupt Controller
static inline void pic_mask1(byte mask)
{
outportb(PIC1_DATA, mask); //0x21, maskfield *OCW1*
}
//Masks interrupts on second Programmable Interrupt Controller
static inline void pic_mask2(byte mask)
{
outportb(PIC2_DATA, mask); //0xA1, maskfield *OCW1*
}
//Signals an End Of Interrupt signal to the first PIC
static inline void pic_eoi()
{
outportb(0x20, 0x20);
}
//Signals an End Of Interrupt signal to both the second and first PIC unit
static inline void pic_eoi2()
{
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
#endif
-83
View File
@@ -1,83 +0,0 @@
// rtc.c
// Author: Josh Holtrop
// Created: 02/26/04
// Implements Real-Time Clock function calls
// These functions are for reading and writing various values stored on the CMOS Real Time Clock
// Parameters / return values are in BCD format
#include "hos_defines.h"
#include "rtc.h"
#include "sys/io.h"
unsigned char rtc_readDay()
{
outportb(0x70, 7);
return inportb(0x71);
}
unsigned char rtc_readMonth()
{
outportb(0x70, 8);
return inportb(0x71);
}
unsigned char rtc_readYear()
{
outportb(0x70, 9);
return inportb(0x71);
}
unsigned char rtc_readSecond()
{
outportb(0x70, 0);
return inportb(0x71);
}
unsigned char rtc_readMinute()
{
outportb(0x70, 2);
return inportb(0x71);
}
unsigned char rtc_readHour()
{
outportb(0x70, 4);
return inportb(0x71);
}
void rtc_setDay(unsigned char day)
{
outportb(0x70, 7);
outportb(0x71, day);
}
void rtc_setMonth(unsigned char month)
{
outportb(0x70, 8);
outportb(0x71, month);
}
void rtc_setYear(unsigned char year)
{
outportb(0x70, 9);
outportb(0x71, year);
}
void rtc_setSecond(unsigned char second)
{
outportb(0x70, 0);
outportb(0x71, second);
}
void rtc_setMinute(unsigned char minute)
{
outportb(0x70, 2);
outportb(0x71, minute);
}
void rtc_setHour(unsigned char hour)
{
outportb(0x70, 4);
outportb(0x71, hour);
}
-28
View File
@@ -1,28 +0,0 @@
// rtc.h
// Author: Josh Holtrop
// Created: 02/26/04
// Implements Real-Time Clock function calls
// These functions are for reading and writing various values stored on the CMOS Real Time Clock
// Parameters / return values are in BCD format
#ifndef __HOS_RTC__
#define __HOS_RTC__ __HOS_RTC__
#include "hos_defines.h"
unsigned char rtc_readDay();
unsigned char rtc_readMonth();
unsigned char rtc_readYear();
unsigned char rtc_readSecond();
unsigned char rtc_readMinute();
unsigned char rtc_readHour();
void rtc_setDay(unsigned char dat);
void rtc_setMonth(unsigned char month);
void rtc_setYear(unsigned char year);
void rtc_setSecond(unsigned char second);
void rtc_setMinute(unsigned char minute);
void rtc_setHour(unsigned char hour);
#endif
-551
View File
@@ -1,551 +0,0 @@
// stdfont.c
// Author: Josh Holtrop
// Created: 02/26/04
#include "stdfont.h"
const unsigned char stdfont8x5[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xE0, 0xC0, 0x80,
0x00, 0x08, 0x18, 0x38, 0x78, 0x38, 0x18, 0x08,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0x20,
0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0x00, 0xA0, 0xA0,
0x00, 0x78, 0xA8, 0xA8, 0x78, 0x28, 0x28, 0x68,
0x00, 0x78, 0x80, 0x70, 0x88, 0x70, 0x08, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x20, 0x20, 0x20, 0xA8, 0x70, 0x20,
0x00, 0x00, 0x20, 0x10, 0xF8, 0x10, 0x20, 0x00,
0x00, 0x00, 0x20, 0x40, 0xF8, 0x40, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x60, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x70, 0xF8, 0xF8, 0x00, 0x00,
0x00, 0x00, 0xF8, 0xF8, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x20,
0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x50, 0xF8, 0x50, 0x50, 0x50, 0xF8, 0x50,
0x00, 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20,
0x00, 0x00, 0x08, 0x90, 0x20, 0x48, 0x80, 0x00,
0x00, 0x20, 0x50, 0x50, 0x20, 0x58, 0x90, 0x68,
0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20,
0x00, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40,
0x00, 0x00, 0xA8, 0x70, 0xF8, 0x70, 0xA8, 0x00,
0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40,
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60,
0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x20, 0x60, 0xA0, 0x20, 0x20, 0x20, 0x20,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x70, 0x88, 0x08, 0x10, 0x08, 0x88, 0x70,
0x00, 0x30, 0x50, 0x90, 0x90, 0xF8, 0x10, 0x10,
0x00, 0xF8, 0x80, 0x80, 0xF8, 0x08, 0x88, 0x70,
0x00, 0x38, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40,
0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70,
0x00, 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x40,
0x00, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10,
0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00,
0x00, 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20,
0x00, 0x70, 0x88, 0x88, 0xB8, 0xB0, 0x80, 0x78,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0xC8, 0xE8, 0xB8, 0x98, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x88, 0x88, 0xA8, 0x98, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88,
0x00, 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x88, 0x50, 0x20, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8,
0x00, 0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70,
0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, 0x00,
0x00, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0,
0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x00, 0x70, 0x88, 0x80, 0x88, 0x70,
0x00, 0x08, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x30, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x70,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90,
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x00, 0xD0, 0xA8, 0xA8, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x38,
0x00, 0x00, 0x00, 0x70, 0x48, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0,
0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88,
0x00, 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0xF0,
0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x30, 0x40, 0x40, 0x80, 0x40, 0x40, 0x30,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0xC0, 0x20, 0x20, 0x10, 0x20, 0x20, 0xC0,
0x00, 0x00, 0x68, 0x90, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF8, 0x88, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x48, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0xF0, 0x50, 0x50, 0x50, 0x50, 0x78, 0x88,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xA8, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x70, 0x88, 0x08, 0x30, 0x08, 0x88, 0x70,
0x00, 0x88, 0x98, 0xA8, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0xA8, 0xC8, 0x98, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0xF8, 0x50, 0x50, 0x50, 0x50, 0x50, 0x90,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x70, 0x20, 0xF8, 0xA8, 0xF8, 0x20, 0x70,
0x00, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x08, 0x38,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0xC0, 0x40, 0x40, 0x78, 0x48, 0x48, 0x78,
0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xA8, 0xE8,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x08, 0x78, 0x08, 0x88, 0xF0,
0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0xA8, 0x90,
0x00, 0x78, 0x88, 0x88, 0x78, 0x28, 0x48, 0x88,
0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x88, 0x78,
0x00, 0x00, 0xF8, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF0, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x78, 0x50, 0x50, 0x50, 0x70, 0x88,
0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x88, 0x70,
0x00, 0x00, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x30, 0x88, 0x70,
0x00, 0x00, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x88,
0x00, 0x50, 0x20, 0x88, 0x98, 0xA8, 0xC8, 0x88,
0x00, 0x00, 0x88, 0x90, 0xA0, 0xE0, 0x90, 0x88,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x48, 0x48, 0xC8,
0x00, 0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x50, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x90, 0x00, 0xF0, 0x80, 0xE0, 0x80, 0xF0,
0x00, 0x00, 0x70, 0x48, 0x70, 0x48, 0x48, 0xF0,
0x00, 0x88, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x70, 0x50, 0x70, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x88, 0xF8, 0x80, 0xE0, 0x80, 0x80, 0xF8,
0x00, 0x40, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x10, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x20, 0x50, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x40, 0x20, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x20, 0x50, 0x00, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x10, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x80, 0x80, 0x70, 0x20,
0x00, 0x70, 0x88, 0x40, 0xF0, 0x40, 0x40, 0xF8,
0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x70, 0x88, 0x80, 0x80, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x00, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x00, 0x70, 0x20, 0xF8, 0xF8, 0x20, 0x70,
0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x38,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0x00, 0xC0, 0x40, 0x70, 0x48, 0x48, 0x70,
0x00, 0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xE8,
0x00, 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x70, 0x88, 0x38, 0x08, 0x88, 0x70,
0x00, 0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0x90,
0x00, 0x00, 0x38, 0x48, 0x48, 0x38, 0x28, 0x48,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const unsigned char stdfont10x7[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xE0, 0xF0, 0xFC, 0xF0, 0xE0, 0x80, 0x00, 0x00,
0x00, 0x02, 0x0E, 0x1E, 0x7E, 0x1E, 0x0E, 0x02, 0x00, 0x00,
0x00, 0x10, 0x7C, 0x92, 0x10, 0x92, 0x7C, 0x10, 0x00, 0x00,
0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x90, 0x90, 0x00, 0x00,
0x00, 0x7E, 0x92, 0x92, 0x7E, 0x12, 0x12, 0x72, 0x00, 0x00,
0x00, 0x7E, 0x80, 0x7C, 0x82, 0x7C, 0x02, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
0x00, 0x10, 0x7C, 0x92, 0x10, 0x92, 0x7C, 0xFE, 0x00, 0x00,
0x00, 0x10, 0x7C, 0x92, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x10, 0x10, 0x10, 0x10, 0x92, 0x7C, 0x10, 0x00, 0x00,
0x00, 0x00, 0x08, 0x04, 0xFE, 0x04, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x40, 0xFE, 0x40, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,
0x00, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x44, 0xFE, 0x44, 0x44, 0x44, 0xFE, 0x44, 0x00, 0x00,
0x00, 0x10, 0x7E, 0x90, 0x7C, 0x12, 0xFC, 0x10, 0x00, 0x00,
0x00, 0x00, 0x04, 0x88, 0x10, 0x22, 0x40, 0x00, 0x00, 0x00,
0x00, 0x38, 0x44, 0x44, 0x78, 0x86, 0x84, 0x7A, 0x00, 0x00,
0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10, 0x00, 0x00,
0x00, 0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
0x00, 0x00, 0x10, 0x54, 0x38, 0x54, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x10, 0x30, 0x50, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x7C, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x0C, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x38, 0x48, 0x88, 0x88, 0xFE, 0x08, 0x08, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFE, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x3E, 0x40, 0x80, 0xFC, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x7C, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x7E, 0x02, 0x02, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x60, 0x00, 0x00,
0x00, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x0C, 0x10, 0x00, 0x10, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x9A, 0x9C, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFC, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFC, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x9E, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x84, 0x88, 0x90, 0xE0, 0x90, 0x88, 0x84, 0x00, 0x00,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x82, 0xEE, 0x92, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0xC2, 0xA2, 0x92, 0x8A, 0x86, 0x82, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x92, 0x8A, 0x7C, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x88, 0x84, 0x82, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x7C, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x92, 0x92, 0x6C, 0x00, 0x00,
0x00, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00,
0x00, 0x82, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0xFE, 0x02, 0x0C, 0x10, 0x60, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00, 0x00,
0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00,
0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00, 0x00,
0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,
0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x80, 0x80, 0xFC, 0x82, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x82, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x02, 0x02, 0x7E, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x30, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7E, 0x82, 0x82, 0x82, 0x7E, 0x02, 0x7C,
0x00, 0x80, 0x80, 0xF8, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00,
0x00, 0x40, 0x00, 0xC0, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00,
0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x80, 0x80, 0x88, 0xB0, 0xC0, 0xB0, 0x88, 0x00, 0x00,
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x82, 0x82, 0x82, 0xFC, 0x80, 0x80,
0x00, 0x00, 0x00, 0x7C, 0x84, 0x84, 0x84, 0x7C, 0x04, 0x3C,
0x00, 0x00, 0x00, 0xB8, 0x44, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x80, 0x78, 0x04, 0xF8, 0x00, 0x00,
0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x84, 0x84, 0x84, 0x84, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x82, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x82, 0x82, 0x82, 0x92, 0x6C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x00,
0x00, 0x00, 0x00, 0x84, 0x84, 0x84, 0x84, 0x7C, 0x04, 0xF8,
0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00, 0x00,
0x00, 0x18, 0x20, 0x20, 0x40, 0x20, 0x20, 0x18, 0x00, 0x00,
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x60, 0x10, 0x10, 0x08, 0x10, 0x10, 0x60, 0x00, 0x00,
0x00, 0x00, 0x72, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0xFE, 0x82, 0x80, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFE, 0x62, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0xFC, 0x6C, 0x6C, 0x6C, 0x6C, 0x7E, 0x82, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFC, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x92, 0x92, 0x7C, 0x10, 0x7C, 0x92, 0x92, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x1C, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x8E, 0x92, 0x92, 0x92, 0xE2, 0x82, 0x00, 0x00,
0x00, 0x92, 0xE2, 0x8E, 0x92, 0x92, 0xE2, 0x82, 0x00, 0x00,
0x00, 0x82, 0x8C, 0x90, 0xE0, 0x90, 0x8C, 0x82, 0x00, 0x00,
0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x8C, 0x00, 0x00,
0x00, 0x82, 0xEE, 0x92, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x6C, 0x10, 0x60, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x10, 0xFE, 0x92, 0xFE, 0x10, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x82, 0x6C, 0x10, 0x6C, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x02, 0x1E, 0x00, 0x00,
0x00, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00,
0x00, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x02, 0x00, 0x00,
0x00, 0xE0, 0x60, 0x60, 0x7E, 0x62, 0x62, 0x7E, 0x00, 0x00,
0x00, 0x82, 0x82, 0xE2, 0x92, 0x92, 0x92, 0xF2, 0x00, 0x00,
0x00, 0x80, 0x80, 0xFC, 0x82, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x02, 0x7E, 0x02, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x8C, 0x92, 0x92, 0xF2, 0x92, 0x92, 0x8C, 0x00, 0x00,
0x00, 0x7E, 0x82, 0x82, 0x7E, 0x12, 0x62, 0x82, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x02, 0x7E, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x80, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x6C, 0x6C, 0x6C, 0x7C, 0x82, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0xFE, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x92, 0x7C, 0x10, 0x7C, 0x92, 0x92, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x82, 0x1C, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x82, 0x8E, 0x92, 0xE2, 0x82, 0x82, 0x00, 0x00,
0x00, 0x6C, 0x10, 0x82, 0x8E, 0x92, 0xE2, 0x82, 0x00, 0x00,
0x00, 0x00, 0x82, 0x8C, 0x90, 0xF0, 0x8C, 0x82, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x62, 0x62, 0x62, 0x62, 0xE2, 0x00, 0x00,
0x00, 0x00, 0x82, 0xEE, 0x92, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7C, 0x44, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x44, 0x00, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x44, 0x00, 0x7C, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x8C, 0x00, 0xFC, 0x80, 0xF0, 0x80, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x62, 0x7C, 0x62, 0x62, 0xFC, 0x00, 0x00,
0x00, 0x82, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x82, 0x00, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x7C, 0x44, 0x7C, 0x82, 0xFE, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x82, 0xFE, 0x80, 0xF0, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x60, 0x10, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x0C, 0x10, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x10, 0x6C, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x60, 0x10, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x10, 0x6C, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x10, 0x0C, 0x82, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x80, 0x80, 0x7C, 0x10, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x60, 0xFC, 0x60, 0x60, 0xFE, 0x00, 0x00,
0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x6C, 0x10, 0x60, 0x80, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x10, 0xFE, 0xFE, 0x10, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x82, 0x6C, 0x10, 0x6C, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x02, 0x00, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x7C, 0x62, 0x62, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0xE2, 0x92, 0x92, 0xF2, 0x00, 0x00,
0x00, 0x00, 0x80, 0x80, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0x1E, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x8C, 0x92, 0x92, 0xF2, 0x92, 0x8C, 0x00, 0x00,
0x00, 0x00, 0x1E, 0x62, 0x62, 0x1E, 0x12, 0x62, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
StdFont fonts[] = {
{stdfont8x5, 8, 5},
{stdfont10x7, 10, 7}
};
//Returns the width of a given, 0 = invalid font
unsigned int stdfont_getFontWidth(unsigned int fontNumber)
{
if (fontNumber >= STDFONTS)
return 0;
return fonts[fontNumber].charWidth;
}
//Returns the height of a given, 0 = invalid font
unsigned int stdfont_getFontHeight(unsigned int fontNumber)
{
if (fontNumber >= STDFONTS)
return 0;
return fonts[fontNumber].charHeight;
}
//Returns a pointer to the desired font's bitmap representation
unsigned char *stdfont_getBitmap(unsigned int fontNumber)
{
if (fontNumber >= STDFONTS)
return 0;
return (unsigned char *)fonts[fontNumber].fontPtr;
}
-27
View File
@@ -1,27 +0,0 @@
// stdfont.c
// Author: Josh Holtrop
// Created: 02/26/04
// Standard font server
#ifndef __HOS_STDFONT__
#define __HOS_STDFONT__ __HOS_STDFONT__
#define STDFONTS 2
typedef struct {
const unsigned char *fontPtr;
unsigned int charHeight;
unsigned int charWidth;
} StdFont;
//Returns the standard font size, 0 = invalid font
unsigned int stdfont_getFontWidth(unsigned int fontNumber);
//Returns the height of a given, 0 = invalid font
unsigned int stdfont_getFontHeight(unsigned int fontNumber);
//Returns a pointer to the desired font's bitmap representation
unsigned char *stdfont_getBitmap(unsigned int fontNumber);
#endif
-265
View File
@@ -1,265 +0,0 @@
// video.c
// 08/13/03 Josh Holtrop
// Modified: 03/08/04
#include "hos_defines.h"
#include "video.h"
#include "video/stdfont.h"
#include "mm/vmm.h"
ModeInfoBlock video_mode;
dword videoMode = 0; //what video mode # we are in, 0 for console mode
word *vid_ptr16 = (word *)0xF0000000;
byte *vid_ptr24 = (byte *)0xF0000000;
dword *vid_ptr32 = (dword *)0xF0000000;
void (*video_psetp)(int, dword) = video_psetpnull; //function pointer to set a pixel
//Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
void video_init()
{
videoMode = *(word *)BOOT_VIDEO_MODE;
if (!videoMode) //we are in console mode
return;
video_mode = *(ModeInfoBlock *) BOOT_VIDEO_MODE_INFO_BLOCK;
switch(video_mode.BitsPerPixel)
{
case 16:
video_psetp = &video_psetp16;
break;
case 24:
video_psetp = &video_psetp24;
break;
case 32:
video_psetp = &video_psetp32;
}
unsigned int vidPages = video_mode.XResolution * video_mode.YResolution * (video_mode.BitsPerPixel >> 3);
if (vidPages % 4096)
vidPages = (vidPages >> 12) + 1;
else
vidPages = (vidPages >> 12);
vmm_mapn(0xF0000000, video_mode.PhysBasePtr, vidPages);
}
//Renders a character using stdfont[] as a bitmask
void video_renderChar(int x, int y, int character, int font, dword color, int drawBack, dword backColor)
{
int charWidth = stdfont_getFontWidth(font);
if (!charWidth)
return;
int charHeight = stdfont_getFontHeight(font);
int charpos = (character & 0xFF) * charHeight;
byte *charBMP = (byte *)stdfont_getBitmap(font);
int row;
int col;
for (row = 0; row < charHeight; row++)
{
for (col = 0; col < charWidth; col++)
{
if ((charBMP[charpos + row] << col) & 0x80)
video_pset(x + col, y + row, color);
else if (drawBack)
video_pset(x + col, y + row, backColor);
}
}
}
//Draws a horizontal line
void video_horiz(int y, int x1, int x2, dword color)
{
if (x1 > x2)
{
int tmp = x2;
x2 = x1;
x1 = tmp; //x2 >= x1 now
}
if (x2 < 0)
return;
if (x1 >= video_mode.XResolution)
return;
if (x1 < 0)
x1 = 0;
if (x2 >= video_mode.XResolution)
x2 = video_mode.XResolution - 1;
int pixel = y * video_mode.XResolution + x1;
for (; x1 <= x2; x1++)
{
video_psetp(pixel++, color);
}
}
//Draws a single pixel
void video_pset(int x, int y, dword color)
{
if ((x < 0) || (x >= video_mode.XResolution) || (y < 0) || (y >= video_mode.YResolution))
return;
video_psetp(y * video_mode.XResolution + x, color);
}
//Draws a pixel at the specified pixel position
//This function is needed because external modules do not have access to the function pointer video_psetp
void video_pseti(int pixel, dword color)
{
video_psetp(pixel, color);
}
//Draws a vertical line
void video_vert(int x, int y1, int y2, dword color)
{
if (y1 > y2)
{
int tmp = y2;
y2 = y1;
y1 = tmp; //y2 >= y1 now
}
if (y2 < 0)
return;
if (y1 >= video_mode.YResolution)
return;
if (y1 < 0)
y1 = 0;
if (y2 >= video_mode.YResolution)
y2 = video_mode.YResolution - 1;
int pixel = y1 * video_mode.XResolution + x;
for (; y1 <= y2; y1++)
{
video_psetp(pixel, color);
pixel += video_mode.XResolution;
}
}
//Draws a rectangle
void video_rect(int x1, int y1, int x2, int y2, dword color)
{
video_horiz(y1, x1, x2, color);
video_horiz(y2, x1, x2, color);
video_vert(x1, y1, y2, color);
video_vert(x2, y1, y2, color);
}
//Draws a filled rectangle
void video_rectf(int x1, int y1, int x2, int y2, dword color)
{
if (y2 < y1)
{
int tmp = y2;
y2 = y1;
y1 = tmp;
}
for (; y1 <= y2; y1++)
video_horiz(y1, x1, x2, color);
}
//Draws a pixel at the specified pixel position
void video_psetp16(int pixel, dword color)
{
vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>2)<<5) | ((((color>>16)&0xFF)>>3)<<11);
}
//Draws a pixel at the specified pixel position
void video_psetp24(int pixel, dword color)
{
vid_ptr24[pixel*3] = color & 0xFF;
vid_ptr24[pixel*3+1] = (color>>8) & 0xFF;
vid_ptr24[pixel*3+2] = (color>>16) & 0xFF;
}
//Draws a pixel at the specified pixel position
void video_psetp32(int pixel, dword color)
{
vid_ptr32[pixel] = color;
}
//Dummy function to not draw anything if there is no graphical mode enabled
void video_psetpnull(int pixel, dword color) {}
int video_getWidth()
{
return video_mode.XResolution;
}
int video_getHeight()
{
return video_mode.YResolution;
}
byte video_getBitsPerPixel()
{
return video_mode.BitsPerPixel;
}
dword video_getPhysBasePtr()
{
return video_mode.PhysBasePtr;
}
dword video_Mode()
{
return videoMode;
}
void video_line(int x0, int y0, int x1, int y1, dword color)
{
int dy = y1 - y0;
int dx = x1 - x0;
int stepx, stepy;
if (dy < 0)
{
dy = -dy;
stepy = -1;
}
else
{
stepy = 1;
}
if (dx < 0)
{
dx = -dx;
stepx = -1;
}
else
{
stepx = 1;
}
dy <<= 1; // dy is now 2*dy
dx <<= 1; // dx is now 2*dx
video_pset(x0, y0, color);
if (dx > dy)
{
int fraction = dy - (dx >> 1); // same as 2*dy - dx
while (x0 != x1)
{
if (fraction >= 0)
{
y0 += stepy;
fraction -= dx; // same as fraction -= 2*dx
}
x0 += stepx;
fraction += dy; // same as fraction -= 2*dy
video_pset(x0, y0, color);
}
}
else
{
int fraction = dx - (dy >> 1);
while (y0 != y1)
{
if (fraction >= 0)
{
x0 += stepx;
fraction -= dy;
}
y0 += stepy;
fraction += dx;
video_pset(x0, y0, color);
}
}
}
-72
View File
@@ -1,72 +0,0 @@
// video.h
// 08/18/03 Josh Holtrop
// Modified: 03/08/04
#ifndef __HOS_VIDEO__
#define __HOS_VIDEO__ __HOS_VIDEO__
#include "hos_defines.h"
void video_init();
void video_horiz(int y, int x1, int x2, dword color);
void video_vert(int x, int y1, int y2, dword color);
void video_rect(int x1, int y1, int x2, int y2, dword color);
void video_rectf(int x1, int y1, int x2, int y2, dword color);
void video_pset(int x, int y, dword color);
void video_pseti(int pixel, dword color);
void video_psetp16(int pixel, dword color);
void video_psetp24(int pixel, dword color);
void video_psetp32(int pixel, dword color);
void video_psetpnull(int pixel, dword color);
void video_renderChar(int x, int y, int character, int font, dword color, int drawBack, dword backColor);
int video_getWidth();
int video_getHeight();
byte video_getBitsPerPixel();
dword video_getPhysBasePtr();
dword video_Mode();
void video_line(int x0, int y0, int x1, int y1, dword color);
typedef struct{
word ModeAttributes;
byte WinAAttributes;
byte WinBAttributes;
word WinGranularity;
word WinSize;
word WinASegment;
word WinBSegment;
dword WinFuncPtr;
word BytesPerScanLine;
word XResolution;
word YResolution;
byte XCharSize;
byte YCharSize;
byte NumberOfPlanes;
byte BitsPerPixel;
byte NumberOfBanks;
byte MemoryModel;
byte BankSize;
byte NumberOfImagePages;
byte Reserved1;
byte RedMaskSize;
byte RedFieldPosition;
byte GreenMaskSize;
byte GreenFieldPosition;
byte BlueMaskSize;
byte BlueFieldPosition;
byte RsvdMaskSize;
byte RsvdFieldPosition;
byte DirectColorModeInfo;
dword PhysBasePtr;
dword OffScreenMemOffset;
word OffScreenMemSize;
byte Reserved[206];
} ModeInfoBlock;
#endif
+89 -74
View File
@@ -1,74 +1,89 @@
HOS - Holtrop's Operating System
--------------------------------
HOS is a 32-bit, protected mode, graphical, multitasking operating system.
It was written by me, Josh Holtrop, with help from a few others along the way.
Goals: (A = accomplished, P = in progress, T = todo)
----------------------------------------------------
(A) Custom bootloader to load kernel from FAT-formatted boot media, options for video mode/ram disk
(A) 32-bit protected mode environment
(A) VESA Support for graphics modes
(A) PS/2 keyboard & mouse drivers
(A) Utilize x86's paging architecture for virtual memory management
(P) VFS abstraction layer for a single file system
(P) ram disk driver
(P) devfs file system driver
(T) ext2 file system support
(T) vfat file system support
(T) Multitasking support
(T) Console Manager
(T) HASH command shell
(T) Window Manager
(T) Various other utilities/applications
(T) Hard Drive (ATA) driver
(T) cdrom (ATAPI) driver
Change Log
----------
0.14
05/21/04 - C++ support in kernel, can use classes & templates
04/04/04 - video_line function for diagonal lines
03/16/04 - new VFS design with support for a loop device
03/01/04 - Thanks to Ben Meyer for helping me get a Makefile working and building on linux to work!
0.13
01/26/04 - functions added to read/write CMOS clock date and time
01/19/04 - fixed bug GDTR/IDTR pointing to physical rather than linear table base address
01/07/04 - fixed bug not reading sectors correctly from floppy
12/28/03 - fixed bug not storing eax on interrupt
12/25/03 - fixed bug in mm_palloc()
12/25/03 - incorporated output functions as regular functions rather than as part of a linked library
12/23/03 - re-written physical memory manager using bitmap instead of stack
12/22/03 - kernel relocated to 3gb linear / 1mb+24kb physical to allow for app. address space
0.12
12/21/03 - sample bmp loader tested, works (tests loading a kernel of size ~ 932kb
12/20/03 - GDT/IDT now located at 1mb physical, before kernel
10/30/03 - turns floppy motor off
10/30/03 - keyboard LEDs working
10/29/03 - paging functions working
10/15/03 - physical memory management page allocators working
0.11
10/09/03 - PS/2 mouse driver
0.10
09/11/03 - Rewritten C and assembly kernel with VESA GUI mode support, keyboard driver
0.05
05/14/03 - HGUI24/HGUI32 commands finished for testing GUI on both 24bpp and 32bpp graphics cards
05/14/03 - first web release!
0.04
03/09/03 - added VM shortcut command
03/09/03 - press up to fill retrieve last inputted command for Nate Scholten
03/08/03 - press clear to clear console input
03/07/03 - added "shortcut" commands PC, IC, ? for Nate Scholten
03/06/03 - added PROMPTC, INPUTC commands
0.03
12/30/02 - Command Line Interface working, accepting basic commands
HOS - Holtrop's Operating System
--------------------------------
HOS is (in the process of becoming) a 32-bit, protected mode, graphical, multitasking operating system.
It was written by me, Josh Holtrop, with help from a few others along the way.
Goals: (A = accomplished, P = in progress, T = todo)
----------------------------------------------------
(A) Custom bootloader to load kernel from FAT-formatted boot media, options for video mode/ram disk
(A) Multiboot compliance - kernel can be loaded by GRUB
(A) 32-bit protected mode environment
(A) VESA Support for graphics modes
(A) PS/2 keyboard & mouse drivers
(A) Utilize x86's paging architecture for virtual memory management
(P) Console Manager
(P) VFS abstraction layer for a single file system
(P) ram disk driver
(P) devfs file system driver
(P) ext2 file system support
(T) vfat file system support
(T) Multitasking support
(T) HASH command shell
(T) Window Manager
(T) Various other utilities/applications
(T) Hard Drive (ATA) driver
(T) cdrom (ATAPI) driver
Change Log
----------
0.16
12/16/04 - initrd going to be loaded as a gzipped ext2 image (kernel module) - faster loading!
0.15
07/10/04 - Multiboot support added, loadable by GRUB
0.14
05/21/04 - C++ support in kernel, can use classes & templates
04/04/04 - video_line function for diagonal lines
03/16/04 - new VFS design with support for a loop device
03/01/04 - Thanks to Ben Meyer for helping me get a Makefile working and building on linux to work!
0.13
01/26/04 - functions added to read/write CMOS clock date and time
01/19/04 - fixed bug GDTR/IDTR pointing to physical rather than linear table base address
01/07/04 - fixed bug not reading sectors correctly from floppy
12/28/03 - fixed bug not storing eax on interrupt
12/25/03 - fixed bug in mm_palloc()
12/25/03 - incorporated output functions as regular functions rather than as part of a linked library
12/23/03 - re-written physical memory manager using bitmap instead of stack
12/22/03 - kernel relocated to 3gb linear / 1mb+24kb physical to allow for app. address space
0.12
12/21/03 - sample bmp loader tested, works (tests loading a kernel of size ~ 932kb)
12/20/03 - GDT/IDT now located at 1mb physical, before kernel
10/30/03 - turns floppy motor off
10/30/03 - keyboard LEDs working
10/29/03 - paging functions working
10/15/03 - physical memory management page allocators working
0.11
10/09/03 - PS/2 mouse driver
0.10
09/11/03 - Rewritten C and assembly kernel with VESA GUI mode support, keyboard driver
0.05
05/14/03 - HGUI24/HGUI32 commands finished for testing GUI on both 24bpp and 32bpp graphics cards
05/14/03 - first web release!
0.04
03/09/03 - added VM shortcut command
03/09/03 - press up to fill retrieve last inputted command for Nate Scholten
03/08/03 - press clear to clear console input
03/07/03 - added "shortcut" commands PC, IC, ? for Nate Scholten
03/06/03 - added PROMPTC, INPUTC commands
0.03
12/30/02 - Command Line Interface working, accepting basic commands
0.02
12/11/02 - Assembly bootsector can load stage2 ("console")
0.01
12/01/02 - Real mode assembly bootsector boots from floppy disk successfully
Executable
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env ruby
# Copyright (c) 2013-2022 Josh Holtrop
#
# MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
script = File.join(File.dirname(__FILE__), ".rscons-3.1.0-4892f95d56c30bbe9aa0c9964062ec5b.rb")
unless File.exist?(script)
if File.read(__FILE__, mode: "rb") =~ /^#==>(.*)/
require "zlib"
require "base64"
encoded_compressed = $1
unescaped_compressed = Base64.decode64(encoded_compressed)
inflated = Zlib::Inflate.inflate(unescaped_compressed)
File.open(script, "wb") do |fh|
fh.write(inflated)
end
else
raise "Could not decompress."
end
end
load script
if __FILE__ == $0
Rscons::Cli.new.run(ARGV)
end
#==>eJztff13GzeS4O/5K9ptJyZlirIzN7PvMVYkW5IT7cmWT5KznqUZDkU2pR6T3dxuUrJW5v7thyp8VQHoJiXbuey+87yJ2PgoAIVCoVAoVD18sLUoi63zNNtKsquoWJzffFck/7FIiySKs2S+dTmfz2KbNEovknIefzfNR4tJEp2Uwzwrv4si9f0iK1PxFUXDyaAso+fPozKZjDElik4OTg/Oou0o/pB0n05jlTpKxtF1kc6TRpq3oo1pUpaDi6SpckV+3h/mk7wQFWVr7cFsNkmHg3maZ22ROxBtyiKmTjo21dpZOtkxGQycqrsjGrbNJdnI/M4Xc+huHIJLQA4XRZFkc9tNGCdtMikF7kaV+WrI7WQwvBTwo8/TzyQXW52207I/2Gmczos0u2iy7CiapFlSCsDTdikwM2/EH7K4FW0+C5bDZvrX6fyyn2aj5BO2CDmtKP3sVMC2IS96wPDA8vnwRUE23kAdidgn6xR0UbuqBp09rzkYiJcbqiEGlUbPFbrK9D+TaDN6tubg3cn1elFdYBUdrTVImPs1BummJJPSxc1wUCbR1Em8vkyyqCOm4Cea6lI4rvCf/vJs6nZFVr8okiT7aWX1Hyuq3ySTSX7906rqf6mofj5ZJLT3FdX/V0X1qViq2Xzw04rqf62oPrwZZGu0/reK6teXglOuRt2/VI09n4zo5IWqP6ueOKhOJ6+ietXEQXU6eRXVKydOVKeTV1G9auKgOp28iupVEwfV6eRVVK+aOKhOJ6+iet3ErSKbqlkrkjKZ19BMiM94/IF986/12GAF+6OgHCb0xfuianK65kjo7zRvS6FEwNBgbf6sSK8Gc91XkGCCsoTo4Mm7l3/vvz16cfbq+OR1tP1f0dZUdPT687S8KbdIPxoHb37rxmcHJ6/jXrQt5vPTPCmmcTP64Yfo++vuOB3n0fByUAyGIv10lgzTwaTXTrPhZDFKoNV2OR/M2+P5zYzITg5CRan5/GYnMGD9S/6F/8L/jdQn6McX+aSI98IKYwhhMJ8X/SIZjJIi6ojepldJ/2pQpINsXtoCg+FQTK4glc75Ip2M+qO0CGX60p1TIOvPL6Gx0m+7HBbpbB6qVKYTSavZOL1YFEmozFVSnOcKeTC/QlZK5wLnQhhQKNt1wYiVNC8WJtsMTKTj5J6c7h2/Oe2/fHd4tN/fPzwRE/35cxRjOb1wRcH2KJkkgvD88nped82oBeh383QiqgC1CHGlzxEiyirc9y+KfDGDCt0emWk5uPmg/NhPPiXDBUxjf3Ypdn5NJbuhTA9CscgaBRIGYr2FIMXKzEb9mSDaadmKysv8uo/JrWgwmeifSTY4nwhmpGlED3JPLPpEELgg62yYdOPxIJ0gz5pOBdQSVokeiuokbQ7mwknSRd0GRVE36TuzfP3CIAfDonzgwreLMTYkETNeMIQh9QPtu2PV9XFV9UeD+SDudWO3YtwjSzs0rHB7NasfiBrnT1Q+xR/tLLm22BBTuBA0PckHoz5ZXqRiG/IoJdCDFfTD7YZtWsJXJGJqYZIEJXMahnYs6CKZL4oseurBhJPiDZZWk9QYDwRLbNbRNl/G6dgjpHYynVEuKpA8FPCLHHiHQPdVWuTZNKGoFlDOBJQ2gurGYsUMFpM5m0DIJzltCVX2LQnNGWXtfhf1lokjzAZTcbqTWZ/dNk2JNdo0v556HCA8vYtsIpAS7Zp0TY4UNT7tuqfN5JPYScTEPGgE6Fzsqb83Pjz5vNncogJAYEF4lfV5uRXTmiVsr+OU171d1sC2+OZo4PIKz6Md32m0N5qPtkKlR2kJf1uRZuQwVaI/j561okc/shp+v7u0Us9wOg0U8bzJEM2FI9AU6O7C6ILDgoXrtWy5oUrpdrAProhmchVKoZPV41BAehxRkxI4NZDIGsCRAdxDIPRJmDMKW1atohDbpQsGORvsaloCiSJnjwvsDN4uGK4Z1PGoTKbmAX2dEnQflfOREHZbeLpvRfErBBmpWlHj4W0aPYmeLbce3rqtgYpk2ezELXXWaKEWwk61At2eLcRSQoFFVe3P837ZUB+umE2RNZwkg0zjF3Di4YZmCj5bXCRzze0pN4R0O3xZukimuZBSZWZD/rGdfyXGCn0u28W0P3ayyawjKCHuJcN5XqSJaVyIk/Po9vOgFZ1/js6lOun59s/RQKLNdk7Xvanon8lvmF+2l1nyaa65LfTY9ORmJ1RcLJjGflq0xS6FfbVFos2o+7j9uBU9brcf95ruZhdFUK2Yigq0kpj24SKJsnRSu23I8SC9eVMseNJ8/Wl2C7YhRWsE2ZQV44aVxZs+ZeFq5WeBkOAAS93Oes1et54wZxocESkA9kIlRw0W8xzKEMS7faw+v9GR1cglZnNWZcSSDkovBzax26Nb3RXdCMRnWwGqYKDhZsJslA3EGbjpt0UiacUmcsiAQCAnnX08A+G2sevKqefJRZqRcekZMXAFv6KiJxK+PBQfFAUoVH6OEjZtgjbFUZKLnlh3kApxMzSd/vFn3SNBSMr5zusKJ2Yf44sMW57o1XwHlougv4zjerws+SR4w45XDreT+ARgpdlF9PBWFljGsJDoAR7+3ZuNywH9T+PiHu5M3TD6vh3fV1TakIeUfAYELgVuPVBgiyFNEvx78MDNao+FyCOmSsuqEZcd4QQPP7Q4z85R0BJXmPiYY/nBtWvHoH61R6SkSjPdwd74uURk1VDGyXx42eioM2IroquY1PyY3ARqidQWNmVruEOdDEqBJY3HHtzeKiA1rELDUP018n6ftrX6IJGOA/NEQVG+KY/7nnRfS4JW7g/1HjHQ2BBMoWxFP5xP8uFHQn2QLMiqKOcV6mZ1JsNy5SQdJg8aT33eYunCAgQVoDlauso6OwHtaSL4Fa6RTiRXip6nTtTtkb5i3+1mBl9GTRaaPzwkaFgNb+iVC09uXjGrLtZ5luVzsYWKXxM4PUB2mkUDkXqZFLwx2bnYQ9PqRbh+21GWG0TBcNMsGQVanCdF/+oCZmYymJ6PBkijMlVVZpTKcuReIKjV7XRpdcU4uQ4mRWMcjjgGzfgZls9eBRDGe/nZ1ulR1+93j6x3u4dVHfOrVxzHI29InBr1+d09ua9x8vZnqdvtcRU2vY2xgm+FFOSRljNomf6Z9ESCGeYL0NlwjkGxJwtUoG8dXsUUzqq5baPUhH/qQgyu+94Qutb6iLEQPjWTxe5RzU46druObJbNh4YPZgRCJAiVB+FvJnb/ZbXWSK5OIhGjnO3Z9dQfXuiOcc+Zq5ypOjq/SZPJKOINr+rrGjpqKW6BvrXsaMyh9rWHkmVQXws/GduBhPYokS2JXQH2DtOSK9t9343EFJZibWTzcSP+fvPHfyljCVRuzUsUmDnEJaUHzHT1yfhNFcqcSYiNrT8HIRYUi5sPb23xJb+bFsPBPHFu+JiIPbW4cHiJgQTEuE0htRczME1xALoX1gYJLhr+CmiIH97qBpYxokL2pgoXq3iTPpLW71t3pWBNNx+y3+iyDq/MaEcs2sfhvOXjOOpEcbzsUKTda4HoPkWWQehGSIKRXqFTDfXVVJ2oYh31q8xXyeSZSDDHcnaps/IyhMCxo1OzyOHCZZ+piBpze73nrBavQW+1CJY2WSTexop5Ys24FzISXteCcXdct0KZzPukoUZFB7gWPmD7Febh8bvsY5ZfZxIU3DlHbGHqvQF3IuiVYjGKATRrFuz6dFB5CamOBXAqQhmy/t7OKX1vrZ2Cg8cLPJD77YqjVykO5N9fd42OUyowrZ7FPaIbvRU3yAibYLwclOmQKOkMqqzNQiN0rgZ2JAhGpAn2cprgZW9Dwu509g9evXh3dNYHG4Szk3d7Z4fHb/q/vTg5fPHy6OBUg8BZ8HH1QLfHytklInd2wRPKB978dnsNgTCnj1041HpFLwS1i/xA+baXxZvYbuB5WCyGUEMo5k1CHEh8NnAFlW6DgUwmz3yaAUWIwkUybsg/LZE6LwaQqAR5DVSmMLnQlHQNmlUH6s4A0D95gLRgQoKYPPzAZoyGIkl21UH7bTxsioMm/LdHutgOj4qA4YgQpDgo+4JxXOYjbfljbqU6DJhB3Ay63x9PBhdlA/9LDqf4Le9RHzg3qCpLcItkMmk8euafxosreqt7nRd44XYK5fFD3Q2zNsuP6cy5Q5RlQ/dtkMMu2+CiVAAgkxOAB/9ADRg8IEgi48dUgS8kZLqpFFdw4gL7ImIkQzOeWAp327gUkzBJVreBB4oJUmOEB4+JrysDMpkIUIikLt4f8h1MIYCp6QPmhQAFLiHhgF/RkERNF3sq/jvprRbfEDR0Da16NgfF8NI7MdX2XrUZ7+29Onrxy6mQK7sKDGKrFy59tL+6NMdACEvy1lv2HhbAw1vN8uK9t28F9357cvDq8L0Qbj3bAjnDXVXu8M0B9OURGRuFDZhRd/lfATka0peOGHtV3pRFns+/Rrc0qLXnrabGF83d4Zu9tSbu7YuzX2tmzYF6dPjy6PDN/14NWRSsIwYf7P7hyVpQV/QX5nOa5ZvDm4vrlD1gCMwXVGEYD8yQU8ZrS7Qyyq/LUEvrQ5lJW8tv213A+ea/DVoedjWYF6cazKNnxKCpDtqkGprt1NrQZtXQBKWuDQ4smIs57qI7jXiTHRdWo7UKzpM7wllzepJQBbl4vNIBfUFx5UmIRNB5wKUOLctUikIo24Uy8MNrqb64lGVmg7TArV/LyVyMEUIhE7HVvciLohjcNHGrhm2aJlKWKGpLOdsVQzhebbkqaSV0PhwtplrEkqJv/3JQXkbbRhKe5/1LvwCe0lAZ1z+/afzQAcukJtOEMM1iv5wXUhusr4Rupuf5pBntyDR5Eo5QZjb1gtZW8KakpUESCyqwI0CNiu4hSm7mjE0MrEJYWPdgJtXC6xshQ2FusaKuI/UpBv50475OjZ2VRTQrtFcUSPgtpmjJ3HAuSqYIQQJrsFwyc+LT07eINNZfB2B9X3Xlr6POqG6HtpHqVcuwjEkLine truncated
+173
View File
@@ -0,0 +1,173 @@
#include <stdlib.h>
#include <stdint.h>
#include <ft2build.h>
#include <stdio.h>
#include FT_FREETYPE_H
#include <string.h>
#include <strings.h>
#include <ctype.h>
#define N_CHARS 128
#define round_up_26_6(val) (((val) + 63) >> 6u)
int max_advance;
int max_top = -9999;
int min_bottom = 9999;
int line_height;
int baseline_offset;
typedef struct {
int width;
int height;
int top;
int left;
uint8_t * bitmap;
} char_info_t;
static char_info_t char_infos[N_CHARS];
static void load_char(FT_Face face, int char_code)
{
if (FT_Load_Char(face, char_code, FT_LOAD_RENDER) != 0)
{
return;
}
int advance = round_up_26_6(face->glyph->advance.x);
if (advance > max_advance)
{
max_advance = advance;
}
if ((face->glyph->bitmap.width == 0) ||
(face->glyph->bitmap.rows == 0))
{
return;
}
char_infos[char_code].width = face->glyph->bitmap.width;
char_infos[char_code].height = face->glyph->bitmap.rows;
char_infos[char_code].top = face->glyph->bitmap_top;
if (char_infos[char_code].top > max_top)
{
max_top = char_infos[char_code].top;
}
int bottom = char_infos[char_code].top - char_infos[char_code].height;
if (bottom < min_bottom)
{
min_bottom = bottom;
}
char_infos[char_code].left = face->glyph->bitmap_left;
char_infos[char_code].bitmap = malloc(char_infos[char_code].width * char_infos[char_code].height);
memcpy(char_infos[char_code].bitmap,
face->glyph->bitmap.buffer,
char_infos[char_code].width * char_infos[char_code].height);
}
static void generate_bytes(FILE * file, const uint8_t * bytes, int count)
{
for (int i = 0; i < count; i++)
{
if (i % 8 == 0)
{
fprintf(file, " ");
}
fprintf(file, "0x%02xu,", bytes[i]);
if ((i + 1) % 8 == 0)
{
fprintf(file, "\n");
}
else if (i < (count - 1))
{
fprintf(file, " ");
}
}
if (count % 8 != 0)
{
fprintf(file, "\n");
}
}
static void generate(const char * d_file_name)
{
FILE * fh = fopen(d_file_name, "wb");
fprintf(fh, "module hulk.kfont;\n");
fprintf(fh, "struct CharInfo {\n");
fprintf(fh, " uint width;\n");
fprintf(fh, " uint height;\n");
fprintf(fh, " int top;\n");
fprintf(fh, " int left;\n");
fprintf(fh, " const ubyte[] bitmap;\n");
fprintf(fh, "};\n");
fprintf(fh, "struct FontInfo {\n");
fprintf(fh, " uint line_height;\n");
fprintf(fh, " uint advance;\n");
fprintf(fh, " int baseline_offset;\n");
fprintf(fh, " const CharInfo[] chars;\n");
fprintf(fh, "};\n");
fprintf(fh, "__gshared const FontInfo kfont = {\n");
fprintf(fh, " %du,\n", line_height);
fprintf(fh, " %du,\n", max_advance);
fprintf(fh, " %d,\n", baseline_offset);
fprintf(fh, " [\n");
for (int i = 0; i < N_CHARS; i++)
{
fprintf(fh, " CharInfo(\n");
fprintf(fh, " %du,\n", char_infos[i].width);
fprintf(fh, " %du,\n", char_infos[i].height);
fprintf(fh, " %d,\n", char_infos[i].top);
fprintf(fh, " %d,\n", char_infos[i].left);
if (char_infos[i].width > 0)
{
fprintf(fh, " [\n");
generate_bytes(fh, char_infos[i].bitmap, char_infos[i].width * char_infos[i].height);
fprintf(fh, " ]\n");
}
else
{
fprintf(fh, " []\n");
}
fprintf(fh, " ),\n");
}
fprintf(fh, " ],\n");
fprintf(fh, "};\n");
fclose(fh);
}
int main(int argc, char * argv[])
{
/* Expect: font file, size, out file */
if (argc != 4)
{
fprintf(stderr, "Incorrect arguments\n");
return 1;
}
const char * font_file = argv[1];
int size = atoi(argv[2]);
const char * out_file = argv[3];
FT_Library ft_library;
if (FT_Init_FreeType(&ft_library) != 0)
{
fprintf(stderr, "Could not initialize freetype\n");
return 2;
}
FT_Face face;
if (FT_New_Face(ft_library, font_file, 0, &face) != 0)
{
fprintf(stderr, "Could not open %s\n", font_file);
return 3;
}
FT_Set_Pixel_Sizes(face, 0, size);
for (int i = 0; i < N_CHARS; i++)
{
load_char(face, i);
}
line_height = round_up_26_6(face->size->metrics.height);
baseline_offset = (line_height - (max_top - min_bottom)) / 2 - min_bottom;
generate(out_file);
return 0;
}
+181
View File
@@ -0,0 +1,181 @@
/**
* HELLO console support.
*/
module hello.console;
import uefi;
import hello.hello;
import core.stdc.stdarg;
struct console
{
/**
* Format a hexadecimal value to a string.
*
* @param s String buffer.
* @param v Value to format.
* @param ptr If true, always output all 16 digits, and separate the upper and
* lower halves with an underscore.
*/
private static size_t format_hex(CHAR16 * s, ulong v, bool ptr)
{
string hex_chars = "0123456789ABCDEF";
bool print = ptr;
size_t si = 0u;
for (size_t i = 0u; i < 16u; i++)
{
if (ptr && (i == 8u))
{
s[si++] = '_';
}
ulong n = (v >> (60u - 4u * i)) & 0xFu;
if (n != 0u)
{
print = true;
}
if (print || (i == 15u))
{
s[si++] = hex_chars[n];
}
}
return si;
}
/**
* Format a decimal value to a string.
*
* @param s String buffer.
* @param v Value to format.
*/
private static size_t format_dec(CHAR16 * s, ulong v)
{
string dec_chars = "0123456789";
bool print;
char[20] buf;
size_t buf_i;
while ((buf_i == 0u) || (v != 0u))
{
ulong n = v % 10u;
buf[buf_i++] = dec_chars[n];
v /= 10u;
}
for (size_t si = 0u; si < buf_i; si++)
{
s[si] = buf[buf_i - si - 1u];
}
return buf_i;
}
/**
* Write a string to the console.
*
* @param s Format string.
* @param args Variable arguments structure.
*/
public static void write(string s, va_list args)
{
__gshared static CHAR16[256] s16;
size_t i = 0u;
bool escape = false;
foreach (char c; s)
{
if (escape)
{
if (c == '%')
{
s16[i++] = '%';
}
else if (c == 'x')
{
ulong v;
va_arg(args, v);
i += format_hex(&s16[i], v, false);
}
else if (c == 'p')
{
ulong v;
va_arg(args, v);
i += format_hex(&s16[i], v, true);
}
else if (c == 'S')
{
const(CHAR16) * s2;
va_arg(args, s2);
for (size_t s2_i = 0u; s2[s2_i] != 0; s2_i++)
{
s16[i++] = s2[s2_i];
}
}
else if (c == 'u')
{
ulong v;
va_arg(args, v);
i += format_dec(&s16[i], v);
}
else
{
s16[i++] = c;
}
escape = false;
}
else if (c == '%')
{
escape = true;
}
else
{
s16[i++] = c;
}
}
s16[i++] = 0u;
st.ConOut.OutputString(st.ConOut, &s16[0]);
}
/**
* Write a string to the console.
*
* @param s Format string.
*/
public static extern (C) void write(string s, ...)
{
va_list args;
va_start(args, s);
write(s, args);
va_end(args);
}
/**
* Write a string to the console.
*
* @param s Format string.
*/
public static extern (C) void writeln(string s, ...)
{
va_list args;
va_start(args, s);
write(s, args);
write("\r\n", args);
va_end(args);
}
/**
* Write a message to press any key and wait for a key to be pressed.
*/
public static void wait_key()
{
writeln("Press any key...");
st.ConIn.Reset(st.ConIn, FALSE);
EFI_INPUT_KEY key;
while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY)
{
}
}
/**
* Clear the console.
*/
public static void clear()
{
st.ConOut.ClearScreen(st.ConOut);
}
}
+562
View File
@@ -0,0 +1,562 @@
/**
* HELLO, the HOS EFI Lightweight LOader.
*/
module hello.hello;
import uefi;
import hello.console;
import hulk.bootinfo;
import hulk.header;
import hulk.pagetable;
import hulk.cpu;
import hulk.memory;
import ldc.llvmasm;
__gshared EFI_SYSTEM_TABLE * st;
/** HULK binary start address, 4KB-aligned. */
extern extern(C) __gshared ubyte _hulk_bin_start;
/** HULK binary end address, 4KB-aligned. */
extern extern(C) __gshared ubyte _hulk_bin_end;
private align(4096) __gshared ubyte[1024 * 1024] scratch_buffer;
/** Index to the memory map region being used to allocate page tables. */
private __gshared size_t memory_map_page_table_alloc_index;
private HulkHeader * hulk_header()
{
return cast(HulkHeader *)&_hulk_bin_start;
}
private BootInfo * bootinfo()
{
return &hulk_header().bootinfo;
}
private ulong hulk_bin_phys()
{
return cast(ulong)&_hulk_bin_start;
}
private ulong hulk_bin_size()
{
return cast(ulong)&_hulk_bin_end - cast(ulong)&_hulk_bin_start;
}
private ulong hulk_bss_size()
{
return cast(ulong)hulk_header().hulk_bss_size;
}
private ulong hulk_stack_size()
{
return hulk_header().stack_size;
}
private ulong hulk_virt_base_address()
{
return hulk_header().virt_base;
}
private ulong hulk_virt_stack_top()
{
return hulk_header().virt_stack_top;
}
private ulong hulk_virt_framebuffer_address()
{
return hulk_header().virt_fb_buffer;
}
/**
* Detect if we're running in QEMU.
*/
private bool in_qemu()
{
ulong * firmware_vendor = cast(ulong *) st.FirmwareVendor;
ulong fv1 = firmware_vendor[0];
return fv1 ==
((cast(ulong)'E') |
(cast(ulong)'D' << 16) |
(cast(ulong)'K' << 32) |
(cast(ulong)' ' << 48));
}
/**
* Set a graphics mode.
*/
private bool set_graphics_mode()
{
uint max_horizontal_resolution = in_qemu() ? 1920u : 0xFFFFFFFFu;
UINTN buffer_size = scratch_buffer.sizeof;
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_HANDLE * handles = cast(EFI_HANDLE *)&scratch_buffer[0];
EFI_STATUS status = st.BootServices.LocateHandle(ByProtocol,
&gop_guid, null, &buffer_size, handles);
if (status != EFI_SUCCESS)
{
console.writeln("LocateHandle: error %x", status);
return false;
}
EFI_HANDLE gop_handle = handles[0];
EFI_HANDLE gop_interface;
status = st.BootServices.HandleProtocol(gop_handle,
&gop_guid, &gop_interface);
if (status != EFI_SUCCESS)
{
console.writeln("HandleProtocol: error %x", status);
return false;
}
if (gop_interface == null)
{
console.writeln("null interface from HandleProtocol");
return false;
}
EFI_GRAPHICS_OUTPUT_PROTOCOL * gop = cast(EFI_GRAPHICS_OUTPUT_PROTOCOL *)gop_interface;
UINTN info_size;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * info;
uint best_width;
uint best_mode_number;
for (uint mode_number = 0u;
(status = gop.QueryMode(gop, mode_number, &info_size, &info)) == EFI_SUCCESS;
mode_number++)
{
if ((info.HorizontalResolution > best_width) &&
(info.HorizontalResolution <= max_horizontal_resolution))
{
best_width = info.HorizontalResolution;
best_mode_number = mode_number;
}
st.BootServices.FreePool(info);
}
if ((status = gop.SetMode(gop, best_mode_number)) != EFI_SUCCESS)
{
console.writeln("SetMode: Error %x\n", status);
return false;
}
bootinfo().fb.buffer = cast(uint *)gop.Mode.FrameBufferBase;
bootinfo().fb.width = gop.Mode.Info.HorizontalResolution;
bootinfo().fb.height = gop.Mode.Info.VerticalResolution;
bootinfo().fb.stride = gop.Mode.Info.PixelsPerScanLine;
bootinfo().fb.format = gop.Mode.Info.PixelFormat;
return true;
}
/**
* Walk the EFI memory map and translate it to the HULK bootinfo format.
*/
private void get_memory_map(ulong * physical_address_limit, UINTN * memory_map_key)
{
immutable static ubyte[] efi_to_hulk_memory_map_type = [
BootInfo.MemoryRegion.Type.Reserved, // EfiReservedMemoryType
BootInfo.MemoryRegion.Type.Bootloader, // EfiLoaderCode
BootInfo.MemoryRegion.Type.Bootloader, // EfiLoaderData
BootInfo.MemoryRegion.Type.Bootloader, // EfiBootServicesCode
BootInfo.MemoryRegion.Type.Bootloader, // EfiBootServicesData
BootInfo.MemoryRegion.Type.Reserved, // EfiRuntimeServicesCode
BootInfo.MemoryRegion.Type.Reserved, // EfiRuntimeServicesData
BootInfo.MemoryRegion.Type.Conventional, // EfiConventionalMemory
BootInfo.MemoryRegion.Type.Unusable, // EfiUnusableMemory
BootInfo.MemoryRegion.Type.ACPIReclaim, // EfiACPIReclaimMemory
BootInfo.MemoryRegion.Type.ACPINVS, // EfiACPIMemoryNVS
BootInfo.MemoryRegion.Type.MemoryMappedIO, // EfiMemoryMappedIO
BootInfo.MemoryRegion.Type.MemoryMappedIOPortSpace, // EfiMemoryMappedIOPortSpace
BootInfo.MemoryRegion.Type.PalCode, // EfiPalCode
];
*physical_address_limit = 0u;
UINTN memory_map_size = scratch_buffer.sizeof;
UINTN descriptor_size;
UINT32 descriptor_version;
ubyte * scratch_base = cast(ubyte *)&scratch_buffer[0];
UINTN status = st.BootServices.GetMemoryMap(
&memory_map_size,
cast(EFI_MEMORY_DESCRIPTOR *)scratch_base,
memory_map_key,
&descriptor_size,
&descriptor_version);
if (status != EFI_SUCCESS)
{
console.writeln("GetMemoryMap: Error %x", status);
for (;;) {}
}
size_t n_entries = memory_map_size / descriptor_size;
size_t count;
bool found_bss;
bool found_stack;
bool found_fb_buffer1;
const(size_t) fb_size = (bootinfo().fb.stride * bootinfo().fb.height * 4u + PAGE_SIZE - 1u) & ~(PAGE_SIZE - 1u);
for (count = 0u; count < n_entries; count++)
{
if (count > bootinfo().memory_map.length)
{
console.writeln("Memory map too large");
for (;;) {}
}
EFI_MEMORY_DESCRIPTOR * descriptor = cast(EFI_MEMORY_DESCRIPTOR *)&scratch_base[count * descriptor_size];
ulong end_address = descriptor.PhysicalStart + descriptor.NumberOfPages * 4096u;
if ((end_address > *physical_address_limit) &&
((descriptor.Type == EfiLoaderCode) ||
(descriptor.Type == EfiLoaderData) ||
(descriptor.Type == EfiBootServicesCode) ||
(descriptor.Type == EfiBootServicesData) ||
(descriptor.Type == EfiRuntimeServicesCode) ||
(descriptor.Type == EfiRuntimeServicesData) ||
(descriptor.Type == EfiConventionalMemory)))
{
*physical_address_limit = end_address;
}
if (descriptor.Type >= efi_to_hulk_memory_map_type.length)
{
continue;
}
bootinfo().memory_map[count].base = descriptor.PhysicalStart;
bootinfo().memory_map[count].size = descriptor.NumberOfPages * 4096u;
bootinfo().memory_map[count].type = efi_to_hulk_memory_map_type[descriptor.Type];
if ((!found_bss) &&
(descriptor.Type == EfiConventionalMemory) &&
(bootinfo().memory_map[count].size >= hulk_bss_size()))
{
bootinfo().bss_phys = bootinfo().memory_map[count].base;
bootinfo().memory_map[count].base += hulk_bss_size();
bootinfo().memory_map[count].size -= hulk_bss_size();
found_bss = true;
}
if ((!found_stack) &&
(descriptor.Type == EfiConventionalMemory) &&
(bootinfo().memory_map[count].size >= hulk_stack_size()))
{
bootinfo().stack_phys = bootinfo().memory_map[count].base;
bootinfo().memory_map[count].base += hulk_stack_size();
bootinfo().memory_map[count].size -= hulk_stack_size();
found_stack = true;
}
if ((!found_fb_buffer1) &&
(descriptor.Type == EfiConventionalMemory) &&
(bootinfo().memory_map[count].size >= fb_size))
{
bootinfo().fb_buffer1_phys = bootinfo().memory_map[count].base;
bootinfo().memory_map[count].base += fb_size;
bootinfo().memory_map[count].size -= fb_size;
found_fb_buffer1 = true;
}
}
bootinfo().memory_map_count = count;
if ((!found_bss) || (!found_stack) || (!found_fb_buffer1))
{
for (;;) {}
}
}
private void * alloc_pt_page()
{
BootInfo.MemoryRegion * regions = &bootinfo().memory_map[0];
for (;;)
{
BootInfo.MemoryRegion * region = &bootinfo().memory_map[memory_map_page_table_alloc_index];
if ((region.type == BootInfo.MemoryRegion.Type.Conventional) && (region.size >= PAGE_SIZE))
{
void * addr = cast(void *)region.base;
region.base += PAGE_SIZE;
region.size -= PAGE_SIZE;
return addr;
}
memory_map_page_table_alloc_index++;
if (memory_map_page_table_alloc_index >= bootinfo().memory_map_count)
{
return null;
}
}
}
/**
* Allocate a new page table.
*/
private PageTable * new_page_table()
{
PageTable * pt = cast(PageTable *)alloc_pt_page();
if (pt == null)
{
return null;
}
memset64(pt, 0u, 512);
return pt;
}
/**
* Map a virtual address to a physical address using 4KB pages.
*
* @param source_page Source page address.
* @param dest_page Destination page address.
* @param pt_base Page table base address.
*/
private bool map4k(ulong source_page, ulong dest_page, PageTable * pt_base)
{
PageTable * pt = pt_base;
for (size_t level = 0; level < 4u; level++)
{
PageTableEntry * ppte = pt.entry(source_page, level);
PageTableEntry pte = *ppte;
if (pte.present)
{
pt = pte.follow();
}
else
{
PageTable * next_pt;
ulong addr;
if (level < 3u)
{
next_pt = new_page_table();
if (next_pt == null)
{
return false;
}
addr = cast(ulong)next_pt;
}
else
{
addr = dest_page;
}
*ppte = PageTableEntry(addr, PT_WRITABLE | PT_PRESENT);
pt = next_pt;
}
}
return true;
}
/**
* Map a virtual region to a physical region using 4KB pages.
*
* @param source Source address.
* @param dest Destination address.
* @param size Region size.
* @param pt_base Page table base address.
*/
private bool map4kregion(ulong source, ulong dest, size_t size, PageTable * pt_base)
{
ulong end = source + size;
while (source < end)
{
if (!map4k(source, dest, pt_base))
{
return false;
}
source += 4096u;
dest += 4096u;
}
return true;
}
/**
* Map a virtual address to a physical address using 2MB pages.
*
* @param source_page Source page address.
* @param dest_page Destination page address.
* @param pt_base Page table base address.
*/
private bool map2m(ulong source_page, ulong dest_page, PageTable * pt_base)
{
PageTable * pt = pt_base;
for (size_t level = 0; level < 3u; level++)
{
PageTableEntry * ppte = pt.entry(source_page, level);
PageTableEntry pte = *ppte;
if (pte.present)
{
pt = pte.follow();
}
else
{
PageTable * next_pt;
if (level < 2u)
{
next_pt = new_page_table();
if (next_pt == null)
{
return false;
}
*ppte = PageTableEntry(next_pt, PT_WRITABLE | PT_PRESENT);
}
else
{
*ppte = PageTableEntry(dest_page, PT_HUGE_PAGE | PT_WRITABLE | PT_PRESENT);
}
pt = next_pt;
}
}
return true;
}
/**
* Map HULK virtual addresses to physical kernel location.
*
* @param pt_base Page table base address.
*/
private bool map_hulk(PageTable * pt_base)
{
/* Map HULK bin region. */
ulong virt = hulk_virt_base_address();
if (!map4kregion(virt, hulk_bin_phys(), hulk_bin_size(), pt_base))
{
return false;
}
/* Map HULK bss region. */
virt += hulk_bin_size();
if (!map4kregion(virt, bootinfo().bss_phys, hulk_bss_size(), pt_base))
{
return false;
}
/* Map HULK stack. */
virt = hulk_virt_stack_top() - hulk_stack_size();
if (!map4kregion(virt, bootinfo().stack_phys, hulk_stack_size(), pt_base))
{
return false;
}
return true;
}
/**
* Build page tables in preparation to jump to HULK.
*
* @param physical_address_limit Maximum physical address to identity map.
*/
private bool build_page_tables(ulong physical_address_limit)
{
PageTable * pt_base = new_page_table();
if (pt_base == null)
{
return false;
}
/* Map physical RAM. */
for (size_t addr = 0u; addr < physical_address_limit; addr += (2u * 1024u * 1024u))
{
if (!map2m(addr, addr, pt_base))
{
return false;
}
}
/* Map any memory regions that are outside physical RAM. */
for (size_t i = 0u; i < bootinfo().memory_map_count; i++)
{
ulong addr = bootinfo().memory_map[i].base;
if (addr >= physical_address_limit)
{
if (!map4kregion(addr, addr, bootinfo().memory_map[i].size, pt_base))
{
return false;
}
}
}
/* Map graphics framebuffer. */
ulong framebuffer_size = bootinfo().fb.height * bootinfo().fb.stride * 4u;
ulong fb_phys = cast(ulong)bootinfo().fb.buffer;
ulong fb_virt = hulk_virt_framebuffer_address();
if (!map4kregion(fb_virt, fb_phys, framebuffer_size, pt_base))
{
return false;
}
/* Map HULK regions. */
if (!map_hulk(pt_base))
{
return false;
}
/* Switch to the new page table. */
write_cr3(cast(ulong)pt_base);
return true;
}
/**
* Jump to HULK entry point.
*/
private void jump_to_hulk()
{
__asm(
"jmpq *$0",
"r,{rsp}",
hulk_header().entry, hulk_virt_stack_top());
}
/**
* Find the ACPI XSDT.
*
* @return Whether it was found.
*/
private bool find_acpi_xsdt()
{
for (size_t i = 0u; i < st.NumberOfTableEntries; i++)
{
if ((st.ConfigurationTable[i].VendorGuid == EFI_ACPI_TABLE_GUID) ||
(st.ConfigurationTable[i].VendorGuid == ACPI_TABLE_GUID))
{
enum ulong rsdp_magic = 0x20525450_20445352u;
const(EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER) * rdsp = cast(const(EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER) *)st.ConfigurationTable[i].VendorTable;
if (rdsp.Signature == rsdp_magic)
{
if (rdsp.Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION)
{
bootinfo().acpi_xsdt_phys = rdsp.XsdtAddress;
return true;
}
}
}
}
return false;
}
/**
* EFI application entry point.
*
* @param image_handle EFI application handle.
* @param st Pointer to EFI system table.
*/
extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st)
{
.st = st;
console.clear();
console.writeln("Welcome to HELLO, HOS EFI Lightweight LOader, v0.1.0");
console.writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor);
if (!find_acpi_xsdt())
{
console.writeln("Error: Could not locate ACPI XSDT");
console.wait_key();
return EFI_SUCCESS;
}
if (!set_graphics_mode())
{
console.wait_key();
return EFI_SUCCESS;
}
ulong physical_address_limit;
UINTN memory_map_key;
for (;;)
{
get_memory_map(&physical_address_limit, &memory_map_key);
EFI_STATUS status = st.BootServices.ExitBootServices(image_handle, memory_map_key);
if (status == EFI_INVALID_PARAMETER)
{
continue;
}
if (status == EFI_SUCCESS)
{
break;
}
console.writeln("ExitBootServices: Error %x", status);
console.wait_key();
return EFI_SUCCESS;
}
if (!build_page_tables(physical_address_limit))
{
return EFI_SUCCESS;
}
bootinfo().hulk_phys = hulk_bin_phys();
jump_to_hulk();
return EFI_SUCCESS;
}
+102
View File
@@ -0,0 +1,102 @@
/**
* ACPI (Advanced Configuration and Power Interface) functionality.
*/
module hulk.acpi;
import hulk.hurl;
import hulk.klog;
import hulk.memory;
struct acpi
{
enum uint APIC_SIGNATURE = 0x43495041u;
enum uint XSDT_SIGNATURE = 0x54445358u;
static struct XsdtHeader
{
uint signature;
uint length;
ubyte revision;
ubyte checksum;
char[6] oemid;
ulong oemtableid;
uint oem_revision;
uint creator_id;
uint creator_revision;
}
static struct Xsdt
{
XsdtHeader header;
uint _pad;
ulong[0] tables;
}
static struct MadtHeader
{
uint signature;
uint length;
ubyte revision;
ubyte checksum;
char[6] oemid;
ulong oemtableid;
uint oem_revision;
uint creator_id;
uint creator_revision;
uint local_apic_address;
uint flags;
}
static struct MadtEntry
{
ubyte type;
ubyte length;
}
public static __gshared ulong apic_address;
public static void initialize(ulong acpi_xsdt_phys)
{
/* Map the XSDT header. */
hurl.identity_map_range(acpi_xsdt_phys, Xsdt.sizeof, 0u);
const(Xsdt) * xsdt = cast(const(Xsdt) *)acpi_xsdt_phys;
if (xsdt.header.signature != XSDT_SIGNATURE)
{
klog.writef("XSDT signature invalid\n");
return;
}
/* Map the entire XSDT. */
hurl.identity_map_range(acpi_xsdt_phys, xsdt.header.length, 0u);
size_t n_entries = (xsdt.header.length - xsdt.header.sizeof) / xsdt.tables[0].sizeof;
for (size_t i = 0u; i < n_entries; i++)
{
ulong address = xsdt.tables[i];
hurl.identity_map_range(address, 4u, 0u);
uint signature = *cast(const(uint) *)address;
if (signature == APIC_SIGNATURE)
{
parse_apic_table(address);
}
}
}
private static parse_apic_table(ulong address)
{
const(MadtHeader) * madt_header = cast(const(MadtHeader) *)address;
hurl.identity_map_range(address, madt_header.length, 0u);
apic_address = madt_header.local_apic_address;
klog.writefln("Found 32-bit APIC address: 0x%x", apic_address);
const(void) * madt_end = cast(const(void) *)(address + madt_header.length);
const(MadtEntry) * madt_entry = cast(const(MadtEntry) *)(address + 0x2Cu);
while (madt_entry < madt_end)
{
madt_entry = cast(const(MadtEntry) *)(cast(size_t)madt_entry + madt_entry.length);
if (madt_entry.type == 5u)
{
/* Found a 64-bit Local APIC Address Override entry. */
memcpy(cast(void *)&apic_address, cast(const(void) *)madt_entry + 4u, 8u);
klog.writefln("Found 64-bit APIC address: 0x%x", apic_address);
}
}
}
}
+104
View File
@@ -0,0 +1,104 @@
/**
* APIC (Advanced Programmable Interrupt Controller) functionality.
*/
module hulk.apic;
import hulk.klog;
import hulk.hurl;
import hulk.acpi;
import hulk.idt;
struct apic
{
private enum uint PERIODIC_MODE = 0x2_0000u;
static struct ApicRegister
{
public uint value;
alias value this;
private ubyte[12] _padding;
}
static struct ApicRegisters
{
ApicRegister[2] _reserved0;
ApicRegister lapic_id;
ApicRegister lapic_version;
ApicRegister[4] _reserved1;
ApicRegister task_priority;
ApicRegister arbitration_priority;
ApicRegister processor_priority;
ApicRegister eoi;
ApicRegister remote_read;
ApicRegister logical_destination;
ApicRegister destination_format;
ApicRegister spurious_interrupt_vector;
ApicRegister[8] in_service;
ApicRegister[8] trigger_mode;
ApicRegister[8] interrupt_request;
ApicRegister error_status;
ApicRegister[6] _reserved2;
ApicRegister lvt_cmci;
ApicRegister[2] interrupt_command;
ApicRegister lvt_timer;
ApicRegister lvt_thermal_sensor;
ApicRegister lvt_performance_monitoring_counters;
ApicRegister[2] lvt_lint;
ApicRegister lvt_error;
ApicRegister initial_count;
ApicRegister current_count;
ApicRegister[4] _reserved3;
ApicRegister divide_configuration;
}
static struct IoApicRegisters
{
ApicRegister address;
ApicRegister data;
}
private static __gshared ApicRegisters * apic_registers;
private static __gshared IoApicRegisters * io_apic_registers;
public static void initialize()
{
apic_registers = cast(ApicRegisters *)acpi.apic_address;
io_apic_registers = cast(IoApicRegisters *)0xFEC0_0000u;
hurl.map(cast(ulong)apic_registers, cast(ulong)apic_registers,
PT_WRITABLE | PT_WRITE_THROUGH | PT_DISABLE_CACHE | PT_NO_EXECUTE);
hurl.map(cast(ulong)io_apic_registers, cast(ulong)io_apic_registers,
PT_WRITABLE | PT_WRITE_THROUGH | PT_DISABLE_CACHE | PT_NO_EXECUTE);
klog.writefln("LAPIC ID: 0x%08x", apic_registers.lapic_id.value);
klog.writefln("LAPIC version: 0x%08x", apic_registers.lapic_version.value);
/* Enable local APIC to receive interrupts and set spurious interrupt
* vector to 0xFF. */
apic_registers.spurious_interrupt_vector.value = 0x1FFu;
// apic_registers.lvt_timer.value = idt.INT_LAPIC_TIMER | PERIODIC_MODE;
apic_registers.lvt_timer.value = idt.INT_LAPIC_TIMER;
apic_registers.lvt_lint[0].value = idt.INT_LAPIC_LINT0;
apic_registers.lvt_lint[1].value = idt.INT_LAPIC_LINT1;
// apic_registers.divide_configuration.value = 3u;
configure_io_apic_irq(8u, 0x48u);
}
private static void configure_io_apic_irq(size_t io_apic_irq, size_t interrupt_id)
{
ulong entry = interrupt_id;
io_apic_registers.address.value = cast(uint)(0x10u + io_apic_irq * 2u);
io_apic_registers.data.value = entry & 0xFFFF_FFFFu;
io_apic_registers.address.value = cast(uint)(0x10u + io_apic_irq * 2u + 1u);
io_apic_registers.data.value = entry >> 32u;
}
public static void eoi()
{
apic_registers.eoi.value = 0u;
}
public static void isr(ulong vector)
{
klog.writefln("APIC ISR 0x%x", vector);
eoi();
}
}
+77
View File
@@ -0,0 +1,77 @@
/**
* HULK boot information.
*/
module hulk.bootinfo;
/**
* HULK boot information structure.
*/
struct BootInfo
{
/**
* Framebuffer description structure.
*/
struct Framebuffer
{
/** Framebuffer physical base address. */
uint * buffer;
/** Horizontal resolution. */
uint width;
/** Vertical resolution. */
uint height;
/** Number of pixels per scan line. */
uint stride;
/** Pixel format. */
uint format;
}
/**
* Memory map entry description structure.
*/
struct MemoryRegion
{
enum Type
{
Reserved,
Bootloader,
Conventional,
Unusable,
ACPIReclaim,
ACPINVS,
MemoryMappedIO,
MemoryMappedIOPortSpace,
PalCode,
}
/** Base address of the memory region. */
ulong base;
/** Size in bytes of the memory region. */
size_t size;
/** Type of the memory region. */
ubyte type;
}
/* Framebuffer parameters. */
Framebuffer fb;
/* Memory map. */
MemoryRegion[1000] memory_map;
/* Number of memory map entries. */
size_t memory_map_count;
/* Physical address of HULK. */
ulong hulk_phys;
/* Physical address used for HULK bss section. */
ulong bss_phys;
/* Physical address of stack while jumping to HULK. */
ulong stack_phys;
/* Physical address of framebuffer buffer1. */
ulong fb_buffer1_phys;
/* Physical address of ACPI XSDT table. */
ulong acpi_xsdt_phys;
}
+102
View File
@@ -0,0 +1,102 @@
/**
* HULK Console functionality.
*/
module hulk.console;
import hulk.fb;
import hulk.kfont;
struct console
{
/** Console width in text columns. */
private static __gshared size_t m_width;
/** Console height in text rows. */
private static __gshared size_t m_height;
/** Current console cursor X position. */
private static __gshared size_t m_x;
/** Current console cursor Y position. */
private static __gshared size_t m_y;
/**
* Initialize the console.
*/
public static void initialize()
{
m_width = fb.width / kfont.advance;
m_height = fb.height / kfont.line_height;
}
/**
* Clear the console.
*/
public static void clear()
{
fb.clear();
m_x = 0u;
m_y = 0u;
}
/**
* Write a character to the console.
*
* @param ch Character to write.
*/
public static void write(char ch)
{
if (ch == '\n')
{
m_x = 0u;
m_y++;
}
else
{
render_char(m_x, m_y, ch);
m_x++;
if (m_x == m_width)
{
m_x = 0u;
m_y++;
}
}
if (m_y == m_height)
{
m_y--;
fb.copy_rows_up(fb_y(m_height - 1u),
(m_height - 1u) * kfont.line_height,
kfont.line_height);
fb.rect(0u, fb_y(m_height - 1u), fb_x(m_width), kfont.line_height, 0u);
}
}
/**
* Render a character.
*
* @param x X position.
* @param y Y position.
* @param ch Character to render.
*/
private static void render_char(size_t x, size_t y, char ch)
{
const(CharInfo) * ci = &kfont.chars[ch];
fb.blit_alpha_bitmap(fb_x(x) + ci.left, fb_y(y) + ci.top - ci.height, ci.bitmap, ci.width, ci.height);
}
/**
* Get the framebuffer X coordinate corresponding to the console X position.
*/
private static size_t fb_x(size_t x)
{
return x * kfont.advance;
}
/**
* Get the framebuffer Y coordinate corresponding to the console Y position.
*/
private static size_t fb_y(size_t y)
{
return fb.height - ((y + 1u) * kfont.line_height);
}
}
+247
View File
@@ -0,0 +1,247 @@
/**
* CPU functionality.
*/
module hulk.cpu;
import ldc.llvmasm;
/** CR0 bits. @{ */
enum ulong CR0_PE = 0x1u;
enum ulong CR0_MP = 0x2u;
enum ulong CR0_EM = 0x4u;
enum ulong CR0_TS = 0x8u;
enum ulong CR0_ET = 0x10u;
enum ulong CR0_NE = 0x20u;
enum ulong CR0_WP = 0x1_0000u;
enum ulong CR0_AM = 0x4_0000u;
enum ulong CR0_NW = 0x2000_0000u;
enum ulong CR0_CD = 0x4000_0000u;
enum ulong CR0_PG = 0x8000_0000u;
/** @} */
/** CR4 bits. @{ */
enum ulong CR4_VME = 0x1u;
enum ulong CR4_PVI = 0x2u;
enum ulong CR4_TSD = 0x4u;
enum ulong CR4_DE = 0x8u;
enum ulong CR4_PSE = 0x10u;
enum ulong CR4_PAE = 0x20u;
enum ulong CR4_MCE = 0x40u;
enum ulong CR4_PGE = 0x80u;
enum ulong CR4_PCE = 0x100u;
enum ulong CR4_OSFXSR = 0x200u;
enum ulong CR4_OSXMMEXCPT = 0x400u;
enum ulong CR4_UMIP = 0x800u;
enum ulong CR4_VMXE = 0x2000u;
enum ulong CR4_SMXE = 0x4000u;
enum ulong CR4_FSGSBASE = 0x1_0000u;
enum ulong CR4_PCIDE = 0x2_0000u;
enum ulong CR4_OSXSAVE = 0x4_0000u;
enum ulong CR4_SMEP = 0x10_0000u;
enum ulong CR4_SMAP = 0x20_0000u;
enum ulong CR4_PKE = 0x40_0000u;
enum ulong CR4_CET = 0x80_0000u;
enum ulong CR4_PKS = 0x100_0000u;
/** @} */
/** XCR0 bits. @{ */
enum ulong XCR0_X87 = 0x1u;
enum ulong XCR0_SSE = 0x2u;
enum ulong XCR0_AVX = 0x4u;
enum ulong XCR0_BNDREG = 0x8u;
enum ulong XCR0_BNDSCR = 0x10u;
enum ulong XCR0_OPMASK = 0x20u;
enum ulong XCR0_ZMM_HI256 = 0x40u;
enum ulong XCR0_HI16_ZMM = 0x80u;
enum ulong XCR0_PKRU = 0x100u;
/** @} */
/** MSR register numbers. @{ */
enum uint MSR_EFER = 0xC000_0080u;
/** @} */
/** EFER flags. @{ */
enum uint EFER_SCE = 0x1u;
enum uint EFER_LME = 0x100u;
enum uint EFER_LMA = 0x400u;
enum uint EFER_NXE = 0x800u;
enum uint EFER_SVME = 0x1000u;
enum uint EFER_LMSLE = 0x2000u;
enum uint EFER_FFXSR = 0x4000u;
enum uint EFER_TCE = 0x8000u;
/** @} */
/** CPUID 1 bits. @{ */
enum uint CPUID_1_EDX_FPU = 0x1u;
enum uint CPUID_1_EDX_VME = 0x2u;
enum uint CPUID_1_EDX_DE = 0x4u;
enum uint CPUID_1_EDX_PSE = 0x8u;
enum uint CPUID_1_EDX_TSC = 0x10u;
enum uint CPUID_1_EDX_MSR = 0x20u;
enum uint CPUID_1_EDX_PAE = 0x40u;
enum uint CPUID_1_EDX_MCE = 0x80u;
enum uint CPUID_1_EDX_CX8 = 0x100u;
enum uint CPUID_1_EDX_APIC = 0x200u;
enum uint CPUID_1_EDX_SEP = 0x800u;
enum uint CPUID_1_EDX_MTRR = 0x1000u;
enum uint CPUID_1_EDX_PGE = 0x2000u;
enum uint CPUID_1_EDX_MCA = 0x4000u;
enum uint CPUID_1_EDX_CMOV = 0x8000u;
enum uint CPUID_1_EDX_PAT = 0x1_0000u;
enum uint CPUID_1_EDX_PSE36 = 0x2_0000u;
enum uint CPUID_1_EDX_PSN = 0x4_0000u;
enum uint CPUID_1_EDX_CLFSH = 0x8_0000u;
enum uint CPUID_1_EDX_DS = 0x20_0000u;
enum uint CPUID_1_EDX_ACPI = 0x40_0000u;
enum uint CPUID_1_EDX_MMX = 0x80_0000u;
enum uint CPUID_1_EDX_FXSR = 0x100_0000u;
enum uint CPUID_1_EDX_SSE = 0x200_0000u;
enum uint CPUID_1_EDX_SSE2 = 0x400_0000u;
enum uint CPUID_1_EDX_SS = 0x800_0000u;
enum uint CPUID_1_EDX_HTT = 0x1000_0000u;
enum uint CPUID_1_EDX_TM = 0x2000_0000u;
enum uint CPUID_1_EDX_IA64 = 0x4000_0000u;
enum uint CPUID_1_EDX_PBE = 0x8000_0000u;
enum uint CPUID_1_ECX_SSE3 = 0x1u;
enum uint CPUID_1_ECX_PCLMULQDQ = 0x2u;
enum uint CPUID_1_ECX_DTES64 = 0x4u;
enum uint CPUID_1_ECX_MONITOR = 0x8u;
enum uint CPUID_1_ECX_DSCPL = 0x10u;
enum uint CPUID_1_ECX_VMX = 0x20u;
enum uint CPUID_1_ECX_SMX = 0x40u;
enum uint CPUID_1_ECX_EST = 0x80u;
enum uint CPUID_1_ECX_TM2 = 0x100u;
enum uint CPUID_1_ECX_SSSE3 = 0x200u;
enum uint CPUID_1_ECX_CNXTID = 0x400u;
enum uint CPUID_1_ECX_SDBG = 0x800u;
enum uint CPUID_1_ECX_FMA = 0x1000u;
enum uint CPUID_1_ECX_CX16 = 0x2000u;
enum uint CPUID_1_ECX_XTPR = 0x4000u;
enum uint CPUID_1_ECX_PDCM = 0x8000u;
enum uint CPUID_1_ECX_PCID = 0x2_0000u;
enum uint CPUID_1_ECX_DCA = 0x4_0000u;
enum uint CPUID_1_ECX_SSE41 = 0x8_0000u;
enum uint CPUID_1_ECX_SSE42 = 0x10_0000u;
enum uint CPUID_1_ECX_X2APIC = 0x20_0000u;
enum uint CPUID_1_ECX_MOVBE = 0x40_0000u;
enum uint CPUID_1_ECX_POPCNT = 0x80_0000u;
enum uint CPUID_1_ECX_TSCDEADLINE = 0x100_0000u;
enum uint CPUID_1_ECX_AES = 0x200_0000u;
enum uint CPUID_1_ECX_XSAVE = 0x400_0000u;
enum uint CPUID_1_ECX_OSXSAVE = 0x800_0000u;
enum uint CPUID_1_ECX_AVX = 0x1000_0000u;
enum uint CPUID_1_ECX_F16C = 0x2000_0000u;
enum uint CPUID_1_ECX_RDRND = 0x4000_0000u;
enum uint CPUID_1_ECX_HYPERVISOR = 0x8000_0000u;
/** @} */
void cli()
{
__asm("cli", "");
}
void sti()
{
__asm("sti", "");
}
void hlt()
{
__asm("hlt", "");
}
ulong read_cr0()
{
return __asm!ulong("mov %cr0, %rax", "={rax}");
}
void write_cr0(ulong v)
{
__asm("mov $0, %cr0", "r", v);
}
ulong read_cr2()
{
return __asm!ulong("mov %cr2, %rax", "={rax}");
}
ulong read_cr3()
{
return __asm!ulong("mov %cr3, %rax", "={rax}");
}
void write_cr3(ulong v)
{
__asm("mov $0, %cr3", "r", v);
}
ulong read_cr4()
{
return __asm!ulong("mov %cr4, %rax", "={rax}");
}
void write_cr4(ulong v)
{
__asm("mov $0, %cr4", "r", v);
}
ulong rdmsr(uint msr)
{
return __asm!ulong(`
rdmsr
shl $$32, %rdx
or %rdx, %rax`, "={rax},{ecx},~{rdx}", msr);
}
void wrmsr(uint msr, ulong value)
{
__asm(`wrmsr`, "{ecx},{edx},{eax}", msr, value >> 32u, value);
}
ulong xgetbv(uint xcr)
{
return __asm!ulong(`
xgetbv
shl $$32, %rdx
or %rdx, %rax`, "={rax},{ecx},~{rdx}", xcr);
}
void xsetbv(uint xcr, ulong value)
{
__asm(`xsetbv`, "{ecx},{edx},{eax}", xcr, value >> 32u, value);
}
ubyte in8(ushort ioaddr)
{
return __asm!ubyte("inb %dx, %al", "={al},{dx}", ioaddr);
}
ushort in16(ushort ioaddr)
{
return __asm!ushort("inw %dx, %ax", "={ax},{dx}", ioaddr);
}
ulong in32(ushort ioaddr)
{
return __asm!ulong("inl %dx, %eax", "={eax},{dx}", ioaddr);
}
void out8(ushort ioaddr, ubyte v)
{
__asm("outb %al, %dx", "{dx},{al}", ioaddr, v);
}
void out16(ushort ioaddr, ushort v)
{
__asm("outw %ax, %dx", "{dx},{ax}", ioaddr, v);
}
void out32(ushort ioaddr, ulong v)
{
__asm("outl %eax, %dx", "{dx},{eax}", ioaddr, v);
}
void cpuid1(uint * ebx, uint * ecx, uint * edx)
{
__asm("cpuid", "=*{ebx},=*{ecx},=*{edx},{eax}", ebx, ecx, edx, 1u);
}
+292
View File
@@ -0,0 +1,292 @@
/**
* HULK Framebuffer support.
*/
module hulk.fb;
import hulk.memory;
import hulk.kfont;
/**
* Represent a graphical frame buffer.
*
* TODO: Handle other pixel formats. Currently only BGRx is supported.
*/
struct fb
{
/** Device frame buffer base address. */
private __gshared static uint * m_device_buffer;
/** Frame buffer 1 base address. */
private __gshared static uint * m_buffer1;
/** Frame buffer width. */
private __gshared static uint m_width;
/** Frame buffer height. */
private __gshared static uint m_height;
/** Frame buffer stride. */
private __gshared static uint m_stride;
/** Number of pixels in the frame buffer (whether visible or not). */
private __gshared static uint m_buffer_size;
/**
* Get the framebuffer width.
*/
public static @property uint width()
{
return m_width;
}
/**
* Get the framebuffer height.
*/
public static @property uint height()
{
return m_height;
}
/**
* Initialize a frame buffer.
*
* @param device_buffer Device frame buffer base address.
* @param buffer1 Frame buffer 1 base address.
* @param width Frame buffer width.
* @param height Frame buffer height.
* @param stride Frame buffer stride.
*/
static void initialize(uint * device_buffer, uint * buffer1, uint width, uint height, uint stride)
{
m_device_buffer = device_buffer;
m_buffer1 = buffer1;
m_width = width;
m_height = height;
m_stride = stride;
m_buffer_size = stride * height;
}
/**
* Clear the frame buffer to the given color.
*
* @param color Color to clear to.
*/
static void clear(uint color = 0u)
{
memset32(m_buffer1, color, m_buffer_size);
memset32(m_device_buffer, color, m_buffer_size);
}
/**
* Draw a solid rectangle on the framebuffer.
*
* @param x X coordinate of left side of rectangle.
* @param y Y coordinate of bottom side of rectangle.
* @param width Width of rectangle.
* @param height Height of rectangle.
* @param color Color of rectangle.
*/
static void rect(size_t x, size_t y, size_t width, size_t height, uint color)
{
for (size_t iy = 0u; iy < height; iy++)
{
size_t buffer_index = buffer_index(x, y);
memset32(&m_buffer1[buffer_index], color, width);
memset32(&m_device_buffer[buffer_index], color, width);
y++;
}
}
/**
* Draw a horizontal line.
*
* @param x X coordinate of left side of line.
* @param y Y coordinate of line.
* @param width Width of line.
* @param color Color of line.
*/
static void hline(size_t x, size_t y, size_t width, uint color)
{
size_t buffer_index = buffer_index(x, y);
memset32(&m_buffer1[buffer_index], color, width);
memset32(&m_device_buffer[buffer_index], color, width);
}
/**
* Draw a vertical line.
*
* @param x X coordinate of line.
* @param y Y coordinate of bottom of line.
* @param height Height of line.
* @param color Color of line.
*/
static void vline(size_t x, size_t y, size_t height, uint color)
{
size_t buffer_index = buffer_index(x, y);
for (size_t iy = 0u; iy < height; iy++)
{
m_buffer1[buffer_index] = color;
m_device_buffer[buffer_index] = color;
buffer_index -= m_stride;
}
}
/**
* Draw a character.
*
* @param x X coordinate of left side of character.
* @param y Y coordinate of bottom side of character.
* @param ch Character to draw.
* @param color Color of character.
*/
static void character(int x, int y, char ch, uint color)
{
const(CharInfo) * ci = &kfont.chars[ch];
blend_alpha_bitmap(x + ci.left, y + kfont.baseline_offset + ci.top - ci.height, ci.bitmap, ci.width, ci.height, color);
}
/**
* Blend an 8-bit alpha bitmap to the framebuffer.
*
* @param x X coordinate of left side of target location.
* @param y Y coordinate of bottom side of target location.
* @param alpha_bitmap 8-bit alpha-channel bitmap.
* @param width Bitmap width.
* @param height Bitmap height.
* @param color Color to blend with alpha value.
*/
static void blend_alpha_bitmap(size_t x, size_t y, const(ubyte) * alpha_bitmap,
size_t width, size_t height, uint color)
{
y += height - 1u;
size_t bitmap_index;
for (size_t iy = 0u; iy < height; iy++)
{
size_t row_buffer_index = buffer_index(x, y);
for (size_t ix = 0u; ix < width; ix++)
{
size_t buffer_index = row_buffer_index + ix;
ubyte alpha = alpha_bitmap[bitmap_index];
uint current_color = m_buffer1[buffer_index];
uint in_color_scaled = scale_color(color, alpha);
uint old_color_scaled = scale_color(current_color, 255u - alpha);
uint new_color = old_color_scaled + in_color_scaled;
m_buffer1[buffer_index] = new_color;
bitmap_index++;
}
memcpy32(&m_device_buffer[row_buffer_index], &m_buffer1[row_buffer_index], width);
y--;
}
}
/**
* Blend an 8-bit alpha bitmap to the framebuffer.
*
* @param x X coordinate of left side of target location.
* @param y Y coordinate of bottom side of target location.
* @param alpha_bitmap 8-bit alpha-channel bitmap.
* @param width Bitmap width.
* @param height Bitmap height.
* @param color Color to blend with alpha value.
*/
static void blend_alpha_bitmap(size_t x, size_t y, const(ubyte)[] alpha_bitmap,
size_t width, size_t height, uint color)
{
blend_alpha_bitmap(x, y, alpha_bitmap.ptr, width, height, color);
}
/**
* Blit an 8-bit alpha bitmap to the framebuffer.
* The foreground will be white (based on the alpha value), and the
* background black.
*
* @param x X coordinate of left side of target location.
* @param y Y coordinate of bottom side of target location.
* @param alpha_bitmap 8-bit alpha-channel bitmap.
* @param width Bitmap width.
* @param height Bitmap height.
*/
static void blit_alpha_bitmap(size_t x, size_t y, const(ubyte) * alpha_bitmap,
size_t width, size_t height)
{
y += height - 1u;
size_t bitmap_index;
for (size_t iy = 0u; iy < height; iy++)
{
size_t row_buffer_index = buffer_index(x, y);
for (size_t ix = 0u; ix < width; ix++)
{
size_t buffer_index = row_buffer_index + ix;
ubyte alpha = alpha_bitmap[bitmap_index];
m_buffer1[buffer_index] = (alpha << 16u) | (alpha << 8u) | alpha;
bitmap_index++;
}
memcpy32(&m_device_buffer[row_buffer_index], &m_buffer1[row_buffer_index], width);
y--;
}
}
/**
* Blit an 8-bit alpha bitmap to the framebuffer.
* The foreground will be white (based on the alpha value), and the
* background black.
*
* @param x X coordinate of left side of target location.
* @param y Y coordinate of bottom side of target location.
* @param alpha_bitmap 8-bit alpha-channel bitmap.
* @param width Bitmap width.
* @param height Bitmap height.
*/
static void blit_alpha_bitmap(size_t x, size_t y, const(ubyte)[] alpha_bitmap,
size_t width, size_t height)
{
blit_alpha_bitmap(x, y, alpha_bitmap.ptr, width, height);
}
/**
* Copy framebuffer rows up in the framebuffer.
*
* @param y Y coordinate of bottom side of region to copy up.
* @param height Height of region to copy up.
* @param offset Number of rows to copy region up by.
*/
static void copy_rows_up(size_t y, size_t height, size_t offset)
{
size_t dest_buffer_index = buffer_index(0u, y + height + offset - 1u);
size_t src_buffer_index = buffer_index(0u, y + height - 1u);
memcpy32(&m_buffer1[dest_buffer_index],
&m_buffer1[src_buffer_index],
(m_stride * height));
memcpy32(&m_device_buffer[dest_buffer_index],
&m_buffer1[dest_buffer_index],
(m_stride * height));
}
/**
* Scale a color value by an alpha amount.
*
* @param color Color value.
* @param alpha Alpha amount.
*
* @return Scaled color value.
*/
private static uint scale_color(uint color, ubyte alpha)
{
return ((((color & 0xFFu) * alpha) >> 8u) & 0xFFu) |
((((color & 0xFF00u) * alpha) >> 8u) & 0xFF00u) |
((((color & 0xFF0000u) * alpha) >> 8u) & 0xFF0000u);
}
/**
* Return the buffer index for the given X and Y coordinates.
*
* @param x X coordinate from left side of framebuffer.
* @param y Y coordinate from bottom side of framebuffer.
*
* @return Buffer index for the given X and Y coordinates.
*/
private static size_t buffer_index(size_t x, size_t y)
{
return (m_height - y - 1u) * m_stride + x;
}
}
+58
View File
@@ -0,0 +1,58 @@
/**
* GDT (Global Descriptor Table) functionality.
*/
module hulk.gdt;
import ldc.llvmasm;
struct gdt
{
struct gdtr_t
{
ushort limit;
align(2) ulong offset;
}
static assert(gdtr_t.sizeof == 10u);
public enum size_t SELECTOR_NULL = 0x00u;
public enum size_t SELECTOR_KERNEL_CODE = 0x08u;
public enum size_t SELECTOR_KERNEL_DATA = 0x10u;
public enum size_t SELECTOR_COUNT = 3u;
static __gshared ulong[SELECTOR_COUNT] gdt;
static __gshared gdtr_t gdtr;
public static void initialize()
{
gdt[SELECTOR_KERNEL_CODE / ulong.sizeof] = 0x00_A_F_9A_000000_0000u;
gdt[SELECTOR_KERNEL_DATA / ulong.sizeof] = 0x00_C_F_92_000000_0000u;
gdtr.limit = gdt.sizeof - 1u;
gdtr.offset = cast(ulong)&gdt;
lgdt(&gdtr);
load_data_selectors(SELECTOR_KERNEL_DATA);
load_code_selector(SELECTOR_KERNEL_CODE);
}
private static void lgdt(gdtr_t * gdtr)
{
__asm("lgdt $0", "*m", gdtr);
}
private static void load_data_selectors(ulong selector)
{
__asm(`mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss`, "{rax}", selector);
}
private static void load_code_selector(ulong selector)
{
__asm(`push %rax
movabs $$1f, %rax
push %rax
lretq
1:`, "{rax}", selector);
}
}
+40
View File
@@ -0,0 +1,40 @@
/**
* HULK image header.
*/
module hulk.header;
import hulk.bootinfo;
/**
* Header describing the HULK image.
*/
struct HulkHeader
{
/**
* HULK BSS size.
*
* The OS loader must map memory to a zeroed range of this size.
*
* This value is really an integer, but is stored as a pointer because it
* is provided by the linker and LDC does not like us to cast it.
*/
void * hulk_bss_size;
/** Entry point. */
void * entry;
/** Stack size. */
ulong stack_size;
/** Virtual base address. */
ulong virt_base;
/** Stack top virtual address. */
ulong virt_stack_top;
/** Framebuffer virtual address. */
ulong virt_fb_buffer;
/** HULK boot information. */
BootInfo bootinfo;
}
+69
View File
@@ -0,0 +1,69 @@
/**
* HIPPO, the HOS In-place Physical Page Organizer.
*
* HIPPO maintains a list of free physical pages "in place", meaning that the
* available page itself is used as the linked list entry so separate memory
* is not needed to keep track of the available pages.
*/
module hulk.hippo;
struct hippo
{
/**
* Linked list node entry for a physical page.
*/
private static struct PhysicalPage
{
PhysicalPage * next;
}
/**
* Linked list of free physical pages.
*/
private static __gshared PhysicalPage * free_pages;
/**
* Number of free physical pages.
*/
private static __gshared size_t m_n_free_pages;
/**
* Free a physical page.
*
* @param phys Physical page address.
*/
public static void free_page(T)(T phys)
{
PhysicalPage * pp = cast(PhysicalPage *)phys;
pp.next = free_pages;
free_pages = pp;
m_n_free_pages++;
}
/**
* Allocate a physical page.
*
* @return Page address, or null if no pages are available.
*/
public static void * allocate_page()
{
PhysicalPage * pp;
if (free_pages != null)
{
pp = free_pages;
free_pages = free_pages.next;
m_n_free_pages--;
}
return cast(void *)pp;
}
/**
* Get the number of free pages.
*
* @return The number of free pages.
*/
public @property size_t n_free_pages() const
{
return m_n_free_pages;
}
}
+86
View File
@@ -0,0 +1,86 @@
/**
* HULK, the HOS Ultra Light Kernel.
*/
module hulk.hulk;
import hulk.header;
import hulk.fb;
import hulk.console;
import hulk.memory;
import ldc.attributes;
import hulk.kfont;
import hulk.klog;
import hulk.hurl;
import hulk.hippo;
import hulk.pci;
import hulk.gdt;
import hulk.idt;
import hulk.cpu;
import ldc.llvmasm;
import hulk.pic;
import hulk.acpi;
import hulk.apic;
import hulk.rtc;
import hulk.pit;
extern extern(C) __gshared ubyte _hulk_bss_size;
@(ldc.attributes.section(".hulk_header"))
private __gshared HulkHeader hulk_header = {
&_hulk_bss_size, /* hulk_bss_size */
&hulk_start, /* entry */
16u * 1024u, /* stack_size */
HULK_VIRTUAL_BASE_ADDRESS, /* virt_base */
HULK_VIRTUAL_STACK_TOP_ADDRESS, /* virt_stack_top */
HULK_VIRTUAL_FRAMEBUFFER_ADDRESS, /* virt_fb_buffer */
};
private void initialize_cpu()
{
/* Enable SSE. */
/* Turn off CR0.EM and turn on CR0.MP. */
write_cr0((read_cr0() & ~CR0_EM) | CR0_MP);
/* Set CR4.OSFXSR and CR4.OSXMMEXCPT. */
write_cr4(read_cr4() | CR4_OSFXSR | CR4_OSXMMEXCPT);
/* Enable OSXSAVE. */
write_cr4(read_cr4() | CR4_OSXSAVE);
/* Turn on NXE (no execute enable) flag in the EFER MSR. */
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE);
}
/**
* HULK entry point.
*/
void hulk_start()
{
cli();
initialize_cpu();
gdt.initialize();
idt.initialize();
fb.initialize(cast(uint *)HULK_VIRTUAL_FRAMEBUFFER_ADDRESS,
cast(uint *)hulk_header.bootinfo.fb_buffer1_phys,
hulk_header.bootinfo.fb.width,
hulk_header.bootinfo.fb.height,
hulk_header.bootinfo.fb.stride);
console.initialize();
console.clear();
klog.initialize();
klog.writefln("Welcome to HULK, the HOS UltraLight Kernel!");
hurl.initialize(&hulk_header);
pci.initialize();
pic.initialize();
acpi.initialize(hulk_header.bootinfo.acpi_xsdt_phys);
apic.initialize();
rtc.initialize();
pit.initialize();
sti();
for (;;)
{
hlt();
}
}
+61
View File
@@ -0,0 +1,61 @@
SECTIONS
{
. = 0xFFFF800000000000;
_hulk_mem_start = .;
_hulk_header_start = .;
.hulk_header :
{
*(.hulk_header)
}
. = ALIGN(4K);
_hulk_header_end = .;
_hulk_text_start = .;
.text :
{
*(.text)
}
. = ALIGN(4K);
_hulk_text_end = .;
_hulk_rodata_start = .;
.rodata :
{
*(.rodata)
}
. = ALIGN(4K);
_hulk_rodata_end = .;
_hulk_data_start = .;
.data :
{
*(.data)
}
. = ALIGN(4K);
_hulk_data_end = .;
_hulk_binary_size = . - _hulk_mem_start;
_hulk_bss_start = .;
.bss :
{
*(COMMON)
*(.bss)
}
. = ALIGN(4K);
_hulk_bss_end = .;
_hulk_mem_end = .;
_hulk_header_size = _hulk_header_end - _hulk_header_start;
_hulk_text_size = _hulk_text_end - _hulk_text_start;
_hulk_rodata_size = _hulk_rodata_end - _hulk_rodata_start;
_hulk_data_size = _hulk_data_end - _hulk_data_start;
_hulk_bss_size = _hulk_bss_end - _hulk_bss_start;
_hulk_mem_size = _hulk_mem_end - _hulk_mem_start;
}
+296
View File
@@ -0,0 +1,296 @@
/**
* HURL, the HOS Unreal Region Locator.
*
* HURL provides virtual memory management for HULK.
*/
module hulk.hurl;
public import hulk.pagetable;
import hulk.cpu;
import hulk.hippo;
import hulk.memory;
import hulk.klog;
import hulk.bootinfo;
import hulk.header;
import hulk.linker_addresses;
/** HULK virtual base address. */
enum ulong HULK_VIRTUAL_BASE_ADDRESS = 0xFFFF_8000_0000_0000u;
/** HULK virtual stack top address. */
enum ulong HULK_VIRTUAL_STACK_TOP_ADDRESS = 0xFFFF_A000_0000_0000u;
/** HULK virtual framebuffer address. */
enum ulong HULK_VIRTUAL_FRAMEBUFFER_ADDRESS = 0xFFFF_A000_0000_0000u;
struct hurl
{
/**
* Pointer to the base page table.
*/
private static __gshared PageTable * m_pt_base;
/**
* Build HULK page tables.
*
* @param physical_address_limit
* Limit of physical memory.
*/
private static void build_page_tables(HulkHeader * header, size_t physical_address_limit)
{
m_pt_base = allocate_pt();
/* Identity map all physical RAM. */
map_range(0u,
0u,
physical_address_limit,
PT_WRITABLE | PT_NO_EXECUTE);
ulong phys_address = header.bootinfo.hulk_phys;
ulong virt_address = HULK_VIRTUAL_BASE_ADDRESS;
/* Map HULK header region. */
map_range(virt_address,
phys_address,
LinkerAddresses.hulk_header_size,
PT_NO_EXECUTE);
phys_address += LinkerAddresses.hulk_header_size;
virt_address += LinkerAddresses.hulk_header_size;
/* Map HULK text region. */
map_range(virt_address,
phys_address,
LinkerAddresses.hulk_text_size,
0u);
phys_address += LinkerAddresses.hulk_text_size;
virt_address += LinkerAddresses.hulk_text_size;
/* Map HULK rodata region. */
map_range(virt_address,
phys_address,
LinkerAddresses.hulk_rodata_size,
PT_NO_EXECUTE);
phys_address += LinkerAddresses.hulk_rodata_size;
virt_address += LinkerAddresses.hulk_rodata_size;
/* Map HULK data region. */
map_range(virt_address,
phys_address,
LinkerAddresses.hulk_data_size,
PT_WRITABLE | PT_NO_EXECUTE);
virt_address += LinkerAddresses.hulk_data_size;
/* Map HULK BSS region. */
map_range(virt_address,
header.bootinfo.bss_phys,
LinkerAddresses.hulk_bss_size,
PT_WRITABLE | PT_NO_EXECUTE);
/* Map HULK stack. */
map_range(HULK_VIRTUAL_STACK_TOP_ADDRESS - header.stack_size,
header.bootinfo.stack_phys,
header.stack_size,
PT_WRITABLE | PT_NO_EXECUTE);
/* Map device framebuffer. */
map_range(HULK_VIRTUAL_FRAMEBUFFER_ADDRESS,
cast(ulong)header.bootinfo.fb.buffer,
header.bootinfo.fb.height * header.bootinfo.fb.stride * 4u,
PT_WRITABLE | PT_NO_EXECUTE);
/* Map framebuffer buffer1. */
map_range(cast(ulong)header.bootinfo.fb_buffer1_phys,
cast(ulong)header.bootinfo.fb_buffer1_phys,
header.bootinfo.fb.height * header.bootinfo.fb.stride * 4u,
PT_WRITABLE | PT_NO_EXECUTE);
write_cr3(cast(ulong)m_pt_base);
}
/**
* Reclaim the pages that were used for the bootloader page tables.
*
* @param pt
* The page table to reclaim pages from.
* @param level
* Page table level (internally used while recursing the page tables).
*
* @return Number of pages reclaimed.
*/
private static size_t reclaim_bootloader_page_table_pages(PageTable * pt, size_t level = 0u)
{
map(pt, pt, PT_WRITABLE | PT_NO_EXECUTE);
size_t reclaimed_pages;
for (size_t i = 0u; i < PageTable.N_ENTRIES; i++)
{
PageTableEntry pte = (*pt)[i];
if (pte.present && (level < 2u) && !pte.huge)
{
/* For the first two levels of page tables, first
* recurse and free pages from the lower level page
* tables before reclaiming this entry. */
reclaimed_pages += reclaim_bootloader_page_table_pages(pte.follow(), level + 1u);
}
}
hippo.free_page(pt);
reclaimed_pages++;
return reclaimed_pages;
}
/**
* Initialize HURL.
*
* @param bootinfo HULK boot information structure.
*/
public static void initialize(HulkHeader * header)
{
PageTable * bootloader_pt_base = cast(PageTable *)read_cr3();
/*
* Ok, what we do here is iterate through all of the memory map regions
* in the bootinfo memory_map array and mark each page that is not in
* use in a reserved range as available. Within the available memory
* regions, we have to watch out for the following items:
* 1) HULK binary (header + text + rodata + data)
* 2) Framebuffer
* In addition to these ranges, there are also pages for the following
* purposes that are not represented in the memory map from the
* bootloader:
* 3) HULK BSS
* 4) HULK stack
* 5) bootloader page table pages
* 6) framebuffer buffer1
*/
size_t usable_memory;
size_t physical_address_limit;
const(size_t) fb_size = (header.bootinfo.fb.height * header.bootinfo.fb.stride * 4u + PAGE_SIZE - 1u) & ~(PAGE_SIZE - 1u);
ulong[2][2] reserved = [
[header.bootinfo.hulk_phys, LinkerAddresses.hulk_binary_size],
[cast(ulong)header.bootinfo.fb.buffer, fb_size],
];
for (size_t ri = 0u; ri < reserved.length; ri++)
{
reserved[ri][1] += reserved[ri][0];
}
for (size_t bii = 0u; bii < header.bootinfo.memory_map_count; bii++)
{
if ((header.bootinfo.memory_map[bii].type == BootInfo.MemoryRegion.Type.Bootloader) ||
(header.bootinfo.memory_map[bii].type == BootInfo.MemoryRegion.Type.Conventional))
{
ulong phys = header.bootinfo.memory_map[bii].base;
ulong phys_end = phys + header.bootinfo.memory_map[bii].size;
if (phys_end > physical_address_limit)
{
physical_address_limit = phys_end;
}
usable_memory += header.bootinfo.memory_map[bii].size;
while (phys < phys_end)
{
bool is_reserved = false;
for (size_t ri = 0u; ri < reserved.length; ri++)
{
if ((reserved[ri][0] <= phys) && (phys < reserved[ri][1]))
{
is_reserved = true;
break;
}
}
if (!is_reserved)
{
hippo.free_page(phys);
}
phys += PAGE_SIZE;
}
}
}
/*
* Now that we have available physical pages to allocate from, we can
* build new page tables to replace the bootloader page tables.
*/
build_page_tables(header, physical_address_limit);
/*
* After we have switched to the newly constructed page tables, we can
* iterate through and free the bootloader page tables. They are most
* likely already mapped because we just identity mapped every page up
* to the physical_address_limit determined above. But just in case the
* bootloader used the last pages of RAM for the page table pages, we
* will make sure to map them as we traverse them.
*/
size_t reclaimed_bootloader_page_table_memory = reclaim_bootloader_page_table_pages(bootloader_pt_base) << 10u;
usable_memory += reclaimed_bootloader_page_table_memory;
usable_memory += LinkerAddresses.hulk_bss_size;
usable_memory += header.stack_size;
usable_memory += fb_size;
klog.writefln("Usable memory: %uKB", usable_memory >> 10u);
klog.writefln("Kernel size: %uKB", (LinkerAddresses.hulk_binary_size + LinkerAddresses.hulk_bss_size + header.stack_size) >> 10u);
}
public static void map(T, U)(T virtual, U physical, ulong flags)
{
PageTable * pt = m_pt_base;
for (size_t level = 0; level < 4u; level++)
{
PageTableEntry * ppte = pt.entry(virtual, level);
if (level < 3u)
{
PageTableEntry pte = *ppte;
if (pte.present)
{
pt = pte.follow();
}
else
{
PageTable * next_pt = allocate_pt();
*ppte = PageTableEntry(next_pt, PT_WRITABLE | PT_PRESENT);
pt = next_pt;
}
}
else
{
*ppte = PageTableEntry(cast(ulong)physical, flags | PT_PRESENT);
}
}
}
public static void map_range(size_t virtual, size_t physical, size_t length, ulong flags)
{
size_t end = virtual + length;
while (virtual < end)
{
map(virtual, physical, flags);
virtual += PAGE_SIZE;
physical += PAGE_SIZE;
}
}
public static void identity_map_range(size_t address, size_t length, ulong flags)
{
size_t end = address + length;
for (size_t page = address & ~0xFFFu; page < end; page += PAGE_SIZE)
{
map(page, page, flags);
}
}
public static void debug_lookup(void * address)
{
klog.writefln("Debugging page table lookup of 0x%x", address);
PageTable * pt = m_pt_base;
for (size_t level = 0; level < 4u; level++)
{
PageTableEntry pte = *pt.entry(address, level);
klog.writefln("Level %u, index %u, entry = 0x%x", level, pt.index(address, level), pte);
if (pte.present)
{
pt = pte.follow();
}
else
{
break;
}
if (pte.huge)
{
break;
}
}
}
private static PageTable * allocate_pt()
{
PageTable * pt = cast(PageTable *)hippo.allocate_page();
memset64(pt, 0u, PAGE_SIZE / 8u);
return pt;
}
}
+128
View File
@@ -0,0 +1,128 @@
/**
* IDT (Interrupt Descriptor Table) functionality.
*/
module hulk.idt;
import hulk.gdt;
import ldc.llvmasm;
import hulk.fb;
import hulk.console;
import hulk.klog;
import hulk.apic;
import hulk.rtc;
struct idt
{
/* The I/O APIC is configured to map IRQ 0 to interrupt 64 (0x40). */
public static enum ulong INT_RTC = 0x48u; /* IRQ 8 */
public static enum ulong INT_LAPIC_TIMER = 0x70u;
public static enum ulong INT_LAPIC_LINT0 = 0x71u;
public static enum ulong INT_LAPIC_LINT1 = 0x72u;
struct idtr_t
{
ushort limit;
align(2) ulong offset;
}
static assert(idtr_t.sizeof == 10u);
alias descriptor_t = ulong[2];
static __gshared align(0x10) descriptor_t[256] idt;
static assert(idt.sizeof == (256u * 16u));
static __gshared idtr_t idtr;
public static void initialize()
{
set_isrs();
idtr.limit = idt.sizeof - 1u;
idtr.offset = cast(ulong)&idt;
lidt(&idtr);
}
private static void lidt(idtr_t * idtr)
{
__asm("lidt $0", "*m", idtr);
}
private static bool isr_has_error_code(size_t isr)
{
return (isr == 8) ||
((10 <= isr) && (isr <= 14)) ||
(isr == 17) ||
(isr == 21) ||
(isr == 29) ||
(isr == 30);
}
private static bool isr_is_trap(size_t isr)
{
return (isr < 32u) && (isr != 2u);
}
private static void set_isrs()
{
ulong isr_address;
static foreach(isr; 0 .. 256)
{
mixin("isr_address = __asm!ulong(`
movabs $$1f, %rax
jmp 2f
1:
pushq %rdi
pushq %rsi
pushq %rax
mov $$", isr, ", %rdi
" ~ (isr_has_error_code(isr) ? "mov 0x18(%rsp), %rsi" : "") ~ "
movabs $$isr, %rax
callq *%rax
popq %rax
popq %rsi
popq %rdi
" ~ (isr_has_error_code(isr) ? "add $$8, %rsp" : "") ~ "
iretq
2:`, `={rax}`);");
mixin("set_descriptor(", isr, ", 0u, " ~
(isr_is_trap(isr) ? "true" : "false") ~ ", isr_address);");
}
}
private static void set_descriptor(size_t index, ulong dpl, bool trap, ulong offset)
{
idt[index][0] =
0x0000_8E_00_0000_0000u |
((offset & 0xFFFF_0000u) << 32u) |
(dpl << 45u) |
((trap ? 1uL : 0uL) << 40u) |
(gdt.SELECTOR_KERNEL_CODE << 16u) |
(offset & 0xFFFFu);
idt[index][1] = offset >> 32u;
}
}
public extern(C) void isr(ulong vector, ulong arg)
{
switch (vector)
{
case idt.INT_RTC:
rtc.isr();
break;
case idt.INT_LAPIC_TIMER:
case idt.INT_LAPIC_LINT0:
case idt.INT_LAPIC_LINT1:
apic.isr(vector);
break;
default:
console.clear();
fb.clear(0xFF8000u);
klog.writefln("ISR %u, 0x%x", vector, arg);
__asm("cli", "");
for (;;)
{
__asm("hlt", "");
}
}
}
+73
View File
@@ -0,0 +1,73 @@
/**
* HULK Kernel Log buffer.
*/
module hulk.klog;
import core.stdc.stdarg;
import hulk.console;
static import hulk.writef;
struct klog
{
/**
* Kernel buffer size log.
* 16 gives a kernel buffer size of 64KB.
*/
private enum size_t KLOG_SIZE_LOG = 16u;
/** Kernel buffer size. */
private enum size_t KLOG_SIZE = 1u << KLOG_SIZE_LOG;
/** Kernel log buffer. */
private static __gshared align(4096) ubyte[KLOG_SIZE] klog_buffer;
/** Write index in the kernel log buffer. */
private static __gshared size_t klog_index;
/**
* Initialize the klog module.
*/
public static void initialize()
{
}
/**
* Write a formatted string to the kernel log.
*
* @param s Format string.
* @param args Variable arguments structure.
*/
public static void writef(string s, va_list args)
{
hulk.writef.writef(s, args, function void(ubyte ch) {
console.write(ch);
});
}
/**
* Write a formatted string to the kernel log.
*
* @param s Format string.
*/
public static extern (C) void writef(string s, ...)
{
va_list args;
va_start(args, s);
writef(s, args);
va_end(args);
}
/**
* Write a formatted string and newline to the console.
*
* @param s Format string.
*/
public static extern (C) void writefln(string s, ...)
{
va_list args;
va_start(args, s);
writef(s, args);
writef("\n", args);
va_end(args);
}
}
+139
View File
@@ -0,0 +1,139 @@
/**
* This module provides access to linker-defined symbols.
*/
module hulk.linker_addresses;
private extern extern(C) __gshared ubyte _hulk_header_start;
private extern extern(C) __gshared ubyte _hulk_header_end;
private extern extern(C) __gshared ubyte _hulk_header_size;
private extern extern(C) __gshared ubyte _hulk_text_start;
private extern extern(C) __gshared ubyte _hulk_text_end;
private extern extern(C) __gshared ubyte _hulk_text_size;
private extern extern(C) __gshared ubyte _hulk_rodata_start;
private extern extern(C) __gshared ubyte _hulk_rodata_end;
private extern extern(C) __gshared ubyte _hulk_rodata_size;
private extern extern(C) __gshared ubyte _hulk_data_start;
private extern extern(C) __gshared ubyte _hulk_data_end;
private extern extern(C) __gshared ubyte _hulk_data_size;
private extern extern(C) __gshared ubyte _hulk_bss_start;
private extern extern(C) __gshared ubyte _hulk_bss_end;
private extern extern(C) __gshared ubyte _hulk_bss_size;
/* hulk_binary includes header, text, rodata, and data */
private extern extern(C) __gshared ubyte _hulk_binary_size;
/* hulk_mem includes header, text, rodata, data, and bss */
private extern extern(C) __gshared ubyte _hulk_mem_start;
private extern extern(C) __gshared ubyte _hulk_mem_end;
private extern extern(C) __gshared ubyte _hulk_mem_size;
/**
* This struct provides access to linker-defined symbols.
*/
public struct LinkerAddresses
{
public static @property ulong hulk_header_start()
{
return cast(ulong)&_hulk_header_start;
}
public static @property ulong hulk_header_end()
{
return cast(ulong)&_hulk_header_end;
}
public static @property ulong hulk_header_size()
{
return cast(ulong)&_hulk_header_size;
}
public static @property ulong hulk_text_start()
{
return cast(ulong)&_hulk_text_start;
}
public static @property ulong hulk_text_end()
{
return cast(ulong)&_hulk_text_end;
}
public static @property ulong hulk_text_size()
{
return cast(ulong)&_hulk_text_size;
}
public static @property ulong hulk_rodata_start()
{
return cast(ulong)&_hulk_rodata_start;
}
public static @property ulong hulk_rodata_end()
{
return cast(ulong)&_hulk_rodata_end;
}
public static @property ulong hulk_rodata_size()
{
return cast(ulong)&_hulk_rodata_size;
}
public static @property ulong hulk_data_start()
{
return cast(ulong)&_hulk_data_start;
}
public static @property ulong hulk_data_end()
{
return cast(ulong)&_hulk_data_end;
}
public static @property ulong hulk_data_size()
{
return cast(ulong)&_hulk_data_size;
}
public static @property ulong hulk_bss_start()
{
return cast(ulong)&_hulk_bss_start;
}
public static @property ulong hulk_bss_end()
{
return cast(ulong)&_hulk_bss_end;
}
public static @property ulong hulk_bss_size()
{
return cast(ulong)&_hulk_bss_size;
}
public static @property ulong hulk_binary_size()
{
return cast(ulong)&_hulk_binary_size;
}
public static @property ulong hulk_mem_start()
{
return cast(ulong)&_hulk_mem_start;
}
public static @property ulong hulk_mem_end()
{
return cast(ulong)&_hulk_mem_end;
}
public static @property ulong hulk_mem_size()
{
return cast(ulong)&_hulk_mem_size;
}
}
+62
View File
@@ -0,0 +1,62 @@
/**
* Memory-related functions.
*/
module hulk.memory;
import ldc.llvmasm;
void memset(void * dest, ubyte v, size_t n)
{
__asm("rep stosb",
"{al},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
v, n, dest);
}
void memset16(void * dest, ushort v, size_t n)
{
__asm("rep stosw",
"{ax},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
v, n, dest);
}
void memset32(void * dest, uint v, size_t n)
{
__asm("rep stosl",
"{eax},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
v, n, dest);
}
void memset64(void * dest, ulong v, size_t n)
{
__asm("rep stosq",
"{rax},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
v, n, dest);
}
void memcpy(void * dest, const(void) * src, size_t n)
{
__asm("rep movsb",
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
n, src, dest);
}
void memcpy16(void * dest, const(void) * src, size_t n)
{
__asm("rep movsw",
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
n, src, dest);
}
void memcpy32(void * dest, const(void) * src, size_t n)
{
__asm("rep movsl",
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
n, src, dest);
}
void memcpy64(void * dest, const(void) * src, size_t n)
{
__asm("rep movsq",
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
n, src, dest);
}
+70
View File
@@ -0,0 +1,70 @@
/**
* MTRR (Memory Type Range Register) support for HULK.
*/
module hulk.mtrr;
import hulk.cpu;
import hulk.klog;
enum ulong MTRR_TYPE_UC = 0u; /* Uncacheable */
enum ulong MTRR_TYPE_WC = 1u; /* Write-Combining */
enum ulong MTRR_TYPE_WT = 4u; /* Writethrough */
enum ulong MTRR_TYPE_WP = 5u; /* Write-Protect */
enum ulong MTRR_TYPE_WB = 6u; /* Writeback */
enum uint MSR_MTRRCAP = 0xFEu;
enum uint MSR_MTRRDEFTYPE = 0x2FFu;
enum uint MSR_MTRRPHYSBASE0 = 0x200u;
enum uint MSR_MTRRPHYSMASK0 = 0x201u;
enum ulong MTRRCAP_WC = 0x400u;
enum ulong MTRRCAP_FIX = 0x100u;
enum ulong MTRRCAP_VCNT_MASK = 0xFFu;
enum ulong MTRRDEFTYPE_E = 0x800u;
enum ulong MTRRDEFTYPE_FE = 0x400u;
enum ulong MTRRDEFTYPE_TYPE_MASK = 0xFFu;
enum ulong MTRRPHYSBASE_PHYSBASE_MASK = 0x000F_FFFF_FFFF_F000u;
enum ulong MTRRPHYSBASE_TYPE_MASK = 0xFFu;
enum ulong MTRRPHYSMASK_PHYSMASK_MASK = 0x000F_FFFF_FFFF_F000u;
enum ulong MTRRPHYSMASK_VALID = 0x800u;
struct mtrr
{
public static void initialize()
{
uint ebx;
uint ecx;
uint edx;
cpuid1(&ebx, &ecx, &edx);
if ((edx & CPUID_1_EDX_MTRR) == 0u)
{
klog.writefln("CPU does not support MTRR");
return;
}
const(ulong) mtrrcap = rdmsr(MSR_MTRRCAP);
const(ulong) mtrrdeftype = rdmsr(MSR_MTRRDEFTYPE);
}
private static ulong get_phys_base(uint n)
{
return rdmsr(MSR_MTRRPHYSBASE0 + 2u * n);
}
private static void set_phys_base(uint n, ulong physbase)
{
wrmsr(MSR_MTRRPHYSBASE0 + 2u * n, physbase);
}
private static ulong get_phys_mask(uint n)
{
return rdmsr(MSR_MTRRPHYSMASK0 + 2u * n);
}
private static void set_phys_mask(uint n, ulong physmask)
{
wrmsr(MSR_MTRRPHYSMASK0 + 2u * n, physmask);
}
}
+185
View File
@@ -0,0 +1,185 @@
/**
* Page table structures.
*/
module hulk.pagetable;
/** Page table entry attributes. @{ */
enum ulong PT_PRESENT = 0x1u;
enum ulong PT_WRITABLE = 0x2u;
enum ulong PT_USER = 0x4u;
enum ulong PT_WRITE_THROUGH = 0x8u;
enum ulong PT_DISABLE_CACHE = 0x10u;
enum ulong PT_ACCESSED = 0x20u;
enum ulong PT_DIRTY = 0x40u;
enum ulong PT_HUGE_PAGE = 0x80u;
enum ulong PT_GLOBAL = 0x100u;
enum ulong PT_NO_EXECUTE = 0x8000_0000_0000_0000u;
/** @} */
/** Page size in bytes. */
enum ulong PAGE_SIZE = 4096u;
/**
* Structure that represents a page table entry.
*/
struct PageTableEntry
{
/** The raw page table entry is a 64-bit ulong. */
public ulong entry;
alias entry this;
/**
* Construct a page table entry.
*
* @param address
* Address pointed to by the page table entry (ulong or pointer).
* @param flags
* Page table flags (ORed set of PT_*).
*/
this(T)(T address, ulong flags = 0u)
{
entry = cast(ulong)address | flags;
}
/**
* Return whether the page is present.
*/
public @property bool present() const
{
return (entry & PT_PRESENT) != 0u;
}
/**
* Return whether the page is writable.
*/
public @property bool writable() const
{
return (entry & PT_WRITABLE) != 0u;
}
/**
* Return whether the page is a user page.
*/
public @property bool user() const
{
return (entry & PT_USER) != 0u;
}
/**
* Return whether the page is write-through.
*/
public @property bool write_through() const
{
return (entry & PT_WRITE_THROUGH) != 0u;
}
/**
* Return whether the page has disable cache set.
*/
public @property bool disable_cache() const
{
return (entry & PT_DISABLE_CACHE) != 0u;
}
/**
* Return whether the page is huge.
*/
public @property bool huge() const
{
return (entry & PT_HUGE_PAGE) != 0u;
}
/**
* Return whether the page is global.
*/
public @property bool global() const
{
return (entry & PT_GLOBAL) != 0u;
}
/**
* Return whether the page is no-execute.
*/
public @property bool no_execute() const
{
return (entry & PT_NO_EXECUTE) != 0u;
}
/**
* Return whether the page is dirty.
*/
public @property bool dirty() const
{
return (entry & PT_DIRTY) != 0u;
}
/**
* Return whether the page is accessed.
*/
public @property bool accessed() const
{
return (entry & PT_ACCESSED) != 0u;
}
/**
* Follow the page table entry to the next page table it points to.
*/
public PageTable * follow() const
{
return cast(PageTable *)(entry & 0x7FFF_FFFF_FFFF_F000u);
}
}
static assert(PageTableEntry.sizeof == 8u);
/**
* Structure that represents a page table.
*/
struct PageTable
{
/** Number of page table entries in a page table. */
enum size_t N_ENTRIES = 512u;
/** Page table entries. */
private PageTableEntry[N_ENTRIES] entries;
/**
* Access the PageTableEntry for the given address and page table level.
*
* @param address
* Address to look up the page table entry (ulong or pointer).
* @param level
* Page table level (0-4).
*/
public PageTableEntry * entry(T)(T address, ulong level)
{
return &entries[index(cast(ulong)address, level)];
}
/**
* Determine the index into the page table for the given address and page
* table level.
*
* @param address
* Address to look up the page table entry (ulong or pointer).
* @param level
* Page table level (0-4).
*/
public ulong index(T)(T address, ulong level)
{
return (cast(ulong)address >> (39u - (9u * level))) & 0x1FFu;
}
/**
* Access a page table entry by linear index.
*
* @param index
* Page table index (0-511).
*
* @return PageTableEntry at the given index.
*/
public PageTableEntry opIndex(size_t index)
{
return entries[index];
}
}
static assert(PageTable.sizeof == 4096u);
+48
View File
@@ -0,0 +1,48 @@
module hulk.pci;
import hulk.cpu;
import hulk.klog;
struct pci
{
/* IO address for PCI configuration address. */
enum IO_ADDR_CONFIG_ADDRESS = 0xCF8u;
/* IO address for PCI configuration data. */
enum IO_ADDR_CONFIG_DATA = 0xCFCu;
private static ulong read_config_register(ulong bus_id, ulong device_id, ulong register_id)
{
ulong addr = 0x8000_0000u | (bus_id << 16u) | (device_id << 11u) | (register_id << 2u);
out32(IO_ADDR_CONFIG_ADDRESS, addr);
return in32(IO_ADDR_CONFIG_DATA);
}
private static void scan(ulong bus_id, ulong device_id)
{
ulong reg0 = read_config_register(bus_id, device_id, 0u);
if (reg0 != 0xFFFFFFFFu)
{
ulong reg2 = read_config_register(bus_id, device_id, 2u);
klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u",
(reg0 & 0xFFFFu), (reg0 >> 16u),
(reg2 >> 24u) & 0xFFu,
(reg2 >> 16u) & 0xFFu,
(reg2 >> 8u) & 0xFFu,
bus_id, device_id);
}
}
public static void initialize()
{
klog.writefln("Scanning PCI devices...");
for (ulong bus_id = 0u; bus_id < 256u; bus_id++)
{
for (ulong device_id = 0u; device_id < 32u; device_id++)
{
scan(bus_id, device_id);
}
}
klog.writefln("PCI scan complete.");
}
}
+16
View File
@@ -0,0 +1,16 @@
/**
* PIC (Programmable Interrupt Controller) functionality.
*/
module hulk.pic;
import hulk.cpu;
struct pic
{
public static void initialize()
{
/* Disable the PIC. */
out8(0xA1u, 0xFFu);
out8(0x21u, 0xFFu);
}
}
+42
View File
@@ -0,0 +1,42 @@
/**
* PIT (Programmable Interval Timer) functionality.
*/
module hulk.pit;
import hulk.cpu;
import hulk.klog;
struct pit
{
/** PIT input frequency in 1/1000 Hz. */
private enum ulong PIT_FREQUENCY_1000HZ = 1_193_181_667u;
private enum ulong TARGET_INTERRUPT_HZ = 100u;
private enum ulong TARGET_INTERRUPT_1000HZ = TARGET_INTERRUPT_HZ * 1000u;
private enum ulong PIT_DIVIDER = (PIT_FREQUENCY_1000HZ + TARGET_INTERRUPT_1000HZ / 2u) / TARGET_INTERRUPT_1000HZ;
/** PIT channel 0 I/O port. */
private enum ubyte PORT_CH_0 = 0x40u;
/** PIT channel 1 I/O port. */
private enum ubyte PORT_CH_1 = 0x41u;
/** PIT channel 2 I/O port. */
private enum ubyte PORT_CH_2 = 0x42u;
/** PIT mode/command register I/O port. */
private enum ubyte PORT_MC = 0x43u;
private enum ubyte MC_CH_0 = 0x00u;
private enum ubyte MC_LO_HI = 0x30u;
private enum ubyte MC_RATE_GENERATOR = 0x04u;
private enum ubyte MC_BINARY = 0x00u;
public static void initialize()
{
out8(PORT_MC, MC_CH_0 | MC_LO_HI | MC_RATE_GENERATOR | MC_BINARY);
out8(PORT_CH_0, PIT_DIVIDER & 0xFFu);
out8(PORT_CH_0, PIT_DIVIDER >> 8u);
}
public static void isr()
{
klog.writefln("PIT ISR");
}
}
+58
View File
@@ -0,0 +1,58 @@
/**
* RTC (Real-Time Clock) functionality.
*/
module hulk.rtc;
import hulk.cpu;
import hulk.klog;
import hulk.apic;
struct rtc
{
private enum ubyte PORT_SELECT = 0x70u;
private enum ubyte PORT_DATA = 0x71u;
private enum ubyte DISABLE_NMI = 0x80u;
private enum ubyte SR_A = 0xAu;
private enum ubyte SR_B = 0xBu;
private enum ubyte SR_C = 0xCu;
private enum ubyte SR_B_ENABLE_IRQ = 0x40u;
public static void initialize()
{
/* Enable IRQ 8 to receive RTC interrupts. */
out8(PORT_SELECT, DISABLE_NMI | SR_B);
ubyte sr_b = in8(PORT_DATA);
out8(PORT_SELECT, DISABLE_NMI | SR_B);
out8(PORT_DATA, sr_b | SR_B_ENABLE_IRQ);
out8(PORT_SELECT, DISABLE_NMI | SR_A);
klog.writefln("SR_A = 0x%x", in8(PORT_DATA));
/* Send EOI to enable more RTC interrupts and re-enable NMIs. */
eoi();
}
private static void eoi()
{
/* Read from status register C to clear the interrupt. */
out8(PORT_SELECT, SR_C);
in8(PORT_DATA);
}
public static void isr()
{
static __gshared ulong count;
static __gshared ulong seconds;
count++;
if ((count % 1024) == 0u)
{
seconds++;
klog.writefln("Seconds: %u", seconds);
}
eoi();
apic.eoi();
}
}
+151
View File
@@ -0,0 +1,151 @@
/**
* HULK Formatted stream writing support.
*/
module hulk.writef;
import core.stdc.stdarg;
alias ch_out_fn = void function(ubyte);
/**
* Format a string and write characters to the given output function.
*
* @param s Format string.
* @param args Variable arguments structure.
* @param ch_out Character output function.
*
* @return Number of characters written.
*/
size_t writef(string s, va_list args, ch_out_fn ch_out)
{
size_t length_written;
bool escape = false;
char pad = ' ';
size_t width;
foreach (char c; s)
{
if (escape)
{
if (c == 'x')
{
ulong v;
va_arg(args, v);
length_written += write_hex(v, false, pad, width, ch_out);
escape = false;
}
else if (c == 'X')
{
ulong v;
va_arg(args, v);
length_written += write_hex(v, true, pad, width, ch_out);
escape = false;
}
else if (c == 'u')
{
ulong v;
va_arg(args, v);
length_written += write_udec(v, pad, width, ch_out);
escape = false;
}
else if ((c == '0') && (width == 0u))
{
pad = '0';
}
else if (('0' <= c) && (c <= '9'))
{
width = (width * 10u) + (c - '0');
}
else
{
ch_out(c);
escape = false;
}
}
else if (c == '%')
{
escape = true;
pad = ' ';
width = 0u;
}
else
{
ch_out(c);
}
}
return length_written;
}
/**
* Format a value in hexadecimal to the given output function.
*
* @param v Value to format.
* @param upper Whether to use uppercase letters.
* @param pad Pad character to use.
* @param width Field width.
* @param ch_out Character output function.
*
* @return Number of characters written.
*/
private size_t write_hex(ulong v, bool upper, char pad, size_t width, ch_out_fn ch_out)
{
static __gshared const(char)[16] hex_chars_lower = "0123456789abcdef";
static __gshared const(char)[16] hex_chars_upper = "0123456789ABCDEF";
char[16] buf;
size_t i;
do
{
ulong n = v & 0xFu;
buf[i] = upper ? hex_chars_upper[n] : hex_chars_lower[n];
v >>= 4u;
i++;
} while (v != 0u);
size_t length_written = i;
while (width > i)
{
ch_out(pad);
width--;
length_written++;
}
do
{
i--;
ch_out(buf[i]);
} while (i != 0u);
return length_written;
}
/**
* Format a value in decimal to the given output function.
*
* @param v Value to format.
* @param pad Pad character to use.
* @param width Field width.
* @param ch_out Character output function.
*
* @return Number of characters written.
*/
private size_t write_udec(ulong v, char pad, size_t width, ch_out_fn ch_out)
{
char[20] buf;
size_t i;
do
{
ulong d = v % 10u;
buf[i] = cast(char)(d + '0');
v /= 10u;
i++;
} while (v != 0u);
size_t length_written = i;
while (width > i)
{
ch_out(pad);
width--;
length_written++;
}
do
{
i--;
ch_out(buf[i]);
} while (i != 0u);
return length_written;
}
Submodule
+1
Submodule uefi-d added at e70959ce8a.
+76
View File
@@ -0,0 +1,76 @@
project_name "x86_64-elf-gcc"
binutils_version = "2.35"
binutils_checksum = "1b11659fb49e20e18db460d44485f09442c8c56d5df165de9461eb09c8302f85"
gcc_version = "10.2.0"
gcc_checksum = "b8dd4368bb9c7f0b98188317ee0254dd8cc99d1e3a18d0ff146c855fe16c1d8c"
install_path = File.expand_path("x86_64-elf-gcc")
target = "x86_64-elf"
path_prepend "#{install_path}/bin"
configure do
check_c_compiler "gcc"
check_program "make"
check_program "bison"
check_program "flex"
check_program "texi2any", on_fail: "Install the texinfo package"
check_program "wget"
check_lib "gmp", on_fail: "Install the libgmp-dev package"
check_lib "mpc", on_fail: "Install the libmpc-dev package"
check_lib "mpfr", on_fail: "Install the libmpfr-dev package"
end
default do
unless Dir.exist?(install_path)
# Download archives.
download "https://ftp.gnu.org/gnu/binutils/binutils-#{binutils_version}.tar.xz",
"#{build_dir}/binutils-#{binutils_version}.tar.xz",
sha256sum: binutils_checksum
download "https://ftp.gnu.org/gnu/gcc/gcc-#{gcc_version}/gcc-#{gcc_version}.tar.xz",
"#{build_dir}/gcc-#{gcc_version}.tar.xz",
sha256sum: gcc_checksum
# Extract archives.
sh "tar", "xJf", "binutils-#{binutils_version}.tar.xz",
chdir: build_dir
sh "tar", "xJf", "gcc-#{gcc_version}.tar.xz",
chdir: build_dir
# Build binutils.
rm_rf "#{build_dir}/build-binutils"
mkdir_p "#{build_dir}/build-binutils"
cd "#{build_dir}/build-binutils" do
sh %W[../binutils-#{binutils_version}/configure
--target=#{target} --prefix=#{install_path} --with-sysroot --disable-nls
--disable-werror]
sh "make"
sh "make install"
end
# Build gcc.
rm_rf "#{build_dir}/build-gcc"
mkdir_p "#{build_dir}/build-gcc"
cd "#{build_dir}/build-gcc" do
sh %W[../gcc-#{gcc_version}/configure
--target=#{target} --prefix=#{install_path} --disable-nls
--enable-languages=c --without-headers]
sh "make all-gcc"
sh "make all-target-libgcc"
sh "make install-gcc"
sh "make install-target-libgcc"
end
# Remove archives and build directories if everything succeeded.
rm_f "#{build_dir}/binutils-#{binutils_version}.tar.xz"
rm_rf "#{build_dir}/binutils-#{binutils_version}"
rm_rf "#{build_dir}/build-binutils"
rm_f "#{build_dir}/gcc-#{gcc_version}.tar.xz"
rm_rf "#{build_dir}/gcc-#{gcc_version}"
rm_rf "#{build_dir}/build-gcc"
end
end
distclean do
rm_rf install_path
end