232 Commits

Author SHA1 Message Date
a047edc97d fix(kernel/std): handle empty list case in begin() and cbegin() methods in foward_list
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
Build OS / Upload Nightly Build to GitHub Releases (push) Has been cancelled
2025-06-13 19:09:03 +00:00
2c1d6c2608 fix(workflow): add GH_TOKEN environment variable for GitHub CLI
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
Build OS / Upload Nightly Build to GitHub Releases (push) Has been cancelled
2025-06-13 14:49:59 +00:00
97a892d114 fix(workflow): ensure nightly build upload runs unconditionally 2025-06-13 14:44:19 +00:00
3be150da53 fix(workflow): fix xhost error 2025-06-13 13:24:49 +00:00
455224ceb4 fix(workflow): fix issues with packages 2025-06-13 13:15:14 +00:00
e01f1dc97c fix(workflow): add installation step for Dev Container 2025-06-13 13:06:41 +00:00
76113df5a9 ci: upload nightly builds to GitHub Releases 2025-06-13 13:01:32 +00:00
1addd310ad fix(kernel/std): remove unnecessary algorithm include from utility 2025-06-11 03:49:50 +00:00
3d92a87bef fix(kernel/std): cast lhs and rhs to __UINTPTR_TYPE__ 2025-06-11 03:45:34 +00:00
f7177f92cf test(kernel): add tests for std::foward_list and std::is_sorted 2025-06-10 02:02:58 +00:00
6a6c3bfc67 feat(kernel/std): complete the std::foward_list implementation 2025-06-10 02:00:23 +00:00
8dbeee4d9a fix(kernel/std): 🎨 reorder is_sorted_until function declaration 2025-06-10 01:52:58 +00:00
5d5b674aed feat(kernel/std): 🎨 add stub std::foward_list 2025-06-09 07:41:49 +00:00
31bbc29c9f feat(kernel/std): add is_sorted and is_sorted_until functions 2025-06-09 07:41:13 +00:00
f5c8ae9323 fix(devcontainer): use xhost to allow qemu to run inside the container
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
I did this because on every reboot xauth directory was changing, and had to rebuild the container.
2025-05-30 01:50:05 +00:00
154d857c2e refactor(kernel): remove debug log from Sleep function 2025-05-28 02:15:11 +00:00
12ae5a83da feat(kernel): 🎨 add whileto macro for conditional looping with timeout 2025-05-28 02:05:16 +00:00
13ce994edf fix(kernel): 🐛 interrupt handler was broken for PCI 2025-05-28 00:43:21 +00:00
814175ddaf fix(kernel/pci): 🔥 do not map I/O BARs 2025-05-24 17:24:32 +00:00
43e7ddb9de fix(kernel): remove redundant HPET counter test loop 2025-05-24 00:39:20 +00:00
0187fa5b66 feat(kernel): 🎨 add the logo to the kernel as a png resource 2025-05-23 23:32:37 +00:00
33c284091d refactor(kernel): ♻️ rewrite time manager 2025-05-23 23:30:04 +00:00
9538589c11 feat(kernel): add kvm cpuid structures 2025-05-23 20:52:29 +00:00
905b6933c9 fix(kernel/std): 🎨 implementation for <chrono>, <ratio> & <thread> were broken 2025-05-23 15:16:04 +00:00
07d0ca0438 fix(kernel/efi): 🐛 check if ImageHandle and SystemTable has valid, pointers
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
2025-05-19 23:39:29 +00:00
7d37f8a8a1 feat(kernel): 🎨 update BGRT header
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Deploy Website / Deploy Website to GitHub Pages (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
2025-05-18 19:45:09 +00:00
8103caa52c feat(kernel): ⬆️ update stb headers 2025-05-18 19:42:50 +00:00
4929b76c7c fix(kernel/std): 🐛 correct bucket assignment inside [] operator in std::unordered_map 2025-05-18 19:39:20 +00:00
d20d4f7bf9 feat(kernel): 🎨 show stack on panic screen by default
This is good if the PS/2 keyboard doesn't work. It clearly needs a rework tho.
2025-05-18 19:37:18 +00:00
f06c0b19fa fix(kernel/vfs): fully implement ustar driver implementation + mounting system 2025-05-18 11:38:42 +00:00
70a08e46bd fix(rootfs): 🐛 fix subsystem tar to not use PaxHeader 2025-05-17 12:05:45 +00:00
2349610e47 test(kernel): add debug playground functions for testing purposes 2025-05-16 17:23:41 +00:00
fda5ede37f fix(drivers): 🐛 prevent unnecessary recompilation by leaving trusted.c unchanged if no updates are detected 2025-05-14 11:11:35 +00:00
81da8dd989 refactor(kernel/drivers): 🎨 rename filesystem name to "devfs" 2025-05-13 16:28:37 +00:00
557c7e6235 fix(kernel/vfs): 🎉 a complete rewrite of the vfs
This is the fourth time re-writing the VFS, hope this will be the last. Tried to make it as modular as possible so this won't be necessary in the future. 🙏

This change required the entire kernel code to be modified.
2025-05-13 15:59:12 +00:00
83a7f83f81 feat(kernel): 🎨 always include the uptime in KPrint output 2025-05-13 15:54:05 +00:00
6592db3f4e build(kernel): fix compiling in release mode 2025-05-13 15:11:32 +00:00
d7abd36717 feat(kernel/std): add iterator_traits specialization for pointer types 2025-05-11 16:31:33 +00:00
7873d0e724 revert(kernel/std): 🔥 std::set is too hard to implement for now 2025-05-11 16:31:12 +00:00
9626ec4662 feat(kernel/std): add three way compare for std::basic_string and std::vector 2025-05-10 16:32:54 +00:00
dbb5a483e0 feat(kernel/std): implement std::compare 2025-05-10 15:02:37 +00:00
aca55f993f feat(kernel/std): implement std::less specializations for pointer types and void 2025-05-10 15:00:47 +00:00
41fe55fd1f feat(kernel/std): implement lexicographical_compare* functions 2025-05-10 14:59:57 +00:00
c491351fd0 feat(kernel/std): add is_floating_point type trait 2025-05-10 14:58:16 +00:00
75d51fb9d9 feat(kernel/std): add stub std::set implementation 2025-05-10 06:45:42 +00:00
21db83b943 refactor(kernel/std): ♻️ rename test function to test_stl_shared_ptr 2025-05-10 06:03:58 +00:00
fa2e37f603 feat(kernel/std): add stub lexicographical_compare and lexicographical_compare_three_way functions 2025-05-10 04:34:50 +00:00
fab3be67ee refactor(kernel/std): ♻️ rename pragma regions from "Member Functions" to "Constructors" 2025-05-10 04:17:19 +00:00
6e26184a04 test(kernel/std): 🧪 add tests for std::shared_ptr 2025-05-09 07:34:28 +00:00
6b6028434d feat(kernel/std): implement std::shared_ptr 2025-05-09 07:06:25 +00:00
ca02557df4 fix(kernel/std): 🐛 handle empty string case in append and resize methods 2025-05-09 07:05:08 +00:00
527ad803d3 chore(kernel): add custom pretty printer for std::string 2025-05-07 09:32:29 +00:00
2791a602b5 fix(kernel): ✏️ correct ReturnLogError macro structure
Missing "do".
2025-04-27 04:24:24 +00:00
3404bbc3bc feat(rootfs): update subsystem configs 2025-04-23 17:54:38 +00:00
c254b96256 fix(kernel/bootstrap): enable SSE
This shouldn't be an issue, I guess all 64-bit CPU's support SSE anyway...
2025-04-22 21:24:51 +00:00
1e4d404a43 refactor(kernel/efi): rename main efi file 2025-04-20 00:58:19 +00:00
16ec6cbdb6 feat(kernel/efi): add more efi tables 2025-04-20 00:52:32 +00:00
ba99275700 fix(kernel): reset color even on serial output 2025-04-19 19:19:26 +00:00
80c313b02d refactor(kernel/efi): improve code and add more debug messages 2025-04-19 19:18:45 +00:00
fe8682aa85 feat(kernel): use efi in kernel for smbios and rsdp info 2025-04-19 12:27:28 +00:00
cd23c59c46 fix(userspace/libc): interpreter didn't worked at all 2025-04-18 12:38:21 +00:00
f5c9b561a9 fix(kernel/elf): check if vector is empty before calling .front() 2025-04-18 12:36:33 +00:00
366fd97c0a refactor(kernel/elf): simplify dynamic tag and section handling in ELF parsing 2025-04-18 12:35:44 +00:00
d3fd61c068 refactor(kernel/drivers): update trusted drivers hash 2025-04-17 16:04:10 +00:00
0a037f1ae1 test(kernel): add more memory allocator tests 2025-04-17 16:03:03 +00:00
292bfa362a refactor(kernel): change IDT debug message color from blue to green when debugger is attached 2025-04-17 16:02:22 +00:00
bcc2c9d0ab refactor(kernel): change color arrays to static 2025-04-17 16:01:40 +00:00
e270c9f35b refactor(kernel): update debug messages 2025-04-17 16:01:03 +00:00
7902726239 fix(kernel/tty): wrong calculation of cell index
Instead of ws_row, now it's ws_col.
2025-04-17 15:56:16 +00:00
abb7899a9d fix(kernel/std): improve capacity growth strategy in std::vector operations
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
2025-04-15 16:48:23 +00:00
8c4c8d36de fix(kernel/std): ensure null termination after removing elements in std::string::erase 2025-04-15 15:38:20 +00:00
0fffc6c914 build: fix "limine.h: No such file or directory" error 2025-04-14 01:29:25 +00:00
34e24df7c9 build: add __ci-prepare-archive 2025-04-14 01:27:20 +00:00
550e98e87c ci: fix job names 2025-04-14 01:26:18 +00:00
4ff6790072 ci: add separate build steps in workflow 2025-04-14 01:20:57 +00:00
205ddb1e49 ci: ensure artifact upload occurs regardless of previous steps 2025-04-13 13:50:02 +00:00
0735743f44 build: fix kernel build on different architectures
Userspace still fails to compile on non-x86!!!
2025-04-13 13:47:59 +00:00
33eee9c628 feat(kernel/syscalls): implement stub linux_poll 2025-04-13 10:18:15 +00:00
ef5d61df9d build(kernel/tty): fix vtable linking error 2025-04-13 10:08:49 +00:00
11d326b693 feat(kernel/tty): implement processing control characters (^C, ^D, etc) 2025-04-13 09:49:09 +00:00
5293bb2039 feat(kernel/tty): implement blinking cursor 2025-04-12 10:55:01 +00:00
bc84c406d9 build: update Linux Subsystem boot configuration to use compressed rootfs 2025-04-12 04:39:30 +00:00
ed1f4f3c1b test: reduce debug qemu memory allocation for amd64 architecture 2025-04-12 04:38:24 +00:00
ec04e5abe9 build: update rootfs tar command to use gzip compression 2025-04-12 04:37:48 +00:00
5ecfffc049 build: create mnt directory in root filesystem setup 2025-04-12 04:37:23 +00:00
c7d501b466 build: add support for quiet build mode in CMakeLists 2025-04-12 04:36:16 +00:00
1f646d6826 fix(kernel): improve error message for failed init program startup 2025-04-12 04:33:10 +00:00
3315d79742 fix(kernel/vfs): support multiple roots 2025-04-08 05:04:04 +00:00
a1b58bacd8 refactor(kernel): remove unused assert_allow_continue macro 2025-04-08 03:37:32 +00:00
69122746de refactor(kernel): change NIF to nif 2025-04-08 03:25:38 +00:00
764dfe67a5 refactor(kernel): replace manual sorting with std::sort 2025-04-08 02:37:22 +00:00
3d87345a51 fix(kernel/memory): correct bitmap address calculation 2025-04-08 02:31:40 +00:00
eb89b060f6 fix(kernel/vfs): accessing null pointer 2025-04-07 07:42:27 +00:00
25713e0f13 refactor(kernel): improve code readability and formatting 2025-04-07 07:30:48 +00:00
03147b532c fix(kernel/memory): correct loop control in ReservePages function 2025-04-07 07:25:11 +00:00
d8cd27196d feat(kernel/std): add std::sort implementations 2025-04-07 06:32:25 +00:00
832833a56f fix(kernel/vfs): forgot ';' inside ramfs.hpp 2025-04-07 05:38:24 +00:00
a4e5f4785c refactor(kernel): clean up KPrint formatting and fix memory reporting 2025-04-07 05:37:45 +00:00
a268f8dc2f feat(kernel/vfs): implement RAMFS filesystem 2025-04-07 05:37:23 +00:00
a16a88b5f9 fix(kernel): validate symbol entries to prevent processing of invalid symbols 2025-04-07 05:35:17 +00:00
2d2d28689c fix(kernel/vfs): correct root assignment logic in filesystem 2025-04-07 05:31:13 +00:00
d4346202ca refactor(kernel): ramfs loading 2025-04-07 05:04:23 +00:00
b1a30059ed feat(kernel): add initial subsystem implementation files 2025-04-07 04:51:05 +00:00
58accf8acf feat(kernel): add initial security implementation files 2025-04-07 04:02:02 +00:00
24c0848797 refactor(workspace): remove useless settings in vscode workspaces 2025-04-05 17:20:34 +00:00
b232dc6b40 feat(kernel/vfs): add AddRootAt, SetRootAt, RemoveRoot & RootExists functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 11:51:47 +00:00
120d67fb1a refactor(kernel): remove unnecessary type casting in Execute::Spawn call
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 11:01:40 +00:00
f6eb4bd3dc test(kernel/std): add <array> header tests
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:58:13 +00:00
7e7e475dac feat(kernel/std): implement <array> header
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:57:40 +00:00
23d0056098 feat(kernel/std): implement std::is_pointer_v
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:57:10 +00:00
3edb4b4761 feat(kernel/std): implement std::reverse_iterator
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:56:46 +00:00
fd24431eea feat(kernel/std): implement std::runtime_error and std::length_error
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:55:44 +00:00
5c1c26b135 refactor(kernel): use default constructor for std::exception class
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:54:33 +00:00
a333d8aa7c refactor(kernel): change Spawn function parameter type from char* to const char*
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:53:40 +00:00
f054e9976a build: increase qemu debug RAM to 1GB
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 10:50:39 +00:00
f87c3d7e11 feat(kernel/tty): add TCSETS
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-04 04:14:19 +00:00
0041300a00 style(kernel/elf): change code style
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Deploy Website / Deploy Website to GitHub Pages (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 12:06:23 +00:00
fe6d7f4b08 fix(kernel/syscalls): remove unused variable 'vma' in linux_fchmod
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 11:01:57 +00:00
a1622cc885 ci: fix 'tmp_rootfs/sys/drv/': No such file or directory
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 10:53:38 +00:00
bd32020876 revert: last commit
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 10:53:07 +00:00
44323c85a3 ci: rootfs structure was not created
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 10:48:53 +00:00
027d77ed66 fix(devcontainer): move installation of autoconf and automake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 09:15:39 +00:00
bbb70eb621 feat: add advanced options for Fennix boot menu in grub.cfg
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 07:13:13 +00:00
1593e3107d fix(kernel/syscalls): convert error codes in linux_getdents64 to Linux
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 07:12:11 +00:00
1a48d05042 feat(kernel/syscalls): implement semi-stub linux_sysinfo
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 06:46:26 +00:00
75dd958316 feat(kernel/syscalls): implemented stub linux_syslog
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 06:32:51 +00:00
cccbfd2c95 build: add libstdc++ target
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 06:17:34 +00:00
bf20bd89ed build(kernel): add -fdiagnostics-all-candidates flag
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 06:16:23 +00:00
c3fd55bb00 fix(devcontainer): set network mode to host
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 06:15:32 +00:00
c660a7fe4f fix(kernel/elf): interpreter loading is now correctly implemented
ref: linux @ fs/binfmt_elf.c
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-04-03 06:15:12 +00:00
91ad0e14df test(kernel): expand coroutine tests
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-31 09:39:22 +00:00
a6ca98987e fix(kernel/scheduler): threads were skipped if one has affinity for other core
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-30 19:08:18 +00:00
f8f08a11db refactor: add SYS_DEBUG_REPORT
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-30 18:42:04 +00:00
5d64c05446 feat(kernel): enhance chrono and thread
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-30 18:41:05 +00:00
a1064d8978 feat(kernel): add std::terminate() function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-30 18:07:26 +00:00
6d01cf4e69 refactor(kernel): check for __cpp_impl_coroutine in <coroutine>
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-30 17:36:24 +00:00
ffd992cd74 refactor(kernel): improve future implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-29 23:39:44 +00:00
8d71ed0ad5 refactor(kernel): remove 'foreach' macro
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-29 22:43:07 +00:00
93d897e95c feat(kernel): update stl headers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-29 18:27:57 +00:00
31181d5b5d refactor(kernel/syscalls): improve linux_execve implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 18:45:25 +00:00
2f18d390e4 fix(kernel/tty): add stub implementation for TIOCSCTTY ioctl
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 16:46:55 +00:00
5ffb0e704d refactor(kernel/syscalls): add fixme comments for Ctrl+Alt+Del reboot commands
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 16:42:59 +00:00
ad0c1e15e0 fix(kernel/syscalls): add null check for argp in linux_ioctl function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 16:41:58 +00:00
b74d4db23b fix(kernel): update device file references from 'kcon' to 'console'
Feels more right to be 'console'.

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 16:09:16 +00:00
022d99f795 refactor(kernel): remove unused kernel argument from SpawnInit()
There is no reason to use this

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 16:04:46 +00:00
3482131b3f fix(kernel/scheduler): use GetKernelProcess() for idle threads
This will make the init process to be pid 1

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 16:00:22 +00:00
0a32c19923 refactor(kernel): comment out printf declarations in <stdio.h> and include <printf.h> instead
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 15:56:09 +00:00
36c5c8ad67 fix(kernel/elf): segment mapping and handling of program headers were wrongly implemented
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 15:55:29 +00:00
6240d6638f feat(kernel/syscalls): implement linux_chmod and linux_fchmod
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 15:52:50 +00:00
7491f19f9a feat(kernel): implement handling symbolic links in paths
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 14:33:29 +00:00
13d52897b8 feat(kernel): update configuration
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 14:31:22 +00:00
4cc058ab42 feat(kernel/elf): add OS-specific segment types and GNU properties
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 02:09:00 +00:00
a7f754c5e8 fix(kernel): options were not properly parsed
Had to set the context.index to 0 because here argv[0] is not the program name.

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 01:07:27 +00:00
9304cafe0c feat(kernel): update cargs to v1.2.0
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 00:46:34 +00:00
7b42b46942 style(kernel): tab spaces in cargs.c
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-27 00:13:03 +00:00
2ce0e0ed79 feat(kernel/syscalls): add SYS_DEBUG_REPORT syscall
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-26 23:25:16 +00:00
d69eb73a59 chore: update CHANGELOG.md
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-26 23:24:24 +00:00
aa8f415b98 ci: set fetch-depth to 0 for submodule checkout
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-26 23:24:01 +00:00
ec792f1fe2 docs: update contributing guidelines for commit messages and versioning
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-26 23:18:11 +00:00
4c31568329 fix(devcontainer): update XAUTHORITY source to use localEnv
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-26 23:00:29 +00:00
e9dd70c6c4 feat(kernel): add <utf8.h> header
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-26 23:00:10 +00:00
4e9d25143e fix(kernel): add LD_LIBRARY_PATH
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-26 02:33:03 +00:00
92fe4bdd81 feat(kernel): add KERNEL_HHDM_OFFSET macro
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-25 19:43:50 +00:00
0b21c57ee5 fix(vscode): problem matcher lagging the interface
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-25 19:43:30 +00:00
c412a75f91 feat(kernel): update limine
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-25 18:15:45 +00:00
0cc4d5096b fix: accidentally hit CTRL+Z
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Deploy Website / Deploy Website to GitHub Pages (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-25 15:20:57 +00:00
34bd348f25 fix(devcontainer): qemu cannot access /dev/kvm "failed to initialize kvm: Permission denied"
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-25 15:18:43 +00:00
d251d9d03f refactor(rootfs): reorganize file structure and remove unnecessary .gitkeep files
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 15:33:07 +00:00
8f88d9028e feat(devcontainer): add libtool and libltdl-dev packages
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 15:32:42 +00:00
fcdc26c1f7 refactor(tools): update boot configurations
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 15:07:22 +00:00
fc588f10bc feat(kernel): enable SIMD by default
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 15:05:14 +00:00
527e1708ce refactor(rootfs): change "initrd" to "rootfs"
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 00:51:00 +00:00
1286c4cd90 feat(userspace/libs): add libexpat, libffi and libxml2
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 00:42:47 +00:00
0d8c65e44b feat(userspace/libc): implement functions for porting apps
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 00:40:07 +00:00
27356b7826 fix(userspace/libc): mark ABI and build ID notes as used to prevent optimization removal
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-24 00:38:03 +00:00
d06b6d3270 feat(kernel): add hot and cold attributes to optimize function performance
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-22 03:04:23 +00:00
f9476d8c57 fix(kernel/syscalls): cast syscall arguments to scarg type for call_time
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-22 01:44:46 +00:00
79f2faf55b feat(devcontainer): install meson in Dockerfile
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 22:59:58 +00:00
2d0245f2ac feat(kernel): move kernel note to a separate file
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Deploy Website / Deploy Website to GitHub Pages (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 03:29:40 +00:00
79e55140e3 feat(kernel/driver): implement driver sha512 verification
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 03:23:25 +00:00
ae7f39d0de feat(kernel/drivers): add trusted drivers list
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 03:22:40 +00:00
be72d2dc06 fix(kernel/driver): filter out non-.drv files in driver loading
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 03:21:32 +00:00
a8e4dd08bb feat(kernel): add SHA-512 implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 03:15:57 +00:00
c2e31827d8 refactor(kernel): remove unused TaskingPanic() function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 02:19:01 +00:00
7087ce7ec5 feat(userspace/libc): implement brk(), chdir() and getcwd()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 02:01:57 +00:00
36bb7b7a88 refactor: sync headers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 02:00:10 +00:00
2080d1f2b7 feat(kernel/syscalls): add fcntl() syscall
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:58:14 +00:00
b05a6a14e8 fix(kernel): compilation issues due to header changes
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:57:51 +00:00
c4225f7bdf feat(userspace/coreutils): improve fennix shell implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:27:09 +00:00
76b3d30db9 build(userspace/libc): correctly detect linux in cmake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:17:44 +00:00
e89e984ccb feat(userspace/libc): implement access()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:17:21 +00:00
dd1ffe0d17 fix(userspace/libc): add .gitkeep to arch directories
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:16:58 +00:00
3feb4e72aa refactor(userspace/coreutils): change code style
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:16:21 +00:00
a43fac0c2d feat(kernel/api): add fcntl.h
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-21 01:12:08 +00:00
67a3527e29 fix(userspace): change version of libc and coreutils
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-20 00:10:06 +00:00
f4a96e0b2e docs: add note in echo.c PrintHelp()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-17 23:22:00 +00:00
7e69b8f82a feat(userspace/libc): support for linux target
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-17 23:18:54 +00:00
8258d40115 feat(userspace/coreutils): add stub "sh" command
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-17 02:26:47 +00:00
568dffbca1 feat(userspace/libc): add <getopt.h> header
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-16 03:14:14 +00:00
9a82d812d6 feat(userspace/libc): add <regex.h> header
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-16 01:43:57 +00:00
49ee634822 feat(userspace/coreutils): add alias command
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-16 00:54:59 +00:00
babf792c30 feat(userspace/coreutils): add stub "admin" command
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/admin.html
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-16 00:47:56 +00:00
65f9a805e2 build(userspace/coreutils): generate symlink "[" on install
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-16 00:25:04 +00:00
6e077acc66 fix(userspace/coreutils): fix test command to correctly detect the bracket
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-16 00:15:51 +00:00
5af9c9b0a2 feat(userspace/coreutils): add test command
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-16 00:00:09 +00:00
201ace7eec refactor(userspace): build using cmake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-15 23:05:17 +00:00
40f46312f8 fix(userspace/apps/test): make gcc shut up about "infinite recursion detected"
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-13 23:25:52 +00:00
a53d41008c fix(userspace/coreutils): handle combined uname options (-sv, -np, etc.)
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-11 15:38:07 +00:00
8a6910bf04 refactor(userspace/coreutils): improve uname command
The IEEE Std 1003.1-2024 specifies this for output:

    By default, the output shall be a single line of the following form:

    "%s\n", <sysname>

    If the -a option is specified, the output shall be a single line of the following form:

    "%s %s %s %s %s\n", <sysname>, <nodename>, <release>,
        <version>, <machine>

    Additional implementation-defined symbols may be written; all such symbols shall be written at the end of the line of output before the <newline>.

    If options are specified to select different combinations of the symbols, only those symbols shall be written, in the order shown above for the -a option. If a symbol is not selected for writing, its corresponding trailing <blank> characters also shall not be written.

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-11 15:33:08 +00:00
1d7a9edd46 feat(userspace/coreutils): implement arch command
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-11 15:29:17 +00:00
58477bae6a refactor(userspace): move uname program to coreutils
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-11 00:53:36 +00:00
cbc6238d9d fix(userspace/libc): implement uname()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 22:39:26 +00:00
9f393754f6 feat(kernel/syscalls): implement uname syscall
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 22:38:52 +00:00
fc43512c75 feat: add /etc/hostname file
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 22:05:54 +00:00
551853c5d6 fix(userspace/libc): implement gethostname()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 22:05:28 +00:00
6b4faf9f78 fix(userspace/libc): remove stub macros in termios.c
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 21:04:53 +00:00
4a6cf4f2e5 chore(userspace/coreutils): update .gitignore
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 19:34:35 +00:00
b008b8089c fix(userspace/libc): missing include <sys/ioctl.h>
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 19:32:16 +00:00
2f33ea4dfd build(devcontainer): install cmake too
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 13:48:23 +00:00
87540ab0b9 feat(coreutils): implement coreutils and compile it using cmake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 02:29:14 +00:00
88a3b0912b feat(userspace): add dummy libstdc++ library
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 02:20:32 +00:00
7ec85e67df style(kernel): format document
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 01:14:47 +00:00
67692f2cef feat(userspace/libc): define TIOC*WINSZ constants in <sys/ioctl.h>
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 01:14:18 +00:00
cc81facf50 feat(userspace/apps/usr): stub implementation for mdview
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 01:12:10 +00:00
95cc190b54 build(devcontainer): potential fix for "failed to initialize kvm: Permission denied"
qemu-system-x86_64: Could not access KVM kernel module: Permission denied
qemu-system-x86_64: failed to initialize kvm: Permission denied

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-10 01:07:56 +00:00
1c842ef3d1 docs: update build instructions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-08 00:47:43 +00:00
27ad61fa17 chore(devcontainer): cleanup devcontainer.json file
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-07 22:58:04 +00:00
45d34c688f fix(userspace/libc): fix puts() in interpreter
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-07 02:09:16 +00:00
1ff62e22bf feat(kernel/syscalls): implement sys_fork()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-07 01:31:50 +00:00
2c02da7eaf build: add Clean, Build & Run tasks for vscode
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build OS (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 15:19:21 +00:00
8ef7a25728 ci: separate github pages deploy workflow
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 13:46:52 +00:00
b4cc1d9e66 fix(kernel): crash on ACPI shutdown/reboot
The deletion of DriverManager invalidates "DriverManager->GlobalKeyboardInputReports" which results in a crash if other processes are waiting for keyboard input.

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 13:38:42 +00:00
424 changed files with 45138 additions and 18218 deletions

View File

@ -24,20 +24,6 @@ RUN apt-get -y install --no-install-recommends \
file \
python3-dev
# Required packages for building gcc & binutils
RUN <<EOF
wget https://launchpad.net/ubuntu/+archive/primary/+files/autoconf_2.69-11.1_all.deb -O /tmp/autoconf.deb
sudo dpkg --force-all -i /tmp/autoconf.deb
EOF
# Required packages for building gcc & binutils
RUN <<EOF
wget https://ftp.gnu.org/gnu/automake/automake-1.15.1.tar.gz -O /tmp/automake.tar.gz
tar -xzf /tmp/automake.tar.gz -C /tmp
cd /tmp/automake-1.15.1
./configure && make && sudo make install
EOF
# Required packages for building qemu
RUN apt-get -y install --no-install-recommends \
git \
@ -80,7 +66,9 @@ RUN apt-get -y install --no-install-recommends \
# Required packages for building test apps in userspace
RUN apt-get -y install --no-install-recommends \
mingw-w64
mingw-w64 \
libtool \
libltdl-dev
# Required packages for building the OS and misc
RUN apt-get -y install --no-install-recommends \
@ -94,11 +82,15 @@ RUN apt-get -y install --no-install-recommends \
grub-pc-bin \
grub-pc \
grub2-common \
pip
pip \
cmake
# Install git-cliff
RUN pip install git-cliff --break-system-packages
# Install meson
RUN pip install meson --break-system-packages
# Configure git
RUN <<EOF
git config --global advice.detachedHead false
@ -114,3 +106,22 @@ ENV NO_AT_BRIDGE=1
RUN <<EOF
echo PATH=$PATH:/workspaces/Fennix/cross/bin >> /etc/profile
EOF
ENV CHMOD_KVM=1
# Remove autoconf & automake
RUN sudo apt-get -y remove autoconf automake
# Required packages for building gcc & binutils
RUN <<EOF
wget https://launchpad.net/ubuntu/+archive/primary/+files/autoconf_2.69-11.1_all.deb -O /tmp/autoconf.deb
sudo dpkg --force-all -i /tmp/autoconf.deb
EOF
# Required packages for building gcc & binutils
RUN <<EOF
wget https://ftp.gnu.org/gnu/automake/automake-1.15.1.tar.gz -O /tmp/automake.tar.gz
tar -xzf /tmp/automake.tar.gz -C /tmp
cd /tmp/automake-1.15.1
./configure && make && sudo make install
EOF

View File

@ -25,27 +25,21 @@
}
},
// From this line below are for qemu, so not that important.
"initializeCommand": "[ -x \"$(command -v xhost)\" ] && xhost +local:docker || true", // "xhost -local:docker" to disable
"mounts": [
"source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached",
"source=${localEnv:XAUTHORITY},target=/home/vscode/.Xauthority,type=bind,consistency=cached",
"source=/dev/kvm,target=/dev/kvm,type=bind,consistency=cached",
"source=/run/user/1000/pulse/native,target=/run/user/1000/pulse/native,type=bind,consistency=cached"
{
"source": "/tmp/.X11-unix",
"target": "/tmp/.X11-unix",
"type": "bind"
},
{
"source": "/run/user/1000/pulse/native",
"target": "/run/user/1000/pulse/native",
"type": "bind"
}
],
"runArgs": [
"--privileged"
"--privileged",
"--network=host"
]
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "gcc -v",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

View File

@ -19,3 +19,8 @@ indent_size = 2
[{CMakeLists.txt,*.cmake}]
indent_size = 2
indent_style = space
[*.md]
indent_style = space
indent_size = 4
trim_trailing_whitespace = false

View File

@ -7,31 +7,6 @@ on:
branches: [ master ]
jobs:
deploydoc:
name: Deploy Documentation to GitHub Pages
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Doxygen
run: |
sudo apt update
sudo apt --no-install-recommends -y install doxygen make
- name: Generate Documentation
run: make doxygen
- name: Copy GitHub Pages Website
run: cp -r tools/website/* doxygen-doc/
- name: Deploy documentation
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: doxygen-doc
buildcompiler:
name: Build Cross-Compiler & Toolchain
runs-on: ubuntu-latest
@ -51,9 +26,7 @@ jobs:
run: |
sudo mkdir -p /tmp/.X11-unix
sudo mkdir -p /run/user/1000/pulse
sudo touch /tmp/.Xauthority
sudo touch /run/user/1000/pulse/native
echo "XAUTHORITY=/tmp/.Xauthority" >> $GITHUB_ENV
- name: Run make ci-setup in dev container
if: steps.cache-cross.outputs.cache-hit != 'true'
@ -146,6 +119,7 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Cache cross Folder
id: cache-cross
@ -158,18 +132,94 @@ jobs:
run: |
sudo mkdir -p /tmp/.X11-unix
sudo mkdir -p /run/user/1000/pulse
sudo touch /tmp/.Xauthority
sudo touch /run/user/1000/pulse/native
echo "XAUTHORITY=/tmp/.Xauthority" >> $GITHUB_ENV
- name: Run make ci-build in dev container
- name: Build AMD64 Debug
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make ci-build
runCmd: /usr/bin/make __ci-amd64-debug
- name: Build AMD64 Release
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-amd64-release
- name: Build i386 Debug
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-i386-debug
- name: Build i386 Release
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-i386-release
- name: Build ARM Debug
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-arm-debug
- name: Build ARM Release
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-arm-release
- name: Build AArch64 Debug
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-aarch64-debug
- name: Build AArch64 Release
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-aarch64-release
- name: Build Prepare Archive
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: /usr/bin/make __ci-prepare-archive
- name: Upload Artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: Fennix
name: artifacts
path: artifacts/
nightly:
if: always()
name: Upload Nightly Build to GitHub Releases
runs-on: ubuntu-latest
needs: [compile]
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Download All Builds
uses: actions/download-artifact@v4
- name: Update Nightly
run: gh release upload nightly artifacts/* -R ${{github.repository}} --clobber
env:
GH_TOKEN: ${{ github.token }}

33
.github/workflows/website.yml vendored Normal file
View File

@ -0,0 +1,33 @@
name: Deploy Website
on:
push:
branches: [ master ]
paths:
- tools/website/**
- Kernel/include/interface/**
- Doxyfile
jobs:
deploydoc:
name: Deploy Website to GitHub Pages
runs-on: ubuntu-latest
steps:
- name: Checkout code 🛎️
uses: actions/checkout@v4
- name: Install Doxygen 📦
run: |
sudo apt update
sudo apt --no-install-recommends -y install doxygen make
- name: Generate Documentation 📚
run: make doxygen
- name: Copy GitHub Pages Website 📁
run: cp -r tools/website/* doxygen-doc/
- name: Deploy documentation 🚀
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: doxygen-doc

8
.gitignore vendored
View File

@ -1,10 +1,10 @@
iso_tmp_data
artifacts
initrd_tmp_data
initrd/usr/include/*
!initrd/usr/include/.gitkeep
tmp_rootfs
rootfs/usr/include/*
!rootfs/usr/include/.gitkeep
doxygen-doc
initrd.tar
rootfs.tar.gz
.dccache
*.log
*.log.*

16
.vscode/launch.json vendored
View File

@ -19,12 +19,12 @@
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/utest",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "/bin/utest (0x00400000)",
"ignoreFailures": true
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/libc_test",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true
},
@ -52,12 +52,12 @@
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/utest",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "/bin/utest (0x00400000)",
"ignoreFailures": true
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/libc_test",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true
},
@ -85,12 +85,12 @@
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/utest",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "/bin/utest (0x00400000)",
"ignoreFailures": true
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/libc_test",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true
},
@ -118,12 +118,12 @@
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/utest",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "/bin/utest (0x00400000)",
"ignoreFailures": true
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/libc_test",
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true
},

View File

@ -16,5 +16,6 @@
"**/tools/qemu/**": true,
"**/tools/cross/**": true,
"**/doxygen-doc/**": true,
}
},
"cmake.ignoreCMakeListsMissing": true
}

325
.vscode/tasks.json vendored
View File

@ -1,11 +1,87 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Clean",
"type": "shell",
"command": "make clean",
"isBackground": false,
"hide": false,
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "never",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Build",
"type": "shell",
"command": "make build",
"isBackground": false,
"hide": false,
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Run",
"type": "shell",
"command": "make qemu",
"isBackground": false,
"hide": false,
"dependsOn": [
"Build"
],
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Build Bootloader",
"type": "shell",
"command": "make -C ../ build_bootloader",
"isBackground": false,
"hide": true,
"group": {
"kind": "build",
"isDefault": false
@ -28,6 +104,7 @@
"type": "shell",
"command": "make -C ../ build_kernel",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Bootloader"
],
@ -53,6 +130,7 @@
"type": "shell",
"command": "make -C ../ build_drivers",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Kernel"
],
@ -78,6 +156,7 @@
"type": "shell",
"command": "make -C ../ build_userspace",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Drivers"
],
@ -103,6 +182,7 @@
"type": "shell",
"command": "make -C ../ build_image",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Userspace"
],
@ -147,7 +227,7 @@
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "CR0 update",
"endsPattern": "CPU Reset",
}
}
],
@ -170,6 +250,249 @@
]
}
}
},
{
"label": "CI AMD64 Debug",
"type": "shell",
"command": "make __ci-amd64-debug",
"isBackground": false,
"hide": true,
"dependsOn": [
"Clean"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "CI AMD64 Release",
"type": "shell",
"command": "make __ci-amd64-release",
"isBackground": false,
"hide": true,
"dependsOn": [
"CI AMD64 Debug"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "CI i386 Debug",
"type": "shell",
"command": "make __ci-i386-debug",
"isBackground": false,
"hide": true,
"dependsOn": [
"CI AMD64 Release"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "CI i386 Release",
"type": "shell",
"command": "make __ci-i386-release",
"isBackground": false,
"hide": true,
"dependsOn": [
"CI i386 Debug"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "CI ARM Debug",
"type": "shell",
"command": "make __ci-arm-debug",
"isBackground": false,
"hide": true,
"dependsOn": [
"CI i386 Release"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "CI ARM Release",
"type": "shell",
"command": "make __ci-arm-release",
"isBackground": false,
"hide": true,
"dependsOn": [
"CI ARM Debug"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "CI AARCH64 Debug",
"type": "shell",
"command": "make __ci-aarch64-debug",
"isBackground": false,
"hide": true,
"dependsOn": [
"CI ARM Release"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "CI AARCH64 Release",
"type": "shell",
"command": "make __ci-aarch64-release",
"isBackground": false,
"hide": true,
"dependsOn": [
"CI AARCH64 Debug"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Test CI Build",
"type": "shell",
"command": "make __ci-restore-config",
"isBackground": false,
"dependsOn": [
"CI AARCH64 Release",
"clean"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}/../",
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
}
]
}

View File

@ -6,21 +6,45 @@ All notable changes to this project will be documented in this file.
### <!-- 0 -->🚀 Features
- *(coreutils)* Implement coreutils and compile it using cmake
- *(devcontainer)* Install meson in Dockerfile
- *(devcontainer)* Add libtool and libltdl-dev packages
- *(initrd)* Add /etc/hosts file
- *(kernel)* Add stub device /dev/fb0
- *(kernel)* Add SHA-512 implementation
- *(kernel)* Move kernel note to a separate file
- *(kernel)* Add hot and cold attributes to optimize function performance
- *(kernel)* Enable SIMD by default
- *(kernel)* Update limine
- *(kernel)* Add KERNEL_HHDM_OFFSET macro
- *(kernel)* Add <utf8.h> header
- *(kernel/api)* Implement i386 syscall wrappers
- *(kernel/api)* Implement arm syscall wrappers
- *(kernel/api)* Add fcntl.h
- *(kernel/driver)* Add ReloadDriver method to manage driver reloading
- *(kernel/driver)* Add CreateDeviceFile method
- *(kernel/driver)* Add CreateDeviceFile function in the API
- *(kernel/driver)* Implement built-in driver support
- *(kernel/driver)* Implement driver sha512 verification
- *(kernel/drivers)* Migrate drivers to the kernel
- *(kernel/drivers)* Add trusted drivers list
- *(kernel/pci)* Add device initialization method for PCI devices
- *(kernel/syscalls)* Implement sys_fork()
- *(kernel/syscalls)* Implement uname syscall
- *(kernel/syscalls)* Add fcntl() syscall
- *(userspace)* Add dummy libstdc++ library
- *(userspace/apps/sys/init)* Handle termination signals for graceful shutdown
- *(userspace/apps/test)* Update utest
- *(userspace/apps/test/libc_test)* Add more tests
- *(userspace/apps/test/libc_test)* Rewrite a lot of the code and improve debugging with vscode using .devcontainer
- *(userspace/apps/test/utest)* Add TestProcess function for executing test programs
- *(userspace/apps/usr)* Stub implementation for mdview
- *(userspace/coreutils)* Implement arch command
- *(userspace/coreutils)* Add test command
- *(userspace/coreutils)* Add stub "admin" command
- *(userspace/coreutils)* Add alias command
- *(userspace/coreutils)* Add stub "sh" command
- *(userspace/coreutils)* Improve fennix shell implementation
- *(userspace/libc)* Implement strcpy function
- *(userspace/libc)* Implement all <string.h> functions
- *(userspace/libc)* Complete <string.h> implementation
@ -44,25 +68,45 @@ All notable changes to this project will be documented in this file.
- *(userspace/libc)* Implementation <fenv.h> header
- *(userspace/libc)* Implement <math.h> header
- *(userspace/libc)* Add experimental __aeabi_dcmpun() function
- *(userspace/libc)* Define TIOC*WINSZ constants in <sys/ioctl.h>
- *(userspace/libc)* Add <regex.h> header
- *(userspace/libc)* Add <getopt.h> header
- *(userspace/libc)* Support for linux target
- *(userspace/libc)* Implement access()
- *(userspace/libc)* Implement brk(), chdir() and getcwd()
- *(userspace/libc)* Implement functions for porting apps
- *(userspace/libs)* Add libexpat, libffi and libxml2
- *(userspace/libs/libdemo)* Add template library
- *(userspace/libs/libm)* Add stub libm
- *(No Category)* Synchronize syscalls.h
- *(No Category)* Add /etc/hostname file
### <!-- 1 -->🐛 Bug Fixes
- *(devcontainer)* Qemu cannot access /dev/kvm "failed to initialize kvm: Permission denied"
- *(devcontainer)* Update XAUTHORITY source to use localEnv
- *(drivers)* Remove drivers that are now in kernel
- *(kernel)* Add TZ environment variable to init process
- *(kernel)* Fix empty initialization of std::string (str = "")
- *(kernel)* Crash on ACPI shutdown/reboot
- *(kernel)* Compilation issues due to header changes
- *(kernel)* Add LD_LIBRARY_PATH
- *(kernel/driver)* Remove unused device handling code in daemon
- *(kernel/driver)* Node device & offset were not set for new created files under /dev
- *(kernel/driver)* Set unused file system operation pointers to nullptr
- *(kernel/driver)* Filter out non-.drv files in driver loading
- *(kernel/pci)* Map BAR address using PWT and PCD flags
- *(kernel/pci)* Fix MapPCIAddresses when BAR size of zero
- *(kernel/syscalls)* Cast syscall arguments to scarg type for call_time
- *(kernel/tty)* Temporal removal of ICANON checking
- *(userspace)* Change version of libc and coreutils
- *(userspace/apps/test)* Fix noreturn compiler warning
- *(userspace/apps/test)* Update expected results for rounding and special functions
- *(userspace/apps/test)* Adjust fflush(stdout) calls for better output control
- *(userspace/apps/test)* Make gcc shut up about "infinite recursion detected"
- *(userspace/coreutils)* Handle combined uname options (-sv, -np, etc.)
- *(userspace/coreutils)* Fix test command to correctly detect the bracket
- *(userspace/libc)* Fix error handling in ioctl function
- *(userspace/libc)* Include <ctype.h> in stdlib.c
- *(userspace/libc)* Cast status to int in __check_errno for proper error handling
@ -76,20 +120,33 @@ All notable changes to this project will be documented in this file.
- *(userspace/libc)* Disable debug info in memory allocation functions
- *(userspace/libc)* Fix wrong implementation of ioctl()
- *(userspace/libc)* Add libgcc link to fix softfloat
- *(userspace/libc)* Fix puts() in interpreter
- *(userspace/libc)* Missing include <sys/ioctl.h>
- *(userspace/libc)* Remove stub macros in termios.c
- *(userspace/libc)* Implement gethostname()
- *(userspace/libc)* Implement uname()
- *(userspace/libc)* Add .gitkeep to arch directories
- *(userspace/libc)* Mark ABI and build ID notes as used to prevent optimization removal
- *(vscode)* Problem matcher lagging the interface
- *(No Category)* Fixme
- *(No Category)* Fixme
- *(No Category)* Correct project name references in license headers
- *(No Category)* Accidentally hit CTRL+Z
### <!-- 10 -->💼 Other
- *(devcontainer)* Improve Dev Container development
- *(devcontainer)* Potential fix for "failed to initialize kvm: Permission denied"
- *(devcontainer)* Install cmake too
- *(kernel)* Fix compiling issues on i386
- *(kernel)* Fix compiling issues on arm
- *(kernel)* Fix i386 build
- *(tools)* Rewrite makefile to be more efficient and easy to understand
- *(tools)* Fix gdb error 'Scripting in the "Python" language is not supported in this copy of GDB.'
- *(userspace)* Update vscode launch configuration and Makefiles for utest and libc_test
- *(userspace/coreutils)* Generate symlink "[" on install
- *(userspace/libc)* Correctly detect linux in cmake
- *(vscode)* Add separated tasks for building bootloader, kernel, drivers, userspace, and image
- *(No Category)* Initial commit
- *(No Category)* Delete README.md
@ -1696,17 +1753,26 @@ Use SetWorkingDirectory()
- *(No Category)* Add <sys/socket.h> for socket programming support
- *(No Category)* Implement strcoll()
- *(No Category)* Implement qsort, realloc and reallocarray functions in stdlib
- *(No Category)* Add Clean, Build & Run tasks for vscode
### <!-- 2 -->🚜 Refactor
- *(driver/api)* Fix formatting
- *(driver/api)* Delegate memory allocation and deallocation to DriverManager
- *(kernel)* Remove unused TaskingPanic() function
- *(kernel/pci)* Simplify PCI device initialization by delegating to PCIManager
- *(kernel/syscalls)* Simplify argument handling in HandleNativeSyscalls
- *(rootfs)* Change "initrd" to "rootfs"
- *(rootfs)* Reorganize file structure and remove unnecessary .gitkeep files
- *(tests)* Remove obsolete SIMD and web test files
- *(tools)* Update boot configurations
- *(userspace)* Move uname program to coreutils
- *(userspace)* Build using cmake
- *(userspace/apps/test)* :recycle: move all functions in one file
- *(userspace/apps/test/libc_test)* Remove deprecated string test files
- *(userspace/coreutils)* Improve uname command
- *(userspace/coreutils)* Change code style
- *(userspace/libc)* Replace syscall2 with call_kill in kill function
- *(userspace/libc)* Implement pthread_sigmask, sigaddset, sigfillset & sigprocmask
- *(userspace/libs)* Rename libdemo to libexample
@ -1714,6 +1780,7 @@ Use SetWorkingDirectory()
- *(No Category)* Fix build on i386
- *(No Category)* Fix softfloat on aarch64 and arm
- *(No Category)* Fix release building for aarch64 and arm
- *(No Category)* Sync headers
### <!-- 3 -->📚 Documentation
@ -1723,6 +1790,14 @@ Use SetWorkingDirectory()
- *(syscalls)* Add documentation for FBIOGET_SCREEN_INFO ioctl
- *(No Category)* Remove .dockerignore, Dockerfile, and compose.yaml
- *(No Category)* Update README.md
- *(No Category)* Update build instructions
- *(No Category)* Add note in echo.c PrintHelp()
- *(No Category)* Update contributing guidelines for commit messages and versioning
### <!-- 5 -->🎨 Styling
- *(kernel)* Format document
### <!-- 6 -->🧪 Testing
@ -1734,6 +1809,8 @@ Use SetWorkingDirectory()
### <!-- 7 -->⚙️ Miscellaneous Tasks
- *(devcontainer)* Rename dev container (libc_test)
- *(devcontainer)* Cleanup devcontainer.json file
- *(userspace/coreutils)* Update .gitignore
- *(userspace/libc)* Update vscode workspace config
- *(vscode)* Add conventional commit scopes for kernel
- *(vscode)* Add recommended extensions for improved development experience
@ -1798,6 +1875,9 @@ Use SetWorkingDirectory()
- *(No Category)* Fix ci
- *(No Category)* Fix limine in ci build
- *(No Category)* Add "push: never" to devcontainers/ci
- *(No Category)* Add git-cliff
- *(No Category)* Add CHANGELOG.md in artifacts
- *(No Category)* Separate github pages deploy workflow
<!-- generated by git-cliff -->

View File

@ -62,6 +62,8 @@ Follow the coding style used in the repository to ensure consistency. Adhere to:
- Start function and global declaration names with an uppercase letter.
- Start local variable names with a lowercase letter.
- Maintain consistent formatting and commenting guidelines.
- Commit messages must follow [Conventional Commits](https://conventionalcommits.org).
- Release versions must follow [Semantic Versioning](https://semver.org).
Refer to the [style guide document](STYLE_GUIDE.md) if available.

View File

@ -27,6 +27,9 @@ License information can be found in the [LICENSES.md](LICENSES.md) file.
## CPUID 0x7
- [CPUID](https://en.wikipedia.org/wiki/CPUID)
## KVM CPUID
- [kernel.org KVM CPUID](https://www.kernel.org/doc/html/v6.9/virt/kvm/x86/cpuid.html?highlight=cpuid)
## Network
- [Beej's Guide to Network Programming](https://web.archive.org/web/20051210132103/http://users.pcnet.ro/dmoroian/beej/Beej.html)
- [UDP Socket Programming](https://web.archive.org/web/20060229214053/http://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html)
@ -120,6 +123,18 @@ License information can be found in the [LICENSES.md](LICENSES.md) file.
## UART
- [Interfacing the Serial / RS232 Port V5.0](http://www.senet.com.au/~cpeacock)
## UEFI
- [U-Boot EFI Commands](https://docs.u-boot.org/en/latest/usage/cmd/efi.html)
- [UEFI Specification 2.10](https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf)
- [UEFI Boot Process Overview](https://gist.github.com/Velocet/d394281d96191e235ff46a8aa2018d80)
- [Rust OS Development: UEFI](https://blog.malware.re/2023/09/01/rust-os-part2/index.html)
- [GUIDs Database](https://github.com/DSecurity/efiSeek/blob/master/data/guids-db.ini)
## BGRT
- [BGRT on OSDev](https://wiki.osdev.org/BGRT)
- [BMP File Structure @ Gdansk University of Technology](http://www.ue.eti.pg.gda.pl/fpgalab/zadania.spartan3/zad_vga_struktura_pliku_bmp_en.html)
- [BGRT @ Purdue University](https://engineering.purdue.edu/ece264/16au/hw/HW13)
---
Special thanks to all contributors and the creators of the referenced projects and resources!

View File

@ -43,30 +43,47 @@ endif
export DRIVER_LDFLAGS
export DRIVER_CFLAGS
copy_driver_signatures:
@TMP_FILE="$(OUTPUT_DIR)../../Kernel/drivers/trusted.c.tmp"; \
OUT_FILE="$(OUTPUT_DIR)../../Kernel/drivers/trusted.c"; \
mkdir -p $(OUTPUT_DIR)../../Kernel/drivers/; \
echo "const char *trusted_drivers[] = {" > $$TMP_FILE; \
find $(OUTPUT_DIR) -name "*.drv" -exec sha512sum {} \; | awk '{gsub(/.*\//, "", $$2); gsub(/\./, "_", $$2); sub(/_drv$$/, "_drv", $$2); print "\"" $$1 "\"," }' >> $$TMP_FILE; \
echo "};" >> $$TMP_FILE; \
echo "const __SIZE_TYPE__ trusted_drivers_count = sizeof(trusted_drivers) / sizeof(trusted_drivers[0]);" >> $$TMP_FILE; \
if [ ! -f $$OUT_FILE ] || ! cmp -s $$TMP_FILE $$OUT_FILE; then \
mv $$TMP_FILE $$OUT_FILE; \
printf '\033[0;32m[trusted.c updated]\033[0m\n'; \
else \
rm $$TMP_FILE; \
printf '\033[0;33m[trusted.c unchanged]\033[0m\n'; \
fi
build:
cp -rf ../Kernel/include/interface/* include/
mkdir -p out
make -C library build
$(MAKE) -C library build
ifneq ($(filter amd64 i386,$(OSARCH)),)
make -C audio build
make -C input build
make -C misc build
make -C network build
make -C storage build
make -C filesystem build
$(MAKE) -C audio build
$(MAKE) -C input build
$(MAKE) -C misc build
$(MAKE) -C network build
$(MAKE) -C storage build
$(MAKE) -C filesystem build
endif
$(MAKE) copy_driver_signatures
prepare:
$(info Nothing to prepare)
clean:
rm -rf out
make -C library clean
$(MAKE) -C library clean
ifneq ($(filter amd64 i386,$(OSARCH)),)
make -C audio clean
make -C input clean
make -C misc clean
make -C network clean
make -C storage clean
make -C filesystem clean
$(MAKE) -C audio clean
$(MAKE) -C input clean
$(MAKE) -C misc clean
$(MAKE) -C network clean
$(MAKE) -C storage clean
$(MAKE) -C filesystem clean
endif

110
Drivers/include/block.h Normal file
View File

@ -0,0 +1,110 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_API_BLOCK_H__
#define __FENNIX_API_BLOCK_H__
#include <types.h>
#if __has_include(<interface/fs.h>)
#include <interface/fs.h>
#else
#include <fs.h>
#endif
struct BlockDevice
{
/**
* @brief Base name of the device.
*
* This name is used to identify the device in the system. It should be unique
* across all block devices. The kernel may append a number to this name to
* create a unique device name (e.g., "ahci0", "ahci1").
*/
const char *Name;
/**
* @brief Total size of the device in bytes.
*
* This value represents the total addressable storage capacity of the device.
* It is used for bounds checking and partitioning.
*/
size_t Size;
/**
* @brief Size of a single block in bytes.
*
* All read and write operations are performed in multiples of this block size.
* Typical values are 512 or 4096 bytes.
*/
uint32_t BlockSize;
/**
* @brief Number of blocks in the device.
*
* This value is calculated as Size / BlockSize. It represents the total number
* of addressable blocks on the device.
*/
size_t BlockCount;
/**
* @brief Pointer to the block device operations structure.
*
* This structure contains function pointers for various operations that can
* be performed on the block device, such as read, write, and ioctl.
*
* Yea, inode operations are used for block devices too.
*/
const InodeOperations *Ops;
/**
* @brief Opaque pointer to driver-specific or hardware-specific data.
*
* This field allows the driver to associate private context or state with the
* device, such as controller registers or internal buffers.
*/
void *PrivateData;
};
#ifndef __kernel__
/**
* @brief Registers a block device with the kernel block subsystem.
*
* This function should be called by block device drivers after initializing
* a device. The kernel will take ownership of the device structure and assign
* it a unique device ID. The device will then be accessible for filesystem
* mounting and I/O operations.
*
* @param Device Pointer to a fully initialized BlockDevice structure. All required fields must be set and valid for the lifetime of the device.
* @return Device ID (dev_t) assigned by the kernel on success, or an error code on failure.
*/
dev_t RegisterBlockDevice(struct BlockDevice *Device);
/**
* @brief Unregisters a block device from the kernel block subsystem.
*
* This function should be called by drivers when a device is being removed
* or is no longer available. The kernel will release any resources associated
* with the device and invalidate its device ID.
*
* @param DeviceID The device ID (dev_t) previously returned by RegisterBlockDevice().
* @return 0 on success, or an error code.
*/
int UnregisterBlockDevice(dev_t DeviceID);
#endif // __kernel__
#endif // __FENNIX_API_BLOCK_H__

View File

@ -25,14 +25,13 @@
* Full list:
* https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html
*/
typedef enum
{
/**
/**
* No Error
*/
EOK = 0,
#define EOK 0
/**
/**
* Argument list too long. The sum of the number of bytes used by the
* new process image's argument list and environment list is greater
* than the system-imposed limit of {ARG_MAX} bytes.
@ -41,52 +40,52 @@ typedef enum
* or:
* Argument is greater than the system-imposed maximum.
*/
E2BIG = 1,
#define E2BIG 1
/**
/**
* Permission denied. An attempt was made to access a file in a way
* forbidden by its file access permissions.
*/
EACCES = 2,
#define EACCES 2
/**
/**
* Address in use. The specified address is in use.
*/
EADDRINUSE = 3,
#define EADDRINUSE 3
/**
/**
* Address not available. The specified address is not available from
* the local system.
*/
EADDRNOTAVAIL = 4,
#define EADDRNOTAVAIL 4
/**
/**
* Address family not supported. The implementation does not support
* the specified address family, or the specified address is not a
* valid address for the address family of the specified socket.
*/
EAFNOSUPPORT = 5,
#define EAFNOSUPPORT 5
/**
/**
* Resource temporarily unavailable. This is a temporary condition
* and later calls to the same routine may complete normally.
*/
EAGAIN = 6,
#define EAGAIN 6
/**
/**
* Connection already in progress. A connection request is already in
* progress for the specified socket.
*/
EALREADY = 7,
#define EALREADY 7
/**
/**
* Bad file descriptor. A file descriptor argument is out of range,
* refers to no open file, or a read (write) request is made to a
* file that is only open for writing (reading).
*/
EBADF = 8,
#define EBADF 8
/**
/**
* Bad message. During a read(), getmsg(), getpmsg(), or ioctl()
* I_RECVFD request to a STREAMS device, a message arrived at the
* head of the STREAM that is inappropriate for the function
@ -99,191 +98,191 @@ typedef enum
* Control or data information was received instead of a file
* descriptor when I_RECVFD was specified.
*/
EBADMSG = 9,
#define EBADMSG 9
/**
/**
* Resource busy. An attempt was made to make use of a system
* resource that is not currently available, as it is being
* used by another process in a manner that would have
* conflicted with the request being made by this process.
*/
EBUSY = 10,
#define EBUSY 10
/**
/**
* Operation canceled. The associated asynchronous operation was
* canceled before completion.
*/
ECANCELED = 11,
#define ECANCELED 11
/**
/**
* No child process. A wait(), waitid(), or waitpid() function was
* executed by a process that had no existing or unwaited-for
* child process.
*/
ECHILD = 12,
#define ECHILD 12
/**
/**
* Connection aborted. The connection has been aborted.
*/
ECONNABORTED = 13,
#define ECONNABORTED 13
/**
/**
* Connection refused. An attempt to connect to a socket was refused
* because there was no process listening or because the queue of
* connection requests was full and the underlying protocol does not
* support retransmissions.
*/
ECONNREFUSED = 14,
#define ECONNREFUSED 14
/**
/**
* Connection reset. The connection was forcibly closed by the peer.
*/
ECONNRESET = 15,
#define ECONNRESET 15
/**
/**
* Resource deadlock would occur. An attempt was made to lock a system
* resource that would have resulted in a deadlock situation.
*/
EDEADLK = 16,
#define EDEADLK 16
/**
/**
* Destination address required. No bind address was established.
*/
EDESTADDRREQ = 17,
#define EDESTADDRREQ 17
/**
/**
* Domain error. An input argument is outside the defined domain of the
* mathematical function (defined in the ISO C standard).
*/
EDOM = 18,
#define EDOM 18
/**
/**
* Reserved.
*/
EDQUOT = 19,
#define EDQUOT 19
/**
/**
* File exists. An existing file was mentioned in an inappropriate
* context; for example, as a new link name in the link() function.
*/
EEXIST = 20,
#define EEXIST 20
/**
/**
* Bad address. The system detected an invalid address in attempting
* to use an argument of a call. The reliable detection of this error
* cannot be guaranteed, and when not detected may result in the
* generation of a signal, indicating an address violation, which is
* sent to the process.
*/
EFAULT = 21,
#define EFAULT 21
/**
/**
* File too large. The size of a file would exceed the maximum file
* size of an implementation or offset maximum established in the
* corresponding file description.
*/
EFBIG = 22,
#define EFBIG 22
/**
/**
* Host is unreachable. The destination host cannot be reached
* (probably because the host is down or a remote router cannot
* reach it).
*/
EHOSTUNREACH = 23,
#define EHOSTUNREACH 23
/**
/**
* Identifier removed. Returned during XSI interprocess communication
* if an identifier has been removed from the system.
*/
EIDRM = 24,
#define EIDRM 24
/**
/**
* Illegal byte sequence. A wide-character code has been detected that
* does not correspond to a valid character, or a byte sequence does
* not form a valid wide-character code (defined in the ISO C standard).
*/
EILSEQ = 25,
#define EILSEQ 25
/**
/**
* Operation in progress. This code is used to indicate that an
* asynchronous operation has not yet completed.
* or:
* O_NONBLOCK is set for the socket file descriptor and the connection
* cannot be immediately established.
*/
EINPROGRESS = 26,
#define EINPROGRESS 26
/**
/**
* Interrupted function call. An asynchronous signal was caught by the
* process during the execution of an interruptible function. If the
* signal handler performs a normal return, the interrupted function
* call may return this condition (see the Base Definitions volume
* of POSIX.1-2017, <signal.h>).
*/
EINTR = 27,
#define EINTR 27
/**
/**
* Invalid argument. Some invalid argument was supplied; for example,
* specifying an undefined signal in a signal() function or a
* kill() function.
*/
EINVAL = 28,
#define EINVAL 28
/**
/**
* Input/output error. Some physical input or output error has occurred.
* This error may be reported on a subsequent operation on the same
* file descriptor. Any other error-causing operation on the same file
* descriptor may cause the [EIO] error indication to be lost.
*/
EIO = 29,
#define EIO 29
/**
/**
* Socket is connected. The specified socket is already connected.
*/
EISCONN = 30,
#define EISCONN 30
/**
/**
* Is a directory. An attempt was made to open a directory with write
* mode specified.
*/
EISDIR = 31,
#define EISDIR 31
/**
/**
* Symbolic link loop. A loop exists in symbolic links encountered
* during pathname resolution. This error may also be returned if
* more than {SYMLOOP_MAX} symbolic links are encountered during
* pathname resolution.
*/
ELOOP = 32,
#define ELOOP 32
/**
/**
* File descriptor value too large or too many open streams. An
* attempt was made to open a file descriptor with a value greater
* than or equal to {OPEN_MAX}, or an attempt was made to open more
* than the maximum number of streams allowed in the process.
*/
EMFILE = 33,
#define EMFILE 33
/**
/**
* Too many links. An attempt was made to have the link count of a
* single file exceed {LINK_MAX}.
*/
EMLINK = 34,
#define EMLINK 34
/**
/**
* Message too large. A message sent on a transport provider was
* larger than an internal message buffer or some other network limit.
* or:
* Inappropriate message buffer length.
*/
EMSGSIZE = 35,
#define EMSGSIZE 35
/**
/**
* Reserved.
*/
EMULTIHOP = 36,
#define EMULTIHOP 36
/**
/**
* Filename too long. The length of a pathname exceeds {PATH_MAX} and
* the implementation considers this to be an error, or a pathname
* component is longer than {NAME_MAX}. This error may also occur
@ -291,267 +290,267 @@ typedef enum
* symbolic link during pathname resolution, results in a pathname
* string the size of which exceeds {PATH_MAX}.
*/
ENAMETOOLONG = 37,
#define ENAMETOOLONG 37
/**
/**
* Network is down. The local network interface used to reach the
* destination is down.
*/
ENETDOWN = 38,
#define ENETDOWN 38
/**
/**
* The connection was aborted by the network.
*/
ENETRESET = 39,
#define ENETRESET 39
/**
/**
* Network unreachable. No route to the network is present.
*/
ENETUNREACH = 40,
#define ENETUNREACH 40
/**
/**
* Too many files open in system. Too many files are currently open
* in the system. The system has reached its predefined limit for
* simultaneously open files and temporarily cannot accept requests
* to open another one.
*/
ENFILE = 41,
#define ENFILE 41
/**
/**
* No buffer space available. Insufficient buffer resources were
* available in the system to perform the socket operation.
*/
ENOBUFS = 42,
#define ENOBUFS 42
/**
/**
* No message available. No message is available on the STREAM head
* read queue.
*/
ENODATA = 43,
#define ENODATA 43
/**
/**
* No such device. An attempt was made to apply an inappropriate
* function to a device; for example, trying to read a write-only
* device such as a printer.
*/
ENODEV = 44,
#define ENODEV 44
/**
/**
* No such file or directory. A component of a specified pathname
* does not exist, or the pathname is an empty string.
*/
ENOENT = 45,
#define ENOENT 45
/**
/**
* Executable file format error. A request is made to execute a file
* that, although it has appropriate privileges, is not in the
* format required by the implementation for executable files.
*/
ENOEXEC = 46,
#define ENOEXEC 46
/**
/**
* No locks available. A system-imposed limit on the number of
* simultaneous file and record locks has been reached and no more
* are currently available.
*/
ENOLCK = 47,
#define ENOLCK 47
/**
/**
* Reserved.
*/
ENOLINK = 48,
#define ENOLINK 48
/**
/**
* Not enough space. The new process image requires more memory than
* is allowed by the hardware or system-imposed memory management
* constraints.
*/
ENOMEM = 49,
#define ENOMEM 49
/**
/**
* No message of the desired type. The message queue does not contain
* a message of the required type during XSI interprocess communication.
*/
ENOMSG = 50,
#define ENOMSG 50
/**
/**
* Protocol not available. The protocol option specified to
* setsockopt() is not supported by the implementation.
*/
ENOPROTOOPT = 51,
#define ENOPROTOOPT 51
/**
/**
* No space left on a device. During the write() function on a
* regular file or when extending a directory, there is no free
* space left on the device.
*/
ENOSPC = 52,
#define ENOSPC 52
/**
/**
* No STREAM resources. Insufficient STREAMS memory resources are
* available to perform a STREAMS-related function. This is a
* temporary condition; it may be recovered from if other
* processes release resources.
*/
ENOSR = 53,
#define ENOSR 53
/**
/**
* Not a STREAM. A STREAM function was attempted on a file descriptor
* that was not associated with a STREAMS device.
*/
ENOSTR = 54,
#define ENOSTR 54
/**
/**
* Functionality not supported. An attempt was made to use optional
* functionality that is not supported in this implementation.
*/
ENOSYS = 55,
#define ENOSYS 55
/**
/**
* Socket not connected. The socket is not connected.
*/
ENOTCONN = 56,
#define ENOTCONN 56
/**
/**
* Not a directory. A component of the specified pathname exists, but
* it is not a directory, when a directory was expected; or an
* attempt was made to create a non-directory file, and the specified
* pathname contains at least one non- \<slash\> character and ends
* with one or more trailing \<slash\> characters.
*/
ENOTDIR = 57,
#define ENOTDIR 57
/**
/**
* Directory not empty. A directory other than an empty directory
* was supplied when an empty directory was expected.
*/
ENOTEMPTY = 58,
#define ENOTEMPTY 58
/**
/**
* State not recoverable. The state protected by a robust mutex
* is not recoverable.
*/
ENOTRECOVERABLE = 59,
#define ENOTRECOVERABLE 59
/**
/**
* Not a socket. The file descriptor does not refer to a socket.
*/
ENOTSOCK = 60,
#define ENOTSOCK 60
/**
/**
* Not supported. The implementation does not support the requested
* feature or value.
*/
ENOTSUP = 61,
#define ENOTSUP 61
/**
/**
* Inappropriate I/O control operation. A control function has been
* attempted for a file or special file for which the operation
* is inappropriate.
*/
ENOTTY = 62,
#define ENOTTY 62
/**
/**
* No such device or address. Input or output on a special file
* refers to a device that does not exist, or makes a request
* beyond the capabilities of the device. It may also occur when,
* for example, a tape drive is not on-line.
*/
ENXIO = 63,
#define ENXIO 63
/**
/**
* Operation not supported on socket. The type of socket (address
* family or protocol) does not support the requested operation.
*/
EOPNOTSUPP = 64,
#define EOPNOTSUPP 64
/**
/**
* Value too large to be stored in data type. An operation was
* attempted which would generate a value that is outside the
* range of values that can be represented in the relevant data
* type or that are allowed for a given data item.
*/
EOVERFLOW = 65,
#define EOVERFLOW 65
/**
/**
* Previous owner died. The owner of a robust mutex terminated
* while holding the mutex lock.
*/
EOWNERDEAD = 66,
#define EOWNERDEAD 66
/**
/**
* Operation not permitted. An attempt was made to perform an
* operation limited to processes with appropriate privileges or
* to the owner of a file or other resource.
*/
EPERM = 67,
#define EPERM 67
/**
/**
* Broken pipe. A write was attempted on a socket, pipe, or FIFO
* for which there is no process to read the data.
*/
EPIPE = 68,
#define EPIPE 68
/**
/**
* Protocol error. Some protocol error occurred. This error is
* device-specific, but is generally not related to a
* hardware failure.
*/
EPROTO = 69,
#define EPROTO 69
/**
/**
* Protocol not supported. The protocol is not supported by the
* address family, or the protocol is not supported by
* the implementation.
*/
EPROTONOSUPPORT = 70,
#define EPROTONOSUPPORT 70
/**
/**
* Protocol wrong type for socket. The socket type is not
* supported by the protocol.
*/
EPROTOTYPE = 71,
#define EPROTOTYPE 71
/**
/**
* Result too large or too small. The result of the function
* is too large (overflow) or too small (underflow) to be
* represented in the available space.
*/
ERANGE = 72,
#define ERANGE 72
/**
/**
* Read-only file system. An attempt was made to modify a file
* or directory on a file system that is read-only.
*/
EROFS = 73,
#define EROFS 73
/**
/**
* Invalid seek. An attempt was made to access the file offset
* associated with a pipe or FIFO.
*/
ESPIPE = 74,
#define ESPIPE 74
/**
/**
* No such process. No process can be found corresponding to that
* specified by the given process ID.
*/
ESRCH = 75,
#define ESRCH 75
/**
/**
* Reserved.
*/
ESTALE = 76,
#define ESTALE 76
/**
/**
* STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call
* has expired. The cause of this error is device-specific and could
* indicate either a hardware or software failure, or a timeout
* value that is too short for the specific operation. The status
* of the ioctl() operation is unspecified.
*/
ETIME = 77,
#define ETIME 77
/**
/**
* Connection timed out. The connection to a remote machine has
* timed out.
* If the connection timed out during execution of the function that
@ -563,43 +562,30 @@ typedef enum
* Operation timed out. The time limit associated with the operation
* was exceeded before the operation completed.
*/
ETIMEDOUT = 78,
#define ETIMEDOUT 78
/**
/**
* Text file busy. An attempt was made to execute a pure-procedure
* program that is currently open for writing, or an attempt has
* been made to open for writing a pure-procedure program that
* is being executed.
*/
ETXTBSY = 79,
#define ETXTBSY 79
/**
/**
* Operation would block. An operation on a socket marked as
* non-blocking has encountered a situation such as no data available
* that otherwise would have caused the function to suspend execution.
*/
EWOULDBLOCK = 80,
#define EWOULDBLOCK 80
/**
/**
* Improper link. A link to a file on another file system was attempted.
*/
EXDEV = 81,
#define EXDEV 81
__ERRNO_MAX
} KernelErrors;
#ifdef __cplusplus
extern "C"
{
#ifdef __kernel__
#define __ERRNO_MAX 82
#endif
int *__errno_location(void) __attribute__((const));
char *strerror(int errnum);
#ifdef __cplusplus
}
#endif
#define errno (*__errno_location())
#endif // !__FENNIX_API_ERRNO_H__

109
Drivers/include/fcntl.h Normal file
View File

@ -0,0 +1,109 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_API_FCNTL_H__
#define __FENNIX_API_FCNTL_H__
#ifdef __kernel__
#include <types.h>
#endif
/* cmd */
#define F_DUPFD 0x1
#define F_DUPFD_CLOEXEC 0x101
#define F_DUPFD_CLOFORK 0x201
#define F_GETFD 0x2
#define F_SETFD 0x3
#define F_GETFL 0x4
#define F_SETFL 0x5
#define F_GETLK 0x6
#define F_SETLK 0x7
#define F_SETLKW 0x8
#define F_OFD_GETLK 0x9
#define F_OFD_SETLK 0xA
#define F_OFD_SETLKW 0xB
#define F_GETOWN 0xC
#define F_GETOWN_EX 0xD
#define F_SETOWN 0xE
#define F_SETOWN_EX 0xF
#define FD_CLOEXEC 0x1
#define FD_CLOFORK 0x2
/* l_type */
#define F_RDLCK 0x1
#define F_UNLCK 0x2
#define F_WRLCK 0x3
/* type */
#define F_OWNER_PID 0
#define F_OWNER_PGRP 1
/* oflag */
#define O_CLOEXEC 02000000
#define O_CLOFORK 04000000
#define O_CREAT 0x8
#define O_DIRECTORY 0200000
#define O_EXCL 0x20
#define O_NOCTTY 0x40
#define O_NOFOLLOW 0400000
#define O_TRUNC 0x400
#define O_TTY_INIT 0x800
#define O_APPEND 0x4
#define O_DSYNC 0x10
#define O_NONBLOCK 0x80
#define O_RSYNC 0x100
#define O_SYNC 0x200
#define O_ACCMODE 0x3
#define O_EXEC 0x4
#define O_RDONLY 0x1
#define O_RDWR 0x3
#define O_SEARCH 0x10
#define O_WRONLY 0x2
#define AT_FDCWD
#define AT_EACCESS
#define AT_SYMLINK_NOFOLLOW
#define AT_SYMLINK_FOLLOW
#define AT_REMOVEDIR
#define POSIX_FADV_DONTNEED
#define POSIX_FADV_NOREUSE
#define POSIX_FADV_NORMAL
#define POSIX_FADV_RANDOM
#define POSIX_FADV_SEQUENTIAL
#define POSIX_FADV_WILLNEED
typedef struct f_owner_ex
{
int type; /* Discriminator for pid. */
pid_t pid; /* Process ID or process group ID. */
} f_owner_ex;
typedef struct flock
{
short l_type; /* Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. */
short l_whence; /* Flag for starting offset. */
off_t l_start; /* Relative offset in bytes. */
off_t l_len; /* Size; if 0 then until EOF. */
pid_t l_pid; /* For a process-owned file lock, ignored on input or the process ID of the owning process on output; for an OFD-owned file lock, zero on input or (pid_t)-1 on output. */
} flock;
#endif // !__FENNIX_API_FCNTL_H__

View File

@ -95,16 +95,6 @@
/** Other: X */
#define S_IXOTH 0001
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 0100
#define O_EXCL 0200
#define O_TRUNC 01000
#define O_APPEND 02000
#define O_NOFOLLOW 0400000
#define O_CLOEXEC 02000000
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
@ -332,11 +322,29 @@ struct InodeOperations
int (*Stat)(struct Inode *Node, struct kstat *Stat);
} __attribute__((packed));
#define I_FLAG_ROOT 0x1
#define I_FLAG_MOUNTPOINT 0x2
#define I_FLAG_CACHE_KEEP 0x4
struct FileSystemInfo;
struct FileSystemDevice
{
struct
{
/**
* @brief Inode
*
* If the device is a block device, this will be NULL.
*/
struct Inode *node;
struct InodeOperations *ops;
} inode;
/**
* @brief Block Device
*
* If the device is a block device, this will be non-NULL.
*/
struct BlockDevice *Block;
};
struct SuperBlockOperations
{
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
@ -347,8 +355,8 @@ struct SuperBlockOperations
*
* Write all pending changes to the disk.
*
* @param Info Inode to synchronize. If NULL, synchronize all inodes.
* @param Node Inode to synchronize.
* @param Info Inode to synchronize.
* @param Node Inode to synchronize. If NULL, synchronize all inodes.
*
* @return Zero on success, otherwise an error code.
*/
@ -364,13 +372,50 @@ struct SuperBlockOperations
* @return Zero on success, otherwise an error code.
*/
int (*Destroy)(struct FileSystemInfo *Info);
/**
* Probe the filesystem.
*
* Check if the filesystem is supported by the driver.
*
* @param Device Device to probe.
*
* @return Zero on success, otherwise an error code.
*/
int (*Probe)(struct FileSystemDevice *Device);
/**
* Mount the filesystem.
*
* Mount the filesystem on the given device.
*
* @param FS Filesystem to mount.
* @param Root Pointer to the root inode.
* @param Device Device to mount. This pointer will be undefined after the function returns!
*
* @return Zero on success, otherwise an error code.
*/
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, struct FileSystemDevice *Device);
/**
* Unmount the filesystem.
*
* Unmount the filesystem from the given device.
*
* @param FS Filesystem to unmount.
*
* @return Zero on success, otherwise an error code.
*/
int (*Unmount)(struct FileSystemInfo *FS);
} __attribute__((packed));
struct FileSystemInfo
{
const char *Name;
const char *RootName;
int Flags;
int Capabilities;
struct SuperBlockOperations SuperOps;
struct InodeOperations Ops;
@ -378,6 +423,9 @@ struct FileSystemInfo
} __attribute__((packed));
#ifndef __kernel__
dev_t RegisterMountPoint(FileSystemInfo *fsi, Inode *Root);
int UnregisterMountPoint(dev_t Device);
dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
int UnregisterFileSystem(dev_t Device);
#endif // !__kernel__

View File

@ -15,8 +15,18 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_API_SYSCALLS_LIST_H__
#define __FENNIX_API_SYSCALLS_LIST_H__
#ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__
#define __FENNIX_API_SYSTEM_CALLS_LIST_H__
#if __has_include(<interface/fcntl.h>)
#include <interface/fcntl.h>
#else
#include <fcntl.h>
#endif
#ifndef __fennix__
#error "__fennix__ not defined"
#endif
#pragma region Syscall Wrappers
@ -393,18 +403,18 @@ typedef enum
typedef enum
{
__SYS_O_RDONLY = 0x1,
__SYS_O_WRONLY = 0x2,
__SYS_O_RDWR = 0x3,
__SYS_O_APPEND = 0x4,
__SYS_O_CREAT = 0x8,
__SYS_O_DSYNC = 0x10,
__SYS_O_EXCL = 0x20,
__SYS_O_NOCTTY = 0x40,
__SYS_O_NONBLOCK = 0x80,
__SYS_O_RSYNC = 0x100,
__SYS_O_SYNC = 0x200,
__SYS_O_TRUNC = 0x400
__SYS_O_RDONLY = O_RDONLY,
__SYS_O_WRONLY = O_WRONLY,
__SYS_O_RDWR = O_RDWR,
__SYS_O_APPEND = O_APPEND,
__SYS_O_CREAT = O_CREAT,
__SYS_O_DSYNC = O_DSYNC,
__SYS_O_EXCL = O_EXCL,
__SYS_O_NOCTTY = O_NOCTTY,
__SYS_O_NONBLOCK = O_NONBLOCK,
__SYS_O_RSYNC = O_RSYNC,
__SYS_O_SYNC = O_SYNC,
__SYS_O_TRUNC = O_TRUNC
} syscall_open_flags_t;
typedef enum
@ -624,6 +634,14 @@ typedef struct FramebufferScreenInfo
*/
#define FBIOGET_SCREEN_INFO 0xf0
struct kutsname
{
char sysname[65];
char release[65];
char version[65];
char machine[65];
};
/**
* @brief List of syscalls
*
@ -656,6 +674,8 @@ typedef enum
*/
SYS_API_VERSION = 0,
SYS_DEBUG_REPORT = 1,
/* I/O */
/**
@ -812,6 +832,25 @@ typedef enum
* - #EINVAL if the request is invalid
*/
SYS_IOCTL,
/**
* @brief Function control
*
* @code
* int fcntl(int fd, int cmd, void *arg);
* @endcode
*
* @details Manipulates the underlying parameters of a device.
*
* @param fd File descriptor referring to the device
* @param cmd Device-specific request code
* @param arg Argument for the request
*
* @return
* - #EOK on success
* - #EBADF if `fd` is not valid
* - #EINVAL if the request is invalid
*/
SYS_FCNTL,
/* File Status */
@ -1601,6 +1640,22 @@ typedef enum
* - #EACCES if permission is denied
*/
SYS_RENAME,
/**
* @brief Get unix name information
*
* @code
* int uname(struct kutsname *buf);
* @endcode
*
* @details Retrieves information about the operating system.
*
* @param buf Pointer to `kutsname` structure to store information
*
* @return
* - #EOK on success
* - #EFAULT if `buf` is outside accessible address space
*/
SYS_UNAME,
/**
* @brief Max number of syscalls
@ -1644,6 +1699,9 @@ typedef enum
/** @copydoc SYS_IOCTL */
#define call_ioctl(fd, request, argp) syscall3(SYS_IOCTL, (scarg)fd, (scarg)request, (scarg)argp)
/** @copydoc SYS_FCNTL */
#define call_fcntl(fd, cmd, arg) syscall3(SYS_FCNTL, (scarg)fd, (scarg)cmd, (scarg)arg)
/* File Status */
/** @copydoc SYS_STAT */
@ -1751,7 +1809,7 @@ typedef enum
/* Time */
/** @copydoc SYS_TIME */
#define call_time(t) syscall1(SYS_TIME, t)
#define call_time(t) syscall1(SYS_TIME, (scarg)t)
/** @copydoc SYS_CLOCK_GETTIME */
#define call_clock_gettime(clockid, tp) syscall2(SYS_CLOCK_GETTIME, (scarg)clockid, (scarg)tp)
@ -1782,4 +1840,7 @@ typedef enum
/** @copydoc SYS_RENAME */
#define call_rename(oldpath, newpath) syscall2(SYS_RENAME, (scarg)oldpath, (scarg)newpath)
#endif // !__FENNIX_API_SYSCALLS_LIST_H__
/** @copydoc SYS_UNAME */
#define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf)
#endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__

View File

@ -7,9 +7,8 @@
"settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false
"C_Cpp.autoAddFileAssociations": false,
}
}

View File

@ -7,9 +7,8 @@
"settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false
"C_Cpp.autoAddFileAssociations": false,
}
}

View File

@ -7,23 +7,6 @@
"settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true,
"editor.tabCompletion": "on",
"diffEditor.codeLens": true,
"editor.quickSuggestionsDelay": 100,
"zenMode.hideLineNumbers": false,
"zenMode.hideActivityBar": false,
"zenMode.hideStatusBar": true,
"zenMode.centerLayout": true,
"zenMode.fullScreen": true,
"zenMode.restore": true,
"zenMode.silentNotifications": true,
"window.commandCenter": false,
"window.density.editorTabHeight": "default",
"editor.cursorBlinking": "blink",
"editor.cursorSmoothCaretAnimation": "on",
"editor.cursorStyle": "line",
"editor.cursorWidth": 2,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false,
@ -34,7 +17,15 @@
"kernel",
"kernel/pci",
"kernel/driver",
"kernel/drivers"
"kernel/drivers",
"kernel/elf",
"kernel/scheduler",
"kernel/tty",
"kernel/std",
"kernel/vfs",
"kernel/memory",
"kernel/efi",
"kernel/bootstrap"
]
}
}

View File

@ -7,18 +7,20 @@
"settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false,
"conventionalCommits.scopes": [
"userspace",
"userspace/libc",
"vscode",
"userspace/apps/sys/init",
"userspace/libs/libm",
"devcontainer",
"userspace/coreutils",
"userspace/apps",
"userspace/libs",
"userspace/apps/test"
"userspace/apps/sys",
"userspace/apps/test",
"userspace/apps/usr",
"devcontainer",
"vscode"
]
}
}

View File

@ -6,7 +6,6 @@
],
"settings": {
"debug.allowBreakpointsEverywhere": true,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false

View File

@ -6,14 +6,14 @@
],
"settings": {
"debug.allowBreakpointsEverywhere": true,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false,
"conventionalCommits.scopes": [
"initrd",
"rootfs",
"tools",
"devcontainer"
"devcontainer",
"workspace"
]
}
}

72
INSTALL.md Normal file
View File

@ -0,0 +1,72 @@
# 🚀 Installation Guide
This guide will help you install Fennix on your system.
## 🛠️ Preparing the Environment
There are two ways to build the project:
1. **🐳 Use Dev Container (Recommended)**
* This is the easiest way to prepare the environment for building the project. But firstly, you need to install [Docker](https://docs.docker.com/get-docker/) and [Visual Studio Code](https://code.visualstudio.com/).
* After installing Docker and Visual Studio Code, you can open the project in Visual Studio Code and click on the "Reopen in Container" button.
* This will open the project in a Dev Container with all the required tools installed.
* If you encounter errors while the Dev Container is building, ensure the following are correctly configured:
* `/tmp/.X11-unix`
* Environment variable `XAUTHORITY`
* `/run/user/1000/pulse/native`
* **Note:** These configurations are only necessary if you plan to use QEMU inside the container.
2. **💻 Build the Project Locally**
* The instructions below will guide you through the process of building the project locally.
**NOTE:** You MUST have `autoconf 2.69` and `automake 1.15.1` versions installed on your system. A complete list of dependencies can be found in the [.devcontainer/Dockerfile](.devcontainer/Dockerfile) file.
Before building the project, you need to build the cross-compiler toolchain and QEMU.
You can do this by running the following command:
```sh
make setup
```
This will clone, patch, and build the required tools for you.
Alternatively, if you wish to skip building QEMU, you can run `make setup-no-qemu`.
However, in this case, you will need to manually specify the path to the QEMU binary in the `config.mk` file.
## 🏗️ Building the Project
To build the project, run:
```sh
make build
```
This will build the kernel, userspace, and drivers. The resulting ISO image will be `Fennix.iso`.
## 🚀 Running the OS
To run the OS, execute:
```sh
make run
```
The `run` target will automatically build the project if it hasn't been built yet.
## ⚙️ Additional Configuration
You can customize the project by editing the `config.mk` file.
## 🧪 Debugging
If you use Visual Studio Code, you can press `F5` to start debugging the OS.
The configuration is already set up for you.
Alternatively, you can run the following command to start debugging:
```sh
make debug
```
This will start QEMU in debug mode, allowing you to connect to it using GDB.
The GDB FIFO file is located at `/tmp/gdb-fennix`.

View File

@ -9,5 +9,9 @@ insert_final_newline = true
indent_style = tab
indent_size = 4
[*.py]
indent_size = 4
indent_style = space
[Makefile]
indent_style = tab

View File

@ -1,91 +0,0 @@
# Usage: add-symbol-file-all <filename> [<offset>]
# remove-symbol-file-all <filename> [<offset>]
#
# Credit: https://stackoverflow.com/a/33087762/9352057
# CC BY-SA 4.0
python
import subprocess
import re
def relocatesections(filename, addr):
p = subprocess.Popen(["readelf", "-S", filename], stdout = subprocess.PIPE)
sections = []
textaddr = '0'
for line in p.stdout.readlines():
line = line.decode("utf-8").strip()
if not line.startswith('[') or line.startswith('[Nr]'):
continue
line = re.sub(r' +', ' ', line)
line = re.sub(r'\[ *(\d+)\]', '\g<1>', line)
fieldsvalue = line.split(' ')
fieldsname = ['number', 'name', 'type', 'addr', 'offset', 'size', 'entsize', 'flags', 'link', 'info', 'addralign']
sec = dict(zip(fieldsname, fieldsvalue))
if sec['number'] == '0':
continue
sections.append(sec)
if sec['name'] == '.text':
textaddr = sec['addr']
return (textaddr, sections)
class AddSymbolFileAll(gdb.Command):
"""The right version for add-symbol-file"""
def __init__(self):
super(AddSymbolFileAll, self).__init__("add-symbol-file-all", gdb.COMMAND_USER)
self.dont_repeat()
def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
filename = argv[0]
if len(argv) > 1:
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
else:
offset = 0
(textaddr, sections) = relocatesections(filename, offset)
cmd = "add-symbol-file %s 0x%08x" % (filename, int(textaddr, 16) + offset)
for s in sections:
addr = int(s['addr'], 16)
if s['name'] == '.text' or addr == 0:
continue
cmd += " -s %s 0x%08x" % (s['name'], addr + offset)
gdb.execute(cmd)
class RemoveSymbolFileAll(gdb.Command):
"""The right version for remove-symbol-file"""
def __init__(self):
super(RemoveSymbolFileAll, self).__init__("remove-symbol-file-all", gdb.COMMAND_USER)
self.dont_repeat()
def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
filename = argv[0]
if len(argv) > 1:
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
else:
offset = 0
(textaddr, _) = relocatesections(filename, offset)
cmd = "remove-symbol-file -a 0x%08x" % (int(textaddr, 16) + offset)
gdb.execute(cmd)
AddSymbolFileAll()
RemoveSymbolFileAll()
end

View File

@ -9,6 +9,6 @@
#define __kernel__ 1
#define KERNEL_NAME "Fennix"
#define KERNEL_ARCH "amd64"
#define KERNEL_VERSION "1.0"
#define KERNEL_VERSION "1.0.0"
#define GIT_COMMIT "0000000000000000000000000000000000000000"
#define GIT_COMMIT_SHORT "0000000"

View File

@ -10,14 +10,14 @@ define find-sources
$(shell find ./ -type f -name '$1' $(shell echo $(foreach arch,$(filter-out $(OSARCH),$(AVAILABLE_ARCHS)), -not -path \"./arch/$(arch)/*\")) -print0 | xargs -0)
endef
BMP_SOURCES := $(call find-sources,*.bmp)
PNG_SOURCES := $(call find-sources,*.png)
PSF_SOURCES := $(call find-sources,*.psf)
S_SOURCES := $(call find-sources,*.S)
s_SOURCES := $(call find-sources,*.s)
C_SOURCES := $(call find-sources,*.c)
CXX_SOURCES := $(call find-sources,*.cpp)
OBJ = $(BMP_SOURCES:.bmp=.o) $(PSF_SOURCES:.psf=.o) $(s_SOURCES:.s=.o) $(S_SOURCES:.S=.o) $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
OBJ = $(PNG_SOURCES:.png=.o) $(PSF_SOURCES:.psf=.o) $(s_SOURCES:.s=.o) $(S_SOURCES:.S=.o) $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CXX_SOURCES:.cpp=.gcno)
@ -68,6 +68,7 @@ ifeq ($(DEBUG), 1)
# CFLAGS += -pg
# CFLAGS += -finstrument-functions
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage -fsanitize=undefined
CXXFLAGS += -fdiagnostics-all-candidates
ifeq ($(OSARCH), amd64)
CFLAGS += -fverbose-asm
endif # amd64
@ -111,7 +112,7 @@ $(KERNEL_FILENAME): $(OBJ)
# https://gcc.gnu.org/projects/cxx-status.html
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(__CONF_CXX) $(CFLAGS) -fcoroutines $(CFLAG_STACK_PROTECTOR) $(WARNCFLAG) -std=c++20 -c $< -o $@ -fno-rtti
$(__CONF_CXX) $(CFLAGS) $(CXXFLAGS) -fcoroutines $(CFLAG_STACK_PROTECTOR) $(WARNCFLAG) -std=c++20 -c $< -o $@ -fno-rtti
%.o: %.S
$(info Compiling $<)
@ -133,7 +134,7 @@ else ifeq ($(OSARCH), aarch64)
endif
$(__CONF_NM) $@
%.o: %.bmp
%.o: %.png
ifeq ($(OSARCH), amd64)
$(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@
else ifeq ($(OSARCH), i386)

View File

@ -9,7 +9,7 @@
- [ ] ~~Do not map the entire memory. Map only the needed memory address at allocation time.~~ (we just copy the pages for userland, see `Fork()` inside [core/memory/page_table.cpp](core/memory/page_table.cpp))
- [ ] Implementation of logging (beside serial) with log rotation.
- [x] Implement a better task manager. (replace struct P/TCB with classes)
- [ ] Rewrite virtual file system.
- [x] Rewrite virtual file system.
- [ ] Colors in crash screen are not following the kernel color scheme.
- [x] ~~Find a way to add intrinsics.~~ (not feasible, use inline assembly)
- [ ] Rework PSF1 font loader.

View File

@ -25,33 +25,41 @@
void InitLimine();
static volatile struct limine_entry_point_request EntryPointRequest = {
#define LIMREQ __attribute__((used, section(".limine_requests"))) static volatile
#define LIMREQ_S __attribute__((used, section(".limine_requests_start"))) static volatile
#define LIMREQ_E __attribute__((used, section(".limine_requests_end"))) static volatile
LIMREQ LIMINE_BASE_REVISION(3);
LIMREQ_S LIMINE_REQUESTS_START_MARKER;
LIMREQ_E LIMINE_REQUESTS_END_MARKER;
LIMREQ struct limine_entry_point_request EntryPointRequest = {
.id = LIMINE_ENTRY_POINT_REQUEST,
.revision = 0,
.response = NULL,
.entry = InitLimine};
static volatile struct limine_bootloader_info_request BootloaderInfoRequest = {
LIMREQ struct limine_bootloader_info_request BootloaderInfoRequest = {
.id = LIMINE_BOOTLOADER_INFO_REQUEST,
.revision = 0};
static volatile struct limine_framebuffer_request FramebufferRequest = {
LIMREQ struct limine_framebuffer_request FramebufferRequest = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0};
static volatile struct limine_memmap_request MemmapRequest = {
LIMREQ struct limine_memmap_request MemmapRequest = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0};
static volatile struct limine_kernel_address_request KernelAddressRequest = {
LIMREQ struct limine_kernel_address_request KernelAddressRequest = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
.revision = 0};
static volatile struct limine_rsdp_request RsdpRequest = {
LIMREQ struct limine_rsdp_request RsdpRequest = {
.id = LIMINE_RSDP_REQUEST,
.revision = 0};
static volatile struct limine_kernel_file_request KernelFileRequest = {
LIMREQ struct limine_kernel_file_request KernelFileRequest = {
.id = LIMINE_KERNEL_FILE_REQUEST,
.revision = 0};
static volatile struct limine_module_request ModuleRequest = {
LIMREQ struct limine_module_request ModuleRequest = {
.id = LIMINE_MODULE_REQUEST,
.revision = 0};
static volatile struct limine_smbios_request SmbiosRequest = {
LIMREQ struct limine_smbios_request SmbiosRequest = {
.id = LIMINE_SMBIOS_REQUEST,
.revision = 0};
@ -84,7 +92,7 @@ __naked __used __no_stack_protector void InitLimine()
asmv("jmp InitLimineAfterStack");
}
nsa NIF void InitLimineAfterStack()
nsa nif void InitLimineAfterStack()
{
struct BootInfo binfo = {};
struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response;

View File

@ -38,14 +38,14 @@ union __attribute__((packed)) PageTableEntry
};
uint64_t raw;
__always_inline inline nsa NIF void SetAddress(uintptr_t _Address)
__always_inline inline nsa nif void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline nsa NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline nsa nif uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageTableEntryPtr
@ -72,14 +72,14 @@ union __attribute__((packed)) PageDirectoryEntry
};
uint64_t raw;
__always_inline inline nsa NIF void SetAddress(uintptr_t _Address)
__always_inline inline nsa nif void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline nsa NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline nsa nif uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageDirectoryEntryPtr
@ -106,14 +106,14 @@ union __attribute__((packed)) PageDirectoryPointerTableEntry
};
uint64_t raw;
__always_inline inline nsa NIF void SetAddress(uintptr_t _Address)
__always_inline inline nsa nif void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline nsa NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline nsa nif uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr
@ -140,14 +140,14 @@ union __attribute__((packed)) PageMapLevel4
};
uint64_t raw;
__always_inline inline nsa NIF void SetAddress(uintptr_t _Address)
__always_inline inline nsa nif void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline nsa NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline nsa nif uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct PageTable4
@ -161,7 +161,7 @@ extern uintptr_t _kernel_start, _kernel_end;
__attribute__((section(".bootstrap.data"))) static PageTable4 *BPTable = (PageTable4 *)BootPageTable;
__attribute__((section(".bootstrap.data"))) static size_t BPT_Allocated = 0x4000;
__always_inline inline nsa NIF void *RequestPage()
__always_inline inline nsa nif void *RequestPage()
{
void *Page = (void *)(BootPageTable + BPT_Allocated);
BPT_Allocated += 0x1000;
@ -180,7 +180,7 @@ public:
uintptr_t PDPTEIndex = 0;
uintptr_t PDEIndex = 0;
uintptr_t PTEIndex = 0;
__always_inline inline nsa NIF PageMapIndexer(uintptr_t VirtualAddress)
__always_inline inline nsa nif PageMapIndexer(uintptr_t VirtualAddress)
{
uintptr_t Address = VirtualAddress;
Address >>= 12;
@ -194,7 +194,7 @@ public:
}
};
__attribute__((section(".bootstrap.text"))) nsa NIF void MB2_64_Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
__attribute__((section(".bootstrap.text"))) nsa nif void MB2_64_Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
{
PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress);
// Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only
@ -280,7 +280,7 @@ __attribute__((section(".bootstrap.text"))) nsa NIF void MB2_64_Map(void *Virtua
: "memory");
}
EXTERNC __attribute__((section(".bootstrap.text"))) nsa NIF __attribute__((section(".bootstrap.text"))) void UpdatePageTable64()
EXTERNC __attribute__((section(".bootstrap.text"))) nsa nif __attribute__((section(".bootstrap.text"))) void UpdatePageTable64()
{
BPTable = (PageTable4 *)BootPageTable;

View File

@ -24,10 +24,8 @@
void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
{
auto InfoAddress = Info;
for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8);
;
Tag = (struct multiboot_tag *)((multiboot_uint8_t *)Tag + ((Tag->size + 7) & ~7)))
auto infoAddr = Info;
for (auto Tag = (struct multiboot_tag *)((uint8_t *)infoAddr + 8);; Tag = (struct multiboot_tag *)((multiboot_uint8_t *)Tag + ((Tag->size + 7) & ~7)))
{
if (Tag->type == MULTIBOOT_TAG_TYPE_END)
{
@ -39,17 +37,17 @@ void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
{
case MULTIBOOT_TAG_TYPE_CMDLINE:
{
strncpy(mb2binfo.Kernel.CommandLine,
((multiboot_tag_string *)Tag)->string,
strlen(((multiboot_tag_string *)Tag)->string));
multiboot_tag_string *cmdline = (multiboot_tag_string *)Tag;
strncpy(mb2binfo.Kernel.CommandLine, cmdline->string, strlen(cmdline->string));
debug("Kernel command line: %s", mb2binfo.Kernel.CommandLine);
break;
}
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
{
strncpy(mb2binfo.Bootloader.Name,
((multiboot_tag_string *)Tag)->string,
strlen(((multiboot_tag_string *)Tag)->string));
multiboot_tag_string *blName = (multiboot_tag_string *)Tag;
strncpy(mb2binfo.Bootloader.Name, blName->string, strlen(blName->string));
debug("Bootloader name: %s", mb2binfo.Bootloader.Name);
break;
}
@ -60,24 +58,29 @@ void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
mb2binfo.Modules[module_count].Address = (void *)(uint64_t)module->mod_start;
mb2binfo.Modules[module_count].Size = module->mod_end - module->mod_start;
strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6);
strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline,
strlen(module->cmdline));
debug("Module: %s", mb2binfo.Modules[module_count].Path);
strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline, strlen(module->cmdline));
debug("Module: %s", mb2binfo.Modules[module_count].CommandLine);
module_count++;
break;
}
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
{
multiboot_tag_basic_meminfo *meminfo = (multiboot_tag_basic_meminfo *)Tag;
fixme("basic_meminfo->[mem_lower: %#x, mem_upper: %#x]",
meminfo->mem_lower, meminfo->mem_upper);
meminfo->mem_lower,
meminfo->mem_upper);
break;
}
case MULTIBOOT_TAG_TYPE_BOOTDEV:
{
multiboot_tag_bootdev *bootdev = (multiboot_tag_bootdev *)Tag;
fixme("bootdev->[biosdev: %#x, slice: %#x, part: %#x]",
bootdev->biosdev, bootdev->slice, bootdev->part);
bootdev->biosdev,
bootdev->slice,
bootdev->part);
break;
}
case MULTIBOOT_TAG_TYPE_MMAP:
@ -92,6 +95,7 @@ void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
warn("Too many memory entries, skipping the rest...");
break;
}
multiboot_mmap_entry entry = mmap->entries[i];
mb2binfo.Memory.Size += entry.len;
switch (entry.type)
@ -127,6 +131,7 @@ void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
mb2binfo.Memory.Entry[i].Type = Unknown;
break;
}
debug("Memory entry: [BaseAddress: %#x, Length: %#x, Type: %d]",
mb2binfo.Memory.Entry[i].BaseAddress,
mb2binfo.Memory.Entry[i].Length,
@ -137,54 +142,52 @@ void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
case MULTIBOOT_TAG_TYPE_VBE:
{
multiboot_tag_vbe *vbe = (multiboot_tag_vbe *)Tag;
fixme("vbe->[vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x]",
vbe->vbe_mode, vbe->vbe_interface_seg, vbe->vbe_interface_off, vbe->vbe_interface_len);
vbe->vbe_mode,
vbe->vbe_interface_seg,
vbe->vbe_interface_off,
vbe->vbe_interface_len);
break;
}
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
{
multiboot_tag_framebuffer *fb = (multiboot_tag_framebuffer *)Tag;
static int fb_count = 0;
mb2binfo.Framebuffer[fb_count].BaseAddress = (void *)fb->common.framebuffer_addr;
mb2binfo.Framebuffer[fb_count].Width = fb->common.framebuffer_width;
mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height;
mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch;
mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp;
static int fbCount = 0;
mb2binfo.Framebuffer[fbCount].BaseAddress = (void *)fb->common.framebuffer_addr;
mb2binfo.Framebuffer[fbCount].Width = fb->common.framebuffer_width;
mb2binfo.Framebuffer[fbCount].Height = fb->common.framebuffer_height;
mb2binfo.Framebuffer[fbCount].Pitch = fb->common.framebuffer_pitch;
mb2binfo.Framebuffer[fbCount].BitsPerPixel = fb->common.framebuffer_bpp;
switch (fb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
{
mb2binfo.Framebuffer[fb_count].Type = Indexed;
mb2binfo.Framebuffer[fbCount].Type = Indexed;
break;
}
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
{
mb2binfo.Framebuffer[fb_count].Type = RGB;
mb2binfo.Framebuffer[fb_count].RedMaskSize = fb->framebuffer_red_mask_size;
mb2binfo.Framebuffer[fb_count].RedMaskShift = fb->framebuffer_red_field_position;
mb2binfo.Framebuffer[fb_count].GreenMaskSize = fb->framebuffer_green_mask_size;
mb2binfo.Framebuffer[fb_count].GreenMaskShift = fb->framebuffer_green_field_position;
mb2binfo.Framebuffer[fb_count].BlueMaskSize = fb->framebuffer_blue_mask_size;
mb2binfo.Framebuffer[fb_count].BlueMaskShift = fb->framebuffer_blue_field_position;
mb2binfo.Framebuffer[fbCount].Type = RGB;
mb2binfo.Framebuffer[fbCount].RedMaskSize = fb->framebuffer_red_mask_size;
mb2binfo.Framebuffer[fbCount].RedMaskShift = fb->framebuffer_red_field_position;
mb2binfo.Framebuffer[fbCount].GreenMaskSize = fb->framebuffer_green_mask_size;
mb2binfo.Framebuffer[fbCount].GreenMaskShift = fb->framebuffer_green_field_position;
mb2binfo.Framebuffer[fbCount].BlueMaskSize = fb->framebuffer_blue_mask_size;
mb2binfo.Framebuffer[fbCount].BlueMaskShift = fb->framebuffer_blue_field_position;
break;
}
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
{
mb2binfo.Framebuffer[fb_count].Type = EGA;
mb2binfo.Framebuffer[fbCount].Type = EGA;
break;
}
default:
{
mb2binfo.Framebuffer[fb_count].Type = Unknown_Framebuffer_Type;
mb2binfo.Framebuffer[fbCount].Type = Unknown_Framebuffer_Type;
break;
}
}
debug("Framebuffer %d: %dx%d %d bpp", fb_count, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp);
debug("More info:\nAddress: %p\nPitch: %d\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d",
debug("fb %d: %dx%d %d bpp", fbCount, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp);
debug("More info: addr:%#lx pitch:%d mm:%d RMSize:%d RMShift:%d GMSize:%d GMShift:%d BMSize:%d BMShift:%d",
fb->common.framebuffer_addr, fb->common.framebuffer_pitch, fb->common.framebuffer_type,
fb->framebuffer_red_mask_size, fb->framebuffer_red_field_position, fb->framebuffer_green_mask_size,
fb->framebuffer_green_field_position, fb->framebuffer_blue_mask_size, fb->framebuffer_blue_field_position);
fb_count++;
fb->framebuffer_red_mask_size, fb->framebuffer_red_field_position,
fb->framebuffer_green_mask_size, fb->framebuffer_green_field_position,
fb->framebuffer_blue_mask_size, fb->framebuffer_blue_field_position);
fbCount++;
break;
}
case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
@ -194,73 +197,115 @@ void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
mb2binfo.Kernel.Symbols.EntSize = elf->entsize;
mb2binfo.Kernel.Symbols.Shndx = elf->shndx;
mb2binfo.Kernel.Symbols.Sections = r_cst(uintptr_t, elf->sections);
debug("elf_sections->[num: %d, entsize: %d, shndx: %d, sections: %#lx]",
elf->num, elf->entsize, elf->shndx, elf->sections);
break;
}
case MULTIBOOT_TAG_TYPE_APM:
{
multiboot_tag_apm *apm = (multiboot_tag_apm *)Tag;
fixme("apm->[version: %d, cseg: %d, offset: %d, cseg_16: %d, dseg: %d, flags: %d, cseg_len: %d, cseg_16_len: %d, dseg_len: %d]",
apm->version, apm->cseg, apm->offset, apm->cseg_16, apm->dseg, apm->flags, apm->cseg_len, apm->cseg_16_len, apm->dseg_len);
fixme("apm->[version:%d, cseg:%d, offset:%d, cseg_16:%d, dseg:%d, flags:%d, cseg_len:%d, cseg_16_len:%d, dseg_len:%d]",
apm->version, apm->cseg, apm->offset, apm->cseg_16, apm->dseg,
apm->flags, apm->cseg_len, apm->cseg_16_len, apm->dseg_len);
break;
}
case MULTIBOOT_TAG_TYPE_EFI32:
{
mb2binfo.EFI.Info.Enabled = 1;
mb2binfo.EFI.Info.ST = 1;
multiboot_tag_efi32 *efi32 = (multiboot_tag_efi32 *)Tag;
fixme("efi32->[pointer: %p, size: %d]", efi32->pointer, efi32->size);
mb2binfo.EFI.SystemTable = (void *)(uintptr_t)efi32->pointer;
debug("efi32->[pointer: %#lx, size: %d]", efi32->pointer, efi32->size);
break;
}
case MULTIBOOT_TAG_TYPE_EFI64:
{
mb2binfo.EFI.Info.Enabled = 1;
mb2binfo.EFI.Info.ST = 1;
multiboot_tag_efi64 *efi64 = (multiboot_tag_efi64 *)Tag;
fixme("efi64->[pointer: %p, size: %d]", efi64->pointer, efi64->size);
mb2binfo.EFI.SystemTable = (void *)(uintptr_t)efi64->pointer;
debug("efi64->[pointer: %#lx, size: %d]", efi64->pointer, efi64->size);
break;
}
case MULTIBOOT_TAG_TYPE_SMBIOS:
{
multiboot_tag_smbios *smbios = (multiboot_tag_smbios *)Tag;
fixme("smbios->[major: %d, minor: %d]", smbios->major, smbios->minor);
mb2binfo.SMBIOSPtr = (void *)smbios->tables;
debug("smbios->[major: %d, minor: %d]", smbios->major, smbios->minor);
break;
}
case MULTIBOOT_TAG_TYPE_ACPI_OLD:
{
mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp;
debug("OLD ACPI RSDP: %p", mb2binfo.RSDP);
debug("OLD ACPI RSDP: %#lx", mb2binfo.RSDP);
break;
}
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
{
mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp;
debug("NEW ACPI RSDP: %p", mb2binfo.RSDP);
debug("NEW ACPI RSDP: %#lx", mb2binfo.RSDP);
break;
}
case MULTIBOOT_TAG_TYPE_NETWORK:
{
multiboot_tag_network *net = (multiboot_tag_network *)Tag;
fixme("network->[dhcpack: %p]", net->dhcpack);
fixme("network->[dhcpack: %#lx]", net->dhcpack);
break;
}
case MULTIBOOT_TAG_TYPE_EFI_MMAP:
{
mb2binfo.EFI.Info.Enabled = 1;
mb2binfo.EFI.Info.MemoryMap = 1;
multiboot_tag_efi_mmap *efi_mmap = (multiboot_tag_efi_mmap *)Tag;
fixme("efi_mmap->[descr_size: %d, descr_vers: %d, efi_mmap: %p]",
mb2binfo.EFI.MemoryMap.BaseAddress = (void *)efi_mmap->efi_mmap;
mb2binfo.EFI.MemoryMap.DescriptorSize = efi_mmap->descr_size;
mb2binfo.EFI.MemoryMap.DescriptorVersion = efi_mmap->descr_vers;
mb2binfo.EFI.MemoryMap.NumberOfEntries = (efi_mmap->size - sizeof(multiboot_tag_efi_mmap)) / efi_mmap->descr_size;
// mb2binfo.EFI.MemoryMap.NumberOfEntries = efi_mmap->size / efi_mmap->descr_size;
debug("efi_mmap->[descr_size: %d, descr_vers: %d, efi_mmap: %#lx]",
efi_mmap->descr_size, efi_mmap->descr_vers, efi_mmap->efi_mmap);
break;
}
case MULTIBOOT_TAG_TYPE_EFI_BS:
{
fixme("efi_bs->[%p] (unknown structure)", Tag);
mb2binfo.EFI.Info.Enabled = 1;
mb2binfo.EFI.Info.BS = 1;
debug("efi_bs");
break;
}
case MULTIBOOT_TAG_TYPE_EFI32_IH:
{
mb2binfo.EFI.Info.Enabled = 1;
mb2binfo.EFI.Info.IH = 1;
multiboot_tag_efi32_ih *efi32_ih = (multiboot_tag_efi32_ih *)Tag;
fixme("efi32_ih->[pointer: %p]", efi32_ih->pointer);
mb2binfo.EFI.ImageHandle = (void *)(uintptr_t)efi32_ih->pointer;
debug("efi32_ih->[pointer: %#lx]", efi32_ih->pointer);
break;
}
case MULTIBOOT_TAG_TYPE_EFI64_IH:
{
mb2binfo.EFI.Info.Enabled = 1;
mb2binfo.EFI.Info.IH = 1;
multiboot_tag_efi64_ih *efi64_ih = (multiboot_tag_efi64_ih *)Tag;
fixme("efi64_ih->[pointer: %p]", efi64_ih->pointer);
mb2binfo.EFI.ImageHandle = (void *)(uintptr_t)efi64_ih->pointer;
debug("efi64_ih->[pointer: %#lx]", efi64_ih->pointer);
break;
}
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
@ -269,7 +314,8 @@ void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr;
mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 0xFFFFFFFF80000000);
mb2binfo.Kernel.Size = ((uint64_t)&_kernel_end - (uint64_t)&_kernel_start) + ((uint64_t)&_bootstrap_end - (uint64_t)&_bootstrap_start);
debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase);
debug("Kernel base: %#lx (physical) %#lx (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase);
break;
}
default:

View File

@ -68,8 +68,10 @@ Multiboot_start:
je x32Hang
mov %cr4, %ecx
or $0x00000010, %ecx /* PSE */
or $0x00000020, %ecx /* PAE */
or $0x10, %ecx /* PSE */
or $0x20, %ecx /* PAE */
or $0x200, %ecx /* OSFXSR */
or $0x400, %ecx /* OSXMMEXCPT */
mov %ecx, %cr4
call LoadGDT32
@ -86,6 +88,8 @@ Multiboot_start:
wrmsr
mov %cr0, %ecx
and $~0x4, %ecx /* EM */
or $0x2, %ecx /* MP */
or $0x80000000, %ecx /* PG */
or $0x1, %ecx /* PE */
mov %ecx, %cr0

View File

@ -442,7 +442,7 @@ namespace APIC
this->lapic->Write(APIC_TICR, 0xFFFFFFFF);
}
TimeManager->Sleep(1, Time::Units::Milliseconds);
TimeManager->Sleep(Time::FromMilliseconds(1));
// Mask the timer
if (this->lapic->x2APIC)

View File

@ -650,7 +650,7 @@ namespace InterruptDescriptorTable
#ifdef DEBUG
EnableISRs = !DebuggerIsAttached;
if (!EnableISRs)
KPrint("\x1b[34mThe debugger is attached, disabling all ISRs.");
KPrint("\x1b[32mThe debugger is attached, disabling all ISRs.");
#endif
/* ISR */

View File

@ -167,14 +167,14 @@ namespace SMP
}
apic->SendInitIPI(lapic->APICId);
TimeManager->Sleep(20, Time::Units::Milliseconds);
TimeManager->Sleep(Time::FromMilliseconds(20));
apic->SendStartupIPI(lapic->APICId, TRAMPOLINE_START);
debug("Waiting for CPU %d to load...", lapic->APICId);
uint64_t Timeout = TimeManager->CalculateTarget(2, Time::Units::Seconds);
uint64_t Timeout = TimeManager->GetTimeNs() + Time::FromSeconds(2);
while (CPUEnabled.load(std::memory_order_acquire) == false)
{
if (TimeManager->GetCounter() > Timeout)
if (TimeManager->GetTimeNs() > Timeout)
{
error("CPU %d failed to load!", lapic->APICId);
KPrint("\x1b[1;37;41mCPU %d failed to load!",

View File

@ -46,9 +46,17 @@ SECTIONS
*(.bootstrap .bootstrap.*)
} :bootstrap
_bootstrap_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += KERNEL_VMA;
/* . += KERNEL_VMA;
_bootstrap_start = .;
.limine_requests : {
KEEP(*(.limine_requests_start))
KEEP(*(.limine_requests))
KEEP(*(.limine_requests_end))
} :bootstrap
_bootstrap_end = ALIGN(CONSTANT(MAXPAGESIZE)); */
_kernel_start = ALIGN(CONSTANT(MAXPAGESIZE));
_kernel_text_start = ALIGN(CONSTANT(MAXPAGESIZE));
.text ALIGN(CONSTANT(MAXPAGESIZE)) : AT(ADDR(.text) - KERNEL_VMA)

View File

@ -368,7 +368,7 @@ namespace APIC
this->lapic->Write(APIC_TDCR, DivideBy128);
else
this->lapic->Write(APIC_TDCR, DivideBy16);
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks * Miliseconds));
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks *Miliseconds));
this->lapic->Write(APIC_TIMER, s_cst(uint32_t, timer.raw));
}
@ -383,7 +383,7 @@ namespace APIC
this->lapic->Write(APIC_TDCR, Divider);
this->lapic->Write(APIC_TICR, 0xFFFFFFFF);
TimeManager->Sleep(1, Time::Units::Milliseconds);
TimeManager->Sleep(Time::FromMilliseconds(1));
// Mask the timer
this->lapic->Write(APIC_TIMER, 0x10000 /* LVTTimer.Mask flag */);

View File

@ -464,7 +464,7 @@ namespace InterruptDescriptorTable
// #ifdef DEBUG
EnableISRs = !DebuggerIsAttached;
if (!EnableISRs)
KPrint("\x1b[34mThe debugger is attached, disabling all ISRs.");
KPrint("\x1b[32mThe debugger is attached, disabling all ISRs.");
// #endif
SetEntry(0x0, InterruptHandler_0x0, TRAP_GATE_32BIT, RING0, EnableISRs, GDT_KERNEL_CODE);

View File

@ -20,13 +20,16 @@
#include <memory.hpp>
#include <stropts.h>
#include <string.h>
#include <thread>
#include <ini.h>
#include "../kernel.h"
using namespace std::chrono_literals;
namespace KernelConsole
{
int TermColors[] = {
static int TermColors[] = {
[TerminalColor::BLACK] = 0x000000,
[TerminalColor::RED] = 0xAA0000,
[TerminalColor::GREEN] = 0x00AA00,
@ -37,7 +40,7 @@ namespace KernelConsole
[TerminalColor::GREY] = 0xAAAAAA,
};
int TermBrightColors[] = {
static int TermBrightColors[] = {
[TerminalColor::BLACK] = 0x858585,
[TerminalColor::RED] = 0xFF5555,
[TerminalColor::GREEN] = 0x55FF55,
@ -112,6 +115,33 @@ namespace KernelConsole
FontRenderer Renderer;
ConsoleTerminal *Terminals[16] = {nullptr};
std::atomic<ConsoleTerminal *> CurrentTerminal = nullptr;
void paint_blinker(bool Enable)
{
if (CurrentTerminal == nullptr)
return;
ConsoleTerminal *term = CurrentTerminal.load();
ConsoleTerminal::Blinker &blinker = term->Blink;
size_t cellIndex = Renderer.Cursor.Y * term->Term->GetWinsize()->ws_col + Renderer.Cursor.X;
TerminalCell *cell = term->Term->GetCell(cellIndex);
uint32_t bgColor = cell->attr.Bright ? TermBrightColors[cell->attr.Background] : TermColors[cell->attr.Background];
Renderer.Paint(Renderer.Cursor.X, Renderer.Cursor.Y, blinker.Character, Enable ? blinker.Color : bgColor, bgColor);
}
void paint_blinker_thread()
{
bool blink = false;
while (true)
{
paint_blinker(blink);
blink = !blink;
std::this_thread::sleep_for(std::chrono::milliseconds(CurrentTerminal.load()->Blink.Delay));
}
}
void paint_callback(TerminalCell *cell, long x, long y)
{
if (cell->attr.Bright)
@ -123,22 +153,20 @@ namespace KernelConsole
void cursor_callback(TerminalCursor *cur)
{
Renderer.Cursor = {cur->X, cur->Y};
paint_blinker(false);
}
VirtualTerminal *Terminals[16] = {nullptr};
std::atomic<VirtualTerminal *> CurrentTerminal = nullptr;
bool SetTheme(std::string Theme)
{
FileNode *rn = fs->GetByPath("/etc/term", thisProcess->Info.RootNode);
Node rn = fs->Lookup(thisProcess->Info.RootNode, "/sys/cfg/term");
if (rn == nullptr)
return false;
kstat st{};
rn->Stat(&st);
kstat st;
fs->Stat(rn, &st);
char *sh = new char[st.Size];
rn->Read(sh, st.Size, 0);
fs->Read(rn, sh, st.Size, 0);
ini_t *ini = ini_load(sh, NULL);
int themeSection, c0, c1, c2, c3, c4, c5, c6, c7, colorsIdx;
@ -267,24 +295,15 @@ namespace KernelConsole
size_t Rows = Display->GetWidth / Renderer.CurrentFont->GetInfo().Width;
size_t Cols = Display->GetHeight / Renderer.CurrentFont->GetInfo().Height;
debug("Terminal size: %ux%u", Rows, Cols);
Terminals[0] = new VirtualTerminal(Rows, Cols, Display->GetWidth, Display->GetHeight, paint_callback, cursor_callback);
Terminals[0]->Clear(0, 0, Rows, Cols - 1);
Terminals[0] = new ConsoleTerminal;
Terminals[0]->Term = new VirtualTerminal(Rows, Cols, Display->GetWidth, Display->GetHeight, paint_callback, cursor_callback);
Terminals[0]->Term->Clear(0, 0, Rows, Cols - 1);
CurrentTerminal.store(Terminals[0], std::memory_order_release);
}
void LateInit()
void LoadConsoleConfig(std::string &Config)
{
FileNode *rn = fs->GetByPath("/etc/term", thisProcess->Info.RootNode);
if (rn == nullptr)
return;
kstat st{};
rn->Stat(&st);
char *sh = new char[st.Size];
rn->Read(sh, st.Size, 0);
ini_t *ini = ini_load(sh, NULL);
ini_t *ini = ini_load(Config.c_str(), NULL);
int general = ini_find_section(ini, "general", NULL);
int cursor = ini_find_section(ini, "cursor", NULL);
assert(general != INI_NOT_FOUND && cursor != INI_NOT_FOUND);
@ -292,16 +311,22 @@ namespace KernelConsole
int themeIndex = ini_find_property(ini, general, "theme", NULL);
assert(themeIndex != INI_NOT_FOUND);
int cursorColor = ini_find_property(ini, cursor, "color", NULL);
int cursorBlink = ini_find_property(ini, cursor, "blink", NULL);
assert(cursorColor != INI_NOT_FOUND && cursorBlink != INI_NOT_FOUND);
int cursorColor = ini_find_property(ini, cursor, "color", NULL);
int cursorChar = ini_find_property(ini, cursor, "char", NULL);
int cursorDelay = ini_find_property(ini, cursor, "delay", NULL);
assert(cursorBlink != INI_NOT_FOUND && cursorColor != INI_NOT_FOUND && cursorChar != INI_NOT_FOUND && cursorDelay != INI_NOT_FOUND);
const char *colorThemeStr = ini_property_value(ini, general, themeIndex);
const char *cursorColorStr = ini_property_value(ini, cursor, cursorColor);
const char *cursorBlinkStr = ini_property_value(ini, cursor, cursorBlink);
const char *cursorCharStr = ini_property_value(ini, cursor, cursorChar);
const char *cursorDelayStr = ini_property_value(ini, cursor, cursorDelay);
debug("colorThemeStr=%s", colorThemeStr);
debug("cursorColorStr=%s", cursorColorStr);
debug("cursorBlinkStr=%s", cursorBlinkStr);
debug("cursorColorStr=%s", cursorColorStr);
debug("cursorCharStr=%s", cursorCharStr);
debug("cursorDelayStr=%s", cursorDelayStr);
auto getColorComponent = [](const char *str, int &index) -> int
{
@ -335,11 +360,36 @@ namespace KernelConsole
uint32_t blinkColor = 0xFFFFFF;
if (cursorColorStr != 0)
blinkColor = parseColor(cursorColorStr);
fixme("cursor blink with colors %X", blinkColor);
debug("cursor blink with colors %X and char '%s' and delay %s", blinkColor, cursorCharStr, cursorDelayStr);
Terminals[0]->Blink.Enabled = true;
Terminals[0]->Blink.Color = blinkColor;
Terminals[0]->Blink.Character = *cursorCharStr;
Terminals[0]->Blink.Delay = atoi(cursorDelayStr);
}
ini_destroy(ini);
delete[] sh;
}
void LateInit()
{
Node rn = fs->Lookup(thisProcess->Info.RootNode, "/sys/cfg/term");
if (rn == nullptr)
return;
{
kstat st;
fs->Stat(rn, &st);
std::string cfg;
cfg.resize(st.Size);
fs->Read(rn, cfg.data(), st.Size, 0);
LoadConsoleConfig(cfg);
}
if (Terminals[0]->Blink.Enabled)
{
std::thread t = std::thread(paint_blinker_thread);
t.detach();
}
#ifdef DEBUG
// __test_themes();

View File

@ -27,12 +27,12 @@ NewLock(DebuggerLock);
extern bool serialports[8];
EXTERNC NIF void uart_wrapper(char c, void *)
EXTERNC nif void uart_wrapper(char c, void *)
{
uart.DebugWrite(c);
}
static inline NIF bool WritePrefix(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, va_list args)
static inline nif bool WritePrefix(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, va_list args)
{
const char *DbgLvlString;
switch (Level)
@ -79,7 +79,7 @@ static inline NIF bool WritePrefix(DebugLevel Level, const char *File, int Line,
namespace SysDbg
{
NIF void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
nif void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
va_list args;
va_start(args, Format);
@ -92,7 +92,7 @@ namespace SysDbg
va_end(args);
}
NIF void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
nif void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
va_list args;
va_start(args, Format);
@ -106,7 +106,7 @@ namespace SysDbg
uart_wrapper('\n', nullptr);
}
NIF void LockedWrite(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
nif void LockedWrite(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
SmartTimeoutLock(DebuggerLock, 1000);
va_list args;
@ -120,7 +120,7 @@ namespace SysDbg
va_end(args);
}
NIF void LockedWriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
nif void LockedWriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
SmartTimeoutLock(DebuggerLock, 1000);
va_list args;
@ -137,7 +137,7 @@ namespace SysDbg
}
// C compatibility
extern "C" NIF void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
extern "C" nif void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
va_list args;
va_start(args, Format);
@ -151,7 +151,7 @@ extern "C" NIF void SysDbgWrite(enum DebugLevel Level, const char *File, int Lin
}
// C compatibility
extern "C" NIF void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
extern "C" nif void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
va_list args;
va_start(args, Format);
@ -166,7 +166,7 @@ extern "C" NIF void SysDbgWriteLine(enum DebugLevel Level, const char *File, int
}
// C compatibility
extern "C" NIF void SysDbgLockedWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
extern "C" nif void SysDbgLockedWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
SmartTimeoutLock(DebuggerLock, 1000);
va_list args;
@ -181,7 +181,7 @@ extern "C" NIF void SysDbgLockedWrite(enum DebugLevel Level, const char *File, i
}
// C compatibility
extern "C" NIF void SysDbgLockedWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
extern "C" nif void SysDbgLockedWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
{
SmartTimeoutLock(DebuggerLock, 1000);
va_list args;

View File

@ -191,11 +191,11 @@ namespace v0
/* --------- */
dev_t RegisterFileSystem(dev_t DriverID, FileSystemInfo *Info, struct Inode *Root)
dev_t RegisterFileSystem(dev_t DriverID, FileSystemInfo *Info)
{
dbg_api("%d, %#lx, %#lx", DriverID, Info, Root);
dbg_api("%d, %#lx", DriverID, Info);
return fs->RegisterFileSystem(Info, Root);
return fs->RegisterFileSystem(Info);
}
int UnregisterFileSystem(dev_t DriverID, dev_t Device)
@ -273,7 +273,7 @@ namespace v0
{
dbg_api("%d, %d", DriverID, Milliseconds);
TaskManager->Sleep(Milliseconds);
TaskManager->Sleep(Time::FromMilliseconds(Milliseconds));
}
/* --------- */
@ -333,7 +333,7 @@ namespace v0
void PS2Wait(dev_t DriverID, const bool Output)
{
dbg_api("%d, %d", DriverID, Output);
// dbg_api("%d, %d", DriverID, Output);
#if defined(__amd64__) || defined(__i386__)
int Timeout = 100000;
@ -379,7 +379,7 @@ namespace v0
uint8_t PS2ReadData(dev_t DriverID)
{
dbg_api("%d", DriverID);
// dbg_api("%d", DriverID);
#if defined(__amd64__) || defined(__i386__)
WaitOutput;
@ -571,7 +571,7 @@ namespace v0
__PCIArray *head = nullptr;
__PCIArray *array = nullptr;
foreach (auto &dev in Devices)
for (auto &dev : Devices)
{
/* TODO: optimize memory allocation */
PCI::PCIDevice *dptr = (PCI::PCIDevice *)vma->RequestPages(TO_PAGES(sizeof(PCI::PCIDevice)));
@ -710,6 +710,20 @@ namespace v0
return DriverManager->ReportInputEvent(DriverID, Report);
}
dev_t RegisterBlockDevice(dev_t DriverID, struct BlockDevice *Device)
{
dbg_api("%d, %#lx", DriverID, Device);
return DriverManager->RegisterBlockDevice(DriverID, Device);
}
int UnregisterBlockDevice(dev_t DriverID, dev_t DeviceID)
{
dbg_api("%d, %d", DriverID, DeviceID);
return DriverManager->UnregisterBlockDevice(DriverID, DeviceID);
}
}
struct APISymbols
@ -777,6 +791,8 @@ static struct APISymbols APISymbols_v0[] = {
{"__RegisterDevice", (void *)v0::RegisterDevice},
{"__UnregisterDevice", (void *)v0::UnregisterDevice},
{"__ReportInputEvent", (void *)v0::ReportInputEvent},
{"__RegisterBlockDevice", (void *)v0::RegisterBlockDevice},
{"__UnregisterBlockDevice", (void *)v0::UnregisterBlockDevice},
};
long __KernelUndefinedFunction(long arg0, long arg1, long arg2, long arg3,

View File

@ -1,726 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <driver.hpp>
#include <interface/driver.h>
#include <interface/input.h>
#include <memory.hpp>
#include <stropts.h>
#include <ints.hpp>
#include <task.hpp>
#include <printf.h>
#include <exec.hpp>
#include <rand.hpp>
#include <cwalk.h>
#include <md5.h>
#include "../../kernel.h"
using namespace vfs;
namespace Driver
{
/**
* maj = 0
* min:
* 0 - <ROOT>
* 1 - /proc/self
*
* maj = 1
* min:
* 0 - /dev/input/keyboard
* 1 - /dev/input/mouse
* ..- /dev/input/eventN
*/
int __fs_Lookup(struct Inode *_Parent, const char *Name, struct Inode **Result)
{
func("%#lx %s %#lx", _Parent, Name, Result);
assert(_Parent != nullptr);
const char *basename;
size_t length;
cwk_path_get_basename(Name, &basename, &length);
if (basename == NULL)
{
error("Invalid name %s", Name);
return -EINVAL;
}
auto Parent = (Manager::DeviceInode *)_Parent;
for (const auto &child : Parent->Children)
{
debug("Comparing %s with %s", basename, child->Name.c_str());
if (strcmp(child->Name.c_str(), basename) != 0)
continue;
*Result = &child->Node;
return 0;
}
debug("Not found %s", Name);
return -ENOENT;
}
int __fs_Create(struct Inode *_Parent, const char *Name, mode_t Mode, struct Inode **Result)
{
func("%#lx %s %d", _Parent, Name, Mode);
assert(_Parent != nullptr);
/* We expect to be /dev or children of it */
auto Parent = (Manager::DeviceInode *)_Parent;
auto _dev = new Manager::DeviceInode;
_dev->Parent = nullptr;
_dev->ParentInode = _Parent;
_dev->Name = Name;
_dev->Node.Device = Parent->Node.Device;
_dev->Node.Mode = Mode;
_dev->Node.Index = Parent->Node.Index + Parent->Children.size();
_dev->Node.Offset = Parent->Children.size();
Parent->Children.push_back(_dev);
*Result = &_dev->Node;
return 0;
}
ssize_t __fs_Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
{
func("%#lx %d %d", Node, Size, Offset);
switch (Node->GetMajor())
{
case 1:
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
{
if (Size < sizeof(KeyboardReport))
return -EINVAL;
size_t nReads = Size / sizeof(KeyboardReport);
KeyboardReport *report = (KeyboardReport *)Buffer;
while (DriverManager->GlobalKeyboardInputReports.Count() == 0)
TaskManager->Yield();
DriverManager->GlobalKeyboardInputReports.Read(report, nReads);
return sizeof(KeyboardReport) * nReads;
}
case 1: /* /dev/input/mouse */
{
if (Size < sizeof(MouseReport))
return -EINVAL;
size_t nReads = Size / sizeof(MouseReport);
MouseReport *report = (MouseReport *)Buffer;
while (DriverManager->GlobalMouseInputReports.Count() == 0)
TaskManager->Yield();
DriverManager->GlobalMouseInputReports.Read(report, nReads);
return sizeof(MouseReport) * nReads;
}
default:
return -ENOENT;
};
}
default:
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Read, -ENOTSUP);
return dOps->second.Ops->Read(Node, Buffer, Size, Offset);
}
}
}
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
{
func("%#lx %p %d %d", Node, Buffer, Size, Offset);
switch (Node->GetMajor())
{
case 1:
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
{
return -ENOTSUP;
}
case 1: /* /dev/input/mouse */
{
return -ENOTSUP;
}
default:
return -ENOENT;
};
}
default:
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Write, -ENOTSUP);
return dOps->second.Ops->Write(Node, Buffer, Size, Offset);
}
}
}
int __fs_Open(struct Inode *Node, int Flags, mode_t Mode)
{
func("%#lx %d %d", Node, Flags, Mode);
switch (Node->GetMajor())
{
case 1:
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
case 1: /* /dev/input/mouse */
return -ENOTSUP;
default:
return -ENOENT;
};
}
default:
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Open, -ENOTSUP);
return dOps->second.Ops->Open(Node, Flags, Mode);
}
}
}
int __fs_Close(struct Inode *Node)
{
func("%#lx", Node);
switch (Node->GetMajor())
{
case 1:
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
case 1: /* /dev/input/mouse */
return -ENOTSUP;
default:
return -ENOENT;
};
}
default:
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Close, -ENOTSUP);
return dOps->second.Ops->Close(Node);
}
}
}
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
{
func("%#lx %lu %#lx", Node, Request, Argp);
switch (Node->GetMajor())
{
case 1:
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
case 1: /* /dev/input/mouse */
return -ENOSYS;
default:
return -ENOENT;
};
}
default:
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Ioctl, -ENOTSUP);
return dOps->second.Ops->Ioctl(Node, Request, Argp);
}
}
}
__no_sanitize("alignment")
ssize_t __fs_Readdir(struct Inode *_Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries)
{
func("%#lx %#lx %d %d %d", _Node, Buffer, Size, Offset, Entries);
auto Node = (Manager::DeviceInode *)_Node;
off_t realOffset = Offset;
size_t totalSize = 0;
uint16_t reclen = 0;
struct kdirent *ent = nullptr;
if (Offset == 0)
{
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(".") + 1);
if (totalSize + reclen >= Size)
return -EINVAL;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = Node->Node.Index;
ent->d_off = Offset++;
ent->d_reclen = reclen;
ent->d_type = DT_DIR;
strcpy(ent->d_name, ".");
totalSize += reclen;
}
if (Offset <= 1)
{
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen("..") + 1);
if (totalSize + reclen >= Size)
{
if (realOffset == 1)
return -EINVAL;
return totalSize;
}
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
if (Node->Parent)
ent->d_ino = Node->Parent->Node->Index;
else if (Node->ParentInode)
ent->d_ino = Node->ParentInode->Index;
else
{
warn("Parent is null for %s", Node->Name.c_str());
ent->d_ino = Node->Node.Index;
}
ent->d_off = Offset++;
ent->d_reclen = reclen;
ent->d_type = DT_DIR;
strcpy(ent->d_name, "..");
totalSize += reclen;
}
if (!S_ISDIR(Node->Node.Mode))
return -ENOTDIR;
if ((Offset >= 2 ? (Offset - 2) : Offset) > (off_t)Node->Children.size())
return -EINVAL;
off_t entries = 0;
for (const auto &var : Node->Children)
{
debug("iterating \"%s\" inside \"%s\"", var->Name.c_str(), Node->Name.c_str());
if (var->Node.Offset < realOffset)
{
debug("skipping \"%s\" (%d < %d)", var->Name.c_str(), var->Node.Offset, Offset);
continue;
}
if (entries >= Entries)
break;
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(var->Name.c_str()) + 1);
if (totalSize + reclen >= Size)
break;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = var->Node.Index;
ent->d_off = var->Node.Offset;
ent->d_reclen = reclen;
ent->d_type = IFTODT(var->Node.Mode);
strncpy(ent->d_name, var->Name.c_str(), strlen(var->Name.c_str()));
totalSize += reclen;
entries++;
}
if (totalSize + sizeof(struct kdirent) >= Size)
return totalSize;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = 0;
ent->d_off = 0;
ent->d_reclen = 0;
ent->d_type = DT_UNKNOWN;
ent->d_name[0] = '\0';
return totalSize;
}
void ManagerDaemonWrapper() { DriverManager->Daemon(); }
void Manager::Daemon()
{
while (true)
{
TaskManager->Sleep(1000);
}
}
dev_t Manager::RegisterInputDevice(std::unordered_map<dev_t, DriverHandlers> *dop,
dev_t DriverID, size_t i, const InodeOperations *Operations)
{
std::string prefix = "event";
for (size_t j = 0; j < 128; j++)
{
std::string deviceName = prefix + std::to_string(j);
FileNode *node = fs->GetByPath(deviceName.c_str(), devInputNode);
if (node)
continue;
/* c rwx r-- r-- */
mode_t mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFCHR;
node = fs->ForceCreate(devInputNode, deviceName.c_str(), mode);
node->Node->SetDevice(DriverID, i);
DriverHandlers dh{};
dh.Ops = Operations;
dh.Node = node->Node;
dh.InputReports = new RingBuffer<InputReport>(16);
dop->insert({i, std::move(dh)});
return i;
}
ReturnLogError(-1, "No available slots for device %d", DriverID);
return -1; /* -Werror=return-type */
}
dev_t Manager::RegisterBlockDevice(std::unordered_map<dev_t, DriverHandlers> *dop,
dev_t DriverID, size_t i, const InodeOperations *Operations)
{
std::string prefix = "event";
for (size_t j = 0; j < 128; j++)
{
std::string deviceName = prefix + std::to_string(j);
FileNode *node = fs->GetByPath(deviceName.c_str(), devInputNode);
if (node)
continue;
/* c rwx r-- r-- */
mode_t mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFBLK;
node = fs->ForceCreate(devInputNode, deviceName.c_str(), mode);
node->Node->SetDevice(DriverID, i);
DriverHandlers dh{};
dh.Ops = Operations;
dh.Node = node->Node;
dh.InputReports = new RingBuffer<InputReport>(16);
dop->insert({i, std::move(dh)});
return i;
}
ReturnLogError(-1, "No available slots for device %d", DriverID);
return -1; /* -Werror=return-type */
}
dev_t Manager::RegisterDevice(dev_t DriverID, DeviceType Type, const InodeOperations *Operations)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
for (size_t i = 0; i < 128; i++)
{
const auto dOps = dop->find(i);
const auto dOpsEnd = dop->end();
if (dOps != dOpsEnd)
continue;
DeviceType devType = (DeviceType)(Type & DEVICE_TYPE_MASK);
switch (devType)
{
case DEVICE_TYPE_INPUT:
return RegisterInputDevice(dop, DriverID, i, Operations);
case DEVICE_TYPE_BLOCK:
return RegisterBlockDevice(dop, DriverID, i, Operations);
default:
ReturnLogError(-1, "Invalid device type %d", Type);
}
}
ReturnLogError(-1, "No available slots for device %d", DriverID);
}
dev_t Manager::CreateDeviceFile(dev_t DriverID, const char *name, mode_t mode, const InodeOperations *Operations)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
for (size_t i = 0; i < 128; i++)
{
const auto dOps = dop->find(i);
if (dOps != dop->end())
continue;
FileNode *node = fs->GetByPath(name, devNode);
if (node)
ReturnLogError(-EEXIST, "Device file %s already exists", name);
node = fs->Create(devNode, name, mode);
if (node == nullptr)
ReturnLogError(-ENOMEM, "Failed to create device file %s", name);
node->Node->SetDevice(DriverID, i);
DriverHandlers dh{};
dh.Ops = Operations;
dh.Node = node->Node;
dh.InputReports = new RingBuffer<InputReport>(16);
dop->insert({i, std::move(dh)});
return i;
}
ReturnLogError(-1, "No available slots for device %d", DriverID);
return -1; /* -Werror=return-type */
}
int Manager::UnregisterDevice(dev_t DriverID, dev_t Device)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
const auto dOps = dop->find(Device);
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Device);
dop->erase(dOps);
fixme("remove eventX from /dev/input");
fixme("delete InputReports");
return 0;
}
void *Manager::AllocateMemory(dev_t DriverID, size_t Pages)
{
auto itr = Drivers.find(DriverID);
assert(itr != Drivers.end());
void *ptr = itr->second.vma->RequestPages(Pages);
memset(ptr, 0, FROM_PAGES(Pages));
return ptr;
}
void Manager::FreeMemory(dev_t DriverID, void *Pointer, size_t Pages)
{
auto itr = Drivers.find(DriverID);
assert(itr != Drivers.end());
itr->second.vma->FreePages(Pointer, Pages);
}
int Manager::ReportInputEvent(dev_t DriverID, InputReport *Report)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Report->Device);
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Report->Device);
dOps->second.InputReports->Write(Report, 1);
switch (Report->Type)
{
case INPUT_TYPE_KEYBOARD:
{
KeyboardReport *kReport = &Report->Keyboard;
GlobalKeyboardInputReports.Write(kReport, 1);
break;
}
case INPUT_TYPE_MOUSE:
{
MouseReport *mReport = &Report->Mouse;
GlobalMouseInputReports.Write(mReport, 1);
break;
}
default:
assert(!"Invalid input type");
}
return 0;
}
void Manager::InitializeDaemonFS()
{
dev_t MinorID = 0;
DeviceInode *_dev = new DeviceInode;
_dev->Name = "dev";
/* d rwx r-- r-- */
mode_t mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFDIR;
Inode *dev = (Inode *)_dev;
dev->Mode = mode;
dev->Flags = I_FLAG_MOUNTPOINT | I_FLAG_CACHE_KEEP;
FileSystemInfo *fsi = new FileSystemInfo;
fsi->Name = "Device Virtual File System";
fsi->RootName = "dev";
fsi->Flags = I_FLAG_ROOT | I_FLAG_MOUNTPOINT | I_FLAG_CACHE_KEEP;
fsi->SuperOps = {};
fsi->Ops.Lookup = __fs_Lookup;
fsi->Ops.Create = __fs_Create;
fsi->Ops.Remove = nullptr;
fsi->Ops.Rename = nullptr;
fsi->Ops.Read = __fs_Read;
fsi->Ops.Write = __fs_Write;
fsi->Ops.Truncate = nullptr;
fsi->Ops.Open = __fs_Open;
fsi->Ops.Close = __fs_Close;
fsi->Ops.Ioctl = __fs_Ioctl;
fsi->Ops.ReadDir = __fs_Readdir;
fsi->Ops.MkDir = nullptr;
fsi->Ops.RmDir = nullptr;
fsi->Ops.SymLink = nullptr;
fsi->Ops.ReadLink = nullptr;
fsi->Ops.Seek = nullptr;
fsi->Ops.Stat = nullptr;
dev->Device = fs->RegisterFileSystem(fsi, dev);
dev->SetDevice(0, MinorID++);
MinorID++; /* 1 = /proc/self */
devNode = fs->Mount(fs->GetRoot(0), dev, "/dev");
_dev->Parent = devNode->Parent;
_dev->ParentInode = devNode->Parent->Node;
/* d rwx r-- r-- */
mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFDIR;
DeviceInode *input = new DeviceInode;
input->Parent = devNode;
input->ParentInode = devNode->Node;
input->Name = "input";
input->Node.Device = dev->Device;
input->Node.Mode = mode;
input->Node.Flags = I_FLAG_CACHE_KEEP;
input->Node.Offset = _dev->Children.size();
_dev->Children.push_back(input);
devInputNode = fs->GetByPath("input", devNode);
auto createDevice = [](DeviceInode *p1, FileNode *p2, const std::string &name, dev_t maj, dev_t min, mode_t mode)
{
DeviceInode *device = new DeviceInode;
device->Parent = p2;
device->ParentInode = p2->Node;
device->Name = name;
device->Node.Device = p2->Node->Device;
device->Node.Mode = mode;
device->Node.SetDevice(maj, min);
device->Node.Flags = I_FLAG_CACHE_KEEP;
device->Node.Offset = p1->Children.size();
p1->Children.push_back(device);
};
MinorID = 0;
/* c rw- r-- --- */
mode = S_IRUSR | S_IWUSR |
S_IRGRP |
S_IFCHR;
createDevice(input, devInputNode, "keyboard", 1, MinorID++, mode);
/* c rw- r-- --- */
mode = S_IRUSR | S_IWUSR |
S_IRGRP |
S_IFCHR;
createDevice(input, devInputNode, "mouse", 1, MinorID++, mode);
}
}

483
Kernel/core/driver/dev.cpp Normal file
View File

@ -0,0 +1,483 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <driver.hpp>
#include "../../kernel.h"
namespace Driver
{
dev_t DeviceDirID;
int __fs_Lookup(struct Inode *_Parent, const char *Name, struct Inode **Result)
{
func("%#lx %s %#lx", _Parent, Name, Result);
assert(_Parent != nullptr);
const char *basename;
size_t length;
cwk_path_get_basename(Name, &basename, &length);
if (basename == NULL)
{
error("Invalid name %s", Name);
return -EINVAL;
}
auto Parent = (Manager::DeviceInode *)_Parent;
for (const auto &child : Parent->Children)
{
debug("Comparing %s with %s", basename, child->Name.c_str());
if (strcmp(child->Name.c_str(), basename) != 0)
continue;
*Result = &child->inode;
return 0;
}
debug("Not found %s", Name);
return -ENOENT;
}
int __fs_Create(struct Inode *_Parent, const char *Name, mode_t Mode, struct Inode **Result)
{
func("%#lx %s %d", _Parent, Name, Mode);
assert(_Parent != nullptr);
/* We expect to be /dev or children of it */
auto Parent = (Manager::DeviceInode *)_Parent;
auto _dev = new Manager::DeviceInode;
_dev->Parent = nullptr;
_dev->ParentInode = _Parent;
_dev->Name = Name;
_dev->inode.Device = Parent->inode.Device;
_dev->inode.Mode = Mode;
_dev->inode.Index = Parent->inode.Index + Parent->Children.size();
_dev->inode.Offset = Parent->Children.size();
Parent->Children.push_back(_dev);
*Result = &_dev->inode;
return 0;
}
ssize_t __fs_Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
{
func("%#lx %d %d", Node, Size, Offset);
if ((dev_t)Node->GetMajor() == DeviceDirID)
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
{
if (Size < sizeof(KeyboardReport))
return -EINVAL;
size_t nReads = Size / sizeof(KeyboardReport);
KeyboardReport *report = (KeyboardReport *)Buffer;
while (DriverManager->GlobalKeyboardInputReports.Count() == 0)
TaskManager->Yield();
DriverManager->GlobalKeyboardInputReports.Read(report, nReads);
return sizeof(KeyboardReport) * nReads;
}
case 1: /* /dev/input/mouse */
{
if (Size < sizeof(MouseReport))
return -EINVAL;
size_t nReads = Size / sizeof(MouseReport);
MouseReport *report = (MouseReport *)Buffer;
while (DriverManager->GlobalMouseInputReports.Count() == 0)
TaskManager->Yield();
DriverManager->GlobalMouseInputReports.Read(report, nReads);
return sizeof(MouseReport) * nReads;
}
default:
return -ENOENT;
};
}
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Read, -ENOTSUP);
return dOps->second.Ops->Read(Node, Buffer, Size, Offset);
}
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
{
func("%#lx %p %d %d", Node, Buffer, Size, Offset);
if ((dev_t)Node->GetMajor() == DeviceDirID)
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
{
return -ENOTSUP;
}
case 1: /* /dev/input/mouse */
{
return -ENOTSUP;
}
default:
return -ENOENT;
};
}
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Write, -ENOTSUP);
return dOps->second.Ops->Write(Node, Buffer, Size, Offset);
}
int __fs_Open(struct Inode *Node, int Flags, mode_t Mode)
{
func("%#lx %d %d", Node, Flags, Mode);
if ((dev_t)Node->GetMajor() == DeviceDirID)
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
case 1: /* /dev/input/mouse */
return -ENOTSUP;
default:
return -ENOENT;
};
}
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Open, -ENOTSUP);
return dOps->second.Ops->Open(Node, Flags, Mode);
}
int __fs_Close(struct Inode *Node)
{
func("%#lx", Node);
if ((dev_t)Node->GetMajor() == DeviceDirID)
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
case 1: /* /dev/input/mouse */
return -ENOTSUP;
default:
return -ENOENT;
};
}
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Close, -ENOTSUP);
return dOps->second.Ops->Close(Node);
}
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
{
func("%#lx %lu %#lx", Node, Request, Argp);
if ((dev_t)Node->GetMajor() == DeviceDirID)
{
switch (Node->GetMinor())
{
case 0: /* /dev/input/keyboard */
case 1: /* /dev/input/mouse */
return -ENOSYS;
default:
return -ENOENT;
};
}
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(Node->GetMajor());
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", Node->GetMajor());
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Node->GetMinor());
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Node->GetMinor());
AssertReturnError(dOps->second.Ops, -ENOTSUP);
AssertReturnError(dOps->second.Ops->Ioctl, -ENOTSUP);
return dOps->second.Ops->Ioctl(Node, Request, Argp);
}
__no_sanitize("alignment") ssize_t __fs_Readdir(struct Inode *_Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries)
{
func("%#lx %#lx %d %d %d", _Node, Buffer, Size, Offset, Entries);
auto node = (Manager::DeviceInode *)_Node;
off_t realOffset = Offset;
size_t totalSize = 0;
uint16_t reclen = 0;
struct kdirent *ent = nullptr;
if (!S_ISDIR(node->inode.Mode))
return -ENOTDIR;
if (Offset == 0)
{
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(".") + 1);
if (totalSize + reclen > Size)
return -EINVAL;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = node->inode.Index;
ent->d_off = 0;
ent->d_reclen = reclen;
ent->d_type = DT_DIR;
strcpy(ent->d_name, ".");
totalSize += reclen;
Offset++;
}
if (Offset == 1)
{
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen("..") + 1);
if (totalSize + reclen > Size)
return totalSize;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
if (node->Parent)
ent->d_ino = node->Parent->inode->Index;
else if (node->ParentInode)
ent->d_ino = node->ParentInode->Index;
else
ent->d_ino = node->inode.Index;
ent->d_off = 1;
ent->d_reclen = reclen;
ent->d_type = DT_DIR;
strcpy(ent->d_name, "..");
totalSize += reclen;
Offset++;
}
off_t entryIndex = 0;
for (const auto &var : node->Children)
{
if (entryIndex + 2 < realOffset)
{
entryIndex++;
continue;
}
if (Entries && entryIndex >= Entries)
break;
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(var->Name.c_str()) + 1);
if (totalSize + reclen > Size)
break;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = var->inode.Index;
ent->d_off = entryIndex + 2;
ent->d_reclen = reclen;
ent->d_type = IFTODT(var->inode.Mode);
strcpy(ent->d_name, var->Name.c_str());
totalSize += reclen;
entryIndex++;
}
if (totalSize + offsetof(struct kdirent, d_name) + 1 > Size)
return totalSize;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = 0;
ent->d_off = 0;
ent->d_reclen = 0;
ent->d_type = DT_UNKNOWN;
ent->d_name[0] = '\0';
return totalSize;
}
int __fs_Stat(struct Inode *_Node, struct kstat *Stat)
{
func("%#lx %#lx", _Node, Stat);
auto node = (Manager::DeviceInode *)_Node;
assert(node != nullptr);
assert(Stat != nullptr);
Stat->Device = node->inode.Device;
Stat->Index = node->inode.Index;
Stat->HardLinks = 1;
Stat->UserID = 0;
Stat->GroupID = 0;
Stat->RawDevice = node->inode.RawDevice;
Stat->Size = node->Size;
Stat->AccessTime = node->AccessTime;
Stat->ModifyTime = node->ModifyTime;
Stat->ChangeTime = node->ChangeTime;
Stat->BlockSize = node->BlockSize;
Stat->Blocks = node->Blocks;
Stat->Attribute = 0;
return 0;
}
void Manager::InitializeDeviceDirectory()
{
dev_t MinorID = 0;
DeviceInode *_dev = new DeviceInode;
_dev->Name = "dev";
/* d rwx r-- r-- */
mode_t mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFDIR;
Inode *dev = (Inode *)_dev;
dev->Mode = mode;
FileSystemInfo *fsi = new FileSystemInfo;
fsi->Name = "devfs";
fsi->SuperOps = {};
fsi->Ops.Lookup = __fs_Lookup;
fsi->Ops.Create = __fs_Create;
fsi->Ops.Remove = nullptr;
fsi->Ops.Rename = nullptr;
fsi->Ops.Read = __fs_Read;
fsi->Ops.Write = __fs_Write;
fsi->Ops.Truncate = nullptr;
fsi->Ops.Open = __fs_Open;
fsi->Ops.Close = __fs_Close;
fsi->Ops.Ioctl = __fs_Ioctl;
fsi->Ops.ReadDir = __fs_Readdir;
fsi->Ops.MkDir = nullptr;
fsi->Ops.RmDir = nullptr;
fsi->Ops.SymLink = nullptr;
fsi->Ops.ReadLink = nullptr;
fsi->Ops.Seek = nullptr;
fsi->Ops.Stat = __fs_Stat;
DeviceDirID = dev->Device = fs->RegisterFileSystem(fsi);
dev->SetDevice(0, MinorID++);
Node root = fs->GetRoot(0);
devNode = fs->Mount(root, dev, "dev", fsi);
assert(devNode->Parent != nullptr);
_dev->Parent = devNode->Parent;
_dev->ParentInode = devNode->Parent->inode;
/* d rwx r-- r-- */
mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFDIR;
DeviceInode *blk = new DeviceInode;
blk->Parent = devNode;
blk->ParentInode = devNode->inode;
blk->Name = "block";
blk->inode.Device = dev->Device;
blk->inode.Mode = mode;
blk->inode.Offset = _dev->Children.size();
_dev->Children.push_back(blk);
devBlockNode = fs->Lookup(devNode, "block");
/* d rwx r-- r-- */
mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFDIR;
DeviceInode *input = new DeviceInode;
input->Parent = devNode;
input->ParentInode = devNode->inode;
input->Name = "input";
input->inode.Device = dev->Device;
input->inode.Mode = mode;
input->inode.Offset = _dev->Children.size();
_dev->Children.push_back(input);
devInputNode = fs->Lookup(devNode, "input");
auto createDevice = [](DeviceInode *p1, Node p2, const std::string &name, dev_t maj, dev_t min, mode_t mode)
{
DeviceInode *device = new DeviceInode;
device->Parent = p2;
device->ParentInode = p2->inode;
device->Name = name;
device->inode.Device = p2->inode->Device;
device->inode.Mode = mode;
device->inode.SetDevice(maj, min);
device->inode.Offset = p1->Children.size();
p1->Children.push_back(device);
};
MinorID = 0;
/* c rw- r-- --- */
mode = S_IRUSR | S_IWUSR |
S_IRGRP |
S_IFCHR;
createDevice(input, devInputNode, "keyboard", DeviceDirID, MinorID++, mode);
/* c rw- r-- --- */
mode = S_IRUSR | S_IWUSR |
S_IRGRP |
S_IFCHR;
createDevice(input, devInputNode, "mouse", DeviceDirID, MinorID++, mode);
}
}

View File

@ -26,14 +26,48 @@
#include <exec.hpp>
#include <rand.hpp>
#include <cwalk.h>
#include <sha512.h>
#include <md5.h>
#include "../../kernel.h"
using namespace vfs;
extern const char *trusted_drivers[];
extern const __SIZE_TYPE__ trusted_drivers_count;
namespace Driver
{
bool Manager::IsDriverTrusted(Node File)
{
kstat st;
fs->Stat(File, &st);
std::unique_ptr<uint8_t[]> ptr(new uint8_t[st.Size]);
fs->Read(File, ptr.get(), st.Size, 0);
uint8_t *sha = sha512_sum(ptr.get(), st.Size);
char hash_str[129];
for (int j = 0; j < 64; j++)
sprintf(hash_str + j * 2, "%02x", sha[j]);
hash_str[128] = '\0';
for (__SIZE_TYPE__ i = 0; i < trusted_drivers_count; i++)
{
if (strcmp(hash_str, trusted_drivers[i]) == 0)
{
kfree(sha);
return true;
}
else
{
trace("Expected \"%s\" but got \"%s\" for driver %s",
trusted_drivers[i], hash_str, File->GetName().c_str());
}
}
kfree(sha);
return false;
}
void Manager::PreloadDrivers()
{
debug("Initializing driver manager");
@ -68,7 +102,8 @@ namespace Driver
}
const char *DriverDirectory = Config.DriverDirectory;
FileNode *drvDirNode = fs->GetByPath(DriverDirectory, nullptr);
Node root = fs->GetRoot(0);
Node drvDirNode = fs->Lookup(root, DriverDirectory);
if (!drvDirNode)
{
error("Failed to open driver directory %s", DriverDirectory);
@ -76,15 +111,25 @@ namespace Driver
return;
}
foreach (const auto &drvNode in drvDirNode->Children)
for (const auto &drvNode : fs->ReadDirectory(drvDirNode))
{
debug("Checking driver %s", drvNode->Path.c_str());
if (!drvNode->IsRegularFile())
continue;
if (std::string(drvNode->Path).find(".drv") == std::string::npos)
continue;
if (Execute::GetBinaryType(drvNode->Path) != Execute::BinTypeELF)
{
error("Driver %s is not an ELF binary", drvNode->Path.c_str());
error("Driver %s is not an ELF binary", drvNode->GetPath().c_str());
continue;
}
if (!IsDriverTrusted(drvNode))
{
error("Driver %s is not trusted", drvNode->GetName().c_str());
KPrint("%s is not in the list of trusted drivers", drvNode->GetName().c_str());
continue;
}
@ -125,7 +170,7 @@ namespace Driver
return;
}
foreach (auto &var in Drivers)
for (auto &var : Drivers)
{
DriverObject &Drv = var.second;
@ -180,7 +225,7 @@ namespace Driver
void Manager::UnloadAllDrivers()
{
foreach (auto &var in Drivers)
for (auto &var : Drivers)
{
DriverObject *Drv = &var.second;
if (!Drv->Initialized)
@ -196,7 +241,7 @@ namespace Driver
if (!Drv->InterruptHandlers->empty())
{
foreach (auto &rInt in * Drv->InterruptHandlers)
for (auto &rInt : *Drv->InterruptHandlers)
{
Interrupts::RemoveHandler((void (*)(CPU::TrapFrame *))rInt.second);
}
@ -212,7 +257,7 @@ namespace Driver
if (Drivers.size() == 0)
return;
foreach (auto Driver in Drivers)
for (auto Driver : Drivers)
{
if (!Driver.second.Initialized)
continue;
@ -229,12 +274,12 @@ namespace Driver
}
}
int Manager::LoadDriverFile(DriverObject &Drv, FileNode *File)
int Manager::LoadDriverFile(DriverObject &Drv, Node File)
{
trace("Loading driver %s in memory", File->Name.c_str());
Elf_Ehdr ELFHeader{};
File->Read(&ELFHeader, sizeof(Elf_Ehdr), 0);
fs->Read(File, &ELFHeader, sizeof(Elf_Ehdr), 0);
AssertReturnError(ELFHeader.e_ident[EI_CLASS] == ELFCLASS64, -ENOEXEC);
AssertReturnError(ELFHeader.e_ident[EI_DATA] == ELFDATA2LSB, -ENOEXEC);
@ -251,7 +296,7 @@ namespace Driver
Elf_Phdr phdr{};
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
File->Read(&phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
fs->Read(File, &phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
if (phdr.p_type == PT_LOAD || phdr.p_type == PT_DYNAMIC)
{
if (segSize < phdr.p_vaddr + phdr.p_memsz)
@ -262,7 +307,7 @@ namespace Driver
if (phdr.p_type == PT_INTERP)
{
char interp[17];
File->Read(interp, sizeof(interp), phdr.p_offset);
fs->Read(File, interp, sizeof(interp), phdr.p_offset);
if (strncmp(interp, "/boot/fennix.elf", sizeof(interp)) != 0)
{
error("Interpreter is not /boot/fennix.elf");
@ -282,13 +327,13 @@ namespace Driver
Elf_Shdr shstrtab{};
Elf_Shdr shdr{};
__DriverInfo driverInfo{};
File->Read(&shstrtab, sizeof(Elf_Shdr), ELFHeader.e_shoff + (ELFHeader.e_shstrndx * ELFHeader.e_shentsize));
fs->Read(File, &shstrtab, sizeof(Elf_Shdr), ELFHeader.e_shoff + (ELFHeader.e_shstrndx * ELFHeader.e_shentsize));
for (Elf_Half i = 0; i < ELFHeader.e_shnum; i++)
{
if (i == ELFHeader.e_shstrndx)
continue;
File->Read(&shdr, ELFHeader.e_shentsize, ELFHeader.e_shoff + (i * ELFHeader.e_shentsize));
fs->Read(File, &shdr, ELFHeader.e_shentsize, ELFHeader.e_shoff + (i * ELFHeader.e_shentsize));
switch (shdr.sh_type)
{
@ -306,11 +351,11 @@ namespace Driver
}
char symName[16];
File->Read(symName, sizeof(symName), shstrtab.sh_offset + shdr.sh_name);
fs->Read(File, symName, sizeof(symName), shstrtab.sh_offset + shdr.sh_name);
if (strcmp(symName, ".driver.info") != 0)
continue;
File->Read(&driverInfo, sizeof(__DriverInfo), shdr.sh_offset);
fs->Read(File, &driverInfo, sizeof(__DriverInfo), shdr.sh_offset);
/* Perform relocations */
driverInfo.Name = (const char *)(Drv.BaseAddress + (uintptr_t)driverInfo.Name);
@ -319,17 +364,17 @@ namespace Driver
driverInfo.License = (const char *)(Drv.BaseAddress + (uintptr_t)driverInfo.License);
}
for (size_t h = 0; h < (sht_symtab.sh_size / sizeof(Elf64_Sym)); h++)
for (size_t h = 0; h < (sht_symtab.sh_size / sizeof(Elf_Sym)); h++)
{
Elf64_Sym symEntry{};
uintptr_t symOffset = sht_symtab.sh_offset + (h * sizeof(Elf64_Sym));
File->Read(&symEntry, sizeof(Elf64_Sym), symOffset);
Elf_Sym symEntry{};
uintptr_t symOffset = sht_symtab.sh_offset + (h * sizeof(Elf_Sym));
fs->Read(File, &symEntry, sizeof(Elf_Sym), symOffset);
if (symEntry.st_name == 0)
continue;
char symName[16];
File->Read(symName, sizeof(symName), sht_strtab.sh_offset + symEntry.st_name);
fs->Read(File, symName, sizeof(symName), sht_strtab.sh_offset + symEntry.st_name);
switch (symEntry.st_shndx)
{
@ -361,7 +406,7 @@ namespace Driver
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
File->Read(&phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
fs->Read(File, &phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
switch (phdr.p_type)
{
@ -377,7 +422,7 @@ namespace Driver
phdr.p_filesz, phdr.p_memsz);
if (phdr.p_filesz > 0)
File->Read(dest, phdr.p_filesz, phdr.p_offset);
fs->Read(File, (void *)dest, phdr.p_filesz, phdr.p_offset);
if (phdr.p_memsz - phdr.p_filesz > 0)
{
@ -433,10 +478,10 @@ namespace Driver
{
AssertReturnError(relaSize != nullptr, -ENOEXEC);
Elf64_Rela *rela = (Elf64_Rela *)(Drv.BaseAddress + dyn->d_un.d_ptr);
for (size_t i = 0; i < (relaSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
Elf_Rela *rela = (Elf_Rela *)(Drv.BaseAddress + dyn->d_un.d_ptr);
for (size_t i = 0; i < (relaSize->d_un.d_val / sizeof(Elf_Rela)); i++)
{
Elf64_Rela *r = &rela[i];
Elf_Rela *r = &rela[i];
uintptr_t *reloc = (uintptr_t *)(Drv.BaseAddress + r->r_offset);
uintptr_t relocTarget = 0;
@ -456,8 +501,7 @@ namespace Driver
}
default:
{
fixme("Unhandled relocation type: %#lx",
ELF64_R_TYPE(r->r_info));
fixme("Unhandled relocation type: %#lx", ELF_R_TYPE(r->r_info));
break;
}
}
@ -473,26 +517,26 @@ namespace Driver
{
AssertReturnError(pltrelSize != nullptr, -ENOEXEC);
std::vector<Elf64_Dyn> symtab = Execute::ELFGetDynamicTag_x86_64(File, DT_SYMTAB);
Elf64_Sym *symbols = (Elf64_Sym *)((uintptr_t)Drv.BaseAddress + symtab[0].d_un.d_ptr);
std::vector<Elf_Dyn> symtab = Execute::ELFGetDynamicTag(File, DT_SYMTAB);
Elf_Sym *symbols = (Elf_Sym *)((uintptr_t)Drv.BaseAddress + symtab[0].d_un.d_ptr);
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(File, DT_STRTAB);
char *DynStr = (char *)((uintptr_t)Drv.BaseAddress + StrTab[0].d_un.d_ptr);
std::vector<Elf_Dyn> StrTab = Execute::ELFGetDynamicTag(File, DT_STRTAB);
char *dynStr = (char *)((uintptr_t)Drv.BaseAddress + StrTab[0].d_un.d_ptr);
Elf64_Rela *rela = (Elf64_Rela *)(Drv.BaseAddress + dyn->d_un.d_ptr);
for (size_t i = 0; i < (pltrelSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
Elf_Rela *rela = (Elf_Rela *)(Drv.BaseAddress + dyn->d_un.d_ptr);
for (size_t i = 0; i < (pltrelSize->d_un.d_val / sizeof(Elf_Rela)); i++)
{
Elf64_Rela *r = &rela[i];
Elf_Rela *r = &rela[i];
uintptr_t *reloc = (uintptr_t *)(Drv.BaseAddress + r->r_offset);
switch (ELF64_R_TYPE(r->r_info))
switch (ELF_R_TYPE(r->r_info))
{
case R_X86_64_JUMP_SLOT:
{
Elf64_Xword symIndex = ELF64_R_SYM(r->r_info);
Elf64_Sym *sym = symbols + symIndex;
Elf_Xword symIndex = ELF_R_SYM(r->r_info);
Elf_Sym *sym = symbols + symIndex;
const char *symName = DynStr + sym->st_name;
const char *symName = dynStr + sym->st_name;
debug("Resolving symbol %s", symName);
*reloc = (uintptr_t)GetSymbolByName(symName, driverInfo.Version.APIVersion);
@ -500,8 +544,7 @@ namespace Driver
}
default:
{
fixme("Unhandled relocation type: %#lx",
ELF64_R_TYPE(r->r_info));
fixme("Unhandled relocation type: %#lx", ELF_R_TYPE(r->r_info));
break;
}
}
@ -578,7 +621,8 @@ namespace Driver
delete Drv.DeviceOperations;
/* Reload the driver */
FileNode *drvNode = fs->GetByPath(Drv.Path.c_str(), nullptr);
Node root = fs->GetRoot(0);
Node drvNode = fs->Lookup(root, Drv.Path);
if (!drvNode)
{
error("Failed to open driver file %s", Drv.Path.c_str());
@ -642,7 +686,7 @@ namespace Driver
newDrvObj.Initialized = true;
}
Manager::Manager() { this->InitializeDaemonFS(); }
Manager::Manager() { this->InitializeDeviceDirectory(); }
Manager::~Manager()
{

View File

@ -0,0 +1,256 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <driver.hpp>
#include <interface/driver.h>
#include <interface/input.h>
#include <memory.hpp>
#include <stropts.h>
#include <ints.hpp>
#include <task.hpp>
#include <printf.h>
#include <exec.hpp>
#include <rand.hpp>
#include <cwalk.h>
#include <md5.h>
#include "../../kernel.h"
using namespace vfs;
namespace Driver
{
dev_t Manager::RegisterDevice(dev_t DriverID, DeviceType Type, const InodeOperations *Operations)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
for (size_t i = 0; i < 128; i++)
{
const auto dOps = dop->find(i);
const auto dOpsEnd = dop->end();
if (dOps != dOpsEnd)
continue;
DeviceType devType = (DeviceType)(Type & DEVICE_TYPE_MASK);
switch (devType)
{
case DEVICE_TYPE_INPUT:
{
std::string prefix = "event";
for (size_t j = 0; j < 128; j++)
{
std::string deviceName = prefix + std::to_string(j);
Node node = fs->Lookup(devInputNode, deviceName);
if (node)
continue;
/* c rwx r-- r-- */
mode_t mode = S_IRWXU |
S_IRGRP |
S_IROTH |
S_IFCHR;
node = fs->Create(devInputNode, deviceName, mode);
node->inode->SetDevice(DriverID, i);
DriverHandlers dh{};
dh.Ops = Operations;
dh.Node = node->inode;
dh.InputReports = new RingBuffer<InputReport>(16);
dop->insert({i, std::move(dh)});
return i;
}
ReturnLogError(-EOVERFLOW, "No available slots for device %d", DriverID);
}
default:
ReturnLogError(-EINVAL, "Invalid device type %d", Type);
}
}
ReturnLogError(-EOVERFLOW, "No available slots for device %d", DriverID);
}
dev_t Manager::CreateDeviceFile(dev_t DriverID, const char *name, mode_t mode, const InodeOperations *Operations)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
for (size_t i = 0; i < 128; i++)
{
const auto dOps = dop->find(i);
if (dOps != dop->end())
continue;
eNode node = fs->Lookup(devNode, name);
if (node == true)
ReturnLogError(-EEXIST, "Device file %s already exists", name);
node = fs->Create(devNode, name, mode);
if (node == false)
ReturnLogError(-node.Error, "Failed to create device file %s; %s", name, node.what());
node.Value->inode->SetDevice(DriverID, i);
DriverHandlers dh{};
dh.Ops = Operations;
dh.Node = node.Value->inode;
dh.InputReports = new RingBuffer<InputReport>(16);
dop->insert({i, std::move(dh)});
return i;
}
ReturnLogError(-EOVERFLOW, "No available slots for device %d", DriverID);
}
int Manager::UnregisterDevice(dev_t DriverID, dev_t Device)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
const auto dOps = dop->find(Device);
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Device);
dop->erase(dOps);
fixme("remove eventX from /dev/input");
fixme("delete InputReports");
return 0;
}
dev_t Manager::RegisterBlockDevice(dev_t DriverID, struct BlockDevice *Device)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
std::string prefix = Device->Name;
for (size_t j = 0; j < 128; j++)
{
std::string deviceName = prefix + std::to_string(j);
Node node = fs->Lookup(devBlockNode, deviceName);
if (node)
continue;
debug("Creating \"%s\"", deviceName.c_str());
/* b rwx --- --- */
mode_t mode = S_IRWXU |
S_IFBLK;
node = fs->Create(devBlockNode, deviceName, mode);
node->inode->SetDevice(DriverID, j);
auto devNode = (Manager::DeviceInode *)node->inode;
devNode->Size = Device->Size;
devNode->BlockSize = Device->BlockSize;
devNode->Blocks = Device->BlockCount;
devNode->inode.PrivateData = Device->PrivateData;
DriverHandlers dh{};
dh.Ops = Device->Ops;
dh.Node = node->inode;
dop->insert({j, std::move(dh)});
debug("dh ops:%#lx node:%#lx %d", dh.Ops, dh.Node, j);
return j;
}
ReturnLogError(-EOVERFLOW, "No available slots for device %d", DriverID);
}
int Manager::UnregisterBlockDevice(dev_t DriverID, dev_t DeviceID)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers = DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
const auto dOps = dop->find(DeviceID);
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", DeviceID);
dop->erase(dOps);
return 0;
}
void *Manager::AllocateMemory(dev_t DriverID, size_t Pages)
{
auto itr = Drivers.find(DriverID);
assert(itr != Drivers.end());
void *ptr = itr->second.vma->RequestPages(Pages);
memset(ptr, 0, FROM_PAGES(Pages));
return ptr;
}
void Manager::FreeMemory(dev_t DriverID, void *Pointer, size_t Pages)
{
auto itr = Drivers.find(DriverID);
assert(itr != Drivers.end());
itr->second.vma->FreePages(Pointer, Pages);
}
int Manager::ReportInputEvent(dev_t DriverID, InputReport *Report)
{
std::unordered_map<dev_t, Driver::DriverObject> &drivers =
DriverManager->GetDrivers();
const auto it = drivers.find(DriverID);
if (it == drivers.end())
ReturnLogError(-EINVAL, "Driver %d not found", DriverID);
const Driver::DriverObject *drv = &it->second;
auto dop = drv->DeviceOperations;
auto dOps = dop->find(Report->Device);
if (dOps == dop->end())
ReturnLogError(-EINVAL, "Device %d not found", Report->Device);
dOps->second.InputReports->Write(Report, 1);
switch (Report->Type)
{
case INPUT_TYPE_KEYBOARD:
{
KeyboardReport *kReport = &Report->Keyboard;
GlobalKeyboardInputReports.Write(kReport, 1);
break;
}
case INPUT_TYPE_MOUSE:
{
MouseReport *mReport = &Report->Mouse;
GlobalMouseInputReports.Write(mReport, 1);
break;
}
default:
assert(!"Invalid input type");
}
return 0;
}
}

View File

@ -331,6 +331,80 @@ namespace Driver
: ScanCodeConversionTableLower[ScanCode];
}
char GetControlCharacter(KeyScanCodes ScanCode)
{
ScanCode = static_cast<KeyScanCodes>(static_cast<int>(ScanCode) & 0x7F); /* Remove KEY_PRESSED bit */
switch (ScanCode)
{
case KEY_2:
return 0x00; /* Ctrl-@ (NUL) */
case KEY_A:
return 0x01; /* Ctrl-A (SOH) */
case KEY_B:
return 0x02; /* Ctrl-B (STX) */
case KEY_C:
return 0x03; /* Ctrl-C (ETX) */
case KEY_D:
return 0x04; /* Ctrl-D (EOT) */
case KEY_E:
return 0x05; /* Ctrl-E (ENQ) */
case KEY_F:
return 0x06; /* Ctrl-F (ACK) */
case KEY_G:
return 0x07; /* Ctrl-G (BEL) */
case KEY_H:
return 0x08; /* Ctrl-H (BS) */
case KEY_I:
return 0x09; /* Ctrl-I (HT) */
case KEY_J:
return 0x0A; /* Ctrl-J (LF) */
case KEY_K:
return 0x0B; /* Ctrl-K (VT) */
case KEY_L:
return 0x0C; /* Ctrl-L (FF) */
case KEY_M:
return 0x0D; /* Ctrl-M (CR) */
case KEY_N:
return 0x0E; /* Ctrl-N (SO) */
case KEY_O:
return 0x0F; /* Ctrl-O (SI) */
case KEY_P:
return 0x10; /* Ctrl-P (DLE) */
case KEY_Q:
return 0x11; /* Ctrl-Q (DC1) */
case KEY_R:
return 0x12; /* Ctrl-R (DC2) */
case KEY_S:
return 0x13; /* Ctrl-S (DC3) */
case KEY_T:
return 0x14; /* Ctrl-T (DC4) */
case KEY_U:
return 0x15; /* Ctrl-U (NAK) */
case KEY_V:
return 0x16; /* Ctrl-V (SYN) */
case KEY_W:
return 0x17; /* Ctrl-W (ETB) */
case KEY_X:
return 0x18; /* Ctrl-X (CAN) */
case KEY_Y:
return 0x19; /* Ctrl-Y (EM) */
case KEY_Z:
return 0x1A; /* Ctrl-Z (SUB) */
case KEY_LEFT_BRACKET:
return 0x1B; /* Ctrl-[ (ESC) */
case KEY_BACKSLASH:
return 0x1C; /* Ctrl-\ (FS) */
case KEY_RIGHT_BRACKET:
return 0x1D; /* Ctrl-] (GS) */
case KEY_6:
return 0x1E; /* Ctrl-^ (RS) */
case KEY_MINUS:
return 0x1F; /* Ctrl-_ (US) */
default:
return 0x00; /* Not a control character */
}
}
bool IsValidChar(uint8_t ScanCode)
{
ScanCode &= 0x7F; /* Remove KEY_PRESSED bit */

View File

@ -191,7 +191,7 @@ namespace Interrupts
void *ctx, bool Critical)
{
/* Just log a warning if the interrupt is already registered. */
foreach (auto ev in RegisteredEvents)
for (auto ev : RegisteredEvents)
{
if (ev.IRQ == InterruptNumber &&
ev.Callback == Callback)
@ -264,7 +264,7 @@ namespace Interrupts
warn("IRQ%d not found.", InterruptNumber);
}
nsa inline void ReturnFromInterrupt()
nsa hot inline void ReturnFromInterrupt()
{
#if defined(__amd64__) || defined(__i386__)
CPUData *CoreData = GetCurrentCPU();
@ -279,7 +279,7 @@ namespace Interrupts
{ return a.Priority < b.Priority; });
#ifdef DEBUG
foreach (auto ev in RegisteredEvents)
for (auto ev : RegisteredEvents)
{
void *fct = ev.IsHandler
? ev.Data
@ -309,7 +309,7 @@ namespace Interrupts
CPU::Stop();
}
extern "C" nsa void MainInterruptHandler(void *Data)
extern "C" nsa hot void MainInterruptHandler(void *Data)
{
class AutoSwitchPageTable
{
@ -384,7 +384,7 @@ namespace Interrupts
#endif
}
extern "C" nsa void SchedulerInterruptHandler(void *Data)
extern "C" nsa hot void SchedulerInterruptHandler(void *Data)
{
#if defined(__amd64__) || defined(__i386__)
KernelPageTable->Update();
@ -421,13 +421,12 @@ namespace Interrupts
Handler::Handler(int InterruptNumber, bool Critical)
{
foreach (auto ev in RegisteredEvents)
for (auto ev : RegisteredEvents)
{
if (ev.IRQ == InterruptNumber)
{
warn("IRQ%d is already registered.",
InterruptNumber);
}
if (ev.IRQ != InterruptNumber)
continue;
warn("IRQ%d is already registered.", InterruptNumber);
}
this->InterruptNumber = InterruptNumber;
@ -441,15 +440,12 @@ namespace Interrupts
0, /* Priority */
Critical}; /* Critical */
RegisteredEvents.push_back(newEvent);
debug("Registered interrupt handler for IRQ%d.",
InterruptNumber);
debug("Registered interrupt handler for IRQ%d.", InterruptNumber);
}
Handler::Handler(PCI::PCIDevice Device, bool Critical)
: Handler(((PCI::PCIHeader0 *)Device.Header)->InterruptLine, Critical)
{
PCI::PCIHeader0 *hdr0 =
(PCI::PCIHeader0 *)Device.Header;
Handler(hdr0->InterruptLine, Critical);
}
Handler::Handler()
@ -459,17 +455,15 @@ namespace Interrupts
Handler::~Handler()
{
debug("Unregistering interrupt handler for IRQ%d.",
this->InterruptNumber);
debug("Unregistering interrupt handler for IRQ%d.", this->InterruptNumber);
forItr(itr, RegisteredEvents)
{
if (itr->IRQ == this->InterruptNumber)
{
if (itr->IRQ != this->InterruptNumber)
continue;
RegisteredEvents.erase(itr);
return;
}
}
warn("Event %d not found.", this->InterruptNumber);
}

View File

@ -195,7 +195,7 @@ void LockClass::TimeoutDeadLock(SpinLockData &Lock, uint64_t Timeout)
if (CoreData != nullptr)
CCore = CoreData->ID;
uint64_t Counter = TimeManager->GetCounter();
uint64_t Counter = TimeManager->GetTimeNs();
warn("Potential deadlock in lock '%s' held by '%s'! %ld %s in queue. Interrupts are %s. Core %ld held by %ld. Timeout in %ld (%ld ticks remaining).",
Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count, Lock.Count > 1 ? "locks" : "lock",
@ -235,8 +235,7 @@ Retry:
if (i >= DEADLOCK_TIMEOUT)
{
if (Target.load() == 0)
Target.store(TimeManager->CalculateTarget(Timeout,
Time::Units::Milliseconds));
Target.store(TimeManager->GetTimeNs() + Timeout);
TimeoutDeadLock(LockData, Target.load());
goto Retry;
}

View File

@ -28,8 +28,7 @@
namespace Memory
{
__no_sanitize("alignment") void Physical::FindBitmapRegion(uintptr_t &BitmapAddress,
size_t &BitmapAddressSize)
__no_sanitize("alignment") void Physical::FindBitmapRegion(uintptr_t &BitmapAddress, size_t &BitmapAddressSize)
{
size_t BitmapSize = (size_t)(bInfo.Memory.Size / PAGE_SIZE) / 8 + 1;
@ -47,24 +46,19 @@ namespace Memory
uintptr_t RSDPStart = 0x0;
uintptr_t RSDPEnd = 0x0;
if (bInfo.Kernel.Symbols.Num &&
bInfo.Kernel.Symbols.EntSize &&
bInfo.Kernel.Symbols.Shndx)
if (bInfo.Kernel.Symbols.Num && bInfo.Kernel.Symbols.EntSize && bInfo.Kernel.Symbols.Shndx)
{
char *sections = r_cst(char *, bInfo.Kernel.Symbols.Sections);
SectionsStart = (uintptr_t)sections;
SectionsEnd = (uintptr_t)sections + bInfo.Kernel.Symbols.EntSize *
bInfo.Kernel.Symbols.Num;
SectionsEnd = (uintptr_t)sections + bInfo.Kernel.Symbols.EntSize * bInfo.Kernel.Symbols.Num;
for (size_t i = 0; i < bInfo.Kernel.Symbols.Num; ++i)
{
Elf_Shdr *sym = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * i];
Elf_Shdr *str = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize *
sym->sh_link];
Elf_Shdr *str = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * sym->sh_link];
if (sym->sh_type == SHT_SYMTAB &&
str->sh_type == SHT_STRTAB)
if (sym->sh_type == SHT_SYMTAB && str->sh_type == SHT_STRTAB)
{
Symbols = (uintptr_t)sym->sh_addr;
StringAddress = (uintptr_t)str->sh_addr;
@ -95,8 +89,7 @@ namespace Memory
if (Memory::Virtual().Check(ACPIPtr))
{
size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) /
(XSDT ? 8 : 4));
size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / (XSDT ? 8 : 4));
debug("There are %d ACPI tables", TableSize);
}
#endif
@ -131,6 +124,7 @@ namespace Memory
{
uintptr_t Start;
uintptr_t End;
char Description[16];
};
auto SortAddresses = [](AddrRange *Array, size_t n)
@ -151,62 +145,58 @@ namespace Memory
AddrRange PtrArray[] =
{
{KernelStart,
KernelEnd},
{SectionsStart,
SectionsEnd},
{Symbols,
Symbols + SymbolSize},
{StringAddress,
StringAddress + StringSize},
{RSDPStart,
RSDPEnd},
{(uintptr_t)bInfo.Kernel.FileBase,
(uintptr_t)bInfo.Kernel.FileBase + bInfo.Kernel.Size},
{(uintptr_t)bInfo.Modules[0].Address,
(uintptr_t)bInfo.Modules[0].Address + bInfo.Modules[0].Size},
{(uintptr_t)bInfo.Modules[1].Address,
(uintptr_t)bInfo.Modules[1].Address + bInfo.Modules[1].Size},
{(uintptr_t)bInfo.Modules[2].Address,
(uintptr_t)bInfo.Modules[2].Address + bInfo.Modules[2].Size},
{(uintptr_t)bInfo.Modules[3].Address,
(uintptr_t)bInfo.Modules[3].Address + bInfo.Modules[3].Size},
{KernelStart, KernelEnd, "kernel"},
{SectionsStart, SectionsEnd, "sections"},
{Symbols, Symbols + SymbolSize, "symbols"},
{StringAddress, StringAddress + StringSize, "string"},
{RSDPStart, RSDPEnd, "rsdp"},
{(uintptr_t)bInfo.Kernel.FileBase, (uintptr_t)bInfo.Kernel.FileBase + bInfo.Kernel.Size, "file"},
{(uintptr_t)bInfo.Modules[0].Address, (uintptr_t)bInfo.Modules[0].Address + bInfo.Modules[0].Size, "module 0"},
{(uintptr_t)bInfo.Modules[1].Address, (uintptr_t)bInfo.Modules[1].Address + bInfo.Modules[1].Size, "module 1"},
{(uintptr_t)bInfo.Modules[2].Address, (uintptr_t)bInfo.Modules[2].Address + bInfo.Modules[2].Size, "module 2"},
{(uintptr_t)bInfo.Modules[3].Address, (uintptr_t)bInfo.Modules[3].Address + bInfo.Modules[3].Size, "module 3"},
/* MAX_MODULES == 4 */
};
SortAddresses(PtrArray, sizeof(PtrArray) / sizeof(PtrArray[0]));
uintptr_t MaxEnd = RegionAddress;
for (size_t i = 0; i < sizeof(PtrArray) / sizeof(PtrArray[0]); i++)
{
if (PtrArray[i].Start == 0x0)
{
debug("skipping %#lx %zu %s", PtrArray[i].Start, i, PtrArray[i].Description);
continue;
}
uintptr_t Start = PtrArray[i].Start;
uintptr_t End = PtrArray[i].End;
debug("%#lx - %#lx", Start, End);
debug("[%s] %#lx - %#lx", PtrArray[i].Description, Start, End);
if (RegionAddress >= Start &&
End <= (RegionAddress + RegionSize))
if ((Start < (RegionAddress + RegionSize)) && (End > RegionAddress))
{
BitmapAddress = End;
BitmapAddressSize = RegionSize - (End - RegionAddress);
if (End > MaxEnd)
MaxEnd = End;
}
}
if (MaxEnd >= RegionAddress && MaxEnd < (RegionAddress + RegionSize))
{
BitmapAddress = MaxEnd;
BitmapAddressSize = RegionAddress + RegionSize - MaxEnd;
debug("BitmapAddress = %#lx; Size = %zu", BitmapAddress, BitmapAddressSize);
if ((BitmapSize + 0x100) > BitmapAddressSize)
{
debug("Region %p-%p (%d MiB) is too small for bitmap.",
(void *)BitmapAddress,
(void *)(BitmapAddress + BitmapAddressSize),
TO_MiB(BitmapAddressSize));
debug("Region %#lx-%#lx (%d MiB) is too small for bitmap.", BitmapAddress, BitmapAddress + BitmapAddressSize, TO_MiB(BitmapAddressSize));
continue;
}
debug("Found free memory for bitmap: %p (%d MiB)",
(void *)BitmapAddress,
TO_MiB(BitmapAddressSize));
debug("Found free memory for bitmap: %#lx (%d MiB)", BitmapAddress, TO_MiB(BitmapAddressSize));
break;
}
}
}
}
}

View File

@ -52,7 +52,7 @@ Xalloc::V1 *XallocV1Allocator = nullptr;
Xalloc::V2 *XallocV2Allocator = nullptr;
#ifdef DEBUG
NIF void tracepagetable(PageTable *pt)
nif void tracepagetable(PageTable *pt)
{
for (int i = 0; i < 512; i++)
{
@ -71,7 +71,7 @@ NIF void tracepagetable(PageTable *pt)
}
#endif
NIF void MapEntries(PageTable *PT)
nif void MapEntries(PageTable *PT)
{
debug("mapping %d memory entries", bInfo.Memory.Entries);
Virtual vmm = Virtual(PT);
@ -89,7 +89,7 @@ NIF void MapEntries(PageTable *PT)
vmm.Unmap((void *)0);
}
NIF void MapFramebuffer(PageTable *PT)
nif void MapFramebuffer(PageTable *PT)
{
debug("Mapping Framebuffer");
Virtual vmm = Virtual(PT);
@ -123,7 +123,7 @@ NIF void MapFramebuffer(PageTable *PT)
}
}
NIF void MapKernel(PageTable *PT)
nif void MapKernel(PageTable *PT)
{
debug("Mapping Kernel");
@ -237,7 +237,7 @@ NIF void MapKernel(PageTable *PT)
info("Cannot determine kernel file address. Ignoring.");
}
NIF void CreatePageTable(PageTable *pt)
nif void CreatePageTable(PageTable *pt)
{
static int check_cpuid = 0;
@ -286,7 +286,7 @@ NIF void CreatePageTable(PageTable *pt)
#endif
}
NIF void InitializeMemoryManagement()
nif void InitializeMemoryManagement()
{
#ifdef DEBUG
#ifndef __i386__
@ -340,7 +340,7 @@ NIF void InitializeMemoryManagement()
KernelAllocator.Init();
debug("Memory Info:\n\n%lld MiB / %lld MiB (%lld MiB reserved)\n",
TO_MiB(KernelAllocator.GetUsedMemory()),
TO_MiB(KernelAllocator.GetTotalMemory()),
TO_MiB(KernelAllocator.GetTotalMemory() - KernelAllocator.GetReservedMemory()),
TO_MiB(KernelAllocator.GetReservedMemory()));
/* -- Debugging --
@ -361,8 +361,7 @@ NIF void InitializeMemoryManagement()
CreatePageTable(KernelPageTable);
trace("Applying new page table from address %#lx",
KernelPageTable);
trace("Applying new page table from address %#lx", KernelPageTable);
CPU::PageTable(KernelPageTable);
debug("Page table updated.");

View File

@ -1,6 +1,6 @@
#include <memory.hpp>
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <signal.hpp>
#include <utsname.h>
#include <time.h>

View File

@ -264,7 +264,7 @@ namespace Memory
uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == true))
return;
continue;
if (PageBitmap.Set(Index, true))
{
@ -322,8 +322,7 @@ namespace Memory
SmartLock(this->MemoryLock);
uint64_t MemorySize = bInfo.Memory.Size;
debug("Memory size: %lld bytes (%ld pages)",
MemorySize, TO_PAGES(MemorySize));
debug("Memory size: %lld bytes (%ld pages)", MemorySize, TO_PAGES(MemorySize));
TotalMemory.store(MemorySize);
FreeMemory.store(MemorySize);
@ -338,16 +337,10 @@ namespace Memory
CPU::Stop();
}
debug("Initializing Bitmap at %p-%p (%d Bytes)",
BitmapAddress,
(void *)(BitmapAddress + BitmapSize),
BitmapSize);
debug("Initializing Bitmap at %#lx-%#lx (%zu Bytes)", BitmapAddress, BitmapAddress + BitmapSize, BitmapSize);
PageBitmap.Size = BitmapSize;
PageBitmap.Buffer = (uint8_t *)BitmapAddress;
for (size_t i = 0; i < BitmapSize; i++)
*(uint8_t *)(PageBitmap.Buffer + i) = 0;
memset((void *)BitmapAddress, 0, BitmapSize);
ReserveEssentials();
}

View File

@ -80,12 +80,9 @@ namespace Memory
{
char *sections = r_cst(char *, bInfo.Kernel.Symbols.Sections);
debug("Reserving sections region %#lx-%#lx...",
sections,
(void *)((uintptr_t)sections + bInfo.Kernel.Symbols.EntSize *
bInfo.Kernel.Symbols.Num));
sections, (uintptr_t)sections + bInfo.Kernel.Symbols.EntSize * bInfo.Kernel.Symbols.Num);
this->ReservePages(sections, TO_PAGES(bInfo.Kernel.Symbols.EntSize *
bInfo.Kernel.Symbols.Num));
this->ReservePages(sections, TO_PAGES(bInfo.Kernel.Symbols.EntSize * bInfo.Kernel.Symbols.Num));
Elf_Sym *Symbols = nullptr;
uint8_t *StringAddress = nullptr;
@ -101,11 +98,9 @@ namespace Memory
for (size_t i = 0; i < bInfo.Kernel.Symbols.Num; ++i)
{
Elf_Shdr *sym = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * i];
Elf_Shdr *str = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize *
sym->sh_link];
Elf_Shdr *str = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * sym->sh_link];
if (sym->sh_type == SHT_SYMTAB &&
str->sh_type == SHT_STRTAB)
if (sym->sh_type == SHT_SYMTAB && str->sh_type == SHT_STRTAB)
{
Symbols = (Elf_Sym *)sym->sh_addr;
StringAddress = (uint8_t *)str->sh_addr;
@ -145,8 +140,7 @@ namespace Memory
bInfo.Modules[i].Address,
(void *)((uintptr_t)bInfo.Modules[i].Address + bInfo.Modules[i].Size));
this->ReservePages((void *)bInfo.Modules[i].Address,
TO_PAGES(bInfo.Modules[i].Size));
this->ReservePages((void *)bInfo.Modules[i].Address, TO_PAGES(bInfo.Modules[i].Size));
}
#if defined(__amd64__) || defined(__i386__)
@ -200,6 +194,15 @@ namespace Memory
#pragma GCC diagnostic pop
this->ReservePages(SDTHdr, TO_PAGES(SDTHdr->Length));
}
if (bInfo.EFI.Info.Enabled)
{
debug("Reserving EFI related...");
if (bInfo.EFI.Info.IH)
this->ReservePage(bInfo.EFI.ImageHandle);
if (bInfo.EFI.Info.ST)
this->ReservePage(bInfo.EFI.SystemTable);
}
}
#elif defined(__aarch64__)
#endif

View File

@ -79,7 +79,7 @@ namespace Memory
this->Expanded = Parent->Expanded;
std::list<AllocatedPages> ParentAllocatedPages = Parent->GetAllocatedPages();
foreach (auto Page in ParentAllocatedPages)
for (auto Page : ParentAllocatedPages)
{
void *NewPhysical = vma->RequestPages(1);
debug("Forking address %#lx to %#lx", Page.PhysicalAddress, NewPhysical);

View File

@ -82,7 +82,7 @@ namespace Memory
func("%#lx, %lld", Address, Count);
SmartLock(MgrLock);
foreach (auto &apl in AllocatedPagesList)
for (auto &apl : AllocatedPagesList)
{
if (apl.VirtualAddress != Address)
continue;
@ -128,7 +128,7 @@ namespace Memory
/* No need to remap pages, the page table will be destroyed */
Virtual vmm(this->Table);
foreach (auto ap in AllocatedPagesList)
for (auto ap : AllocatedPagesList)
{
KernelAllocator.FreePages(ap.PhysicalAddress, ap.PageCount);

View File

@ -29,7 +29,7 @@ namespace Memory
{
SmartLock(MgrLock);
uint64_t Size = 0;
foreach (auto ap in AllocatedPagesList)
for (auto ap : AllocatedPagesList)
Size += ap.PageCount;
return FROM_PAGES(Size);
}
@ -214,7 +214,7 @@ namespace Memory
return false;
}
foreach (auto sr in SharedRegions)
for (auto sr : SharedRegions)
{
uintptr_t Start = (uintptr_t)sr.Address;
uintptr_t End = (uintptr_t)sr.Address + sr.Length;
@ -263,7 +263,7 @@ namespace Memory
void VirtualMemoryArea::FreeAllPages()
{
SmartLock(MgrLock);
foreach (auto ap in AllocatedPagesList)
for (auto ap : AllocatedPagesList)
{
KernelAllocator.FreePages(ap.Address, ap.PageCount);
Virtual vmm(this->Table);
@ -287,7 +287,7 @@ namespace Memory
Virtual vmm(this->Table);
SmartLock(MgrLock);
foreach (auto &ap in Parent->AllocatedPagesList)
for (auto &ap : Parent->AllocatedPagesList)
{
if (ap.Protected)
{
@ -339,7 +339,7 @@ namespace Memory
(uintptr_t)ap.Address + (ap.PageCount * PAGE_SIZE));
}
foreach (auto &sr in Parent->SharedRegions)
for (auto &sr : Parent->SharedRegions)
{
MgrLock.Unlock();
void *Address = this->CreateCoWRegion(sr.Address, sr.Length,
@ -496,7 +496,7 @@ namespace Memory
/* No need to remap pages, the page table will be destroyed */
SmartLock(MgrLock);
foreach (auto ap in AllocatedPagesList)
for (auto ap : AllocatedPagesList)
KernelAllocator.FreePages(ap.Address, ap.PageCount);
}
}

View File

@ -64,7 +64,7 @@ struct DiagnosticFile
} Data;
};
nsa bool WriteDiagDataToNode(FileNode *node)
nsa bool WriteDiagDataToNode(Node node)
{
uintptr_t KStart = (uintptr_t)&_kernel_start;
uintptr_t kEnd = (uintptr_t)&_kernel_end;
@ -89,7 +89,7 @@ nsa bool WriteDiagDataToNode(FileNode *node)
memcpy(file->Data.KernelMemory, (void *)KStart, kSize);
ExPrint("Writing to %s\n", node->Path.c_str());
size_t w = node->Write(buf, fileSize, 0);
size_t w = fs->Write(node, buf, fileSize, 0);
if (w != fileSize)
{
debug("%d out of %d bytes written", w, fileSize);
@ -115,22 +115,23 @@ nsa void DiagnosticDataCollection()
S_IROTH |
S_IFDIR;
FileNode *panicDir = fs->ForceCreate(nullptr, "/var/panic", mode);
Node root = fs->GetRoot(0);
Node panicDir = fs->Create(root, "/sys/log/panic", mode);
if (!panicDir)
{
ExPrint("\x1b[0;30;41mFailed to create /var/panic\x1b[0m\n");
ExPrint("\x1b[0;30;41mFailed to create /sys/log/panic\x1b[0m\n");
Display->UpdateBuffer();
return;
}
FileNode *dumpFile;
Node dumpFile;
Time::Clock clock = Time::ReadClock();
char filename[64];
for (int i = 0; i < INT32_MAX; i++)
{
sprintf(filename, "dump-%d-%d-%d-%d.dmp",
clock.Year, clock.Month, clock.Day, i);
if (fs->PathExists(filename, panicDir))
if (fs->Lookup(panicDir, filename))
continue;
mode = S_IRWXU |
@ -145,6 +146,6 @@ nsa void DiagnosticDataCollection()
if (!WriteDiagDataToNode(dumpFile))
return;
ExPrint("You can find the diagnostic file in /var/panic/%s\n", filename);
ExPrint("You can find the diagnostic file in /sys/log/panic/%s\n", filename);
Display->UpdateBuffer();
}

View File

@ -52,7 +52,7 @@ void *FbBeforePanic = nullptr;
size_t FbPagesBeforePanic = 0;
FontRenderer CrashFontRenderer;
int ExTermColors[] = {
static int ExTermColors[] = {
[TerminalColor::BLACK] = 0x000000,
[TerminalColor::RED] = 0xAA0000,
[TerminalColor::GREEN] = 0x00AA00,
@ -63,7 +63,7 @@ int ExTermColors[] = {
[TerminalColor::GREY] = 0xAAAAAA,
};
int ExTermBrightColors[] = {
static int ExTermBrightColors[] = {
[TerminalColor::BLACK] = 0x858585,
[TerminalColor::RED] = 0xFF5555,
[TerminalColor::GREEN] = 0x55FF55,
@ -84,7 +84,7 @@ void paint_callback(TerminalCell *cell, long x, long y)
nsa void __printfWrapper(char c, void *)
{
KernelConsole::Terminals[15]->Process(c);
KernelConsole::Terminals[15]->Term->Process(c);
}
nsa void ExPrint(const char *Format, ...)
@ -162,7 +162,8 @@ nsa void InitFont()
{
size_t Cols = Display->GetWidth / CrashFontRenderer.CurrentFont->GetInfo().Width;
size_t Rows = Display->GetHeight / CrashFontRenderer.CurrentFont->GetInfo().Height;
Terminals[15] = new VirtualTerminal(Cols, Rows, Display->GetWidth, Display->GetHeight, paint_callback, nullptr);
Terminals[15] = new ConsoleTerminal;
Terminals[15]->Term = new VirtualTerminal(Cols, Rows, Display->GetWidth, Display->GetHeight, paint_callback, nullptr);
}
}
@ -372,7 +373,8 @@ nsa void BaseBufferStackError(bool Stack)
{
size_t Cols = Display->GetWidth / CrashFontRenderer.CurrentFont->GetInfo().Width;
size_t Rows = Display->GetHeight / CrashFontRenderer.CurrentFont->GetInfo().Height;
Terminals[15] = new VirtualTerminal(Cols, Rows, Display->GetWidth, Display->GetHeight, paint_callback, nullptr);
Terminals[15] = new ConsoleTerminal;
Terminals[15]->Term = new VirtualTerminal(Cols, Rows, Display->GetWidth, Display->GetHeight, paint_callback, nullptr);
}
ExceptionLock.store(true, std::memory_order_release);
@ -406,8 +408,7 @@ nsa __noreturn void HandleBufferOverflow()
CPU::Stop();
}
EXTERNC nsa __noreturn void HandleAssertionFailed(const char *File, int Line,
const char *Expression)
EXTERNC nsa __noreturn void HandleAssertionFailed(const char *File, int Line, const char *Expression)
{
DisplayAssertionFailed(File, Line, Expression);
CPU::Stop();

View File

@ -58,7 +58,7 @@ nsa bool CrashXHCIKeyboardDriver::TakeOwnership()
return true;
exCap->USBLEGSUP.OSOwnsHC = 1;
TimeManager->Sleep(200, Time::Milliseconds);
TimeManager->Sleep(Time::FromMilliseconds(200));
if (exCap->USBLEGSUP.BIOSOwnsHC == 0)
return true;

View File

@ -489,12 +489,12 @@ nsa void DisplayProcessScreen(CPU::ExceptionFrame *Frame, bool IgnoreReady = tru
bool pRdy = false;
bool showNote = false;
/* FIXME: This is slow */
foreach (auto Process in Plist)
for (auto Process : Plist)
{
bool ignore = true;
if (Process->State == Tasking::Ready && IgnoreReady)
{
foreach (auto Thread in Process->Threads)
for (auto Thread : Process->Threads)
{
if (Thread->State == Tasking::Ready)
continue;
@ -522,7 +522,7 @@ nsa void DisplayProcessScreen(CPU::ExceptionFrame *Frame, bool IgnoreReady = tru
: "none");
bool tRdy = false;
foreach (auto Thread in Process->Threads)
for (auto Thread : Process->Threads)
{
if (Thread->State == Tasking::Ready && IgnoreReady)
{
@ -571,6 +571,7 @@ nsa void DisplayCrashScreen(CPU::ExceptionFrame *Frame)
DisplayTopOverlay();
DisplayMainScreen(Frame);
DisplayStackScreen(Frame);
InitializeKeyboards();
DisplayBottomOverlay();

View File

@ -897,8 +897,7 @@ namespace PCI
BAR[4] = hdr0->BAR4;
BAR[5] = hdr0->BAR5;
debug("Type: %d; IOBase: %#lx; MemoryBase: %#lx",
BAR[0] & 1, BAR[1] & (~3), BAR[0] & (~15));
debug("Type: %d; IOBase: %#lx; MemoryBase: %#lx", BAR[0] & 1, BAR[1] & (~3), BAR[0] & (~15));
/* BARs Size */
for (short i = 0; i < 6; i++)
@ -927,7 +926,7 @@ namespace PCI
size = size & UINT32_MAX;
if (size == 0)
{
warn("BAR%d size is zero! Device: %#x:%#x", i, Device.Header->VendorID, Device.Header->DeviceID);
warn("MEM BAR%d size is zero! Device: %#x:%#x", i, Device.Header->VendorID, Device.Header->DeviceID);
size++;
}
BARsSize[i] = size;
@ -943,7 +942,7 @@ namespace PCI
size = size & UINT16_MAX;
if (size == 0)
{
warn("BAR%d size is zero! Device: %#x:%#x", i, Device.Header->VendorID, Device.Header->DeviceID);
warn("I/O BAR%d size is zero! Device: %#x:%#x", i, Device.Header->VendorID, Device.Header->DeviceID);
size++;
}
BARsSize[i] = size;
@ -972,10 +971,7 @@ namespace PCI
uintptr_t BARBase = BAR[i] & (~3);
size_t BARSize = BARsSize[i];
debug("Mapping BAR%d %#x-%#x", i, BARBase, BARBase + BARSize);
Memory::Virtual(Table).Map((void *)BARBase, (void *)BARBase,
BARSize, Memory::RW | Memory::PWT | Memory::PCD);
debug("no need to map BAR%d %#x-%#x as it's an I/O space", i, BARBase, BARBase + BARSize);
}
}
break;
@ -1079,7 +1075,7 @@ namespace PCI
std::list<PCIDevice> Manager::FindPCIDevice(uint8_t Class, uint8_t Subclass, uint8_t ProgIF)
{
std::list<PCIDevice> DeviceFound;
foreach (auto dev in Devices)
for (auto dev : Devices)
{
if (dev.Header->Class == Class &&
dev.Header->Subclass == Subclass &&
@ -1094,7 +1090,7 @@ namespace PCI
std::list<PCIDevice> Manager::FindPCIDevice(uint16_t VendorID, uint16_t DeviceID)
{
std::list<PCIDevice> DeviceFound;
foreach (auto dev in Devices)
for (auto dev : Devices)
{
if (dev.Header->VendorID == VendorID &&
dev.Header->DeviceID == DeviceID)
@ -1109,11 +1105,11 @@ namespace PCI
std::list<uint16_t> DeviceIDs)
{
std::list<PCIDevice> DeviceFound;
foreach (auto dev in Devices)
for (auto dev : Devices)
{
foreach (auto VendorID in VendorIDs)
for (auto VendorID : VendorIDs)
{
foreach (auto DeviceID in DeviceIDs)
for (auto DeviceID : DeviceIDs)
{
if (dev.Header->VendorID == VendorID &&
dev.Header->DeviceID == DeviceID)

View File

@ -67,8 +67,7 @@ namespace Random
if (RDRANDFlag)
{
uint16_t RDRANDValue = 0;
asmv("1: rdrand %0; jnc 1b"
: "=r"(RDRANDValue));
asmv("1: rdrand %0; jnc 1b" : "=r"(RDRANDValue));
return RDRANDValue;
}
@ -84,8 +83,7 @@ namespace Random
if (RDRANDFlag)
{
uint32_t RDRANDValue = 0;
asmv("1: rdrand %0; jnc 1b"
: "=r"(RDRANDValue));
asmv("1: rdrand %0; jnc 1b" : "=r"(RDRANDValue));
return RDRANDValue;
}
@ -101,8 +99,7 @@ namespace Random
if (RDRANDFlag)
{
uintptr_t RDRANDValue = 0;
asmv("1: rdrand %0; jnc 1b"
: "=r"(RDRANDValue));
asmv("1: rdrand %0; jnc 1b" : "=r"(RDRANDValue));
return RDRANDValue;
}

View File

@ -18,6 +18,7 @@
#include <symbols.hpp>
#include <memory.hpp>
#include <convert.h>
#include <algorithm>
#include <debug.h>
#include <elf.h>
@ -25,7 +26,7 @@
namespace SymbolResolver
{
const NIF char *Symbols::GetSymbol(uintptr_t Address)
const nif char *Symbols::GetSymbol(uintptr_t Address)
{
SymbolTable Result{};
@ -115,8 +116,7 @@ namespace SymbolResolver
Elf_Shdr *sym = (Elf_Shdr *)&sections[EntSize * i];
Elf_Shdr *str = (Elf_Shdr *)&sections[EntSize * sym->sh_link];
if (sym->sh_type == SHT_SYMTAB &&
str->sh_type == SHT_STRTAB)
if (sym->sh_type == SHT_SYMTAB && str->sh_type == SHT_STRTAB)
{
Symbols = (Elf_Sym *)sym->sh_addr;
StringAddress = (uint8_t *)str->sh_addr;
@ -124,26 +124,15 @@ namespace SymbolResolver
// StringSize = (int)str->sh_size;
// TotalEntries = Section.sh_size / sizeof(Elf64_Sym)
TotalEntries = sym->sh_size / sym->sh_entsize;
trace("Symbol table found, %d entries",
SymbolSize / sym->sh_entsize);
UNUSED(SymbolSize);
trace("Symbol table found, %d entries", SymbolSize / sym->sh_entsize);
break;
}
}
if (Symbols != nullptr && StringAddress != nullptr)
{
size_t Index, MinimumIndex;
for (size_t i = 0; i < TotalEntries - 1; i++)
{
MinimumIndex = i;
for (Index = i + 1; Index < TotalEntries; Index++)
if (Symbols[Index].st_value < Symbols[MinimumIndex].st_value)
MinimumIndex = Index;
Elf_Sym tmp = Symbols[MinimumIndex];
Symbols[MinimumIndex] = Symbols[i];
Symbols[i] = tmp;
}
std::sort(Symbols, Symbols + TotalEntries, [](const Elf_Sym &a, const Elf_Sym &b)
{ return a.st_value < b.st_value; });
while (Symbols[0].st_value == 0)
{
@ -159,8 +148,7 @@ namespace SymbolResolver
return;
}
trace("Symbol table loaded, %d entries (%ld KiB)",
TotalEntries, TO_KiB(TotalEntries * sizeof(SymbolTable)));
trace("Symbol table loaded, %d entries (%ld KiB)", TotalEntries, TO_KiB(TotalEntries * sizeof(SymbolTable)));
Elf_Sym *sym;
const char *name;
Memory::Virtual vmm;
@ -178,6 +166,12 @@ namespace SymbolResolver
continue;
}
if (unlikely(sym->st_name == (Elf_Word)-1 || sym->st_value == (Elf_Addr)-1 || sym->st_size == (uintptr_t)-1))
{
error("Symbol %d is invalid; ptr:%#lx", i, sym);
continue;
}
name = (const char *)&StringAddress[Symbols[i].st_name];
if (!vmm.Check((void *)name))
{
@ -191,17 +185,13 @@ namespace SymbolResolver
if (strlen(name) == 0)
continue;
SymbolTable tbl{};
SymbolTable tbl;
tbl.Address = sym->st_value;
tbl.FunctionName = new char[strlen(name) + 1];
strcpy(tbl.FunctionName, name);
this->SymTable.push_back(tbl);
this->SymbolTableExists = true;
// debug("Symbol %d: %#lx %s(%#lx)",
// i, tbl.Address,
// tbl.FunctionName,
// name);
// debug("Symbol %d: %#lx %s(%#lx)", i, tbl.Address, tbl.FunctionName, name);
}
}
}
@ -324,7 +314,7 @@ namespace SymbolResolver
debug("- %#lx", this);
debug("Freeing %d symbols",
this->SymTable.size());
foreach (auto tbl in this->SymTable)
for (auto tbl : this->SymTable)
delete[] tbl.FunctionName;
}
}

View File

@ -59,12 +59,12 @@ extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
and switch back when this function returns. */
AutoSwitchPageTable PageSwitcher;
uint64_t _ctime = TimeManager->GetCounter();
uint64_t _ctime = TimeManager->GetTimeNs();
Tasking::TaskInfo *Ptinfo = &thisProcess->Info;
Tasking::TaskInfo *Ttinfo = &thisThread->Info;
uintptr_t ret;
if (Config.UseLinuxSyscalls)
if (Config.LinuxSubsystem)
{
ret = HandleLinuxSyscalls(Frame);
goto Ret;
@ -97,7 +97,7 @@ extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
}
Ret:
Ptinfo->KernelTime += TimeManager->GetCounter() - _ctime;
Ttinfo->KernelTime += TimeManager->GetCounter() - _ctime;
Ptinfo->KernelTime += TimeManager->GetTimeNs() - _ctime;
Ttinfo->KernelTime += TimeManager->GetTimeNs() - _ctime;
return ret;
}

View File

@ -1,111 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <time.hpp>
#include <memory.hpp>
#include <acpi.hpp>
#include <debug.h>
#include <io.h>
#include "../../kernel.h"
namespace Time
{
bool HighPrecisionEventTimer::Sleep(size_t Duration, Units Unit)
{
#if defined(__amd64__)
uint64_t Target = mminq(&hpet->MainCounterValue) + (Duration * ConvertUnit(Unit)) / clk;
while (mminq(&hpet->MainCounterValue) < Target)
CPU::Pause();
return true;
#elif defined(__i386__)
uint64_t Target = mminl(&hpet->MainCounterValue) + (Duration * ConvertUnit(Unit)) / clk;
while (mminl(&hpet->MainCounterValue) < Target)
CPU::Pause();
return true;
#endif
return false;
}
uint64_t HighPrecisionEventTimer::GetCounter()
{
#if defined(__amd64__)
return mminq(&hpet->MainCounterValue);
#elif defined(__i386__)
return mminl(&hpet->MainCounterValue);
#else
return 0;
#endif
}
uint64_t HighPrecisionEventTimer::CalculateTarget(uint64_t Target, Units Unit)
{
#if defined(__amd64__)
return mminq(&hpet->MainCounterValue) + (Target * ConvertUnit(Unit)) / clk;
#elif defined(__i386__)
return mminl(&hpet->MainCounterValue) + (Target * ConvertUnit(Unit)) / clk;
#else
return 0;
#endif
}
uint64_t HighPrecisionEventTimer::GetNanosecondsSinceClassCreation()
{
#if defined(__amd64__) || defined(__i386__)
uint64_t Subtraction = this->GetCounter() - this->ClassCreationTime;
if (Subtraction <= 0 || this->clk <= 0)
return 0;
Subtraction *= ConvertUnit(Units::Nanoseconds);
return uint64_t(Subtraction / this->clk);
#else
return 0;
#endif
}
HighPrecisionEventTimer::HighPrecisionEventTimer(void *hpet)
{
#if defined(__amd64__) || defined(__i386__)
ACPI::ACPI::HPETHeader *HPET_HDR = (ACPI::ACPI::HPETHeader *)hpet;
Memory::Virtual vmm;
vmm.Map((void *)HPET_HDR->Address.Address,
(void *)HPET_HDR->Address.Address,
Memory::PTFlag::RW | Memory::PTFlag::PCD);
this->hpet = (HPET *)HPET_HDR->Address.Address;
trace("%s timer is at address %016p",
HPET_HDR->Header.OEMID,
(void *)HPET_HDR->Address.Address);
clk = s_cst(uint32_t, (uint64_t)this->hpet->GeneralCapabilities >> 32);
KPrint("HPET clock is %u Hz", clk);
#ifdef __amd64__
mmoutq(&this->hpet->GeneralConfiguration, 0);
mmoutq(&this->hpet->MainCounterValue, 0);
mmoutq(&this->hpet->GeneralConfiguration, 1);
#else
mmoutl(&this->hpet->GeneralConfiguration, 0);
mmoutl(&this->hpet->MainCounterValue, 0);
mmoutl(&this->hpet->GeneralConfiguration, 1);
#endif
ClassCreationTime = this->GetCounter();
#endif
}
HighPrecisionEventTimer::~HighPrecisionEventTimer()
{
}
}

View File

@ -1,208 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <time.hpp>
#include <memory.hpp>
#include <acpi.hpp>
#include <debug.h>
#include <io.h>
#include "../../kernel.h"
namespace Time
{
bool time::Sleep(size_t Duration, Units Unit)
{
switch (ActiveTimer)
{
case NONE:
error("No timer is active");
return false;
case RTC:
fixme("RTC sleep not implemented");
return false;
case PIT:
fixme("PIT sleep not implemented");
return false;
case HPET:
return this->hpet->Sleep(Duration, Unit);
case ACPI:
fixme("ACPI sleep not implemented");
return false;
case APIC:
fixme("APIC sleep not implemented");
return false;
case TSC:
return this->tsc->Sleep(Duration, Unit);
default:
error("Unknown timer");
return false;
}
}
uint64_t time::GetCounter()
{
switch (ActiveTimer)
{
case NONE:
error("No timer is active");
return 0;
case RTC:
fixme("RTC sleep not implemented");
return 0;
case PIT:
fixme("PIT sleep not implemented");
return 0;
case HPET:
return this->hpet->GetCounter();
case ACPI:
fixme("ACPI sleep not implemented");
return 0;
case APIC:
fixme("APIC sleep not implemented");
return 0;
case TSC:
return this->tsc->GetCounter();
default:
error("Unknown timer");
return 0;
}
}
uint64_t time::CalculateTarget(uint64_t Target, Units Unit)
{
switch (ActiveTimer)
{
case NONE:
error("No timer is active");
return 0;
case RTC:
fixme("RTC sleep not implemented");
return 0;
case PIT:
fixme("PIT sleep not implemented");
return 0;
case HPET:
return this->hpet->CalculateTarget(Target, Unit);
case ACPI:
fixme("ACPI sleep not implemented");
return 0;
case APIC:
fixme("APIC sleep not implemented");
return 0;
case TSC:
return this->tsc->CalculateTarget(Target, Unit);
default:
error("Unknown timer");
return 0;
}
}
uint64_t time::GetNanosecondsSinceClassCreation()
{
switch (ActiveTimer)
{
case NONE:
error("No timer is active");
return 0;
case RTC:
fixme("RTC sleep not implemented");
return 0;
case PIT:
fixme("PIT sleep not implemented");
return 0;
case HPET:
return this->hpet->GetNanosecondsSinceClassCreation();
case ACPI:
fixme("ACPI sleep not implemented");
return 0;
case APIC:
fixme("APIC sleep not implemented");
return 0;
case TSC:
return this->tsc->GetNanosecondsSinceClassCreation();
default:
error("Unknown timer");
return 0;
}
}
void time::FindTimers(void *acpi)
{
#if defined(__amd64__) || defined(__i386__)
/* TODO: RTC check */
/* TODO: PIT check */
if (acpi)
{
if (((ACPI::ACPI *)acpi)->HPET)
{
hpet = new HighPrecisionEventTimer(((ACPI::ACPI *)acpi)->HPET);
ActiveTimer = HPET;
SupportedTimers |= HPET;
KPrint("HPET found");
}
else
{
KPrint("\x1b[33mHPET not found");
}
/* TODO: ACPI check */
/* TODO: APIC check */
}
else
{
KPrint("\x1b[33mACPI not found");
}
bool TSCInvariant = false;
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
{
CPU::x86::AMD::CPUID0x80000007 cpuid80000007;
if (cpuid80000007.EDX.TscInvariant)
TSCInvariant = true;
}
else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
{
// TODO: Intel 0x80000007
CPU::x86::AMD::CPUID0x80000007 cpuid80000007;
if (cpuid80000007.EDX.TscInvariant)
TSCInvariant = true;
}
if (TSCInvariant)
{
tsc = new TimeStampCounter;
// FIXME: ActiveTimer = TSC;
SupportedTimers |= TSC;
KPrint("Invariant TSC found");
}
else
KPrint("\x1b[33mTSC is not invariant");
#endif
}
time::time()
{
}
time::~time()
{
}
}

View File

@ -1,84 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <time.hpp>
#include <memory.hpp>
#include <acpi.hpp>
#include <debug.h>
#include <io.h>
#include "../../kernel.h"
namespace Time
{
bool TimeStampCounter::Sleep(size_t Duration, Units Unit)
{
#if defined(__amd64__) || defined(__i386__)
uint64_t Target = this->GetCounter() + (Duration * ConvertUnit(Unit)) / this->clk;
while (this->GetCounter() < Target)
CPU::Pause();
return true;
#elif defined(__aarch64__)
return 0;
#endif
}
uint64_t TimeStampCounter::GetCounter()
{
#if defined(__amd64__) || defined(__i386__)
return CPU::Counter();
#elif defined(__aarch64__)
return 0;
#endif
}
uint64_t TimeStampCounter::CalculateTarget(uint64_t Target, Units Unit)
{
#if defined(__amd64__) || defined(__i386__)
return uint64_t((this->GetCounter() + (Target * ConvertUnit(Unit))) / this->clk);
#elif defined(__aarch64__)
return 0;
#endif
}
uint64_t TimeStampCounter::GetNanosecondsSinceClassCreation()
{
#if defined(__amd64__) || defined(__i386__)
return uint64_t((this->GetCounter() - this->ClassCreationTime) / this->clk);
#elif defined(__aarch64__)
return 0;
#endif
}
TimeStampCounter::TimeStampCounter()
{
#if defined(__amd64__) || defined(__i386__)
stub; // FIXME: This is not a good way to measure the clock speed
uint64_t Start = CPU::Counter();
TimeManager->Sleep(1, Units::Milliseconds);
uint64_t End = CPU::Counter();
this->clk = End - Start;
this->ClassCreationTime = this->GetCounter();
#endif
}
TimeStampCounter::~TimeStampCounter()
{
}
}

View File

@ -20,9 +20,9 @@
#include <types.h>
#include <filesystem.hpp>
#include <fs/vfs.hpp>
namespace vfs
namespace Driver::ExtendedFilesystem
{
class EXT2
{

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ namespace Driver::TeleTypeDevices
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Open(Flags, Mode);
return KernelConsole::CurrentTerminal.load()->Term->Open(Flags, Mode);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
@ -55,7 +55,7 @@ namespace Driver::TeleTypeDevices
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Close();
return KernelConsole::CurrentTerminal.load()->Term->Close();
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
@ -73,7 +73,7 @@ namespace Driver::TeleTypeDevices
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Ioctl(Request, Argp);
return KernelConsole::CurrentTerminal.load()->Term->Ioctl(Request, Argp);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
@ -91,7 +91,7 @@ namespace Driver::TeleTypeDevices
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Read(Buffer, Size, Offset);
return KernelConsole::CurrentTerminal.load()->Term->Read(Buffer, Size, Offset);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
@ -109,7 +109,7 @@ namespace Driver::TeleTypeDevices
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Write(Buffer, Size, Offset);
return KernelConsole::CurrentTerminal.load()->Term->Write(Buffer, Size, Offset);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
@ -156,7 +156,7 @@ namespace Driver::TeleTypeDevices
S_IRGRP |
S_IFCHR;
ids.kcon = DriverManager->CreateDeviceFile(DriverID, "kcon", mode, &ops);
ids.kcon = DriverManager->CreateDeviceFile(DriverID, "console", mode, &ops);
/* c rw- rw- rw- */
mode = S_IRUSR | S_IWUSR |

View File

@ -16,6 +16,7 @@
*/
#include <driver.hpp>
#include <interface/block.h>
#include <cpu.hpp>
#include <pci.hpp>
@ -572,6 +573,9 @@ namespace Driver::AHCI
HBAPort *HBAPortPtr;
uint8_t *Buffer;
uint8_t PortNumber;
uint32_t BlockSize;
uint32_t BlockCount;
size_t Size;
ATA_IDENTIFY *IdentifyData;
Port(PortType Type, HBAPort *PortPtr, uint8_t PortNumber)
@ -614,6 +618,7 @@ namespace Driver::AHCI
void Configure()
{
debug("Configuring port %d", PortNumber);
this->StopCMD();
void *CmdBase = v0::AllocateMemory(DriverID, 1);
HBAPortPtr->CommandListBase = (uint32_t)(uint64_t)CmdBase;
@ -639,19 +644,35 @@ namespace Driver::AHCI
Identify();
if (IdentifyData->CommandSetSupport.BigLba)
{
if ((IdentifyData->CommandSetActive.Words119_120Valid & 0x1) != 0)
{
uint32_t wordsPerLogicalSector = (IdentifyData->WordsPerLogicalSector[1] << 16) | IdentifyData->WordsPerLogicalSector[0];
if (wordsPerLogicalSector != 0)
this->BlockSize = wordsPerLogicalSector * 2;
}
}
this->BlockSize = 512;
this->BlockCount = this->IdentifyData->UserAddressableSectors;
this->Size = this->BlockCount * this->BlockSize;
trace("Port %d \"%x %x %x %x\" configured", PortNumber,
HBAPortPtr->Vendor[0], HBAPortPtr->Vendor[1],
HBAPortPtr->Vendor[2], HBAPortPtr->Vendor[3]);
}
bool ReadWrite(uint64_t Sector, uint32_t SectorCount, void *Buffer, bool Write)
int ReadWrite(uint64_t Sector, uint32_t SectorCount, void *Buffer, bool Write)
{
if (this->AHCIPortType == PortType::SATAPI && Write == true)
{
trace("SATAPI port does not support write.");
return false;
return ENOTSUP;
}
debug("%s op on port %d, sector %d, count %d", Write ? "Write" : "Read", this->PortNumber, Sector, SectorCount);
uint32_t SectorL = (uint32_t)Sector;
uint32_t SectorH = (uint32_t)(Sector >> 32);
@ -706,7 +727,7 @@ namespace Driver::AHCI
if (spinLock == 1000000)
{
trace("Port not responding.");
return false;
return ETIMEDOUT;
}
HBAPortPtr->CommandIssue = 1;
@ -723,7 +744,7 @@ namespace Driver::AHCI
spinLock = 0;
retries++;
if (retries > 10)
return false;
return ETIMEDOUT;
}
if (HBAPortPtr->CommandIssue == 0)
@ -733,11 +754,11 @@ namespace Driver::AHCI
if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES)
{
trace("Error reading/writing (%d).", Write);
return false;
return EIO;
}
}
return true;
return 0;
}
void Identify()
@ -840,34 +861,61 @@ namespace Driver::AHCI
}
}
int Open(struct Inode *, int, mode_t)
{
return 0;
}
int Close(struct Inode *)
{
return 0;
}
ssize_t Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
{
uint64_t sector = Offset / 512;
uint32_t sectorCount = uint32_t(Size / 512);
int num = Node->GetMinor();
bool ok = PortDevices[num]->ReadWrite(sector, sectorCount, Buffer, false);
return ok ? Size : 0;
Port *port = static_cast<Port *>(Node->PrivateData);
if ((Offset % port->BlockSize) != 0 || (Size % port->BlockSize) != 0)
{
trace("Read offset or size not aligned to block size (BlockSize=%u)", port->BlockSize);
return -EINVAL;
}
uint64_t sector = Offset / port->BlockSize;
uint32_t sectorCount = uint32_t(Size / port->BlockSize);
if (sectorCount == 0)
{
trace("Attempt to read 0 sectors");
return 0;
}
bool status = port->ReadWrite(sector, sectorCount, Buffer, false);
if (status != 0)
{
trace("Error '%s' reading from port %d", strerror(status), port->PortNumber);
return status;
}
return Size;
}
ssize_t Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
{
uint64_t sector = Offset / 512;
uint32_t sectorCount = uint32_t(Size / 512);
int num = Node->GetMinor();
bool ok = PortDevices[num]->ReadWrite(sector, sectorCount, (void *)Buffer, true);
return ok ? Size : 0;
Port *port = static_cast<Port *>(Node->PrivateData);
if ((Offset % port->BlockSize) != 0 || (Size % port->BlockSize) != 0)
{
trace("Read offset or size not aligned to block size (BlockSize=%u)", port->BlockSize);
return -EINVAL;
}
uint64_t sector = Offset / port->BlockSize;
uint32_t sectorCount = uint32_t(Size / port->BlockSize);
if (sectorCount == 0)
{
trace("Attempt to write 0 sectors");
return 0;
}
bool status = port->ReadWrite(sector, sectorCount, (void *)Buffer, true);
if (status != 0)
{
trace("Error '%s' writing to port %d", strerror(status), port->PortNumber);
return status;
}
return Size;
}
int Open(struct Inode *, int, mode_t) { return 0; }
int Close(struct Inode *) { return 0; }
const struct InodeOperations ops = {
.Lookup = nullptr,
.Create = nullptr,
@ -915,8 +963,18 @@ namespace Driver::AHCI
{
KPrint("%s drive found at port %d", PortTypeName[portType], i);
Port *port = new Port(portType, &hba->Ports[i], i);
dev_t ret = v0::RegisterDevice(DriverID, BLOCK_TYPE_HDD, &ops);
port->Configure();
BlockDevice *dev = new BlockDevice;
dev->Name = "ahci";
dev->BlockSize = port->BlockSize;
dev->BlockCount = port->BlockCount;
dev->Size = port->Size;
dev->Ops = &ops;
dev->PrivateData = port;
dev_t ret = v0::RegisterBlockDevice(DriverID, dev);
PortDevices[ret] = port;
debug("Port %d \"%s\" registered as %d", i, port->IdentifyData->ModelNumber, ret);
break;
}
case PortType::SEMB:
@ -942,10 +1000,6 @@ namespace Driver::AHCI
return -ENODEV;
}
trace("Initializing AHCI ports");
for (auto &&p : PortDevices)
p.second->Configure();
/* We don't use the interrupt handler now... maybe we will in the future */
// RegisterInterruptHandler(iLine(ctx->Device), (void *)OnInterruptReceived);
@ -957,7 +1011,7 @@ namespace Driver::AHCI
for (auto &&p : PortDevices)
{
p.second->StopCMD();
v0::UnregisterDevice(DriverID, p.first);
v0::UnregisterBlockDevice(DriverID, p.first);
delete p.second;
}
@ -966,7 +1020,7 @@ namespace Driver::AHCI
// ctx->Device->Header->Command |= PCI::PCI_COMMAND_INTX_DISABLE;
// std::list<PCI::PCIDevice> Devices = PCIManager->FindPCIDevice(VendorIDs, DeviceIDs);
// foreach (auto dev in Devices)
// for (auto dev : Devices)
// Interrupts::RemoveHandler(OnInterruptReceived, iLine(dev));
return 0;
}

4
Kernel/drivers/trusted.c Normal file
View File

@ -0,0 +1,4 @@
const char *trusted_drivers[] = {
"ae08d2e120c8370278ca9e17085a6b9e2f4a470ab6cec824c77ab1f8706c7144f5d4e1c9820914ed4fc7a4fd22de4b18bfed7c3b5d9c1e604e82280d7d45a5c7",
};
const __SIZE_TYPE__ trusted_drivers_count = sizeof(trusted_drivers) / sizeof(trusted_drivers[0]);

259
Kernel/efi/efi.cpp Normal file
View File

@ -0,0 +1,259 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <efi.h>
#include <boot/binfo.h>
#include <debug.h>
#include <memory/virtual.hpp>
extern struct BootInfo bInfo;
VOID SearchSMBIOS(EFI_SYSTEM_TABLE *SystemTable)
{
EFI_GUID Smbios3TableGuid = SMBIOS3_TABLE_GUID;
EFI_GUID SmbiosTableGuid = SMBIOS_TABLE_GUID;
for (UINTN i = 0; i < SystemTable->NumberOfTableEntries; i++)
{
EFI_CONFIGURATION_TABLE *config = &SystemTable->ConfigurationTable[i];
/* Can a device have multiple smbios tables? If so, use SMBIOS 3.0 over <2.0 */
if (CompareGuid(&config->VendorGuid, &SmbiosTableGuid))
{
bInfo.SMBIOSPtr = config->VendorTable;
debug("SMBIOS found at address: %#lx", bInfo.SMBIOSPtr);
continue;
}
if (CompareGuid(&config->VendorGuid, &Smbios3TableGuid))
{
bInfo.SMBIOSPtr = config->VendorTable;
debug("SMBIOS3 found at address: %#lx", bInfo.SMBIOSPtr);
return;
}
}
}
VOID SearchRSDP(EFI_SYSTEM_TABLE *SystemTable)
{
EFI_GUID AcpiTableGuid = EFI_ACPI_TABLE_GUID;
for (UINTN i = 0; i < SystemTable->NumberOfTableEntries; i++)
{
EFI_CONFIGURATION_TABLE *config = &SystemTable->ConfigurationTable[i];
if (CompareGuid(&config->VendorGuid, &AcpiTableGuid))
{
bInfo.RSDP = (BootInfo::RSDPInfo *)config->VendorTable;
debug("RSDP found at address: %#lx", bInfo.RSDP);
break;
}
}
}
VOID InitializeMemoryEntries(EFI_MEMORY_DESCRIPTOR *MemoryMap, UINTN NumberOfEntries, UINTN DescriptorSize)
{
debug("Memory map: %#lx", MemoryMap);
debug("Number of entries: %d", NumberOfEntries);
debug("Descriptor size: %d", DescriptorSize);
for (UINTN i = 0; i < NumberOfEntries; i++)
{
EFI_MEMORY_DESCRIPTOR *desc = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + i * DescriptorSize);
UNUSED(desc);
#ifdef DEBUG
const char *EFI_MEMORY_TYPE_STRINGS[] = {
"ReservedMemoryType",
"LoaderCode",
"LoaderData",
"BootServicesCode",
"BootServicesData",
"RuntimeServicesCode",
"RuntimeServicesData",
"ConventionalMemory",
"UnusableMemory",
"ACPIReclaimMemory",
"ACPIMemoryNVS",
"MemoryMappedIO",
"MemoryMappedIOPortSpace",
"PalCode",
"PersistentMemory",
"MaxMemoryType",
"out of bounds?!"};
size_t type = desc->Type;
if (type > sizeof(EFI_MEMORY_TYPE_STRINGS) / sizeof(EFI_MEMORY_TYPE_STRINGS[0]))
{
type = 16;
debug("oh uh, %d is out of bounds!!! t:%#lx p:%#lx v:%#lx n:%lu a:%lx",
i, desc->Type,
desc->PhysicalStart,
desc->VirtualStart,
desc->NumberOfPages,
desc->Attribute);
}
debug("Entry %d: Type: %s, PhysicalStart: %p, VirtualStart: %p, NumberOfPages: %lu, Attribute: %lx",
i, EFI_MEMORY_TYPE_STRINGS[type],
desc->PhysicalStart,
desc->VirtualStart,
desc->NumberOfPages,
desc->Attribute);
#endif
}
}
VOID InitializeMemory(EFI_SYSTEM_TABLE *SystemTable)
{
EFI_MEMORY_DESCRIPTOR *MemoryMap = (EFI_MEMORY_DESCRIPTOR *)bInfo.EFI.MemoryMap.BaseAddress;
UINTN NumberOfEntries = bInfo.EFI.MemoryMap.NumberOfEntries;
UINTN DescriptorSize = bInfo.EFI.MemoryMap.DescriptorSize;
EFI_STATUS Status = SystemTable->BootServices->AllocatePool(EfiLoaderData, NumberOfEntries * DescriptorSize, (void **)&MemoryMap);
if (EFI_ERROR(Status))
{
error("Failed to allocate memory for memory map: %#lx", Status);
return;
}
Status = SystemTable->BootServices->GetMemoryMap(&NumberOfEntries, MemoryMap, &DescriptorSize, NULL, NULL);
if (EFI_ERROR(Status))
{
error("Failed to get memory map: %#lx", Status);
return;
}
InitializeMemoryEntries(MemoryMap, NumberOfEntries, DescriptorSize);
}
VOID InitializeMemoryNoBS()
{
EFI_MEMORY_DESCRIPTOR *MemoryMap = (EFI_MEMORY_DESCRIPTOR *)bInfo.EFI.MemoryMap.BaseAddress;
UINTN NumberOfEntries = bInfo.EFI.MemoryMap.NumberOfEntries;
UINTN DescriptorSize = bInfo.EFI.MemoryMap.DescriptorSize;
InitializeMemoryEntries(MemoryMap, NumberOfEntries, DescriptorSize);
}
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
Memory::Virtual va;
bool validST = va.Check(SystemTable);
bool validIH = va.Check(ImageHandle);
trace("map: ST:%d IH:%d", validST, validIH);
#ifdef DEBUG
debug("efi info: %x", bInfo.EFI.Info.raw);
if (bInfo.EFI.Info.ST && validST)
{
EFI_GUID EfiAcpi20Table = EFI_ACPI_20_TABLE_GUID;
EFI_GUID AcpiTable = ACPI_TABLE_GUID;
EFI_GUID SalSystemTable = SAL_SYSTEM_TABLE_GUID;
EFI_GUID SmbiosTable = SMBIOS_TABLE_GUID;
EFI_GUID Smbios3Table = SMBIOS3_TABLE_GUID;
EFI_GUID MpsTable = MPS_TABLE_GUID;
EFI_GUID EfiAcpiTable = EFI_ACPI_TABLE_GUID;
EFI_GUID EfiLzmaCompressed = EFI_LZMA_COMPRESSED_GUID;
EFI_GUID EfiDxeServices = EFI_DXE_SERVICES_GUID;
EFI_GUID EfiHobList = EFI_HOB_LIST_GUID;
EFI_GUID EfiMemoryType = _EFI_MEMORY_TYPE_GUID;
EFI_GUID EfiDebugImageInfoTable = EFI_DEBUG_IMAGE_INFO_TABLE_GUID;
EFI_GUID EfiMemStatusCodeRec = EFI_MEM_STATUS_CODE_REC_GUID;
EFI_GUID EfiGuidEfiAcpi1 = EFI_GUID_EFI_ACPI1_GUID;
EFI_GUID EfiMemoryAttributesTable = EFI_MEMORY_ATTRIBUTES_TABLE_GUID;
EFI_GUID EfiHiiDatabaseProtocol = EFI_HII_DATABASE_PROTOCOL_GUID;
EFI_GUID EfiHiiConfigRoutingProtocol = EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID;
EFI_GUID TCG2FinalEventsTable = TCG2_FINAL_EVENTS_TABLE_GUID;
EFI_GUID EfiImageSecurityDatabase = EFI_IMAGE_SECURITY_DATABASE_GUID;
EFI_GUID EfiSystemResourceTable = EFI_SYSTEM_RESOURCE_TABLE_GUID;
debug("there are %d configuration tables", SystemTable->NumberOfTableEntries);
for (UINTN i = 0; i < SystemTable->NumberOfTableEntries; i++)
{
EFI_CONFIGURATION_TABLE *config = &SystemTable->ConfigurationTable[i];
EFI_GUID *g = &config->VendorGuid;
void *addr = config->VendorTable;
const char *guid_str = NULL;
if (CompareGuid(g, &EfiAcpi20Table))
guid_str = "EFI ACPI 2.0 Table";
else if (CompareGuid(g, &AcpiTable))
guid_str = "ACPI Table";
else if (CompareGuid(g, &SalSystemTable))
guid_str = "SAL System Table";
else if (CompareGuid(g, &SmbiosTable))
guid_str = "SMBIOS Table";
else if (CompareGuid(g, &Smbios3Table))
guid_str = "SMBIOS 3 Table";
else if (CompareGuid(g, &MpsTable))
guid_str = "MPS Table";
else if (CompareGuid(g, &EfiAcpiTable))
guid_str = "EFI ACPI Table";
else if (CompareGuid(g, &EfiLzmaCompressed))
guid_str = "EFI LZMA Compressed";
else if (CompareGuid(g, &EfiDxeServices))
guid_str = "EFI DXE Services";
else if (CompareGuid(g, &EfiHobList))
guid_str = "EFI HOB List";
else if (CompareGuid(g, &EfiMemoryType))
guid_str = "EFI Memory Type";
else if (CompareGuid(g, &EfiDebugImageInfoTable))
guid_str = "EFI Debug Image Info Table";
else if (CompareGuid(g, &EfiMemStatusCodeRec))
guid_str = "EFI Memory Status Code Record";
else if (CompareGuid(g, &EfiGuidEfiAcpi1))
guid_str = "EFI ACPI 1.0 Table";
else if (CompareGuid(g, &EfiMemoryAttributesTable))
guid_str = "EFI Memory Attributes Table";
else if (CompareGuid(g, &EfiHiiDatabaseProtocol))
guid_str = "EFI HII Database Protocol";
else if (CompareGuid(g, &EfiHiiConfigRoutingProtocol))
guid_str = "EFI HII Config Routing Protocol";
else if (CompareGuid(g, &TCG2FinalEventsTable))
guid_str = "TCG2 Final Events Table";
else if (CompareGuid(g, &EfiImageSecurityDatabase))
guid_str = "EFI Image Security Database";
else if (CompareGuid(g, &EfiSystemResourceTable))
guid_str = "EFI System Resource Table";
else
guid_str = "(unknown)";
debug("%016lx %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x %s",
(UINT64)(uintptr_t)addr,
g->Data1, g->Data2, g->Data3,
g->Data4[0], g->Data4[1],
g->Data4[2], g->Data4[3],
g->Data4[4], g->Data4[5],
g->Data4[6], g->Data4[7],
guid_str);
}
}
#endif
if (bInfo.EFI.Info.ST == 1 && validST)
{
SearchSMBIOS(SystemTable);
SearchRSDP(SystemTable);
}
if (bInfo.EFI.Info.BS == 0 && bInfo.EFI.Info.MemoryMap == 1)
InitializeMemoryNoBS();
else if (bInfo.EFI.Info.BS == 1)
InitializeMemory(SystemTable);
return EFI_SUCCESS;
}

36
Kernel/efi/lib.cpp Normal file
View File

@ -0,0 +1,36 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <efi.h>
#include <convert.h>
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
{
if (Guid1 == NULL || Guid2 == NULL)
return FALSE;
return (Guid1->Data1 == Guid2->Data1 &&
Guid1->Data2 == Guid2->Data2 &&
Guid1->Data3 == Guid2->Data3 &&
memcmp(Guid1->Data4, Guid2->Data4, sizeof(Guid1->Data4)) == 0);
}
VOID InitializeLib(IN EFI_HANDLE, IN EFI_SYSTEM_TABLE *)
{
/* Does nothing */
}

View File

@ -25,82 +25,88 @@
namespace Execute
{
BinaryType GetBinaryType(FileNode *Node)
BinaryType GetBinaryType(Node &Node)
{
debug("Checking binary type of %s", Node->Path.c_str());
BinaryType Type;
BinaryType type;
if (Node == nullptr)
ReturnLogError((BinaryType)-ENOENT, "Node is null");
Elf32_Ehdr ELFHeader;
Node->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
Elf_Ehdr ehdr;
fs->Read(Node, &ehdr, sizeof(Elf_Ehdr), 0);
mach_header MachHeader;
Node->Read(&MachHeader, sizeof(mach_header), 0);
mach_header mach;
fs->Read(Node, &mach, sizeof(mach_header), 0);
IMAGE_DOS_HEADER MZHeader;
Node->Read(&MZHeader, sizeof(IMAGE_DOS_HEADER), 0);
IMAGE_DOS_HEADER mz;
fs->Read(Node, &mz, sizeof(IMAGE_DOS_HEADER), 0);
/* Check ELF header. */
if (ELFHeader.e_ident[EI_MAG0] == ELFMAG0 &&
ELFHeader.e_ident[EI_MAG1] == ELFMAG1 &&
ELFHeader.e_ident[EI_MAG2] == ELFMAG2 &&
ELFHeader.e_ident[EI_MAG3] == ELFMAG3)
if (ehdr.e_ident[EI_MAG0] == ELFMAG0 &&
ehdr.e_ident[EI_MAG1] == ELFMAG1 &&
ehdr.e_ident[EI_MAG2] == ELFMAG2 &&
ehdr.e_ident[EI_MAG3] == ELFMAG3)
{
debug("Image - ELF");
Type = BinaryType::BinTypeELF;
type = BinaryType::BinTypeELF;
goto Success;
}
if (MachHeader.magic == MH_MAGIC || MachHeader.magic == MH_CIGAM)
if (mach.magic == MH_MAGIC || mach.magic == MH_CIGAM)
{
debug("Image - Mach-O");
Type = BinaryType::BinTypeMachO;
type = BinaryType::BinTypeMachO;
goto Success;
}
/* Check MZ header. */
else if (MZHeader.e_magic == IMAGE_DOS_SIGNATURE)
else if (mz.e_magic == IMAGE_DOS_SIGNATURE)
{
IMAGE_NT_HEADERS PEHeader;
Node->Read(&PEHeader, sizeof(IMAGE_NT_HEADERS), MZHeader.e_lfanew);
IMAGE_NT_HEADERS pe;
fs->Read(Node, &pe, sizeof(IMAGE_NT_HEADERS), mz.e_lfanew);
IMAGE_OS2_HEADER NEHeader;
Node->Read(&NEHeader, sizeof(IMAGE_OS2_HEADER), MZHeader.e_lfanew);
IMAGE_OS2_HEADER ne;
fs->Read(Node, &ne, sizeof(IMAGE_OS2_HEADER), mz.e_lfanew);
/* TODO: LE, EDOS */
if (PEHeader.Signature == IMAGE_NT_SIGNATURE)
if (pe.Signature == IMAGE_NT_SIGNATURE)
{
debug("Image - PE");
Type = BinaryType::BinTypePE;
type = BinaryType::BinTypePE;
goto Success;
}
else if (NEHeader.ne_magic == IMAGE_OS2_SIGNATURE)
else if (ne.ne_magic == IMAGE_OS2_SIGNATURE)
{
debug("Image - NE");
Type = BinaryType::BinTypeNE;
type = BinaryType::BinTypeNE;
goto Success;
}
else
{
debug("Image - MZ");
Type = BinaryType::BinTypeMZ;
type = BinaryType::BinTypeMZ;
goto Success;
}
}
/* ... */
Type = BinaryType::BinTypeUnknown;
type = BinaryType::BinTypeUnknown;
Success:
return Type;
return type;
}
BinaryType GetBinaryType(std::string Path)
{
FileNode *node = fs->GetByPath(Path.c_str(), nullptr);
debug("Checking binary type of %s (returning %p)", Path.c_str(), node);
Node node = fs->Lookup(thisProcess->Info.RootNode, Path);
if (node->IsSymbolicLink())
{
char buffer[512];
fs->ReadLink(node, buffer, sizeof(buffer));
node = fs->Lookup(node->Parent, buffer);
}
debug("Checking binary type of %s (returning %p)", Path.c_str(), node.get());
assert(node != nullptr);
return GetBinaryType(node);
}

File diff suppressed because it is too large Load Diff

View File

@ -25,52 +25,52 @@ namespace Execute
{
bool ELFIs64(void *Header)
{
Elf32_Ehdr *ELFHeader = (Elf32_Ehdr *)Header;
if (ELFHeader->e_ident[EI_CLASS] == ELFCLASS64)
Elf_Ehdr *ehdr = (Elf_Ehdr *)Header;
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
return true;
return false;
}
/* Originally from https://wiki.osdev.org/ELF_Tutorial */
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header)
Elf_Shdr *GetELFSheader(Elf_Ehdr *Header)
{
return (Elf64_Shdr *)((uintptr_t)Header + Header->e_shoff);
return (Elf_Shdr *)((uintptr_t)Header + Header->e_shoff);
}
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index)
Elf_Shdr *GetELFSection(Elf_Ehdr *Header, uintptr_t Index)
{
return &GetELFSheader(Header)[Index];
}
char *GetELFStringTable(Elf64_Ehdr *Header)
char *GetELFStringTable(Elf_Ehdr *Header)
{
if (Header->e_shstrndx == SHN_UNDEF)
return nullptr;
return (char *)Header + GetELFSection(Header, Header->e_shstrndx)->sh_offset;
}
char *ELFLookupString(Elf64_Ehdr *Header, uintptr_t Offset)
char *ELFLookupString(Elf_Ehdr *Header, uintptr_t Offset)
{
char *StringTable = GetELFStringTable(Header);
if (StringTable == nullptr)
char *table = GetELFStringTable(Header);
if (table == nullptr)
return nullptr;
return StringTable + Offset;
return table + Offset;
}
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, std::string Name)
Elf_Sym *ELFLookupSymbol(Elf_Ehdr *Header, std::string Name)
{
Elf64_Shdr *SymbolTable = nullptr;
Elf64_Shdr *StringTable = nullptr;
Elf_Shdr *symTable = nullptr;
Elf_Shdr *stringTable = nullptr;
for (Elf64_Half i = 0; i < Header->e_shnum; i++)
for (Elf_Half i = 0; i < Header->e_shnum; i++)
{
Elf64_Shdr *shdr = GetELFSection(Header, i);
Elf_Shdr *shdr = GetELFSection(Header, i);
switch (shdr->sh_type)
{
case SHT_SYMTAB:
SymbolTable = shdr;
StringTable = GetELFSection(Header, shdr->sh_link);
symTable = shdr;
stringTable = GetELFSection(Header, shdr->sh_link);
break;
default:
{
@ -79,117 +79,108 @@ namespace Execute
}
}
if (SymbolTable == nullptr || StringTable == nullptr)
if (symTable == nullptr || stringTable == nullptr)
return nullptr;
for (size_t i = 0; i < (SymbolTable->sh_size / sizeof(Elf64_Sym)); i++)
for (size_t i = 0; i < (symTable->sh_size / sizeof(Elf_Sym)); i++)
{
Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
char *String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
Elf_Sym *sym = (Elf_Sym *)((uintptr_t)Header + symTable->sh_offset + (i * sizeof(Elf_Sym)));
char *String = (char *)((uintptr_t)Header + stringTable->sh_offset + sym->st_name);
if (strcmp(String, Name.c_str()) == 0)
return Symbol;
return sym;
}
return nullptr;
}
Elf64_Sym ELFLookupSymbol(FileNode *fd, std::string Name)
Elf_Sym ELFLookupSymbol(Node fd, std::string Name)
{
#if defined(__amd64__)
Elf64_Ehdr Header{};
fd->Read(&Header, sizeof(Elf64_Ehdr), 0);
Elf_Ehdr ehdr{};
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
Elf64_Shdr SymbolTable{};
Elf64_Shdr StringTable{};
Elf_Shdr symTable{};
Elf_Shdr stringTable{};
for (Elf64_Half i = 0; i < Header.e_shnum; i++)
for (Elf64_Half i = 0; i < ehdr.e_shnum; i++)
{
Elf64_Shdr shdr;
fd->Read(&shdr, sizeof(Elf64_Shdr), Header.e_shoff + (i * sizeof(Elf64_Shdr)));
Elf_Shdr shdr;
fs->Read(fd, &shdr, sizeof(Elf_Shdr), ehdr.e_shoff + (i * sizeof(Elf_Shdr)));
switch (shdr.sh_type)
{
case SHT_SYMTAB:
SymbolTable = shdr;
fd->Read(&StringTable, sizeof(Elf64_Shdr), Header.e_shoff + (shdr.sh_link * sizeof(Elf64_Shdr)));
symTable = shdr;
fs->Read(fd, &stringTable, sizeof(Elf_Shdr), ehdr.e_shoff + (shdr.sh_link * sizeof(Elf_Shdr)));
break;
default:
{
break;
}
}
}
if (SymbolTable.sh_name == 0 || StringTable.sh_name == 0)
if (symTable.sh_name == 0 || stringTable.sh_name == 0)
{
error("Symbol table not found.");
return {};
}
for (size_t i = 0; i < (SymbolTable.sh_size / sizeof(Elf64_Sym)); i++)
for (size_t i = 0; i < (symTable.sh_size / sizeof(Elf_Sym)); i++)
{
// Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
Elf64_Sym Symbol;
fd->Read(&Symbol, sizeof(Elf64_Sym), SymbolTable.sh_offset + (i * sizeof(Elf64_Sym)));
// Elf_Sym *sym = (Elf_Sym *)((uintptr_t)Header + symTable->sh_offset + (i * sizeof(Elf_Sym)));
Elf_Sym sym;
fs->Read(fd, &sym, sizeof(Elf_Sym), symTable.sh_offset + (i * sizeof(Elf_Sym)));
// char *String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
char String[256];
fd->Read(&String, sizeof(String), StringTable.sh_offset + Symbol.st_name);
// char *str = (char *)((uintptr_t)Header + stringTable->sh_offset + sym->st_name);
char str[256];
fs->Read(fd, &str, sizeof(str), stringTable.sh_offset + sym.st_name);
if (strcmp(String, Name.c_str()) == 0)
return Symbol;
if (strcmp(str, Name.c_str()) == 0)
return sym;
}
error("Symbol not found.");
#endif
return {};
}
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index)
uintptr_t ELFGetSymbolValue(Elf_Ehdr *Header, uintptr_t Table, uintptr_t Index)
{
#if defined(__amd64__)
if (Table == SHN_UNDEF || Index == SHN_UNDEF)
return 0;
Elf64_Shdr *SymbolTable = GetELFSection(Header, Table);
uint64_t STEntries = SymbolTable->sh_size / SymbolTable->sh_entsize;
if (Index >= STEntries)
Elf_Shdr *symTable = GetELFSection(Header, Table);
uintptr_t entries = symTable->sh_size / symTable->sh_entsize;
if (Index >= entries)
{
error("Symbol index out of range %d-%u.", Table, Index);
return 0xdead;
return -1;
}
uint64_t SymbolAddress = (uint64_t)Header + SymbolTable->sh_offset;
Elf64_Sym *Symbol = &((Elf64_Sym *)SymbolAddress)[Index];
uintptr_t symbolPtr = (uintptr_t)Header + symTable->sh_offset;
Elf_Sym *sym = &((Elf_Sym *)symbolPtr)[Index];
if (Symbol->st_shndx == SHN_UNDEF)
if (sym->st_shndx == SHN_UNDEF)
{
Elf64_Shdr *StringTable = GetELFSection(Header, SymbolTable->sh_link);
const char *Name = (const char *)Header + StringTable->sh_offset + Symbol->st_name;
Elf_Shdr *stringTable = GetELFSection(Header, symTable->sh_link);
const char *name = (const char *)Header + stringTable->sh_offset + sym->st_name;
void *Target = (void *)ELFLookupSymbol(Header, Name)->st_value;
if (Target == nullptr)
void *target = (void *)ELFLookupSymbol(Header, name)->st_value;
if (target == nullptr)
{
if (ELF64_ST_BIND(Symbol->st_info) & STB_WEAK)
if (ELF64_ST_BIND(sym->st_info) & STB_WEAK)
return 0;
else
{
error("Undefined external symbol \"%s\".", Name);
return 0xdead;
error("Undefined external symbol \"%s\".", name);
return -1;
}
}
else
return (uintptr_t)Target;
return (uintptr_t)target;
}
else if (Symbol->st_shndx == SHN_ABS)
return Symbol->st_value;
else if (sym->st_shndx == SHN_ABS)
return sym->st_value;
else
{
Elf64_Shdr *Target = GetELFSection(Header, Symbol->st_shndx);
return (uintptr_t)Header + Symbol->st_value + Target->sh_offset;
Elf_Shdr *shdr = GetELFSection(Header, sym->st_shndx);
return (uintptr_t)Header + sym->st_value + shdr->sh_offset;
}
#elif defined(__i386__)
return 0xdead;
#elif defined(__aarch64__)
return 0xdead;
#endif
}
}

View File

@ -25,77 +25,72 @@ namespace Execute
{
/* Originally from https://wiki.osdev.org/ELF_Tutorial */
void ELFLoadRel(void *BaseImage,
const char *Name,
Tasking::PCB *Process)
void ELFLoadRel(void *BaseImage, const char *Name, Tasking::PCB *Process)
{
#if defined(__amd64__)
UNUSED(Name);
debug("Relocatable");
/* TODO: I have to fully implement this, but for now I will leave it as it is now. */
warn("Relocatable ELF is not fully supported yet");
Elf64_Shdr *shdr = GetELFSheader(((Elf64_Ehdr *)BaseImage));
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)BaseImage)->e_shnum; i++)
Elf_Shdr *shdr = GetELFSheader(((Elf_Ehdr *)BaseImage));
for (Elf_Half i = 0; i < ((Elf_Ehdr *)BaseImage)->e_shnum; i++)
{
Elf64_Shdr *Section = &shdr[i];
if (Section->sh_type == SHT_NOBITS)
Elf_Shdr *section = &shdr[i];
if (section->sh_type == SHT_NOBITS)
{
if (!Section->sh_size)
if (!section->sh_size)
continue;
if (Section->sh_flags & SHF_ALLOC)
if (section->sh_flags & SHF_ALLOC)
{
void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size + 1));
memset(Buffer, 0, Section->sh_size);
void *buffer = KernelAllocator.RequestPages(TO_PAGES(section->sh_size + 1));
memset(buffer, 0, section->sh_size);
Memory::Virtual(Process->PageTable).Map((void *)Buffer, (void *)Buffer, Section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US);
Memory::Virtual(Process->PageTable).Map((void *)buffer, (void *)buffer, section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US);
Section->sh_offset = (uintptr_t)Buffer - (uintptr_t)BaseImage;
debug("Section %ld", Section->sh_size);
section->sh_offset = (uintptr_t)buffer - (uintptr_t)BaseImage;
debug("Section %ld", section->sh_size);
}
}
}
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)BaseImage)->e_shnum; i++)
for (Elf_Half i = 0; i < ((Elf_Ehdr *)BaseImage)->e_shnum; i++)
{
Elf64_Shdr *Section = &shdr[i];
if (Section->sh_type == SHT_REL)
Elf_Shdr *section = &shdr[i];
if (section->sh_type == SHT_REL)
{
for (size_t Index = 0; Index < Section->sh_size / Section->sh_entsize; Index++)
for (size_t i = 0; i < section->sh_size / section->sh_entsize; i++)
{
Elf64_Rel *RelTable = &((Elf64_Rel *)((uintptr_t)BaseImage + Section->sh_offset))[Index];
Elf64_Shdr *Target = GetELFSection(((Elf64_Ehdr *)BaseImage), Section->sh_info);
Elf_Rel *rel = &((Elf_Rel *)((uintptr_t)BaseImage + section->sh_offset))[i];
Elf_Shdr *target = GetELFSection(((Elf_Ehdr *)BaseImage), section->sh_info);
uintptr_t *RelAddress = (uintptr_t *)(((uintptr_t)BaseImage + Target->sh_offset) + RelTable->r_offset);
uint64_t SymbolValue = 0;
uintptr_t *relPtr = (uintptr_t *)(((uintptr_t)BaseImage + target->sh_offset) + rel->r_offset);
uintptr_t value = 0;
if (ELF64_R_SYM(RelTable->r_info) != SHN_UNDEF)
if (ELF_R_SYM(rel->r_info) != SHN_UNDEF)
{
SymbolValue = ELFGetSymbolValue(((Elf64_Ehdr *)BaseImage), Section->sh_link, ELF64_R_SYM(RelTable->r_info));
if (SymbolValue == 0xdead)
value = ELFGetSymbolValue(((Elf_Ehdr *)BaseImage), section->sh_link, ELF_R_SYM(rel->r_info));
if (value == (uintptr_t)-1)
return;
}
switch (ELF64_R_TYPE(RelTable->r_info))
switch (ELF64_R_TYPE(rel->r_info))
{
case R_386_NONE:
break;
case R_386_32:
*RelAddress = DO_64_64(SymbolValue, *RelAddress);
*relPtr = DO_64_64(value, *relPtr);
break;
case R_386_PC32:
*RelAddress = DO_64_PC32(SymbolValue, *RelAddress, (uintptr_t)RelAddress);
*relPtr = DO_64_PC32(value, *relPtr, (uintptr_t)relPtr);
break;
default:
{
error("Unsupported relocation type: %d", ELF64_R_TYPE(RelTable->r_info));
error("Unsupported relocation type: %d", ELF64_R_TYPE(rel->r_info));
return;
}
}
debug("Symbol value: %#lx", SymbolValue);
debug("Symbol value: %#lx", value);
}
}
}
#elif defined(__i386__)
#endif
}
}

View File

@ -21,42 +21,31 @@
namespace Execute
{
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(FileNode *fd,
DynamicArrayTags Tag)
std::vector<Elf_Dyn> ELFGetDynamicTag(Node &fd, DynamicArrayTags Tag)
{
#if defined(__amd64__) || defined(__aarch64__)
std::vector<Elf64_Dyn> Ret;
std::vector<Elf_Dyn> ret;
std::vector<Elf_Phdr> phdrs = ELFGetSymbolType(fd, PT_DYNAMIC);
Elf64_Ehdr ELFHeader{};
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
std::vector<Elf64_Phdr> DYNAMICPhdrs = ELFGetSymbolType_x86_64(fd, PT_DYNAMIC);
if (DYNAMICPhdrs.size() < 1)
if (phdrs.empty())
{
error("No dynamic phdrs found.");
return Ret;
debug("No dynamic phdrs found.");
return ret;
}
foreach (auto Phdr in DYNAMICPhdrs)
for (auto phdr : phdrs)
{
Elf64_Dyn Dynamic{};
for (size_t i = 0; i < Phdr.p_filesz / sizeof(Elf64_Dyn); i++)
Elf_Dyn dyn;
for (size_t i = 0; i < phdr.p_filesz / sizeof(Elf_Dyn); i++)
{
fd->Read(&Dynamic, sizeof(Elf64_Dyn), Phdr.p_offset + (i * sizeof(Elf64_Dyn)));
if (Dynamic.d_tag != Tag)
fs->Read(fd, &dyn, sizeof(Elf_Dyn), phdr.p_offset + (i * sizeof(Elf_Dyn)));
if (dyn.d_tag != Tag)
continue;
debug("Found dynamic tag %d at %#lx [d_val: %#lx]",
Tag, &Dynamic, Dynamic.d_un.d_val);
Ret.push_back(Dynamic);
debug("Found dynamic tag %d at %#lx [d_val: %#lx]", Tag, &dyn, dyn.d_un.d_val);
ret.push_back(dyn);
}
}
return Ret;
#elif defined(__i386__)
return {};
#endif
return ret;
}
}

View File

@ -21,33 +21,26 @@
namespace Execute
{
std::vector<Elf64_Shdr> ELFGetSections_x86_64(FileNode *fd,
const char *SectionName)
std::vector<Elf_Shdr> ELFGetSections(Node fd, const char *SectionName)
{
#if defined(__amd64__) || defined(__aarch64__)
std::vector<Elf64_Shdr> Ret;
std::vector<Elf_Shdr> ret;
Elf64_Ehdr ELFHeader{};
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
Elf_Ehdr ehdr;
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
Elf64_Shdr *SectionHeaders = new Elf64_Shdr[ELFHeader.e_shnum];
fd->Read(SectionHeaders, sizeof(Elf64_Shdr) * ELFHeader.e_shnum, ELFHeader.e_shoff);
std::unique_ptr<Elf_Shdr[]> sections(new Elf_Shdr[ehdr.e_shnum]);
fs->Read(fd, sections.get(), sizeof(Elf_Shdr) * ehdr.e_shnum, ehdr.e_shoff);
char *SectionNames = new char[SectionHeaders[ELFHeader.e_shstrndx].sh_size];
fd->Read(SectionNames, SectionHeaders[ELFHeader.e_shstrndx].sh_size, SectionHeaders[ELFHeader.e_shstrndx].sh_offset);
std::string sectionNames(sections[ehdr.e_shstrndx].sh_size, '\0');
fs->Read(fd, sectionNames.data(), sections[ehdr.e_shstrndx].sh_size, sections[ehdr.e_shstrndx].sh_offset);
for (Elf64_Half i = 0; i < ELFHeader.e_shnum; ++i)
for (Elf_Half i = 0; i < ehdr.e_shnum; ++i)
{
const char *Name = SectionNames + SectionHeaders[i].sh_name;
const char *Name = sectionNames.data() + sections[i].sh_name;
if (strcmp(Name, SectionName) == 0)
Ret.push_back(SectionHeaders[i]);
ret.push_back(sections[i]);
}
delete[] SectionHeaders;
delete[] SectionNames;
return Ret;
#elif defined(__i386__)
return {};
#endif
return ret;
}
}

View File

@ -21,31 +21,26 @@
namespace Execute
{
std::vector<Elf64_Phdr> ELFGetSymbolType_x86_64(FileNode *fd,
SegmentTypes Tag)
std::vector<Elf_Phdr> ELFGetSymbolType(Node &fd, SegmentTypes Tag)
{
#if defined(__amd64__) || defined(__aarch64__)
std::vector<Elf64_Phdr> Ret;
std::vector<Elf_Phdr> ret;
Elf64_Ehdr ELFHeader{};
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
Elf_Ehdr ehdr;
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
Elf64_Phdr ProgramHeaders{};
fd->Read(&ProgramHeaders, sizeof(Elf64_Phdr), ELFHeader.e_phoff);
Elf_Phdr phdr;
fs->Read(fd, &phdr, sizeof(Elf_Phdr), ehdr.e_phoff);
off_t currentOffset = ELFHeader.e_phoff;
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
off_t off = ehdr.e_phoff;
for (Elf_Half i = 0; i < ehdr.e_phnum; i++)
{
if (ProgramHeaders.p_type == Tag)
Ret.push_back(ProgramHeaders);
if (phdr.p_type == Tag)
ret.push_back(phdr);
currentOffset += sizeof(Elf64_Phdr);
fd->Read(&ProgramHeaders, sizeof(Elf64_Phdr), currentOffset);
off += sizeof(Elf_Phdr);
fs->Read(fd, &phdr, sizeof(Elf_Phdr), off);
}
return Ret;
#elif defined(__i386__)
return {};
#endif
return ret;
}
}

View File

@ -30,19 +30,36 @@ using namespace Tasking;
namespace Execute
{
int Spawn(char *Path, const char **argv, const char **envp,
int Spawn(const char *Path, const char **argv, const char **envp,
Tasking::PCB *Parent, bool Fork,
Tasking::TaskCompatibility Compatibility,
bool Critical)
{
FileNode *fd = fs->GetByPath(Path, nullptr);
if (Parent == nullptr)
{
debug("no parent specified, using current process");
Parent = thisProcess;
}
Node fd = fs->Lookup(Parent->Info.RootNode, Path);
if (fd == nullptr)
return -ENOENT;
if (!fd->IsRegularFile())
{
if (fd->IsSymbolicLink())
{
char buffer[512];
fs->ReadLink(fd, buffer, sizeof(buffer));
fd = fs->Lookup(fd->Parent, buffer);
if (fd == nullptr)
return -ENOENT;
}
else
return -ENOEXEC;
}
switch (GetBinaryType(Path))
switch (GetBinaryType(fd))
{
case BinaryType::BinTypeELF:
{
@ -50,7 +67,7 @@ namespace Execute
const char *BaseName;
cwk_path_get_basename(Path, &BaseName, nullptr);
Elf32_Ehdr ELFHeader;
fd->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
fs->Read(fd, &ELFHeader, sizeof(Elf32_Ehdr), 0);
switch (ELFHeader.e_machine)
{
@ -97,11 +114,10 @@ namespace Execute
PCB *Process;
if (Fork)
{
assert(Parent != nullptr);
CriticalSection cs;
Process = Parent;
foreach (auto tcb in Process->Threads)
for (auto tcb : Process->Threads)
{
debug("Deleting thread %d", tcb->ID);
// delete tcb;
@ -113,17 +129,13 @@ namespace Execute
}
else
{
if (Parent == nullptr)
Parent = thisProcess;
Process = TaskManager->CreateProcess(Parent, BaseName,
TaskExecutionMode::User,
false, 0, 0);
Process = TaskManager->CreateProcess(Parent, BaseName, User, false, 0, 0);
Process->Info.Compatibility = Compatibility;
Process->Info.Architecture = Arch;
}
Process->SetWorkingDirectory(fs->GetByPath(Path, nullptr)->Parent);
Node cwdNode = fs->Lookup(Parent->Info.RootNode, Path);
Process->SetWorkingDirectory(fs->Convert(cwdNode->Parent));
Process->SetExe(Path);
ELFObject *obj = new ELFObject(Path, Process, argv, envp);
@ -137,38 +149,37 @@ namespace Execute
vfs::FileDescriptorTable *pfdt = Parent->FileDescriptors;
vfs::FileDescriptorTable *fdt = Process->FileDescriptors;
auto ForkStdio = [pfdt, fdt](FileNode *SearchNode)
auto ForkStdio = [pfdt, fdt](Node SearchNode)
{
if (unlikely(SearchNode == nullptr))
if (unlikely(SearchNode.get() == nullptr))
return false;
foreach (const auto &ffd in pfdt->FileMap)
for (const auto &ffd : pfdt->FileMap)
{
if (ffd.second.Flags & O_CLOEXEC)
continue;
if (ffd.second.Node == SearchNode)
{
fdt->usr_open(ffd.second.Node->Path.c_str(),
ffd.second.Flags, ffd.second.Mode);
if (ffd.second.node.get() != SearchNode.get())
continue;
fdt->usr_open(ffd.second.node->Path.c_str(), ffd.second.Flags, ffd.second.Mode);
return true;
}
}
return false;
};
fixme("remove workarounds for stdio and tty");
if (!Parent->tty)
Process->tty = KernelConsole::CurrentTerminal.load();
Process->tty = KernelConsole::CurrentTerminal.load()->Term;
if (!ForkStdio(Parent->stdin))
fdt->usr_open("/dev/kcon", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
fdt->usr_open("/dev/console", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (!ForkStdio(Parent->stdout))
fdt->usr_open("/dev/kcon", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
fdt->usr_open("/dev/console", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (!ForkStdio(Parent->stderr))
fdt->usr_open("/dev/kcon", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
fdt->usr_open("/dev/console", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
TCB *Thread = nullptr;
{

BIN
Kernel/files/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -15,7 +15,7 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <convert.h>
#include <stropts.h>
@ -47,8 +47,7 @@ namespace vfs
return 0;
}
int FileDescriptorTable::AddFileDescriptor(const char *AbsolutePath,
mode_t Mode, int Flags)
int FileDescriptorTable::AddFileDescriptor(const char *AbsolutePath, mode_t Mode, int Flags)
{
Tasking::PCB *pcb = thisProcess;
@ -77,8 +76,7 @@ namespace vfs
if (Flags & O_RDWR)
{
if (!(Mode & S_IRUSR) ||
!(Mode & S_IWUSR))
if (!(Mode & S_IRUSR) || !(Mode & S_IWUSR))
{
debug("No read/write permission (%d)", Mode);
return -EACCES;
@ -95,12 +93,11 @@ namespace vfs
if (Flags & O_CREAT)
{
FileNode *ret = fs->Create(pcb->CWD, AbsolutePath, Mode);
if (Flags & O_EXCL && ret == nullptr)
eNode ret = fs->Create(pcb->CWD, AbsolutePath, Mode);
if (Flags & O_EXCL && ret == false)
{
debug("%s: File already exists?, returning EEXIST",
AbsolutePath);
return -EEXIST;
debug("%s: File already exists?, returning %s", AbsolutePath, ret.what());
return -ret.Error;
}
}
@ -109,18 +106,18 @@ namespace vfs
fixme("O_CLOEXEC");
}
FileNode *File = fs->GetByPath(AbsolutePath, pcb->CWD);
if (!File)
eNode ret = fs->Lookup(pcb->CWD, AbsolutePath);
if (ret == false)
{
error("Failed to open file %s", AbsolutePath);
return -ENOENT;
error("Failed to open file %s, %s", AbsolutePath, ret.what());
return -ret.Error;
}
Node node = ret;
if (Flags & O_TRUNC)
{
debug("Truncating file %s", AbsolutePath);
File->Truncate(0);
fs->Truncate(node, 0);
}
Fildes fd{};
@ -129,13 +126,13 @@ namespace vfs
{
debug("Appending to file %s", AbsolutePath);
struct kstat stat;
File->Stat(&stat);
fd.Offset = File->Seek(stat.Size);
fs->Stat(node, &stat);
fd.Offset = fs->Seek(node, stat.Size);
}
fd.Mode = Mode;
fd.Flags = Flags;
fd.Node = File;
fd.node = node;
int fdn = this->GetFreeFileDescriptor();
if (fdn < 0)
@ -145,9 +142,8 @@ namespace vfs
char linkName[64];
snprintf(linkName, 64, "%d", fdn);
assert(fs->CreateLink(linkName, this->fdDir, AbsolutePath) != nullptr);
File->Open(Flags, Mode);
assert(fs->CreateLink(this->fdDir, linkName, AbsolutePath) == true);
fs->Open(node, Flags, Mode);
return fdn;
}
@ -157,7 +153,7 @@ namespace vfs
if (it == this->FileMap.end())
ReturnLogError(-EBADF, "Invalid fd %d", FileDescriptor);
fs->Remove(it->second.Node);
fs->Remove(it->second.node);
this->FileMap.erase(it);
return 0;
}
@ -209,7 +205,7 @@ namespace vfs
if (it == this->FileMap.end())
ReturnLogError(-EBADF, "Invalid fd %d", fd);
return it->second.Node->Read(buf, count, it->second.Offset);
return fs->Read(it->second.node, buf, count, it->second.Offset);
}
ssize_t FileDescriptorTable::usr_pread(int fd, void *buf, size_t count, off_t offset)
@ -218,7 +214,7 @@ namespace vfs
if (it == this->FileMap.end())
ReturnLogError(-EBADF, "Invalid fd %d", fd);
return it->second.Node->Read(buf, count, offset);
return fs->Read(it->second.node, buf, count, offset);
}
ssize_t FileDescriptorTable::usr_write(int fd, const void *buf, size_t count)
@ -227,7 +223,7 @@ namespace vfs
if (it == this->FileMap.end())
ReturnLogError(-EBADF, "Invalid fd %d", fd);
return it->second.Node->Write(buf, count, it->second.Offset);
return fs->Write(it->second.node, buf, count, it->second.Offset);
}
ssize_t FileDescriptorTable::usr_pwrite(int fd, const void *buf, size_t count, off_t offset)
@ -236,7 +232,7 @@ namespace vfs
if (it == this->FileMap.end())
ReturnLogError(-EBADF, "Invalid fd %d", fd);
return it->second.Node->Write(buf, count, offset);
return fs->Write(it->second.node, buf, count, offset);
}
int FileDescriptorTable::usr_close(int fd)
@ -260,21 +256,19 @@ namespace vfs
{
case SEEK_SET:
{
newOffset = it->second.Node->Seek(offset);
newOffset = fs->Seek(it->second.node, offset);
break;
}
case SEEK_CUR:
{
newOffset = it->second.Node->Seek(newOffset + offset);
newOffset = fs->Seek(it->second.node, newOffset + offset);
break;
}
case SEEK_END:
{
struct kstat stat
{
};
it->second.Node->Stat(&stat);
newOffset = it->second.Node->Seek(stat.Size + offset);
struct kstat stat{};
fs->Stat(it->second.node, &stat);
newOffset = fs->Seek(it->second.node, stat.Size + offset);
break;
}
default:
@ -284,48 +278,48 @@ namespace vfs
return newOffset;
}
int FileDescriptorTable::usr_stat(const char *pathname,
struct kstat *statbuf)
int FileDescriptorTable::usr_stat(const char *pathname, kstat *statbuf)
{
FileNode *node = fs->GetByPath(pathname, nullptr);
if (node == nullptr)
ReturnLogError(-ENOENT, "Failed to find %s", pathname);
Node root = thisProcess->Info.RootNode;
eNode ret = fs->Lookup(root, pathname);
if (ret == false)
ReturnLogError(-ret.Error, "Error on %s, %s", pathname, ret.what());
Node node = ret;
if (node->IsSymbolicLink())
{
std::unique_ptr<char[]> buffer(new char[1024]);
ssize_t ret = node->ReadLink(buffer.get(), 1024);
if (ret < 0)
return ret;
ssize_t len = fs->ReadLink(node, buffer.get(), 1024);
if (len < 0)
return len;
FileNode *target = fs->GetByPath(buffer.get(), nullptr);
if (target == nullptr)
return -ENOENT;
return target->Stat(statbuf);
ret = fs->Lookup(root, buffer.get());
if (ret == false)
return -ret.Error;
return fs->Stat(ret.Value, statbuf);
}
return node->Stat(statbuf);
return fs->Stat(node, statbuf);
}
int FileDescriptorTable::usr_fstat(int fd, struct kstat *statbuf)
int FileDescriptorTable::usr_fstat(int fd, kstat *statbuf)
{
auto it = this->FileMap.find(fd);
if (it == this->FileMap.end())
ReturnLogError(-EBADF, "Invalid fd %d", fd);
vfs::FileDescriptorTable::Fildes &fildes = it->second;
return fildes.Node->Stat(statbuf);
return fs->Stat(fildes.node, statbuf);
}
int FileDescriptorTable::usr_lstat(const char *pathname,
struct kstat *statbuf)
int FileDescriptorTable::usr_lstat(const char *pathname, kstat *statbuf)
{
FileNode *node = fs->GetByPath(pathname, nullptr);
if (node == nullptr)
ReturnLogError(-ENOENT, "Failed to find %s", pathname);
return node->Stat(statbuf);
Node root = thisProcess->Info.RootNode;
eNode ret = fs->Lookup(root, pathname);
if (ret == false)
ReturnLogError(-ret.Error, "Error on %s, %s", pathname, ret.what());
return fs->Stat(ret.Value, statbuf);
}
int FileDescriptorTable::usr_dup(int oldfd)
@ -339,7 +333,7 @@ namespace vfs
return -EMFILE;
Fildes new_dfd{};
new_dfd.Node = it->second.Node;
new_dfd.node = it->second.node;
new_dfd.Mode = it->second.Mode;
this->FileMap.insert({newfd, new_dfd});
@ -364,7 +358,7 @@ namespace vfs
this->usr_close(newfd);
Fildes new_dfd{};
new_dfd.Node = it->second.Node;
new_dfd.node = it->second.node;
new_dfd.Mode = it->second.Mode;
this->FileMap.insert({newfd, new_dfd});
@ -378,7 +372,7 @@ namespace vfs
if (it == this->FileMap.end())
ReturnLogError(-EBADF, "Invalid fd %d", fd);
return it->second.Node->Ioctl(request, argp);
return fs->Ioctl(it->second.node, request, argp);
}
FileDescriptorTable::FileDescriptorTable(void *_Owner)
@ -386,11 +380,12 @@ namespace vfs
{
debug("+ %#lx", this);
mode_t Mode = S_IXOTH | S_IROTH |
S_IXGRP | S_IRGRP |
S_IXUSR | S_IRUSR |
/* d r-x r-x r-x */
mode_t Mode = S_IROTH | S_IXOTH |
S_IRGRP | S_IXGRP |
S_IRUSR | S_IXUSR |
S_IFDIR;
this->fdDir = fs->Create(((Tasking::PCB *)_Owner)->ProcDirectory, "fd", Mode);
Tasking::PCB *pcb = (Tasking::PCB *)_Owner;
this->fdDir = fs->Create(pcb->ProcDirectory, "fd", Mode);
}
}

412
Kernel/fs/ramfs.cpp Normal file
View File

@ -0,0 +1,412 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <fs/ramfs.hpp>
#include <memory.hpp>
#include <functional>
#include <debug.h>
#include "../kernel.h"
namespace vfs
{
int RAMFS::Lookup(struct Inode *_Parent, const char *Name, struct Inode **Result)
{
auto Parent = (RAMFSInode *)_Parent;
const char *basename;
size_t length;
cwk_path_get_basename(Name, &basename, &length);
if (basename == NULL)
{
if (strcmp(Name, RootName.c_str()) == 0)
{
auto &it = Files.at(0);
*Result = &it->Node;
return 0;
}
error("Invalid name %s", Name);
return -EINVAL;
}
if (Parent)
{
for (auto &&child : Parent->Children)
{
if (strcmp(child->Name.c_str(), basename) != 0)
continue;
*Result = &child->Node;
return 0;
}
return -ENOENT;
}
for (auto &&i : Files)
{
RAMFSInode *node = i.second;
if (strcmp(node->Name.c_str(), basename) != 0)
continue;
*Result = &i.second->Node;
return 0;
}
return -ENOENT;
}
int RAMFS::Create(struct Inode *_Parent, const char *Name, mode_t Mode, struct Inode **Result)
{
RAMFSInode *Parent = (RAMFSInode *)_Parent;
Inode inode{};
inode.Mode = Mode;
inode.Device = this->DeviceID;
inode.RawDevice = 0;
inode.Index = NextInode;
inode.Offset = 0;
inode.PrivateData = this;
const char *basename;
size_t length;
cwk_path_get_basename(Name, &basename, &length);
RAMFSInode *node = new RAMFSInode;
node->Name.assign(basename, length);
node->Mode = Mode;
node->Node = inode;
auto file = Files.insert(std::make_pair(NextInode, node));
assert(file.second == true);
*Result = &Files.at(NextInode)->Node;
if (Parent)
Parent->AddChild(node);
NextInode++;
return 0;
}
ssize_t RAMFS::Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
{
auto fileItr = Files.find(Node->Index);
assert(fileItr != Files.end());
RAMFSInode *node = fileItr->second;
size_t fileSize = node->Stat.Size;
if (Size <= 0)
{
debug("Size is less than or equal to 0");
Size = fileSize;
}
if ((size_t)Offset > fileSize)
{
debug("Offset %d is greater than file size %d", Offset, fileSize);
return 0;
}
if ((fileSize - Offset) == 0)
{
debug("Offset %d is equal to file size %d", Offset, fileSize);
return 0; /* EOF */
}
if ((size_t)Offset + Size > fileSize)
{
debug("Offset %d + Size %d is greater than file size %d",
Offset, Size, fileSize);
Size = fileSize;
}
memcpy(Buffer, node->Buffer.Data, Size);
return Size;
}
ssize_t RAMFS::Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
{
auto fileItr = Files.find(Node->Index);
assert(fileItr != Files.end());
RAMFSInode *node = fileItr->second;
if (node->Buffer.IsAllocated() == false)
node->Buffer.Allocate(node->Stat.Size);
size_t fileSize = node->Stat.Size;
if (Size <= 0)
{
debug("Size is less than or equal to 0");
return -EINVAL;
}
if ((size_t)Offset > fileSize)
{
debug("Offset %d is greater than file size %d", Offset, fileSize);
node->Buffer.Allocate(Offset + Size, true, true);
}
if ((fileSize - Offset) == 0)
{
debug("Offset %d is equal to file size %d", Offset, fileSize);
node->Buffer.Allocate(Size, true, true);
}
if ((size_t)Offset + Size > fileSize)
{
debug("Offset %d + Size %d is greater than file size %d",
Offset, Size, fileSize);
node->Buffer.Allocate(Offset + Size, true, true);
}
memcpy(static_cast<char *>(node->Buffer.Data) + Offset, Buffer, Size);
node->Stat.Size = Size;
return Size;
}
__no_sanitize("alignment")
ssize_t RAMFS::ReadDir(struct Inode *_Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries)
{
/* FIXME: FIX ALIGNMENT FOR DIRENT! */
auto Node = (RAMFSInode *)_Node;
off_t realOffset = Offset;
size_t totalSize = 0;
uint16_t reclen = 0;
struct kdirent *ent = nullptr;
if (Offset == 0)
{
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(".") + 1);
if (totalSize + reclen >= Size)
return -EINVAL;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = Node->Node.Index;
ent->d_off = Offset++;
ent->d_reclen = reclen;
ent->d_type = DT_DIR;
strcpy(ent->d_name, ".");
totalSize += reclen;
}
if (Offset <= 1)
{
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen("..") + 1);
if (totalSize + reclen >= Size)
{
if (realOffset == 1)
return -EINVAL;
return totalSize;
}
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
if (Node->Parent)
ent->d_ino = Node->Parent->Node.Index;
else
{
warn("Parent is null for %s", Node->Name.c_str());
ent->d_ino = Node->Node.Index;
}
ent->d_off = Offset++;
ent->d_reclen = reclen;
ent->d_type = DT_DIR;
strcpy(ent->d_name, "..");
totalSize += reclen;
}
if (!S_ISDIR(Node->Node.Mode))
return -ENOTDIR;
if ((Offset >= 2 ? (Offset - 2) : Offset) > (off_t)Node->Children.size())
return -EINVAL;
off_t entries = 0;
for (const auto &var : Node->Children)
{
if (var->Node.Offset < Offset)
continue;
if (entries >= Entries)
break;
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(var->Name.c_str()) + 1);
if (totalSize + reclen >= Size)
break;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = var->Node.Index;
ent->d_off = var->Node.Offset;
ent->d_reclen = reclen;
if (S_ISREG(var->Stat.Mode))
ent->d_type = DT_REG;
else if (S_ISDIR(var->Stat.Mode))
ent->d_type = DT_DIR;
else if (S_ISLNK(var->Stat.Mode))
ent->d_type = DT_LNK;
else if (S_ISCHR(var->Stat.Mode))
ent->d_type = DT_CHR;
else if (S_ISBLK(var->Stat.Mode))
ent->d_type = DT_BLK;
else if (S_ISFIFO(var->Stat.Mode))
ent->d_type = DT_FIFO;
else if (S_ISSOCK(var->Stat.Mode))
ent->d_type = DT_SOCK;
else
ent->d_type = DT_UNKNOWN;
strncpy(ent->d_name, var->Name.c_str(), strlen(var->Name.c_str()));
totalSize += reclen;
entries++;
}
if (totalSize + sizeof(struct kdirent) >= Size)
return totalSize;
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = 0;
ent->d_off = 0;
ent->d_reclen = 0;
ent->d_type = DT_UNKNOWN;
ent->d_name[0] = '\0';
return totalSize;
}
int RAMFS::SymLink(struct Inode *Node, const char *Name, const char *Target, struct Inode **Result)
{
int ret = this->Create(Node, Name, S_IFLNK, Result);
if (ret < 0)
return ret;
RAMFSInode *node = (RAMFSInode *)*Result;
node->SymLink.assign(Target, strlen(Target));
return 0;
}
ssize_t RAMFS::ReadLink(struct Inode *Node, char *Buffer, size_t Size)
{
auto fileItr = Files.find(Node->Index);
assert(fileItr != Files.end());
RAMFSInode *node = fileItr->second;
if (node->SymLink.size() > Size)
Size = node->SymLink.size();
strncpy(Buffer, node->SymLink.data(), Size);
debug("Read link %d bytes from %d: \"%s\"", Size, Node->Index, Buffer);
return Size;
}
int RAMFS::Stat(struct Inode *Node, struct kstat *Stat)
{
auto fileItr = Files.find(Node->Index);
assert(fileItr != Files.end());
RAMFSInode *node = fileItr->second;
*Stat = node->Stat;
return 0;
}
}
int __ramfs_Lookup(struct Inode *Parent, const char *Name, struct Inode **Result)
{
return ((vfs::RAMFS *)Parent->PrivateData)->Lookup(Parent, Name, Result);
}
int __ramfs_Create(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result)
{
return ((vfs::RAMFS *)Parent->PrivateData)->Create(Parent, Name, Mode, Result);
}
ssize_t __ramfs_Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
{
return ((vfs::RAMFS *)Node->PrivateData)->Read(Node, Buffer, Size, Offset);
}
ssize_t __ramfs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
{
return ((vfs::RAMFS *)Node->PrivateData)->Write(Node, Buffer, Size, Offset);
}
ssize_t __ramfs_Readdir(struct Inode *Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries)
{
return ((vfs::RAMFS *)Node->PrivateData)->ReadDir(Node, Buffer, Size, Offset, Entries);
}
int __ramfs_SymLink(Inode *Parent, const char *Name, const char *Target, Inode **Result)
{
return ((vfs::RAMFS *)Parent->PrivateData)->SymLink(Parent, Name, Target, Result);
}
ssize_t __ramfs_ReadLink(Inode *Node, char *Buffer, size_t Size)
{
return ((vfs::RAMFS *)Node->PrivateData)->ReadLink(Node, Buffer, Size);
}
int __ramfs_Stat(struct Inode *Node, kstat *Stat)
{
return ((vfs::RAMFS *)Node->PrivateData)->Stat(Node, Stat);
}
int __ramfs_DestroyInode(FileSystemInfo *Info, Inode *Node)
{
vfs::RAMFS::RAMFSInode *inode = (vfs::RAMFS::RAMFSInode *)Node;
delete inode;
return 0;
}
int __ramfs_Destroy(FileSystemInfo *fsi)
{
assert(fsi->PrivateData);
delete (vfs::RAMFS *)fsi->PrivateData;
delete fsi;
return 0;
}
bool MountAndRootRAMFS(Node Parent, const char *Name, size_t Index)
{
vfs::RAMFS *ramfs = new vfs::RAMFS;
ramfs->RootName.assign(Name);
FileSystemInfo *fsi = new FileSystemInfo;
fsi->Name = "ramfs";
fsi->SuperOps.DeleteInode = __ramfs_DestroyInode;
fsi->SuperOps.Destroy = __ramfs_Destroy;
fsi->Ops.Lookup = __ramfs_Lookup;
fsi->Ops.Create = __ramfs_Create;
fsi->Ops.Read = __ramfs_Read;
fsi->Ops.Write = __ramfs_Write;
fsi->Ops.ReadDir = __ramfs_Readdir;
fsi->Ops.SymLink = __ramfs_SymLink;
fsi->Ops.ReadLink = __ramfs_ReadLink;
fsi->Ops.Stat = __ramfs_Stat;
fsi->PrivateData = ramfs;
ramfs->DeviceID = fs->RegisterFileSystem(fsi);
Inode *root = nullptr;
ramfs->Create(nullptr, Name, S_IFDIR | 0755, &root);
fs->Mount(Parent, root, Name, fsi);
fs->AddRoot(Index, fs->Convert(root));
return true;
}

View File

@ -15,13 +15,12 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <filesystem/ustar.hpp>
#include <fs/ustar.hpp>
#include <memory.hpp>
#include <functional>
#include <debug.h>
#include "../../kernel.h"
#include "../kernel.h"
#define TMAGIC "ustar"
#define TMAGLEN 6
@ -33,7 +32,7 @@ namespace vfs
int USTAR::Lookup(struct Inode *_Parent, const char *Name, struct Inode **Result)
{
auto Parent = (USTARInode *)_Parent;
debug("looking up for %s", Name);
const char *basename;
size_t length;
cwk_path_get_basename(Name, &basename, &length);
@ -92,7 +91,6 @@ namespace vfs
inode.Index = NextInode;
inode.Offset = 0;
inode.PrivateData = this;
inode.Flags = I_FLAG_CACHE_KEEP;
const char *basename;
size_t length;
@ -160,10 +158,14 @@ namespace vfs
node->Name.assign(basename, length);
node->Path.assign(Name, strlen(Name));
Files.insert(std::make_pair(NextInode, node));
auto file = Files.insert(std::make_pair(NextInode, node));
assert(file.second == true);
*Result = &Files.at(NextInode)->Node;
if (Parent)
{
Parent->Children.push_back(Files.at(NextInode));
Files.at(NextInode)->Parent = Parent;
}
NextInode++;
return 0;
}
@ -214,6 +216,7 @@ namespace vfs
{
/* FIXME: FIX ALIGNMENT FOR DIRENT! */
auto Node = (USTARInode *)_Node;
debug("reading directory %s", Node->Path.c_str());
off_t realOffset = Offset;
@ -234,6 +237,7 @@ namespace vfs
ent->d_type = DT_DIR;
strcpy(ent->d_name, ".");
totalSize += reclen;
debug(".");
}
if (Offset <= 1)
@ -260,6 +264,7 @@ namespace vfs
ent->d_type = DT_DIR;
strcpy(ent->d_name, "..");
totalSize += reclen;
debug("..");
}
// off_t entriesSkipped = 0;
@ -306,10 +311,13 @@ namespace vfs
if (var->Deleted)
continue;
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(var->Name.c_str()) + 1);
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + var->Name.size() + 1);
if (totalSize + reclen >= Size)
if (totalSize + reclen > Size)
{
debug("not enough space for %s (%zu + %zu = %zu > %zu)", var->Name.c_str(), totalSize, reclen, totalSize + reclen, Size);
break;
}
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = var->Node.Index;
@ -346,7 +354,7 @@ namespace vfs
break;
}
strncpy(ent->d_name, var->Name.c_str(), strlen(var->Name.c_str()));
debug("%s", var->Name.c_str());
totalSize += reclen;
entries++;
}
@ -389,7 +397,7 @@ namespace vfs
Size = strlen(node->Header->link);
strncpy(Buffer, node->Header->link, Size);
debug("Read %d bytes from %d", Size, Node->Index);
debug("Read %d bytes from %d: \"%s\"", Size, Node->Index, Buffer);
return Size;
}
@ -491,6 +499,10 @@ namespace vfs
FileHeader *header = (FileHeader *)Address;
if (strncmp(header->signature, TMAGIC, TMAGLEN) != 0)
{
/* For some reason if GRUB inflates the archive, the magic is "ustar " */
if (strncmp(header->signature, TMAGIC, TMAGLEN - 1) == 0)
return true;
error("Invalid signature!");
return false;
}
@ -564,7 +576,7 @@ namespace vfs
FileHeader *header = (FileHeader *)Address;
debug("USTAR signature valid! Name:%s Signature:%s Mode:%d Size:%lu",
debug("USTAR signature valid! Name:\"%s\" Signature:\"%s\" Mode:%d Size:%lu",
header->name, header->signature, StringToInt(header->mode), header->size);
Memory::Virtual vmm;
@ -577,7 +589,7 @@ namespace vfs
return;
}
if (strncmp(header->signature, TMAGIC, TMAGLEN) != 0)
if (strncmp(header->signature, TMAGIC, TMAGLEN - 1) != 0)
break;
// debug("\"%s\"", header->name);
@ -594,7 +606,6 @@ namespace vfs
uNode.RawDevice = 0;
uNode.Index = NextInode;
SetMode(uNode, header);
uNode.Flags = I_FLAG_CACHE_KEEP;
uNode.Offset = 0;
uNode.PrivateData = this;
@ -817,13 +828,13 @@ O2 int __ustar_Stat(struct Inode *Node, kstat *Stat)
return ((vfs::USTAR *)Node->PrivateData)->Stat(Node, Stat);
}
int __ustar_DestroyInode(FileSystemInfo *Info, Inode *Node)
O2 int __ustar_DestroyInode(FileSystemInfo *Info, Inode *Node)
{
((vfs::USTAR::USTARInode *)Node)->Deleted = true;
return 0;
}
int __ustar_Destroy(FileSystemInfo *fsi)
O2 int __ustar_Destroy(FileSystemInfo *fsi)
{
assert(fsi->PrivateData);
delete (vfs::USTAR *)fsi->PrivateData;
@ -831,7 +842,7 @@ int __ustar_Destroy(FileSystemInfo *fsi)
return 0;
}
bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size)
bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size, size_t Index)
{
vfs::USTAR *ustar = new vfs::USTAR();
if (!ustar->TestArchive(Address))
@ -840,17 +851,8 @@ bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size)
return false;
}
ustar->DeviceID = fs->EarlyReserveDevice();
ustar->ReadArchive(Address, Size);
Inode *initrd = nullptr;
ustar->Lookup(nullptr, "/", &initrd);
assert(initrd != nullptr);
FileSystemInfo *fsi = new FileSystemInfo;
fsi->Name = "ustar";
fsi->RootName = "/";
fsi->Flags = I_FLAG_ROOT | I_FLAG_MOUNTPOINT | I_FLAG_CACHE_KEEP;
fsi->SuperOps.DeleteInode = __ustar_DestroyInode;
fsi->SuperOps.Destroy = __ustar_Destroy;
fsi->Ops.Lookup = __ustar_Lookup;
@ -861,8 +863,23 @@ bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size)
fsi->Ops.ReadLink = __ustar_ReadLink;
fsi->Ops.Stat = __ustar_Stat;
fsi->PrivateData = ustar;
fs->LateRegisterFileSystem(ustar->DeviceID, fsi, initrd);
fs->AddRoot(initrd);
ustar->DeviceID = fs->RegisterFileSystem(fsi);
ustar->ReadArchive(Address, Size);
Inode *rootfs = nullptr;
ustar->Lookup(nullptr, "/", &rootfs);
assert(rootfs != nullptr);
eNode _node = fs->Convert(rootfs);
assert(_node.Error == 0);
Node node = _node;
node->fsi = fsi;
node->Flags.MountPoint = true;
node->Name = "/";
node->Path = "/";
fs->AddRoot(Index, node);
return true;
}

627
Kernel/fs/vfs.cpp Normal file
View File

@ -0,0 +1,627 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <fs/vfs.hpp>
#include "../kernel.h"
namespace vfs
{
eNode Virtual::Convert(Inode *inode)
{
Node cache = std::make_shared<NodeCache>();
cache->inode = inode;
return {cache, 0};
}
eNode Virtual::Convert(Node &Parent, Inode *inode)
{
Node cache = std::make_shared<NodeCache>();
cache->inode = inode;
cache->fsi = Parent->fsi;
cache->Parent = Parent;
Parent->Children.push_back(cache);
return {cache, 0};
}
std::string Virtual::NormalizePath(Node &Parent, std::string Path, bool Join)
{
std::string result;
if (Join)
{
size_t len = Path.size() + Parent->Path.size() + 2;
result.reserve(len);
len = cwk_path_join(Parent->Path.c_str(), Path.c_str(), result.data(), result.capacity());
result.resize(len);
return result;
}
size_t len = Path.size() + 2;
result.reserve(len);
len = cwk_path_normalize(Path.c_str(), result.data(), result.capacity());
result.resize(len);
return result;
}
bool Virtual::RootExists(dev_t Index)
{
if (Roots.find(Index) == Roots.end())
return false;
return true;
}
eNode Virtual::GetRoot(dev_t Index)
{
auto it = Roots.find(Index);
if (it == Roots.end())
return {nullptr, ENOENT};
return {it->second, 0};
}
ssize_t Virtual::GetRoot(Node Index)
{
for (auto it = Roots.begin(); it != Roots.end(); ++it)
{
if (it->second == Index)
return it->first;
}
return -ENOENT;
}
int Virtual::AddRoot(dev_t Index, Node Root, bool Replace)
{
assert(Root != nullptr);
auto it = Roots.find(Index);
if (it == Roots.end())
{
Roots[Index] = Root;
return 0;
}
if (Replace)
{
Roots[Index] = Root;
return 0;
}
else
{
debug("Root %ld already exists", Index);
return EEXIST;
}
}
dev_t Virtual::RegisterFileSystem(FileSystemInfo *fsi)
{
assert(fsi != nullptr);
FileSystems.insert({FileSystems.size(), fsi});
return FileSystems.size() - 1;
}
int Virtual::UnregisterFileSystem(dev_t Device)
{
auto it = FileSystems.find(Device);
if (it == FileSystems.end())
return -ENOENT;
FileSystemInfo *fsi = it->second;
/* TODO: unmount */
fixme("Unmounting %d", Device);
if (fsi->SuperOps.Synchronize)
fsi->SuperOps.Synchronize(fsi, nullptr);
if (fsi->SuperOps.Destroy)
fsi->SuperOps.Destroy(fsi);
FileSystems.erase(it);
return 0;
}
eNode Virtual::Lookup(Node &Parent, std::string Path)
{
assert(Parent != nullptr);
debug("looking up \"%s\" in \"%s\"", Path.c_str(), Parent->Path.c_str());
if (Path == ".")
return {Parent, 0};
else if (Path == "..")
return {Parent->Parent ? Parent->Parent : Parent, 0};
Node base = Parent;
bool absolute = PathIsAbsolute(Path);
if (absolute == true)
{
while (base->Parent)
base = base->Parent;
}
debug("base is \"%s\" and path is \"%s\" %d", base->Path.c_str(), Path.c_str(), absolute);
Path = this->NormalizePath(base, Path, !absolute);
debug("after normalizing, path is \"%s\" %d", Path.c_str(), absolute);
struct cwk_segment segment;
if (!cwk_path_get_first_segment(Path.c_str(), &segment))
{
debug("%s no segments; %d", Path.c_str(), absolute);
if (Path == "/")
return {base, 0};
assert(!"Path doesn't have any segments.");
}
Node node = base;
/* We need to go to the root after NormalizePath even if Path is relative */
if (absolute == false)
{
while (node->Parent)
{
debug("current parent \"%s\"", node->Parent->Path.c_str());
node = node->Parent;
debug("new parent \"%s\"", node->Parent ? node->Parent->Path.c_str() : "<null>");
}
}
std::string currentPath = node->Path;
if (currentPath.empty())
currentPath = "/";
do
{
std::string segmentStr(segment.begin, segment.size);
debug("Current segment is \"%s\"", segmentStr.c_str());
eNode ret = node->CachedSearch(segmentStr);
if (ret == false)
{
debug("cache miss for \"%s\"", segmentStr.c_str());
if (node->fsi->Ops.Lookup == nullptr)
return {nullptr, ENOTSUP};
Inode *inode;
int ret = node->fsi->Ops.Lookup(node->inode, segmentStr.c_str(), &inode);
if (ret != 0)
return {nullptr, ret};
if (currentPath == "/")
currentPath += segmentStr;
else
currentPath += "/" + segmentStr;
node = Convert(node, inode);
node->Name = segmentStr;
node->Path = currentPath;
}
else
{
debug("cache hit for \"%s\"", segmentStr.c_str());
node = ret;
if (currentPath == "/")
currentPath += segmentStr;
else
currentPath += "/" + segmentStr;
}
} while (cwk_path_get_next_segment(&segment));
return {node, 0};
}
eNode Virtual::Create(Node &Parent, std::string Name, mode_t Mode, bool ErrorIfExists)
{
eNode exists = this->Lookup(Parent, Name);
if (exists)
{
if (ErrorIfExists)
return {nullptr, EEXIST};
/* I should handle this in a better way */
assert((exists.Value->inode->Mode & S_IFMT) == (Mode & S_IFMT));
debug("File \"%s\" already exists in cache", Name.c_str());
return exists;
}
if (!Parent)
return {nullptr, EINVAL};
if (Parent->fsi->Ops.Create == nullptr)
return {nullptr, ENOTSUP};
Inode *inode;
int ret = Parent->fsi->Ops.Create(Parent->inode, Name.c_str(), Mode, &inode);
if (ret != 0)
return {nullptr, ret};
Node node = Convert(Parent, inode);
node->Name = Name;
std::string unormalized = Parent->Path == "/" ? "/" + Name : Parent->Path + "/" + Name;
node->Path = fs->NormalizePath(Parent, unormalized);
return {node, 0};
}
int Virtual::Remove(Node &Parent, std::string Name)
{
if (!Parent)
return -EINVAL;
if (Parent->fsi->Ops.Remove == nullptr)
return -ENOTSUP;
int ret = Parent->fsi->Ops.Remove(Parent->inode, Name.c_str());
if (ret == 0)
{
for (auto it = Parent->Children.begin(); it != Parent->Children.end(); ++it)
{
if (it->get()->Name != Name)
continue;
Parent->Children.erase(it);
break;
}
}
return ret;
}
int Virtual::Remove(Node &node)
{
if (!node->Parent)
return -EINVAL;
if (node->Parent->fsi->Ops.Remove == nullptr)
return -ENOTSUP;
int ret = node->Parent->fsi->Ops.Remove(node->inode, node->Name.c_str());
if (ret == 0)
{
Node &p = node->Parent;
for (auto it = p->Children.begin(); it != p->Children.end(); ++it)
{
if (it->get() != node.get())
continue;
p->Children.erase(it);
break;
}
}
return ret;
}
int Virtual::Rename(Node &node, std::string NewName)
{
if (node->fsi->Ops.Rename == nullptr)
return -ENOTSUP;
int ret = node->fsi->Ops.Rename(node->inode, node->Name.c_str(), NewName.c_str());
if (ret == 0)
node->Name = NewName;
return ret;
}
ssize_t Virtual::Read(Node &Target, void *Buffer, size_t Size, off_t Offset)
{
if (Target->IsDirectory() || Target->IsMountPoint())
return -EISDIR;
if (Target->IsSymbolicLink())
return -EINVAL;
/* TODO: cache buffer */
return Target->__Read(Buffer, Size, Offset);
}
ssize_t Virtual::Write(Node &Target, const void *Buffer, size_t Size, off_t Offset)
{
if (Target->IsDirectory() || Target->IsMountPoint())
return -EISDIR;
if (Target->IsSymbolicLink())
return -EINVAL;
/* TODO: cache buffer */
return Target->__Write(Buffer, Size, Offset);
}
int Virtual::Truncate(Node &Target, off_t Size)
{
if (Target->IsDirectory() || Target->IsMountPoint())
return -EISDIR;
if (!Target->IsRegularFile())
return -EINVAL;
/* TODO: cache buffer */
return Target->__Truncate(Size);
}
__no_sanitize("alignment") ssize_t Virtual::ReadDirectory(Node &Target, kdirent *Buffer, size_t Size, off_t Offset, off_t Entries)
{
if (!Target->IsDirectory() && !Target->IsMountPoint())
return -ENOTDIR;
ssize_t total = 0;
off_t entryIndex = 0;
std::list<std::string> seen;
uint8_t *bufPtr = reinterpret_cast<uint8_t *>(Buffer);
if (Target->fsi && Target->fsi->Ops.ReadDir)
{
const size_t tempBufSize = 4096;
std::unique_ptr<uint8_t[]> tempBuf(new uint8_t[tempBufSize]);
off_t fsOffset = Offset;
ssize_t read = Target->fsi->Ops.ReadDir(Target->inode, (kdirent *)tempBuf.get(), tempBufSize, fsOffset, Entries);
if (read > 0)
{
ssize_t pos = 0;
while (pos < read)
{
kdirent *ent = (kdirent *)(tempBuf.get() + pos);
if (ent->d_reclen == 0)
break;
size_t reclen = ent->d_reclen;
if (total + reclen > Size)
break;
memcpy(bufPtr, ent, reclen);
seen.push_back(ent->d_name);
bufPtr += reclen;
total += reclen;
pos += reclen;
entryIndex++;
}
}
}
for (const auto &child : Target->Children)
{
if (std::find(seen.begin(), seen.end(), child->Name) != seen.end())
continue;
if (entryIndex < Offset)
{
entryIndex++;
continue;
}
uint16_t reclen = (uint16_t)(offsetof(struct kdirent, d_name) + child->Name.size() + 1);
if (total + reclen > (ssize_t)Size)
break;
kdirent *ent = (kdirent *)bufPtr;
ent->d_ino = child->inode ? child->inode->Index : 0;
ent->d_off = entryIndex++;
ent->d_reclen = reclen;
ent->d_type = child->inode ? IFTODT(child->inode->Mode) : DT_UNKNOWN;
strcpy(ent->d_name, child->Name.c_str());
bufPtr += reclen;
total += reclen;
seen.push_back(child->Name);
}
return total;
}
__no_sanitize("alignment") std::list<Node> Virtual::ReadDirectory(Node &Target)
{
if (!Target->IsDirectory() && !Target->IsMountPoint())
return {};
std::list<Node> ret;
std::list<std::string> seen;
if (Target->fsi && Target->fsi->Ops.ReadDir)
{
const size_t bufSize = 4096;
std::unique_ptr<uint8_t[]> buf(new uint8_t[bufSize]);
off_t offset = 0;
while (true)
{
ssize_t read = Target->fsi->Ops.ReadDir(Target->inode, (kdirent *)buf.get(), bufSize, offset, LONG_MAX);
if (read <= 0)
break;
ssize_t pos = 0;
while (pos < read)
{
kdirent *ent = (kdirent *)(buf.get() + pos);
if (ent->d_reclen == 0)
break;
debug("%s", ent->d_name);
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
{
pos += ent->d_reclen;
continue;
}
seen.push_back(ent->d_name);
auto it = std::find_if(Target->Children.begin(), Target->Children.end(),
[&](const Node &n)
{ return n->Name == ent->d_name; });
if (it != Target->Children.end())
ret.push_back(*it);
else
{
eNode result = Lookup(Target, ent->d_name);
if (result.Error == 0 && result.Value)
{
Target->Children.push_back(result.Value);
result.Value->Parent = Target;
ret.push_back(result.Value);
}
}
pos += ent->d_reclen;
}
offset += read;
}
}
for (const auto &child : Target->Children)
{
if (std::find(seen.begin(), seen.end(), child->Name) != seen.end())
continue;
if (child->Name == "." || child->Name == "..")
continue;
ret.push_back(child);
seen.push_back(child->Name.c_str());
}
return ret;
}
eNode Virtual::CreateLink(Node &Parent, std::string Name, std::string Target)
{
mode_t mode = S_IRWXU |
S_IRWXG |
S_IRWXO |
S_IFLNK;
eNode enode = this->Create(Parent, Name, mode);
if (!enode)
return enode;
Node node = enode;
node->Link = Target;
return {node, 0};
}
int Virtual::Stat(Node &Target, struct kstat *Stat)
{
/* TODO: cache */
return Target->__Stat(Stat);
}
off_t Virtual::Seek(Node &Target, off_t Offset)
{
/* TODO: cache */
return Target->__Seek(Offset);
}
int Virtual::Open(Node &Target, int Flags, mode_t Mode)
{
/* TODO: cache */
return Target->__Open(Flags, Mode);
}
int Virtual::Close(Node &Target)
{
/* TODO: cache */
return Target->__Close();
}
FileSystemInfo *Virtual::Probe(FileSystemDevice *Device)
{
for (auto &&i : FileSystems)
{
if (i.second->SuperOps.Probe == nullptr)
{
debug("%s does not support probing", i.second->Name);
continue;
}
int ret = i.second->SuperOps.Probe(Device);
if (ret == 0)
return i.second;
debug("%s returned %d", i.second->Name, ret);
}
debug("No filesystems matched");
return nullptr;
}
eNode Virtual::Mount(Node &Parent, Inode *inode, std::string Name, FileSystemInfo *fsi)
{
assert(Parent);
assert(inode);
Node ret = this->Convert(inode);
ret->fsi = fsi;
ret->Name = Name;
std::string unormalized = Parent->Path == "/" ? "/" + Name : Parent->Path + "/" + Name;
ret->Path = fs->NormalizePath(Parent, unormalized);
// ret->Link =
ret->Parent = Parent;
Parent->Children.push_back(ret);
return {ret, 0};
}
eNode Virtual::Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device)
{
Inode *inode;
int ret = fsi->SuperOps.Mount(fsi, &inode, Device);
if (ret != 0)
return {nullptr, ret};
return this->Mount(Parent, inode, Name, fsi);
// Node node = std::make_shared<NodeCache>();
// node->inode = nullptr; /* FIXME: ??? */
// node->fsi = fsi;
// node->Flags.MountPoint = true;
// node->Name = Name;
// node->Path = fs->NormalizePath(Parent, Parent->Path + "/" + Name);
// node->Parent = Parent;
// Parent->Children.push_back(node);
// return {node, 0};
}
int Virtual::Umount(Node &node)
{
if (!node->Flags.MountPoint)
{
debug("node %s is not a mountpoint", node->Path.c_str());
return -EINVAL;
}
fixme("untested code");
std::shared_ptr<NodeCache> &ptr = node;
ptr.reset();
return 0;
}
int Virtual::Umount(Node &Parent, std::string Name)
{
eNode node = Parent->CachedSearch(Name);
if (!node)
{
debug("mountpoint %s not found: %s", Name.c_str(), node.what());
return -node.Error;
}
return this->Umount(node.Value);
}
void Virtual::Initialize()
{
debug("Initializing virtual file system...");
Node root = this->GetRoot(0);
/* d rwx rwx rwx */
mode_t mode = S_IRWXU |
S_IRWXG |
S_IRWXO |
S_IFDIR;
Node var = this->Create(root, "var", mode, false);
Node log = this->Create(var, "log", mode, false);
}
Virtual::Virtual() {}
Virtual::~Virtual() {}
}

51
Kernel/gdb_printers.py Normal file
View File

@ -0,0 +1,51 @@
import gdb
class BasicStringPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
try:
data = self.val['_data']
size = int(self.val['_size'])
capacity = int(self.val['_capacity'])
if int(data) == 0:
return '<null>'
content = data.string(length=size)
return f"'{content}' (size={size}, cap={capacity})"
except gdb.error:
return '<invalid string>'
def children(self):
try:
data = self.val['_data']
size = int(self.val['_size'])
if int(data) == 0:
return
for i in range(size):
yield (f'[{i}]', (data + i).dereference())
except gdb.error:
return
def display_hint(self):
return 'array'
def lookup_fennix_string(val):
try:
typename = str(val.type.strip_typedefs())
fields = val.type.fields()
field_names = [f.name for f in fields]
if '_data' in field_names and '_size' in field_names and '_capacity' in field_names:
return BasicStringPrinter(val)
except:
pass
return None
gdb.pretty_printers.append(lookup_fennix_string)
def build_pretty_printers():
pp = gdb.printing.RegexpCollectionPrettyPrinter("fennix")
pp.add_printer('std::string', '^std::string$', BasicStringPrinter)
return pp
gdb.printing.register_pretty_printer(None, build_pretty_printers(), replace=True)

View File

@ -193,11 +193,63 @@ namespace ACPI
struct BGRTHeader
{
ACPIHeader Header;
/**
* Version. This value must be 1.
*/
uint16_t Version;
uint8_t Status;
/**
* Status of the image
*/
union
{
struct
{
/**
* Indicates that the image graphic is displayed.
*/
uint8_t Displayed : 1;
/**
* Orientation
*
* 0b00 - 0˚
* 0b01 - 90˚
* 0b10 - 180˚
* 0b11 - 270˚
*/
uint8_t OrientationOffset : 2;
/**
* This field is reserved and must be zero.
*/
uint8_t Reserved : 5;
};
uint8_t raw;
} Status;
/**
* Image type
*
* 0 - Bitmap
* 1-255 - Reserved
*/
uint8_t ImageType;
/**
* Physical address of the image pointing to firmware's in-memory copy of the image bitmap.
*/
uint64_t ImageAddress;
/**
* X-offset of the boot image.
*/
uint32_t ImageOffsetX;
/**
* Y-offset of the boot image.
*/
uint32_t ImageOffsetY;
} __packed;

View File

@ -150,6 +150,33 @@ struct BootInfo
} Bootloader;
void *SMBIOSPtr;
struct EFIInfo
{
union
{
struct
{
__UINT8_TYPE__ Enabled : 1;
__UINT8_TYPE__ BS : 1;
__UINT8_TYPE__ IH : 1;
__UINT8_TYPE__ ST : 1;
__UINT8_TYPE__ MemoryMap : 1;
} __attribute__((packed));
__UINT8_TYPE__ raw;
} Info;
struct
{
void *BaseAddress;
__SIZE_TYPE__ DescriptorSize;
__SIZE_TYPE__ DescriptorVersion;
__SIZE_TYPE__ NumberOfEntries;
} MemoryMap;
void *ImageHandle;
void *SystemTable;
} EFI;
};
#endif // !__FENNIX_KERNEL_BOOT_INFO_H__

View File

@ -72,12 +72,11 @@
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
#define MULTIBOOT_ARCHITECTURE_I386 0
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
#define MULTIBOOT2_ARCHITECTURE_I386 0
#define MULTIBOOT2_ARCHITECTURE_MIPS32 4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0

View File

@ -33,10 +33,14 @@ SOFTWARE.
#ifndef CAG_LIBRARY_H
#define CAG_LIBRARY_H
#include <types.h>
typedef unsigned int FILE; // TODO: Implement FILE
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
/**
* The following defines CAG_EXPORT and CAG_IMPORT which are required to export
* shared library functions.
*/
#if defined(_WIN32) || defined(__CYGWIN__)
#define CAG_EXPORT __declspec(dllexport)
#define CAG_IMPORT __declspec(dllimport)
@ -48,6 +52,10 @@ typedef unsigned int FILE; // TODO: Implement FILE
#define CAG_IMPORT
#endif
/**
* This block defines CAG_PUBLIC, which only uses CAG_EXPORT and CAG_IMPORT if
* the cargs is compiled as a shared library.
*/
#if defined(CAG_SHARED)
#if defined(CAG_EXPORTS)
#define CAG_PUBLIC CAG_EXPORT
@ -58,6 +66,16 @@ typedef unsigned int FILE; // TODO: Implement FILE
#define CAG_PUBLIC
#endif
/**
* This block defines CAG_DEPRECATED which can be used to deprecate library
* functions including a comment on the deprecation.
*/
#if (!__cplusplus && __STDC_VERSION__ >= 202311L) || (__cplusplus >= 201402L)
#define CAG_DEPRECATED(comment) [[deprecated(comment)]]
#else
#define CAG_DEPRECATED(comment)
#endif
#ifdef __cplusplus
extern "C"
{
@ -88,29 +106,24 @@ extern "C"
char **argv;
int index;
int inner_index;
int error_index;
char error_letter;
bool forced_end;
char identifier;
char *value;
} cag_option_context;
/**
* Prototype for printer used in cag_option_printer. For example fprintf have
* same prototype
*/
typedef int (*cag_printer)(void *ctx, const char *fmt, ...);
/**
* This is just a small macro which calculates the size of an array.
*/
#define CAG_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/**
* @brief Prints all options to the terminal.
*
* This function prints all options to the terminal. This can be used to
* generate the output for a "--help" option.
*
* @param options The options which will be printed.
* @param option_count The option count which will be printed.
* @param destination The destination where the output will be printed.
*/
CAG_PUBLIC void cag_option_print(const cag_option *options, size_t option_count,
FILE *destination);
/**
* @brief Prepare argument options context for parsing.
*
@ -125,7 +138,7 @@ extern "C"
* @param argc The amount of arguments the user supplied in the main function.
* @param argv A pointer to the arguments of the main function.
*/
CAG_PUBLIC void cag_option_prepare(cag_option_context *context,
CAG_PUBLIC void cag_option_init(cag_option_context *context,
const cag_option *options, size_t option_count, int argc, char **argv);
/**
@ -154,7 +167,7 @@ extern "C"
* @param context The context from which the option was fetched.
* @return Returns the identifier of the option.
*/
CAG_PUBLIC char cag_option_get(const cag_option_context *context);
CAG_PUBLIC char cag_option_get_identifier(const cag_option_context *context);
/**
* @brief Gets the value from the option.
@ -180,6 +193,105 @@ extern "C"
*/
CAG_PUBLIC int cag_option_get_index(const cag_option_context *context);
/**
* @brief Retrieves the index of an invalid option.
*
* This function retrieves the index of an invalid option if the provided option
* does not match any of the options specified in the `cag_option` list. This is
* particularly useful when detailed information about an invalid option is
* required.
*
* @param context Pointer to the context from which the option was fetched.
* @return Returns the index of the invalid option, or -1 if it is not invalid.
*/
CAG_PUBLIC int cag_option_get_error_index(const cag_option_context *context);
/**
* @brief Retrieves the letter character of the invalid option.
*
* This function retrieves the character of the invalid option character
* if the provided option does not match any of the options specified in the
* `cag_option` list.
*
* @param context Pointer to the context from which the option was fetched.
* @return Returns the letter that was unknown, or 0 otherwise.
*/
CAG_PUBLIC char cag_option_get_error_letter(const cag_option_context *context);
/**
* @brief Prints the error associated with the invalid option to the specified
* destination.
*
* This function prints information about the error associated with the invalid
* option to the specified destination (such as a file stream). It helps in
* displaying the error of the current context.
*
* @param context Pointer to the context from which the option was fetched.
* @param destination Pointer to the file stream where the error information
* will be printed.
*/
#ifndef CAG_NO_FILE
CAG_PUBLIC void cag_option_print_error(const cag_option_context *context,
FILE *destination);
#endif
/**
* @brief Prints the error associated with the invalid option using user
* callback.
*
* This function prints information about the error associated with the invalid
* option using user callback. Callback prototype is same with fprintf. It helps
* in displaying the error of the current context.
*
* @param context Pointer to the context from which the option was fetched.
* @param printer The printer callback function. For example fprintf.
* @param printer_ctx The parameter for printer callback. For example fprintf
* could use parameter stderr.
*/
CAG_PUBLIC void cag_option_printer_error(const cag_option_context *context,
cag_printer printer, void *printer_ctx);
/**
* @brief Prints all options to the terminal.
*
* This function prints all options to the terminal. This can be used to
* generate the output for a "--help" option.
*
* @param options The options which will be printed.
* @param option_count The option count which will be printed.
* @param destination The destination where the output will be printed.
*/
#ifndef CAG_NO_FILE
CAG_PUBLIC void cag_option_print(const cag_option *options, size_t option_count,
FILE *destination);
#endif
/**
* @brief Prints all options using user callback.
*
* This function prints all options using user callback. This can be used to
* generate the output for a "--help" option.
* Using user callback is useful in tiny system without FILE support
*
* @param options The options which will be printed.
* @param option_count The option count which will be printed.
* @param destination The destination where the output will be printed.
* @param printer The printer callback function. For example fprintf.
* @param printer_ctx The parameter for printer callback. For example fprintf
* could use parameter stderr.
*/
CAG_PUBLIC void cag_option_printer(const cag_option *options,
size_t option_count, cag_printer printer, void *printer_ctx);
CAG_DEPRECATED(
"cag_option_prepare has been deprecated. Use cag_option_init instead.")
CAG_PUBLIC void cag_option_prepare(cag_option_context *context,
const cag_option *options, size_t option_count, int argc, char **argv);
CAG_DEPRECATED(
"cag_option_get has been deprecated. Use cag_option_get_identifier instead.")
CAG_PUBLIC char cag_option_get(const cag_option_context *context);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -0,0 +1,202 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <types.h>
#include <debug.h>
#if defined(__amd64__)
typedef uint64_t cpuid_t;
#elif defined(__i386__)
typedef uint32_t cpuid_t;
#else
typedef uint64_t cpuid_t;
#endif // __amd64__ || __i386__
#if defined(__amd64__) || defined(__i386__)
#define __kvm_cpuid_init(leaf) \
CPUID##leaf() \
{ \
asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), \
"=c"(ECX.raw), "=d"(EDX.raw) : "a"(leaf)); \
if (!EAX.raw && !EBX.raw && !ECX.raw && !EDX.raw) \
warn("cpuid not supported"); \
}
#define __kvm_cpuid_init2(leaf, leaf2, suffix) \
CPUID##leaf##suffix() \
{ \
asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), \
"=c"(ECX.raw), "=d"(EDX.raw) : "a"(leaf), "c"(leaf2)); \
if (!EAX.raw && !EBX.raw && !ECX.raw && !EDX.raw) \
warn("cpuid not supported"); \
}
#else
#define __kvm_cpuid_init(leaf) \
CPUID##leaf() \
{ \
}
#define __kvm_cpuid_init2(leaf, leaf2, suffix) \
CPUID##leaf##suffix() \
{ \
}
#endif
namespace CPU
{
namespace x86
{
namespace KVM
{
/* KVM_CPUID_SIGNATURE */
struct CPUID0x40000000
{
__kvm_cpuid_init(0x40000000);
union
{
struct
{
uint32_t MaximumFunction : 32;
};
cpuid_t raw;
} EAX;
union
{
struct
{
char Vendor[4];
};
cpuid_t raw;
} EBX;
union
{
struct
{
char Vendor[4];
};
cpuid_t raw;
} ECX;
union
{
struct
{
char Vendor[4];
};
cpuid_t raw;
} EDX;
};
/* KVM_CPUID_FEATURES */
struct CPUID0x40000001
{
__kvm_cpuid_init(0x40000001);
union
{
struct
{
/** kvmclock available at msrs 0x11 and 0x12 */
uint32_t KVM_FEATURE_CLOCKSOURCE : 1;
/** not necessary to perform delays on PIO operations */
uint32_t KVM_FEATURE_NOP_IO_DELAY : 1;
/** deprecated */
uint32_t KVM_FEATURE_MMU_OP : 1;
/** kvmclock available at msrs 0x4b564d00 and 0x4b564d01 */
uint32_t KVM_FEATURE_CLOCKSOURCE2 : 1;
/** async pf can be enabled by writing to msr 0x4b564d02 */
uint32_t KVM_FEATURE_ASYNC_PF : 1;
/** steal time can be enabled by writing to msr 0x4b564d03 */
uint32_t KVM_FEATURE_STEAL_TIME : 1;
/** paravirtualized end of interrupt handler can be enabled by writing to msr 0x4b564d04 */
uint32_t KVM_FEATURE_PV_EOI : 1;
/** guest checks this feature bit before enabling paravirtualized spinlock support */
uint32_t KVM_FEATURE_PV_UNHAULT : 1;
uint32_t _reserved8 : 1;
/** guest checks this feature bit before enabling paravirtualized tlb flush */
uint32_t KVM_FEATURE_PV_TLB_FLUSH : 1;
/** paravirtualized async PF VM EXIT can be enabled by setting bit 2 when writing to msr 0x4b564d02 */
uint32_t KVM_FEATURE_ASYNC_PF_VMEXIT : 1;
/** guest checks this feature bit before enabling paravirtualized send IPIs */
uint32_t KVM_FEATURE_PV_SEND_IPI : 1;
/** host-side polling on HLT can be disabled by writing to msr 0x4b564d05 */
uint32_t KVM_FEATURE_PV_POLL_CONTROL : 1;
/** guest checks this feature bit before using paravirtualized sched yield */
uint32_t KVM_FEATURE_PV_SCHED_YIELD : 1;
uint32_t __reserved14_23 : 10;
/** host will warn if no guest-side per-cpu warps are expected in kvmclock */
uint32_t KVM_FEATURE_CLOCKSOURCE_STABLE_BIT : 1;
uint32_t __reserved25_31 : 7;
};
cpuid_t raw;
} EAX;
union
{
struct
{
uint32_t __reserved0_31;
};
cpuid_t raw;
} EBX;
union
{
struct
{
uint32_t __reserved0_31;
};
cpuid_t raw;
} ECX;
union
{
struct
{
/** guest checks this feature bit to determine that vCPUs are never preempted for an unlimited time allowing optimizations */
uint32_t KVM_HINTS_REALTIME : 1;
};
cpuid_t raw;
} EDX;
};
}
}
}
#undef __kvm_cpuid_init
#undef __kvm_cpuid_init2

View File

@ -22,7 +22,8 @@
#include <interface/driver.h>
#include <interface/input.h>
#include <filesystem.hpp>
#include <interface/block.h>
#include <fs/vfs.hpp>
#include <unordered_map>
#include <memory.hpp>
#include <ints.hpp>
@ -86,6 +87,7 @@ extern const BuiltInDriver __kernel_builtin_drivers_end[];
namespace Driver
{
char GetScanCode(uint8_t ScanCode, bool Upper);
char GetControlCharacter(KeyScanCodes Key);
bool IsValidChar(uint8_t ScanCode);
struct DriverHandlers
@ -119,16 +121,15 @@ namespace Driver
* 1 - input/... devices
*/
dev_t DriverIDCounter = 2;
FileNode *devNode = nullptr;
FileNode *devInputNode = nullptr;
Node devNode = nullptr;
Node devInputNode = nullptr;
Node devBlockNode = nullptr;
int LoadDriverFile(DriverObject &Drv, FileNode *File);
bool IsDriverTrusted(Node File);
int LoadDriverFile(DriverObject &Drv, Node File);
void ReloadDriver(dev_t driverID);
void InitializeDaemonFS();
dev_t RegisterInputDevice(std::unordered_map<dev_t, DriverHandlers> *, dev_t, size_t, const InodeOperations *);
dev_t RegisterBlockDevice(std::unordered_map<dev_t, DriverHandlers> *, dev_t, size_t, const InodeOperations *);
void InitializeDeviceDirectory();
public:
RingBuffer<KeyboardReport> GlobalKeyboardInputReports;
@ -136,11 +137,16 @@ namespace Driver
struct DeviceInode
{
struct Inode Node;
FileNode *Parent;
struct Inode inode;
Node Parent;
Inode *ParentInode;
std::string Name;
std::vector<DeviceInode *> Children;
size_t Size;
time_t AccessTime, ModifyTime, ChangeTime;
uint32_t BlockSize;
uint32_t Blocks;
};
std::unordered_map<dev_t, DriverObject> &
@ -183,14 +189,17 @@ namespace Driver
int ReportInputEvent(dev_t DriverID, InputReport *Report);
int UnregisterDevice(dev_t DriverID, dev_t Device);
dev_t RegisterBlockDevice(dev_t DriverID, struct BlockDevice *Device);
int UnregisterBlockDevice(dev_t DriverID, dev_t DeviceID);
void *AllocateMemory(dev_t DriverID, size_t Pages);
void FreeMemory(dev_t DriverID, void *Pointer, size_t Pages);
Manager();
private:
~Manager();
};
void ManagerDaemonWrapper();
}
void *GetSymbolByName(const char *Name, int Version);
@ -211,9 +220,12 @@ namespace v0
int UnregisterInterruptHandler(dev_t DriverID, uint8_t IRQ, void *Handler);
int UnregisterAllInterruptHandlers(dev_t DriverID, void *Handler);
dev_t RegisterFileSystem(dev_t DriverID, FileSystemInfo *Info, struct Inode *Root);
dev_t RegisterFileSystem(dev_t DriverID, FileSystemInfo *Info);
int UnregisterFileSystem(dev_t DriverID, dev_t Device);
dev_t RegisterBlockDevice(dev_t DriverID, struct BlockDevice *Device);
int UnregisterBlockDevice(dev_t DriverID, dev_t DeviceID);
pid_t CreateKernelProcess(dev_t DriverID, const char *Name);
pid_t CreateKernelThread(dev_t DriverID, pid_t pId, const char *Name, void *EntryPoint, void *Argument);
pid_t GetCurrentProcess(dev_t DriverID);

361
Kernel/include/efi.h Normal file
View File

@ -0,0 +1,361 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <types.h>
#ifdef __x86_64__
#define EFIAPI __attribute__((__ms_abi__))
#else
#define EFIAPI
#endif
#define IN
#define OUT
#define OPTIONAL
#define CONST const
#define FALSE 0
#define TRUE 1
#define MAX_BIT (~((UINTN) - 1 >> 1))
typedef intptr_t INTN;
typedef uintptr_t UINTN;
typedef int8_t INT8;
typedef uint8_t UINT8;
typedef int16_t INT16;
typedef uint16_t UINT16;
typedef int32_t INT32;
typedef uint32_t UINT32;
typedef int64_t INT64;
typedef uint64_t UINT64;
typedef int8_t CHAR8;
// typedef uint16_t CHAR16;
typedef wchar_t CHAR16;
typedef void VOID;
typedef bool BOOLEAN;
typedef INTN EFI_STATUS;
typedef VOID *EFI_HANDLE;
typedef VOID *EFI_EVENT;
typedef UINT64 EFI_PHYSICAL_ADDRESS;
typedef UINT64 EFI_VIRTUAL_ADDRESS;
typedef EFI_STATUS RETURN_STATUS;
typedef UINTN EFI_TPL;
enum EFI_MEMORY_TYPE
{
EfiReservedMemoryType,
EfiLoaderCode,
EfiLoaderData,
EfiBootServicesCode,
EfiBootServicesData,
EfiRuntimeServicesCode,
EfiRuntimeServicesData,
EfiConventionalMemory,
EfiUnusableMemory,
EfiACPIReclaimMemory,
EfiACPIMemoryNVS,
EfiMemoryMappedIO,
EfiMemoryMappedIOPortSpace,
EfiPalCode,
EfiPersistentMemory,
EfiMaxMemoryType,
MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000,
MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF,
MEMORY_TYPE_OS_RESERVED_MIN = 0x80000000,
MEMORY_TYPE_OS_RESERVED_MAX = 0xFFFFFFFF
};
enum EFI_ALLOCATE_TYPE
{
AllocateAnyPages,
AllocateMaxAddress,
AllocateAddress,
MaxAllocateType
};
enum EFI_TIMER_DELAY
{
TimerCancel,
TimerPeriodic,
TimerRelative
};
enum EFI_LOCATE_SEARCH_TYPE
{
AllHandles,
ByRegisterNotify,
ByProtocol
};
enum EFI_INTERFACE_TYPE
{
EFI_NATIVE_INTERFACE
};
typedef enum
{
EfiResetCold,
EfiResetWarm,
EfiResetShutdown
} EFI_RESET_TYPE;
#include <efi/errors.h>
struct EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
{
EFI_HANDLE AgentHandle;
EFI_HANDLE ControllerHandle;
UINT32 Attributes;
UINT32 OpenCount;
};
struct EFI_DEVICE_PATH_PROTOCOL
{
UINT8 Type;
UINT8 SubType;
UINT8 Length[2];
};
typedef struct
{
UINT16 ScanCode;
CHAR16 UnicodeChar;
} EFI_INPUT_KEY;
struct EFI_TABLE_HEADER
{
UINT64 Signature;
UINT32 Revision;
UINT32 HeaderSize;
UINT32 CRC32;
UINT32 Reserved;
};
struct _EFI_GUID
{
UINT32 Data1;
UINT16 Data2;
UINT16 Data3;
UINT8 Data4[8];
};
typedef struct
{
_EFI_GUID CapsuleGuid;
UINT32 HeaderSize;
UINT32 Flags;
UINT32 CapsuleImageSize;
} EFI_CAPSULE_HEADER;
typedef struct
{
UINT16 Year;
UINT8 Month;
UINT8 Day;
UINT8 Hour;
UINT8 Minute;
UINT8 Second;
UINT8 Pad1;
UINT32 Nanosecond;
INT16 TimeZone;
UINT8 Daylight;
UINT8 Pad2;
} EFI_TIME;
typedef struct
{
UINT32 Resolution;
UINT32 Accuracy;
BOOLEAN SetsToZero;
} EFI_TIME_CAPABILITIES;
typedef struct _EFI_GUID EFI_GUID;
typedef struct _EFI_GUID GUID;
typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
typedef struct _EFI_MEMORY_DESCRIPTOR EFI_MEMORY_DESCRIPTOR;
#include <efi/calls.h>
#include <efi/tables.h>
struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL
{
EFI_INPUT_RESET Reset;
EFI_INPUT_READ_KEY ReadKeyStroke;
EFI_EVENT WaitForKey;
};
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
{
void * /*EFI_TEXT_RESET*/ Reset;
void * /*EFI_TEXT_STRING*/ OutputString;
void * /*EFI_TEXT_TEST_STRING*/ TestString;
void * /*EFI_TEXT_QUERY_MODE*/ QueryMode;
void * /*EFI_TEXT_SET_MODE*/ SetMode;
void * /*EFI_TEXT_SET_ATTRIBUTE*/ SetAttribute;
void * /*EFI_TEXT_CLEAR_SCREEN*/ ClearScreen;
void * /*EFI_TEXT_SET_CURSOR_POSITION*/ SetCursorPosition;
void * /*EFI_TEXT_ENABLE_CURSOR*/ EnableCursor;
void /*EFI_SIMPLE_TEXT_OUTPUT_MODE*/ *Mode;
};
struct EFI_CONFIGURATION_TABLE
{
EFI_GUID VendorGuid;
VOID *VendorTable;
};
struct EFI_BOOT_SERVICES;
typedef struct
{
EFI_TABLE_HEADER Hdr;
//
// Time services
//
EFI_GET_TIME GetTime;
EFI_SET_TIME SetTime;
EFI_GET_WAKEUP_TIME GetWakeupTime;
EFI_SET_WAKEUP_TIME SetWakeupTime;
//
// Virtual memory services
//
EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
EFI_CONVERT_POINTER ConvertPointer;
//
// Variable serviers
//
EFI_GET_VARIABLE GetVariable;
EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
EFI_SET_VARIABLE SetVariable;
//
// Misc
//
EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;
EFI_RESET_SYSTEM ResetSystem;
EFI_UPDATE_CAPSULE UpdateCapsule;
EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;
EFI_QUERY_VARIABLE_INFO QueryVariableInfo;
} EFI_RUNTIME_SERVICES;
typedef struct
{
EFI_TABLE_HEADER Hdr;
CHAR16 *FirmwareVendor;
UINT32 FirmwareRevision;
EFI_HANDLE ConsoleInHandle;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
EFI_HANDLE ConsoleOutHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
EFI_HANDLE StandardErrorHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
EFI_RUNTIME_SERVICES *RuntimeServices;
EFI_BOOT_SERVICES *BootServices;
UINTN NumberOfTableEntries;
EFI_CONFIGURATION_TABLE *ConfigurationTable;
} EFI_SYSTEM_TABLE;
struct _EFI_MEMORY_DESCRIPTOR
{
UINT32 Type;
EFI_PHYSICAL_ADDRESS PhysicalStart;
EFI_VIRTUAL_ADDRESS VirtualStart;
UINT64 NumberOfPages;
UINT64 Attribute;
};
struct EFI_BOOT_SERVICES
{
EFI_TABLE_HEADER Hdr;
EFI_RAISE_TPL RaiseTPL;
EFI_RESTORE_TPL RestoreTPL;
EFI_ALLOCATE_PAGES AllocatePages;
EFI_FREE_PAGES FreePages;
EFI_GET_MEMORY_MAP GetMemoryMap;
EFI_ALLOCATE_POOL AllocatePool;
EFI_FREE_POOL FreePool;
EFI_CREATE_EVENT CreateEvent;
EFI_SET_TIMER SetTimer;
EFI_WAIT_FOR_EVENT WaitForEvent;
EFI_SIGNAL_EVENT SignalEvent;
EFI_CLOSE_EVENT CloseEvent;
EFI_CHECK_EVENT CheckEvent;
EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
EFI_HANDLE_PROTOCOL HandleProtocol;
VOID *Reserved;
EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
EFI_LOCATE_HANDLE LocateHandle;
EFI_LOCATE_DEVICE_PATH LocateDevicePath;
EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;
EFI_IMAGE_LOAD LoadImage;
EFI_IMAGE_START StartImage;
EFI_EXIT Exit;
EFI_IMAGE_UNLOAD UnloadImage;
EFI_EXIT_BOOT_SERVICES ExitBootServices;
EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
EFI_STALL Stall;
EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
EFI_CONNECT_CONTROLLER ConnectController;
EFI_DISCONNECT_CONTROLLER DisconnectController;
EFI_OPEN_PROTOCOL OpenProtocol;
EFI_CLOSE_PROTOCOL CloseProtocol;
EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;
EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
EFI_LOCATE_PROTOCOL LocateProtocol;
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;
EFI_CALCULATE_CRC32 CalculateCrc32;
EFI_COPY_MEM CopyMem;
EFI_SET_MEM SetMem;
};
VOID InitializeLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2);

301
Kernel/include/efi/calls.h Normal file
View File

@ -0,0 +1,301 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
typedef EFI_STATUS(EFIAPI *EFI_INPUT_RESET)(
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification);
typedef EFI_STATUS(EFIAPI *EFI_INPUT_READ_KEY)(
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key);
typedef EFI_TPL(EFIAPI *EFI_RAISE_TPL)(
IN EFI_TPL NewTpl);
typedef VOID(EFIAPI *EFI_RESTORE_TPL)(
IN EFI_TPL OldTpl);
typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_PAGES)(
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *Memory);
typedef EFI_STATUS(EFIAPI *EFI_FREE_PAGES)(
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN Pages);
typedef EFI_STATUS(EFIAPI *EFI_GET_MEMORY_MAP)(
IN OUT UINTN *MemoryMapSize,
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
OUT UINTN *MapKey,
OUT UINTN *DescriptorSize,
OUT UINT32 *DescriptorVersion);
typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_POOL)(
IN EFI_MEMORY_TYPE PoolType,
IN UINTN Size,
OUT VOID **Buffer);
typedef EFI_STATUS(EFIAPI *EFI_FREE_POOL)(
IN VOID *Buffer);
typedef VOID(EFIAPI *EFI_EVENT_NOTIFY)(
IN EFI_EVENT Event,
IN VOID *Context);
typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT)(
IN UINT32 Type,
IN EFI_TPL NotifyTpl,
IN EFI_EVENT_NOTIFY NotifyFunction,
IN VOID *NotifyContext,
OUT EFI_EVENT *Event);
typedef EFI_STATUS(EFIAPI *EFI_SET_TIMER)(
IN EFI_EVENT Event,
IN EFI_TIMER_DELAY Type,
IN UINT64 TriggerTime);
typedef EFI_STATUS(EFIAPI *EFI_WAIT_FOR_EVENT)(
IN UINTN NumberOfEvents,
IN EFI_EVENT *Event,
OUT UINTN *Index);
typedef EFI_STATUS(EFIAPI *EFI_SIGNAL_EVENT)(
IN EFI_EVENT Event);
typedef EFI_STATUS(EFIAPI *EFI_CLOSE_EVENT)(
IN EFI_EVENT Event);
typedef EFI_STATUS(EFIAPI *EFI_CHECK_EVENT)(
IN EFI_EVENT Event);
typedef EFI_STATUS(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)(
IN OUT EFI_HANDLE *Handle,
IN EFI_GUID const *Protocol,
IN EFI_INTERFACE_TYPE InterfaceType,
IN VOID *Interface);
typedef EFI_STATUS(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)(
IN EFI_HANDLE Handle,
IN EFI_GUID const *Protocol,
IN VOID *OldInterface,
IN VOID *NewInterface);
typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)(
IN EFI_HANDLE Handle,
IN EFI_GUID const *Protocol,
IN VOID *Interface);
typedef EFI_STATUS(EFIAPI *EFI_HANDLE_PROTOCOL)(
IN EFI_HANDLE Handle,
IN EFI_GUID const *Protocol,
OUT VOID **Interface);
typedef EFI_STATUS(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)(
IN EFI_GUID const *Protocol,
IN EFI_EVENT Event,
OUT VOID **Registration);
typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE)(
IN EFI_LOCATE_SEARCH_TYPE SearchType,
IN EFI_GUID const *Protocol, OPTIONAL IN VOID *SearchKey, OPTIONAL IN OUT UINTN *BufferSize,
OUT EFI_HANDLE *Buffer);
typedef EFI_STATUS(EFIAPI *EFI_LOCATE_DEVICE_PATH)(
IN EFI_GUID const *Protocol,
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
OUT EFI_HANDLE *Device);
typedef EFI_STATUS(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)(
IN EFI_GUID const *Guid,
IN VOID *Table);
typedef EFI_STATUS(EFIAPI *EFI_IMAGE_LOAD)(
IN BOOLEAN BootPolicy,
IN EFI_HANDLE ParentImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
OUT EFI_HANDLE *ImageHandle);
typedef EFI_STATUS(EFIAPI *EFI_IMAGE_START)(
IN EFI_HANDLE ImageHandle,
OUT UINTN *ExitDataSize,
OUT CHAR16 **ExitData OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_EXIT)(
IN EFI_HANDLE ImageHandle,
IN EFI_STATUS ExitStatus,
IN UINTN ExitDataSize,
IN CHAR16 *ExitData OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_IMAGE_UNLOAD)(
IN EFI_HANDLE ImageHandle);
typedef EFI_STATUS(EFIAPI *EFI_EXIT_BOOT_SERVICES)(
IN EFI_HANDLE ImageHandle,
IN UINTN MapKey);
typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(
OUT UINT64 *Count);
typedef EFI_STATUS(EFIAPI *EFI_STALL)(
IN UINTN Microseconds);
typedef EFI_STATUS(EFIAPI *EFI_SET_WATCHDOG_TIMER)(
IN UINTN Timeout,
IN UINT64 WatchdogCode,
IN UINTN DataSize,
IN CHAR16 *WatchdogData OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_CONNECT_CONTROLLER)(
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE *DriverImageHandle, OPTIONAL IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, OPTIONAL IN BOOLEAN Recursive);
typedef EFI_STATUS(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE DriverImageHandle, OPTIONAL IN EFI_HANDLE ChildHandle OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL)(
IN EFI_HANDLE Handle,
IN EFI_GUID const *Protocol,
OUT VOID **Interface, OPTIONAL IN EFI_HANDLE AgentHandle,
IN EFI_HANDLE ControllerHandle,
IN UINT32 Attributes);
typedef EFI_STATUS(EFIAPI *EFI_CLOSE_PROTOCOL)(
IN EFI_HANDLE Handle,
IN EFI_GUID const *Protocol,
IN EFI_HANDLE AgentHandle,
IN EFI_HANDLE ControllerHandle);
typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION)(
IN EFI_HANDLE Handle,
IN EFI_GUID const *Protocol,
OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
OUT UINTN *EntryCount);
typedef EFI_STATUS(EFIAPI *EFI_PROTOCOLS_PER_HANDLE)(
IN EFI_HANDLE Handle,
OUT EFI_GUID const ***ProtocolBuffer,
OUT UINTN *ProtocolBufferCount);
typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(
IN EFI_LOCATE_SEARCH_TYPE SearchType,
IN EFI_GUID const *Protocol, OPTIONAL IN VOID *SearchKey, OPTIONAL IN OUT UINTN *NoHandles,
OUT EFI_HANDLE **Buffer);
typedef EFI_STATUS(EFIAPI *EFI_LOCATE_PROTOCOL)(
IN EFI_GUID const *Protocol,
IN VOID *Registration, OPTIONAL OUT VOID **Interface);
typedef EFI_STATUS(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
IN OUT EFI_HANDLE *Handle,
...);
typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
IN EFI_HANDLE Handle,
...);
typedef EFI_STATUS(EFIAPI *EFI_CALCULATE_CRC32)(
IN VOID *Data,
IN UINTN DataSize,
OUT UINT32 *Crc32);
typedef VOID(EFIAPI *EFI_COPY_MEM)(
IN VOID *Destination,
IN VOID *Source,
IN UINTN Length);
typedef VOID(EFIAPI *EFI_SET_MEM)(
IN VOID *Buffer,
IN UINTN Size,
IN UINT8 Value);
typedef EFI_STATUS(EFIAPI *EFI_GET_TIME)(
OUT EFI_TIME *Time,
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_SET_TIME)(
IN EFI_TIME *Time);
typedef EFI_STATUS(EFIAPI *EFI_GET_WAKEUP_TIME)(
OUT BOOLEAN *Enabled,
OUT BOOLEAN *Pending,
OUT EFI_TIME *Time);
typedef EFI_STATUS(EFIAPI *EFI_SET_WAKEUP_TIME)(
IN BOOLEAN Enable,
IN EFI_TIME *Time OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)(
IN UINTN MemoryMapSize,
IN UINTN DescriptorSize,
IN UINT32 DescriptorVersion,
IN EFI_MEMORY_DESCRIPTOR *VirtualMap);
typedef EFI_STATUS(EFIAPI *EFI_CONVERT_POINTER)(
IN UINTN DebugDisposition,
IN OUT VOID **Address);
typedef EFI_STATUS(EFIAPI *EFI_GET_VARIABLE)(
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data);
typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid);
typedef EFI_STATUS(EFIAPI *EFI_SET_VARIABLE)(
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data);
typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT)(
OUT UINT32 *HighCount);
typedef EFI_STATUS(EFIAPI *EFI_RESET_SYSTEM)(
IN EFI_RESET_TYPE ResetType,
IN EFI_STATUS ResetStatus,
IN UINTN DataSize,
IN CHAR16 *ResetData OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_UPDATE_CAPSULE)(
IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
IN UINTN CapsuleCount,
IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL);
typedef EFI_STATUS(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)(
IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
IN UINTN CapsuleCount,
OUT UINT64 *MaximumCapsuleSize,
OUT EFI_RESET_TYPE *ResetType);
typedef EFI_STATUS(EFIAPI *EFI_QUERY_VARIABLE_INFO)(
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize);

106
Kernel/include/efi/errors.h Normal file
View File

@ -0,0 +1,106 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#define ENCODE_ERROR(StatusCode) ((RETURN_STATUS)(MAX_BIT | (StatusCode)))
#define ENCODE_WARNING(StatusCode) ((RETURN_STATUS)(StatusCode))
#define RETURN_ERROR(StatusCode) (((StatusCode)) < 0)
#define RETURN_SUCCESS 0
#define RETURN_LOAD_ERROR ENCODE_ERROR(1)
#define RETURN_INVALID_PARAMETER ENCODE_ERROR(2)
#define RETURN_UNSUPPORTED ENCODE_ERROR(3)
#define RETURN_BAD_BUFFER_SIZE ENCODE_ERROR(4)
#define RETURN_BUFFER_TOO_SMALL ENCODE_ERROR(5)
#define RETURN_NOT_READY ENCODE_ERROR(6)
#define RETURN_DEVICE_ERROR ENCODE_ERROR(7)
#define RETURN_WRITE_PROTECTED ENCODE_ERROR(8)
#define RETURN_OUT_OF_RESOURCES ENCODE_ERROR(9)
#define RETURN_VOLUME_CORRUPTED ENCODE_ERROR(10)
#define RETURN_VOLUME_FULL ENCODE_ERROR(11)
#define RETURN_NO_MEDIA ENCODE_ERROR(12)
#define RETURN_MEDIA_CHANGED ENCODE_ERROR(13)
#define RETURN_NOT_FOUND ENCODE_ERROR(14)
#define RETURN_ACCESS_DENIED ENCODE_ERROR(15)
#define RETURN_NO_RESPONSE ENCODE_ERROR(16)
#define RETURN_NO_MAPPING ENCODE_ERROR(17)
#define RETURN_TIMEOUT ENCODE_ERROR(18)
#define RETURN_NOT_STARTED ENCODE_ERROR(19)
#define RETURN_ALREADY_STARTED ENCODE_ERROR(20)
#define RETURN_ABORTED ENCODE_ERROR(21)
#define RETURN_ICMP_ERROR ENCODE_ERROR(22)
#define RETURN_TFTP_ERROR ENCODE_ERROR(23)
#define RETURN_PROTOCOL_ERROR ENCODE_ERROR(24)
#define RETURN_INCOMPATIBLE_VERSION ENCODE_ERROR(25)
#define RETURN_SECURITY_VIOLATION ENCODE_ERROR(26)
#define RETURN_CRC_ERROR ENCODE_ERROR(27)
#define RETURN_END_OF_MEDIA ENCODE_ERROR(28)
#define RETURN_END_OF_FILE ENCODE_ERROR(31)
#define RETURN_INVALID_LANGUAGE ENCODE_ERROR(32)
#define RETURN_COMPROMISED_DATA ENCODE_ERROR(33)
#define RETURN_HTTP_ERROR ENCODE_ERROR(35)
#define RETURN_WARN_UNKNOWN_GLYPH ENCODE_WARNING(1)
#define RETURN_WARN_DELETE_FAILURE ENCODE_WARNING(2)
#define RETURN_WARN_WRITE_FAILURE ENCODE_WARNING(3)
#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING(4)
#define RETURN_WARN_STALE_DATA ENCODE_WARNING(5)
#define RETURN_WARN_FILE_SYSTEM ENCODE_WARNING(6)
#define EFI_SUCCESS RETURN_SUCCESS
#define EFI_LOAD_ERROR RETURN_LOAD_ERROR
#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER
#define EFI_UNSUPPORTED RETURN_UNSUPPORTED
#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE
#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL
#define EFI_NOT_READY RETURN_NOT_READY
#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR
#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED
#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES
#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED
#define EFI_VOLUME_FULL RETURN_VOLUME_FULL
#define EFI_NO_MEDIA RETURN_NO_MEDIA
#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED
#define EFI_NOT_FOUND RETURN_NOT_FOUND
#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED
#define EFI_NO_RESPONSE RETURN_NO_RESPONSE
#define EFI_NO_MAPPING RETURN_NO_MAPPING
#define EFI_TIMEOUT RETURN_TIMEOUT
#define EFI_NOT_STARTED RETURN_NOT_STARTED
#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED
#define EFI_ABORTED RETURN_ABORTED
#define EFI_ICMP_ERROR RETURN_ICMP_ERROR
#define EFI_TFTP_ERROR RETURN_TFTP_ERROR
#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR
#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION
#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION
#define EFI_CRC_ERROR RETURN_CRC_ERROR
#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA
#define EFI_END_OF_FILE RETURN_END_OF_FILE
#define EFI_INVALID_LANGUAGE RETURN_INVALID_LANGUAGE
#define EFI_COMPROMISED_DATA RETURN_COMPROMISED_DATA
#define EFI_HTTP_ERROR RETURN_HTTP_ERROR
#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH
#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE
#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE
#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
#define EFI_WARN_STALE_DATA RETURN_WARN_STALE_DATA
#define EFI_WARN_FILE_SYSTEM RETURN_WARN_FILE_SYSTEM
#define EFIERR(_a) ENCODE_ERROR(_a)
#define EFI_ERROR(A) RETURN_ERROR(A)

640
Kernel/include/efi/tables.h Normal file
View File

@ -0,0 +1,640 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
/* This part is from "4.6.1.1 Industry Standard Configuration Tables" */
#define EFI_ACPI_20_TABLE_GUID \
{0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}
#define ACPI_TABLE_GUID \
{0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
#define SAL_SYSTEM_TABLE_GUID \
{0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
#define SMBIOS_TABLE_GUID \
{0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
#define SMBIOS3_TABLE_GUID \
{0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94}}
#define MPS_TABLE_GUID \
{0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
//
// ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID
//
#define EFI_ACPI_TABLE_GUID \
{0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}
// #define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID
#define ACPI_TABLE_GUID \
{0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
#define ACPI_10_TABLE_GUID ACPI_TABLE_GUID *
#define EFI_LZMA_COMPRESSED_GUID \
{0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf}}
#define EFI_DXE_SERVICES_GUID \
{0x05ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9}}
#define EFI_HOB_LIST_GUID \
{0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
#define _EFI_MEMORY_TYPE_GUID \
{0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa}}
#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \
{0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b}}
#define EFI_MEM_STATUS_CODE_REC_GUID \
{0x060cc026, 0x4c0d, 0x4dda, {0x8f, 0x41, 0x59, 0x5f, 0xef, 0x00, 0xa5, 0x02}}
#define EFI_GUID_EFI_ACPI1_GUID \
{0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID \
{0xdcfa911d, 0x26eb, 0x469f, {0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20}}
#define EFI_HII_DATABASE_PROTOCOL_GUID \
{0xef9fc172, 0xa1b2, 0x4693, {0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42}}
#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \
{0x587e72d7, 0xcc50, 0x4f79, {0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f}}
#define TCG2_FINAL_EVENTS_TABLE_GUID \
{0x1e2ed096, 0x30e2, 0x4254, {0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25}}
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
{0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f}}
#define EFI_SYSTEM_RESOURCE_TABLE_GUID \
{0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80}}
static EFI_GUID gAdapterInfoPlatformSecurityGuid = {0x6be272c7, 0x1320, 0x4ccd, {0x90, 0x17, 0xd4, 0x61, 0x2c, 0x01, 0x2b, 0x25}};
static EFI_GUID gAprioriGuid = {0xFC510EE7, 0xFFDC, 0x11D4, {0xBD, 0x41, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}};
static EFI_GUID gBootObjectAuthorizationParmsetGuid = {0xEDD35E31, 0x07B9, 0x11D2, {0x83, 0xA3, 0x00, 0xA0, 0xC9, 0x1F, 0xAD, 0xCF}};
static EFI_GUID gEfiAbsolutePointerProtocolGuid = {0x8D59D32B, 0xC655, 0x4AE9, {0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43}};
static EFI_GUID gEfiAcpi10TableGuid = {0xEB9D2D30, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiAcpi20TableGuid = {0x8868E871, 0xE4F1, 0x11D3, {0xBC, 0x22, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}};
static EFI_GUID gEfiAcpiSdtProtocolGuid = {0xeb97088e, 0xcfdf, 0x49c6, {0xbe, 0x4b, 0xd9, 0x6, 0xa5, 0xb2, 0xe, 0x86}};
static EFI_GUID gEfiAcpiTableGuid = {0x8868E871, 0xE4F1, 0x11D3, {0xBC, 0x22, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}};
static EFI_GUID gEfiAcpiTableProtocolGuid = {0xFFE06BDD, 0x6107, 0x46A6, {0x7B, 0xB2, 0x5A, 0x9C, 0x7E, 0xC5, 0x27, 0x5C}};
static EFI_GUID gEfiAdapterInfoMediaStateGuid = {0xD7C74207, 0xA831, 0x4A26, {0xB1, 0xF5, 0xD1, 0x93, 0x06, 0x5C, 0xE8, 0xB6}};
static EFI_GUID gEfiAdapterInfoNetworkBootGuid = {0x1FBD2960, 0x4130, 0x41E5, {0x94, 0xAC, 0xD2, 0xCF, 0x03, 0x7F, 0xB3, 0x7C}};
static EFI_GUID gEfiAdapterInformationProtocolGuid = {0xE5DD1403, 0xD622, 0xC24E, {0x84, 0x88, 0xC7, 0x1B, 0x17, 0xF5, 0xE8, 0x02}};
static EFI_GUID gEfiAdapterInfoSanMacAddressGuid = {0x114da5ef, 0x2cf1, 0x4e12, {0x9b, 0xbb, 0xc4, 0x70, 0xb5, 0x52, 0x5, 0xd9}};
static EFI_GUID gEfiAdapterInfoUndiIpv6SupportGuid = {0x4bd56be3, 0x4975, 0x4d8a, {0xa0, 0xad, 0xc4, 0x91, 0x20, 0x4b, 0x5d, 0x4d}};
static EFI_GUID gEfiArmProcessorErrorSectionGuid = {0xe19e3d16, 0xbc11, 0x11e4, {0x9c, 0xaa, 0xc2, 0x05, 0x1d, 0x5d, 0x46, 0xb0}};
static EFI_GUID gEfiArpProtocolGuid = {0xF4B427BB, 0xBA21, 0x4F16, {0xBC, 0x4E, 0x43, 0xE4, 0x16, 0xAB, 0x61, 0x9C}};
static EFI_GUID gEfiArpServiceBindingProtocolGuid = {0xF44C00EE, 0x1F2C, 0x4A00, {0xAA, 0x09, 0x1C, 0x9F, 0x3E, 0x08, 0x00, 0xA3}};
static EFI_GUID gEfiAtaPassThruProtocolGuid = {0x1d3de7f0, 0x807, 0x424f, {0xaa, 0x69, 0x11, 0xa5, 0x4e, 0x19, 0xa4, 0x6f}};
static EFI_GUID gEfiAuthenticationChapLocalGuid = {0xC280C73E, 0x15CA, 0x11DA, {0xB0, 0xCA, 0x00, 0x10, 0x83, 0xFF, 0xCA, 0x4D}};
static EFI_GUID gEfiAuthenticationChapRadiusGuid = {0xD6062B50, 0x15CA, 0x11DA, {0x92, 0x19, 0x00, 0x10, 0x83, 0xFF, 0xCA, 0x4D}};
static EFI_GUID gEfiAuthenticationInfoProtocolGuid = {0x7671D9D0, 0x53DB, 0x4173, {0xAA, 0x69, 0x23, 0x27, 0xF2, 0x1F, 0x0B, 0xC7}};
static EFI_GUID gEfiBdsArchProtocolGuid = {0x665E3FF6, 0x46CC, 0x11D4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiBisProtocolGuid = {0x0B64AAB0, 0x5429, 0x11D4, {0x98, 0x16, 0x00, 0xA0, 0xC9, 0x1F, 0xAD, 0xCF}};
static EFI_GUID gEfiBlockIo2ProtocolGuid = {0xa77b2472, 0xe282, 0x4e9f, {0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1}};
static EFI_GUID gEfiBlockIoCryptoAlgoAesCbcMsBitlockerGuid = {0x689e4c62, 0x70bf, 0x4cf3, {0x88, 0xbb, 0x33, 0xb3, 0x18, 0x26, 0x86, 0x70}};
static EFI_GUID gEfiBlockIoCryptoAlgoAesXtsGuid = {0x2f87ba6a, 0x5c04, 0x4385, {0xa7, 0x80, 0xf3, 0xbf, 0x78, 0xa9, 0x7b, 0xec}};
static EFI_GUID gEfiBlockIoCryptoProtocolGuid = {0xa00490ba, 0x3f1a, 0x4b4c, {0xab, 0x90, 0x4f, 0xa9, 0x97, 0x26, 0xa1, 0xe8}};
static EFI_GUID gEfiBlockIoProtocolGuid = {0x964E5B21, 0x6459, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiBluetoothAttributeProtocolGuid = {0x898890e9, 0x84b2, 0x4f3a, {0x8c, 0x58, 0xd8, 0x57, 0x78, 0x13, 0xe0, 0xac}};
static EFI_GUID gEfiBluetoothAttributeServiceBindingProtocolGuid = {0x5639867a, 0x8c8e, 0x408d, {0xac, 0x2f, 0x4b, 0x61, 0xbd, 0xc0, 0xbb, 0xbb}};
static EFI_GUID gEfiBluetoothConfigProtocolGuid = {0x62960cf3, 0x40ff, 0x4263, {0xa7, 0x7c, 0xdf, 0xde, 0xbd, 0x19, 0x1b, 0x4b}};
static EFI_GUID gEfiBluetoothHcProtocolGuid = {0xb3930571, 0xbeba, 0x4fc5, {0x92, 0x3, 0x94, 0x27, 0x24, 0x2e, 0x6a, 0x43}};
static EFI_GUID gEfiBluetoothIoProtocolGuid = {0x467313de, 0x4e30, 0x43f1, {0x94, 0x3e, 0x32, 0x3f, 0x89, 0x84, 0x5d, 0xb5}};
static EFI_GUID gEfiBluetoothIoServiceBindingProtocolGuid = {0x388278d3, 0x7b85, 0x42f0, {0xab, 0xa9, 0xfb, 0x4b, 0xfd, 0x69, 0xf5, 0xab}};
static EFI_GUID gEfiBluetoothLeConfigProtocolGuid = {0x8f76da58, 0x1f99, 0x4275, {0xa4, 0xec, 0x47, 0x56, 0x51, 0x5b, 0x1c, 0xe8}};
static EFI_GUID gEfiBootManagerPolicyConnectAllGuid = {0x113B2126, 0xFC8A, 0x11E3, {0xBD, 0x6C, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA}};
static EFI_GUID gEfiBootManagerPolicyConsoleGuid = {0xCAB0E94C, 0xE15F, 0x11E3, {0x91, 0x8D, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA}};
static EFI_GUID gEfiBootManagerPolicyNetworkGuid = {0xD04159DC, 0xE15F, 0x11E3, {0xB2, 0x61, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA}};
static EFI_GUID gEfiBootManagerPolicyProtocolGuid = {0xfedf8e0c, 0xe147, 0x11e3, {0x99, 0x03, 0xb8, 0xe8, 0x56, 0x2c, 0xba, 0xfa}};
static EFI_GUID gEfiBttAbstractionGuid = {0x18633bfc, 0x1735, 0x4217, {0x8a, 0xc9, 0x17, 0x23, 0x92, 0x82, 0xd3, 0xf8}};
static EFI_GUID gEfiBusSpecificDriverOverrideProtocolGuid = {0x3BC1B285, 0x8A15, 0x4A82, {0xAA, 0xBF, 0x4D, 0x7D, 0x13, 0xFB, 0x32, 0x65}};
static EFI_GUID gEfiCapsuleArchProtocolGuid = {0x5053697E, 0x2CBC, 0x4819, {0x90, 0xD9, 0x05, 0x80, 0xDE, 0xEE, 0x57, 0x54}};
static EFI_GUID gEfiCapsuleReportGuid = {0x39b68c46, 0xf7fb, 0x441b, {0xb6, 0xec, 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3}};
static EFI_GUID gEfiCertPkcs7Guid = {0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7}};
static EFI_GUID gEfiCertRsa2048Guid = {0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6}};
static EFI_GUID gEfiCertRsa2048Sha1Guid = {0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80}};
static EFI_GUID gEfiCertRsa2048Sha256Guid = {0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84}};
static EFI_GUID gEfiCertSha1Guid = {0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd}};
static EFI_GUID gEfiCertSha224Guid = {0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd}};
static EFI_GUID gEfiCertSha256Guid = {0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28}};
static EFI_GUID gEfiCertSha384Guid = {0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1}};
static EFI_GUID gEfiCertSha512Guid = {0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a}};
static EFI_GUID gEfiCertTypeRsa2048Sha256Guid = {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf}};
static EFI_GUID gEfiCertX509Guid = {0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72}};
static EFI_GUID gEfiCertX509Sha256Guid = {0x3bd2a492, 0x96c0, 0x4079, {0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed}};
static EFI_GUID gEfiCertX509Sha384Guid = {0x7076876e, 0x80c2, 0x4ee6, {0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b}};
static EFI_GUID gEfiCertX509Sha512Guid = {0x446dbf63, 0x2502, 0x4cda, {0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d}};
static EFI_GUID gEfiComponentName2ProtocolGuid = {0x6A7A5CFF, 0xE8D9, 0x4F70, {0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14}};
static EFI_GUID gEfiComponentNameProtocolGuid = {0x107A772C, 0xD5E1, 0x11D4, {0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiConfigKeywordHandlerProtocolGuid = {0x0a8badd5, 0x03b8, 0x4d19, {0xb1, 0x28, 0x7b, 0x8f, 0x0e, 0xda, 0xa5, 0x96}};
static EFI_GUID gEfiCpuArchProtocolGuid = {0x26BACCB1, 0x6F42, 0x11D4, {0xBC, 0xE7, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}};
static EFI_GUID gEfiCpuIo2ProtocolGuid = {0xad61f191, 0xae5f, 0x4c0e, {0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f}};
static EFI_GUID gEfiDebugImageInfoTableGuid = {0x49152E77, 0x1ADA, 0x4764, {0xB7, 0xA2, 0x7A, 0xFE, 0xFE, 0xD9, 0x5E, 0x8B}};
static EFI_GUID gEfiDebugPortDevicePathGuid = {0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0}};
static EFI_GUID gEfiDebugPortProtocolGuid = {0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0}};
static EFI_GUID gEfiDebugPortVariableGuid = {0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0}};
static EFI_GUID gEfiDebugSupportProtocolGuid = {0x2755590C, 0x6F3C, 0x42FA, {0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25}};
static EFI_GUID gEfiDecompressProtocolGuid = {0xD8117CFE, 0x94A6, 0x11D4, {0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiDeferredImageLoadProtocolGuid = {0x15853d7c, 0x3ddf, 0x43e0, {0xa1, 0xcb, 0xeb, 0xf8, 0x5b, 0x8f, 0x87, 0x2c}};
static EFI_GUID gEfiDeviceIoProtocolGuid = {0xAF6AC311, 0x84C3, 0x11D2, {0x8E, 0x3C, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiDevicePathFromTextProtocolGuid = {0x05C99A21, 0xC70F, 0x4AD2, {0x8A, 0x5F, 0x35, 0xDF, 0x33, 0x43, 0xF5, 0x1E}};
static EFI_GUID gEfiDevicePathProtocolGuid = {0x09576E91, 0x6D3F, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiDevicePathToTextProtocolGuid = {0x8B843E20, 0x8132, 0x4852, {0x90, 0xCC, 0x55, 0x1A, 0x4E, 0x4A, 0x7F, 0x1C}};
static EFI_GUID gEfiDevicePathUtilitiesProtocolGuid = {0x0379BE4E, 0xD706, 0x437D, {0xB0, 0x37, 0xED, 0xB8, 0x2F, 0xB7, 0x72, 0xA4}};
static EFI_GUID gEfiDhcp4ProtocolGuid = {0x8A219718, 0x4EF5, 0x4761, {0x91, 0xC8, 0xC0, 0xF0, 0x4B, 0xDA, 0x9E, 0x56}};
static EFI_GUID gEfiDhcp4ServiceBindingProtocolGuid = {0x9D9A39D8, 0xBD42, 0x4A73, {0xA4, 0xD5, 0x8E, 0xE9, 0x4B, 0xE1, 0x13, 0x80}};
static EFI_GUID gEfiDhcp6ProtocolGuid = {0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b}};
static EFI_GUID gEfiDhcp6ServiceBindingProtocolGuid = {0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5}};
static EFI_GUID gEfiDirectedIoDMArErrorSectionGuid = {0x71761d37, 0x32b2, 0x45cd, {0xa7, 0xd0, 0xb0, 0xfe, 0xdd, 0x93, 0xe8, 0xcf}};
static EFI_GUID gEfiDiskInfoAhciInterfaceGuid = {0x9e498932, 0x4abc, 0x45af, {0xa3, 0x4d, 0x02, 0x47, 0x78, 0x7b, 0xe7, 0xc6}};
static EFI_GUID gEfiDiskInfoIdeInterfaceGuid = {0x5E948FE3, 0x26D3, 0x42B5, {0xAF, 0x17, 0x61, 0x02, 0x87, 0x18, 0x8D, 0xEC}};
static EFI_GUID gEfiDiskInfoNvmeInterfaceGuid = {0x3ab14680, 0x5d3f, 0x4a4d, {0xbc, 0xdc, 0xcc, 0x38, 0x0, 0x18, 0xc7, 0xf7}};
static EFI_GUID gEfiDiskInfoProtocolGuid = {0xD432A67F, 0x14DC, 0x484B, {0xB3, 0xBB, 0x3F, 0x02, 0x91, 0x84, 0x93, 0x27}};
static EFI_GUID gEfiDiskInfoScsiInterfaceGuid = {0x08F74BAA, 0xEA36, 0x41D9, {0x95, 0x21, 0x21, 0xA7, 0x0F, 0x87, 0x80, 0xBC}};
static EFI_GUID gEfiDiskInfoSdMmcInterfaceGuid = {0x8deec992, 0xd39c, 0x4a5c, {0xab, 0x6b, 0x98, 0x6e, 0x14, 0x24, 0x2b, 0x9d}};
static EFI_GUID gEfiDiskInfoUfsInterfaceGuid = {0x4b3029cc, 0x6b98, 0x47fb, {0xbc, 0x96, 0x76, 0xdc, 0xb8, 0x4, 0x41, 0xf0}};
static EFI_GUID gEfiDiskInfoUsbInterfaceGuid = {0xCB871572, 0xC11A, 0x47B5, {0xB4, 0x92, 0x67, 0x5E, 0xAF, 0xA7, 0x77, 0x27}};
static EFI_GUID gEfiDiskIo2ProtocolGuid = {0x151c8eae, 0x7f2c, 0x472c, {0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88}};
static EFI_GUID gEfiDiskIoProtocolGuid = {0xCE345171, 0xBA0B, 0x11D2, {0x8E, 0x4F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiDMArGenericErrorSectionGuid = {0x5b51fef7, 0xc79d, 0x4434, {0x8f, 0x1b, 0xaa, 0x62, 0xde, 0x3e, 0x2c, 0x64}};
static EFI_GUID gEfiDns4ProtocolGuid = {0xae3d28cc, 0xe05b, 0x4fa1, {0xa0, 0x11, 0x7e, 0xb5, 0x5a, 0x3f, 0x14, 0x1}};
static EFI_GUID gEfiDns4ServiceBindingProtocolGuid = {0xb625b186, 0xe063, 0x44f7, {0x89, 0x5, 0x6a, 0x74, 0xdc, 0x6f, 0x52, 0xb4}};
static EFI_GUID gEfiDns6ProtocolGuid = {0xca37bc1f, 0xa327, 0x4ae9, {0x82, 0x8a, 0x8c, 0x40, 0xd8, 0x50, 0x6a, 0x17}};
static EFI_GUID gEfiDns6ServiceBindingProtocolGuid = {0x7f1647c8, 0xb76e, 0x44b2, {0xa5, 0x65, 0xf7, 0xf, 0xf1, 0x9c, 0xd1, 0x9e}};
static EFI_GUID gEfiDriverBindingProtocolGuid = {0x18A031AB, 0xB443, 0x4D1A, {0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71}};
static EFI_GUID gEfiDriverConfiguration2ProtocolGuid = {0xBFD7DC1D, 0x24F1, 0x40D9, {0x82, 0xE7, 0x2E, 0x09, 0xBB, 0x6B, 0x4E, 0xBE}};
static EFI_GUID gEfiDriverConfigurationProtocolGuid = {0x107A772B, 0xD5E1, 0x11D4, {0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiDriverDiagnostics2ProtocolGuid = {0x4D330321, 0x025F, 0x4AAC, {0x90, 0xD8, 0x5E, 0xD9, 0x00, 0x17, 0x3B, 0x63}};
static EFI_GUID gEfiDriverDiagnosticsProtocolGuid = {0x0784924F, 0xE296, 0x11D4, {0x9A, 0x49, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiDriverFamilyOverrideProtocolGuid = {0xb1ee129e, 0xda36, 0x4181, {0x91, 0xf8, 0x4, 0xa4, 0x92, 0x37, 0x66, 0xa7}};
static EFI_GUID gEfiDriverHealthProtocolGuid = {0x2a534210, 0x9280, 0x41d8, {0xae, 0x79, 0xca, 0xda, 0x1, 0xa2, 0xb1, 0x27}};
static EFI_GUID gEfiDriverSupportedEfiVersionProtocolGuid = {0x5c198761, 0x16a8, 0x4e69, {0x97, 0x2c, 0x89, 0xd6, 0x79, 0x54, 0xf8, 0x1d}};
static EFI_GUID gEfiDxeIplPpiGuid = {0xae8ce5d, 0xe448, 0x4437, {0xa8, 0xd7, 0xeb, 0xf5, 0xf1, 0x94, 0xf7, 0x31}};
static EFI_GUID gEfiDxeMmReadyToLockProtocolGuid = {0x60ff8964, 0xe906, 0x41d0, {0xaf, 0xed, 0xf2, 0x41, 0xe9, 0x74, 0xe0, 0x8e}};
static EFI_GUID gEfiDxeServicesTableGuid = {0x05AD34BA, 0x6F02, 0x4214, {0x95, 0x2E, 0x4D, 0xA0, 0x39, 0x8E, 0x2B, 0xB9}};
static EFI_GUID gEfiDxeSmmReadyToLockProtocolGuid = {0x60ff8964, 0xe906, 0x41d0, {0xaf, 0xed, 0xf2, 0x41, 0xe9, 0x74, 0xe0, 0x8e}};
static EFI_GUID gEfiEapConfigurationProtocolGuid = {0xe5b58dbb, 0x7688, 0x44b4, {0x97, 0xbf, 0x5f, 0x1d, 0x4b, 0x7c, 0xc8, 0xdb}};
static EFI_GUID gEfiEapManagement2ProtocolGuid = {0x5e93c847, 0x456d, 0x40b3, {0xa6, 0xb4, 0x78, 0xb0, 0xc9, 0xcf, 0x7f, 0x20}};
static EFI_GUID gEfiEapManagementProtocolGuid = {0xbb62e663, 0x625d, 0x40b2, {0xa0, 0x88, 0xbb, 0xe8, 0x36, 0x23, 0xa2, 0x45}};
static EFI_GUID gEfiEapProtocolGuid = {0x5d9f96db, 0xe731, 0x4caa, {0xa0, 0xd, 0x72, 0xe1, 0x87, 0xcd, 0x77, 0x62}};
static EFI_GUID gEfiEbcProtocolGuid = {0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7}};
static EFI_GUID gEfiEdidActiveProtocolGuid = {0xBD8C1056, 0x9F36, 0x44EC, {0x92, 0xA8, 0xA6, 0x33, 0x7F, 0x81, 0x79, 0x86}};
static EFI_GUID gEfiEdidDiscoveredProtocolGuid = {0x1C0C34F6, 0xD380, 0x41FA, {0xA0, 0x49, 0x8A, 0xD0, 0x6C, 0x1A, 0x66, 0xAA}};
static EFI_GUID gEfiEdidOverrideProtocolGuid = {0x48ECB431, 0xFB72, 0x45C0, {0xA9, 0x22, 0xF4, 0x58, 0xFE, 0x04, 0x0B, 0xD5}};
static EFI_GUID gEfiEndOfDxeEventGroupGuid = {0x2ce967a, 0xdd7e, 0x4ffc, {0x9e, 0xe7, 0x81, 0xc, 0xf0, 0x47, 0x8, 0x80}};
static EFI_GUID gEfiEndOfPeiSignalPpiGuid = {0x605EA650, 0xC65C, 0x42e1, {0xBA, 0x80, 0x91, 0xA5, 0x2A, 0xB6, 0x18, 0xC6}};
static EFI_GUID gEfiEraseBlockProtocolGuid = {0x95a9a93e, 0xa86e, 0x4926, {0xaa, 0xef, 0x99, 0x18, 0xe7, 0x72, 0xd9, 0x87}};
static EFI_GUID gEfiEventDxeDispatchGuid = {0x7081E22F, 0xCAC6, 0x4053, {0x94, 0x68, 0x67, 0x57, 0x82, 0xCF, 0x88, 0xE5}};
static EFI_GUID gEfiEventExitBootServicesGuid = {0x27ABF055, 0xB1B8, 0x4C26, {0x80, 0x48, 0x74, 0x8F, 0x37, 0xBA, 0xA2, 0xDF}};
static EFI_GUID gEfiEventLegacyBootGuid = {0x2A571201, 0x4966, 0x47F6, {0x8B, 0x86, 0xF3, 0x1E, 0x41, 0xF3, 0x2F, 0x10}};
static EFI_GUID gEfiEventMemoryMapChangeGuid = {0x78BEE926, 0x692F, 0x48FD, {0x9E, 0xDB, 0x01, 0x42, 0x2E, 0xF0, 0xD7, 0xAB}};
static EFI_GUID gEfiEventNotificationTypeBootGuid = {0x3D61A466, 0xAB40, 0x409a, {0xA6, 0x98, 0xF3, 0x62, 0xD4, 0x64, 0xB3, 0x8F}};
static EFI_GUID gEfiEventNotificationTypeCmcGuid = {0x2DCE8BB1, 0xBDD7, 0x450e, {0xB9, 0xAD, 0x9C, 0xF4, 0xEB, 0xD4, 0xF8, 0x90}};
static EFI_GUID gEfiEventNotificationTypeCpeGuid = {0x4E292F96, 0xD843, 0x4a55, {0xA8, 0xC2, 0xD4, 0x81, 0xF2, 0x7E, 0xBE, 0xEE}};
static EFI_GUID gEfiEventNotificationTypeDmarGuid = {0x667DD791, 0xC6B3, 0x4c27, {0x8A, 0x6B, 0x0F, 0x8E, 0x72, 0x2D, 0xEB, 0x41}};
static EFI_GUID gEfiEventNotificationTypeInitGuid = {0xCC5263E8, 0x9308, 0x454a, {0x89, 0xD0, 0x34, 0x0B, 0xD3, 0x9B, 0xC9, 0x8E}};
static EFI_GUID gEfiEventNotificationTypeMceGuid = {0xE8F56FFE, 0x919C, 0x4cc5, {0xBA, 0x88, 0x65, 0xAB, 0xE1, 0x49, 0x13, 0xBB}};
static EFI_GUID gEfiEventNotificationTypeNmiGuid = {0x5BAD89FF, 0xB7E6, 0x42c9, {0x81, 0x4A, 0xCF, 0x24, 0x85, 0xD6, 0xE9, 0x8A}};
static EFI_GUID gEfiEventNotificationTypePcieGuid = {0xCF93C01F, 0x1A16, 0x4dfc, {0xB8, 0xBC, 0x9C, 0x4D, 0xAF, 0x67, 0xC1, 0x04}};
static EFI_GUID gEfiEventReadyToBootGuid = {0x7CE88FB3, 0x4BD7, 0x4679, {0x87, 0xA8, 0xA8, 0xD8, 0xDE, 0xE5, 0x0D, 0x2B}};
static EFI_GUID gEfiEventUserProfileChangedGuid = {0xbaf1e6de, 0x209e, 0x4adb, {0x8d, 0x96, 0xfd, 0x8b, 0x71, 0xf3, 0xf6, 0x83}};
static EFI_GUID gEfiEventVirtualAddressChangeGuid = {0x13FA7698, 0xC831, 0x49C7, {0x87, 0xEA, 0x8F, 0x43, 0xFC, 0xC2, 0x51, 0x96}};
static EFI_GUID gEfiExtScsiPassThruProtocolGuid = {0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe}};
static EFI_GUID gEfiFileInfoGuid = {0x09576E92, 0x6D3F, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiFileSystemInfoGuid = {0x09576E93, 0x6D3F, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiFileSystemVolumeLabelInfoIdGuid = {0xDB47D7D3, 0xFE81, 0x11D3, {0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiFirmwareContentsSignedGuid = {0xf9d89e8, 0x9259, 0x4f76, {0xa5, 0xaf, 0xc, 0x89, 0xe3, 0x40, 0x23, 0xdf}};
static EFI_GUID gEfiFirmwareErrorSectionGuid = {0x81212a96, 0x09ed, 0x4996, {0x94, 0x71, 0x8d, 0x72, 0x9c, 0x8e, 0x69, 0xed}};
static EFI_GUID gEfiFirmwareFileSystem2Guid = {0x8c8ce578, 0x8a3d, 0x4f1c, {0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3}};
static EFI_GUID gEfiFirmwareFileSystem3Guid = {0x5473c07a, 0x3dcb, 0x4dca, {0xbd, 0x6f, 0x1e, 0x96, 0x89, 0xe7, 0x34, 0x9a}};
static EFI_GUID gEfiFirmwareManagementProtocolGuid = {0x86c77a67, 0xb97, 0x4633, {0xa1, 0x87, 0x49, 0x10, 0x4d, 0x6, 0x85, 0xc7}};
static EFI_GUID gEfiFirmwareVolume2ProtocolGuid = {0x220e73b6, 0x6bdb, 0x4413, {0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a}};
static EFI_GUID gEfiFirmwareVolumeBlock2ProtocolGuid = {0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4}};
static EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid = {0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4}};
static EFI_GUID gEfiFirmwareVolumeTopFileGuid = {0x1BA0062E, 0xC779, 0x4582, {0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x09}};
static EFI_GUID gEfiFmpCapsuleGuid = {0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a}};
static EFI_GUID gEfiFormBrowser2ProtocolGuid = {0xb9d4c360, 0xbcfb, 0x4f9b, {0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58}};
static EFI_GUID gEfiFtp4ProtocolGuid = {0xeb338826, 0x681b, 0x4295, {0xb3, 0x56, 0x2b, 0x36, 0x4c, 0x75, 0x7b, 0x9}};
static EFI_GUID gEfiFtp4ServiceBindingProtocolGuid = {0xfaaecb1, 0x226e, 0x4782, {0xaa, 0xce, 0x7d, 0xb9, 0xbc, 0xbf, 0x4d, 0xaf}};
static EFI_GUID gEfiGetPcdInfoPpiGuid = {0xa60c6b59, 0xe459, 0x425d, {0x9c, 0x69, 0xb, 0xcc, 0x9c, 0xb2, 0x7d, 0x81}};
static EFI_GUID gEfiGetPcdInfoProtocolGuid = {0xfd0f4478, 0xefd, 0x461d, {0xba, 0x2d, 0xe5, 0x8c, 0x45, 0xfd, 0x5f, 0x5e}};
static EFI_GUID gEfiGlobalVariableGuid = {0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C}};
static EFI_GUID gEfiGraphicsDeviceInfoHobGuid = {0xe5cb2ac9, 0xd35d, 0x4430, {0x93, 0x6e, 0x1d, 0xe3, 0x32, 0x47, 0x8d, 0xe7}};
static EFI_GUID gEfiGraphicsInfoHobGuid = {0x39f62cce, 0x6825, 0x4669, {0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07}};
static EFI_GUID gEfiGraphicsOutputProtocolGuid = {0x9042A9DE, 0x23DC, 0x4A38, {0x96, 0xFB, 0x7A, 0xDE, 0xD0, 0x80, 0x51, 0x6A}};
static EFI_GUID gEfiHardwareErrorVariableGuid = {0x414E6BDD, 0xE47B, 0x47cc, {0xB2, 0x44, 0xBB, 0x61, 0x02, 0x0C, 0xF5, 0x16}};
static EFI_GUID gEfiHash2ProtocolGuid = {0x55b1d734, 0xc5e1, 0x49db, {0x96, 0x47, 0xb1, 0x6a, 0xfb, 0xe, 0x30, 0x5b}};
static EFI_GUID gEfiHash2ServiceBindingProtocolGuid = {0xda836f8d, 0x217f, 0x4ca0, {0x99, 0xc2, 0x1c, 0xa4, 0xe1, 0x60, 0x77, 0xea}};
static EFI_GUID gEfiHashAlgorithmMD5Guid = {0x0AF7C79C, 0x65B5, 0x4319, {0xB0, 0xAE, 0x44, 0xEC, 0x48, 0x4E, 0x4A, 0xD7}};
static EFI_GUID gEfiHashAlgorithmSha1Guid = {0x2AE9D80F, 0x3FB2, 0x4095, {0xB7, 0xB1, 0xE9, 0x31, 0x57, 0xB9, 0x46, 0xB6}};
static EFI_GUID gEfiHashAlgorithmSha1NoPadGuid = {0x24c5dc2f, 0x53e2, 0x40ca, {0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b}};
static EFI_GUID gEfiHashAlgorithmSha224Guid = {0x8DF01A06, 0x9BD5, 0x4BF7, {0xB0, 0x21, 0xDB, 0x4F, 0xD9, 0xCC, 0xF4, 0x5B}};
static EFI_GUID gEfiHashAlgorithmSha256Guid = {0x51AA59DE, 0xFDF2, 0x4EA3, {0xBC, 0x63, 0x87, 0x5F, 0xB7, 0x84, 0x2E, 0xE9}};
static EFI_GUID gEfiHashAlgorithmSha256NoPadGuid = {0x8628752a, 0x6cb7, 0x4814, {0x96, 0xfc, 0x24, 0xa8, 0x15, 0xac, 0x22, 0x26}};
static EFI_GUID gEfiHashAlgorithmSha384Guid = {0xEFA96432, 0xDE33, 0x4DD2, {0xAE, 0xE6, 0x32, 0x8C, 0x33, 0xDF, 0x77, 0x7A}};
static EFI_GUID gEfiHashAlgorithmSha512Guid = {0xCAA4381E, 0x750C, 0x4770, {0xB8, 0x70, 0x7A, 0x23, 0xB4, 0xE4, 0x21, 0x30}};
static EFI_GUID gEfiHashProtocolGuid = {0xC5184932, 0xDBA5, 0x46DB, {0xA5, 0xBA, 0xCC, 0x0B, 0xDA, 0x9C, 0x14, 0x35}};
static EFI_GUID gEfiHashServiceBindingProtocolGuid = {0x42881c98, 0xa4f3, 0x44b0, {0xa3, 0x9d, 0xdf, 0xa1, 0x86, 0x67, 0xd8, 0xcd}};
static EFI_GUID gEfiHiiConfigAccessProtocolGuid = {0x330d4706, 0xf2a0, 0x4e4f, {0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85}};
static EFI_GUID gEfiHiiConfigRoutingProtocolGuid = {0x587e72d7, 0xcc50, 0x4f79, {0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f}};
static EFI_GUID gEfiHiiDatabaseProtocolGuid = {0xef9fc172, 0xa1b2, 0x4693, {0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42}};
static EFI_GUID gEfiHiiDriverHealthFormsetGuid = {0xf22fc20c, 0x8cf4, 0x45eb, {0x8e, 0x6, 0xad, 0x4e, 0x50, 0xb9, 0x5d, 0xd3}};
static EFI_GUID gEfiHiiFontProtocolGuid = {0xe9ca4775, 0x8657, 0x47fc, {0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x08, 0x43, 0x24}};
static EFI_GUID gEfiHiiImageDecoderNameJpegGuid = {0xefefd093, 0x0d9b, 0x46eb, {0xa8, 0x56, 0x48, 0x35, 0x07, 0x00, 0xc9, 0x08}};
static EFI_GUID gEfiHiiImageDecoderNamePngGuid = {0xaf060190, 0x5e3a, 0x4025, {0xaf, 0xbd, 0xe1, 0xf9, 0x05, 0xbf, 0xaa, 0x4c}};
static EFI_GUID gEfiHiiImageDecoderProtocolGuid = {0x9e66f251, 0x727c, 0x418c, {0xbf, 0xd6, 0xc2, 0xb4, 0x25, 0x28, 0x18, 0xea}};
static EFI_GUID gEfiHiiImageExProtocolGuid = {0x1a1241e6, 0x8f19, 0x41a9, {0xbc, 0xe, 0xe8, 0xef, 0x39, 0xe0, 0x65, 0x46}};
static EFI_GUID gEfiHiiImageProtocolGuid = {0x31a6406a, 0x6bdf, 0x4e46, {0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x09, 0x20}};
static EFI_GUID gEfiHiiKeyBoardLayoutGuid = {0x14982a4f, 0xb0ed, 0x45b8, {0xa8, 0x11, 0x5a, 0x7a, 0x9b, 0xc2, 0x32, 0xdf}};
static EFI_GUID gEfiHiiPackageListProtocolGuid = {0x6a1ee763, 0xd47a, 0x43b4, {0xaa, 0xbe, 0xef, 0x1d, 0xe2, 0xab, 0x56, 0xfc}};
static EFI_GUID gEfiHiiPlatformSetupFormsetGuid = {0x93039971, 0x8545, 0x4b04, {0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x04, 0x0e}};
static EFI_GUID gEfiHiiPopupProtocolGuid = {0x4311edc0, 0x6054, 0x46d4, {0x9e, 0x40, 0x89, 0x3e, 0xa9, 0x52, 0xfc, 0xcc}};
static EFI_GUID gEfiHiiStandardFormGuid = {0x3bd2f4ec, 0xe524, 0x46e4, {0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62}};
static EFI_GUID gEfiHiiStringProtocolGuid = {0x0fd96974, 0x23aa, 0x4cdc, {0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a}};
static EFI_GUID gEfiHiiUserCredentialFormsetGuid = {0x337f4407, 0x5aee, 0x4b83, {0xb2, 0xa7, 0x4e, 0xad, 0xca, 0x30, 0x88, 0xcd}};
static EFI_GUID gEfiHobListGuid = {0x7739F24C, 0x93D7, 0x11D4, {0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiHobMemoryAllocBspStoreGuid = {0x564B33CD, 0xC92A, 0x4593, {0x90, 0xBF, 0x24, 0x73, 0xE4, 0x3C, 0x63, 0x22}};
static EFI_GUID gEfiHobMemoryAllocModuleGuid = {0xF8E21975, 0x0899, 0x4F58, {0xA4, 0xBE, 0x55, 0x25, 0xA9, 0xC6, 0xD7, 0x7A}};
static EFI_GUID gEfiHobMemoryAllocStackGuid = {0x4ED4BF27, 0x4092, 0x42E9, {0x80, 0x7D, 0x52, 0x7B, 0x1D, 0x00, 0xC9, 0xBD}};
static EFI_GUID gEfiHttpBootCallbackProtocolGuid = {0xba23b311, 0x343d, 0x11e6, {0x91, 0x85, 0x58, 0x20, 0xb1, 0xd6, 0x52, 0x99}};
static EFI_GUID gEfiHttpProtocolGuid = {0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b}};
static EFI_GUID gEfiHttpServiceBindingProtocolGuid = {0xbdc8e6af, 0xd9bc, 0x4379, {0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c}};
static EFI_GUID gEfiHttpUtilitiesProtocolGuid = {0x3e35c163, 0x4074, 0x45dd, {0x43, 0x1e, 0x23, 0x98, 0x9d, 0xd8, 0x6b, 0x32}};
static EFI_GUID gEfiI2cBusConfigurationManagementProtocolGuid = {0x55b71fb5, 0x17c6, 0x410e, {0xb5, 0xbd, 0x5f, 0xa2, 0xe3, 0xd4, 0x46, 0x6b}};
static EFI_GUID gEfiI2cEnumerateProtocolGuid = {0xda8cd7c4, 0x1c00, 0x49e2, {0x80, 0x3e, 0x52, 0x14, 0xe7, 0x01, 0x89, 0x4c}};
static EFI_GUID gEfiI2cHostProtocolGuid = {0xa5aab9e3, 0xc727, 0x48cd, {0x8b, 0xbf, 0x42, 0x72, 0x33, 0x85, 0x49, 0x48}};
static EFI_GUID gEfiI2cIoProtocolGuid = {0xb60a3e6b, 0x18c4, 0x46e5, {0xa2, 0x9a, 0xc9, 0xa1, 0x06, 0x65, 0xa2, 0x8e}};
static EFI_GUID gEfiI2cMasterProtocolGuid = {0xcd72881f, 0x45b5, 0x4feb, {0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62}};
static EFI_GUID gEfiIa32X64ErrorTypeBusCheckGuid = {0x1CF3F8B3, 0xC5B1, 0x49a2, {0xAA, 0x59, 0x5E, 0xEF, 0x92, 0xFF, 0xA6, 0x3C}};
static EFI_GUID gEfiIa32X64ErrorTypeCacheCheckGuid = {0xA55701F5, 0xE3EF, 0x43de, {0xAC, 0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C}};
static EFI_GUID gEfiIa32X64ErrorTypeMsCheckGuid = {0x48AB7F57, 0xDC34, 0x4f6c, {0xA7, 0xD3, 0xB0, 0xB5, 0xB0, 0xA7, 0x43, 0x14}};
static EFI_GUID gEfiIa32X64ErrorTypeTlbCheckGuid = {0xFC06B535, 0x5E1F, 0x4562, {0x9F, 0x25, 0x0A, 0x3B, 0x9A, 0xDB, 0x63, 0xC3}};
static EFI_GUID gEfiIa32X64ProcessorErrorSectionGuid = {0xdc3ea0b0, 0xa144, 0x4797, {0xb9, 0x5b, 0x53, 0xfa, 0x24, 0x2b, 0x6e, 0x1d}};
static EFI_GUID gEfiIdeControllerInitProtocolGuid = {0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9}};
static EFI_GUID gEfiImageSecurityDatabaseGuid = {0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0, 0xe, 0x67, 0x65, 0x6f}};
static EFI_GUID gEfiIncompatiblePciDeviceSupportProtocolGuid = {0xeb23f55a, 0x7863, 0x4ac2, {0x8d, 0x3d, 0x95, 0x65, 0x35, 0xde, 0x03, 0x75}};
static EFI_GUID gEfiIommuDMArErrorSectionGuid = {0x036f84e1, 0x7f37, 0x428c, {0xa7, 0x9e, 0x57, 0x5f, 0xdf, 0xaa, 0x84, 0xec}};
static EFI_GUID gEfiIp4Config2ProtocolGuid = {0x5b446ed1, 0xe30b, 0x4faa, {0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80}};
static EFI_GUID gEfiIp4ConfigProtocolGuid = {0x3B95AA31, 0x3793, 0x434B, {0x86, 0x67, 0xC8, 0x07, 0x08, 0x92, 0xE0, 0x5E}};
static EFI_GUID gEfiIp4ProtocolGuid = {0x41D94CD2, 0x35B6, 0x455A, {0x82, 0x58, 0xD4, 0xE5, 0x13, 0x34, 0xAA, 0xDD}};
static EFI_GUID gEfiIp4ServiceBindingProtocolGuid = {0xC51711E7, 0xB4BF, 0x404A, {0xBF, 0xB8, 0x0A, 0x04, 0x8E, 0xF1, 0xFF, 0xE4}};
static EFI_GUID gEfiIp6ConfigProtocolGuid = {0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a}};
static EFI_GUID gEfiIp6ProtocolGuid = {0x2c8759d5, 0x5c2d, 0x66ef, {0x92, 0x5f, 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2}};
static EFI_GUID gEfiIp6ServiceBindingProtocolGuid = {0xec835dd3, 0xfe0f, 0x617b, {0xa6, 0x21, 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88}};
static EFI_GUID gEfiIpSec2ProtocolGuid = {0xa3979e64, 0xace8, 0x4ddc, {0xbc, 0x7, 0x4d, 0x66, 0xb8, 0xfd, 0x9, 0x77}};
static EFI_GUID gEfiIpSecConfigProtocolGuid = {0xce5e5929, 0xc7a3, 0x4602, {0xad, 0x9e, 0xc9, 0xda, 0xf9, 0x4e, 0xbf, 0xcf}};
static EFI_GUID gEfiIpSecProtocolGuid = {0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12}};
static EFI_GUID gEfiIsaHcPpiGuid = {0x8d48bd70, 0xc8a3, 0x4c06, {0x90, 0x1b, 0x74, 0x79, 0x46, 0xaa, 0xc3, 0x58}};
static EFI_GUID gEfiIsaHcProtocolGuid = {0xbcdaf080, 0x1bde, 0x4e22, {0xae, 0x6a, 0x43, 0x54, 0x1e, 0x12, 0x8e, 0xc4}};
static EFI_GUID gEfiIsaHcServiceBindingProtocolGuid = {0xfad7933a, 0x6c21, 0x4234, {0xa4, 0x34, 0x0a, 0x8a, 0x0d, 0x2b, 0x07, 0x81}};
static EFI_GUID gEfiIScsiInitiatorNameProtocolGuid = {0x59324945, 0xEC44, 0x4C0D, {0xB1, 0xCD, 0x9D, 0xB1, 0x39, 0xDF, 0x07, 0x0C}};
static EFI_GUID gEfiKmsFormatAescbc128Guid = {0xa0e8ee6a, 0x0e92, 0x44d4, {0x86, 0x1b, 0x0e, 0xaa, 0x4a, 0xca, 0x44, 0xa2}};
static EFI_GUID gEfiKmsFormatAescbc256Guid = {0xd7e69789, 0x1f68, 0x45e8, {0x96, 0xef, 0x3b, 0x64, 0x07, 0xa5, 0xb2, 0xdc}};
static EFI_GUID gEfiKmsFormatAesxts128Guid = {0x4776e33f, 0xdb47, 0x479a, {0xa2, 0x5f, 0xa1, 0xcd, 0x0a, 0xfa, 0xb3, 0x8b}};
static EFI_GUID gEfiKmsFormatAesxts256Guid = {0xdc7e8613, 0xc4bb, 0x4db0, {0x84, 0x62, 0x13, 0x51, 0x13, 0x57, 0xab, 0xe2}};
static EFI_GUID gEfiKmsFormatGeneric1024Guid = {0x43be0b44, 0x874b, 0x4ead, {0xb0, 0x9c, 0x24, 0x1a, 0x4f, 0xbd, 0x7e, 0xb3}};
static EFI_GUID gEfiKmsFormatGeneric128Guid = {0xec8a3d69, 0x6ddf, 0x4108, {0x94, 0x76, 0x73, 0x37, 0xfc, 0x52, 0x21, 0x36}};
static EFI_GUID gEfiKmsFormatGeneric160Guid = {0xa3b3e6f8, 0xefca, 0x4bc1, {0x88, 0xfb, 0xcb, 0x87, 0x33, 0x9b, 0x25, 0x79}};
static EFI_GUID gEfiKmsFormatGeneric2048Guid = {0x40093f23, 0x630c, 0x4626, {0x9c, 0x48, 0x40, 0x37, 0x3b, 0x19, 0xcb, 0xbe}};
static EFI_GUID gEfiKmsFormatGeneric256Guid = {0x70f64793, 0xc323, 0x4261, {0xac, 0x2c, 0xd8, 0x76, 0xf2, 0x7c, 0x53, 0x45}};
static EFI_GUID gEfiKmsFormatGeneric3072Guid = {0xb9237513, 0x6c44, 0x4411, {0xa9, 0x90, 0x21, 0xe5, 0x56, 0xe0, 0x5a, 0xde}};
static EFI_GUID gEfiKmsFormatGeneric512Guid = {0x978fe043, 0xd7af, 0x422e, {0x8a, 0x92, 0x2b, 0x48, 0xe4, 0x63, 0xbd, 0xe6}};
static EFI_GUID gEfiKmsFormatMd2128Guid = {0x78be11c4, 0xee44, 0x4a22, {0x9f, 0x05, 0x03, 0x85, 0x2e, 0xc5, 0xc9, 0x78}};
static EFI_GUID gEfiKmsFormatMd4128Guid = {0xd1c17aa1, 0xcac5, 0x400f, {0xbe, 0x17, 0xe2, 0xa2, 0xae, 0x06, 0x67, 0x7c}};
static EFI_GUID gEfiKmsFormatMd5128Guid = {0xdcbc3662, 0x9cda, 0x4b52, {0xa0, 0x4c, 0x82, 0xeb, 0x1d, 0x23, 0x48, 0xc7}};
static EFI_GUID gEfiKmsFormatMd5sha128Guid = {0x1c178237, 0x6897, 0x459e, {0x9d, 0x36, 0x67, 0xce, 0x8e, 0xf9, 0x4f, 0x76}};
static EFI_GUID gEfiKmsFormatMdc2128Guid = {0xf7ad60f8, 0xefa8, 0x44a3, {0x91, 0x13, 0x23, 0x1f, 0x39, 0x9e, 0xb4, 0xc7}};
static EFI_GUID gEfiKmsFormatMdc4128Guid = {0x3fa4f847, 0xd8eb, 0x4df4, {0xbd, 0x49, 0x10, 0x3a, 0x0a, 0x84, 0x7b, 0xbc}};
static EFI_GUID gEfiKmsFormatRsasha11024Guid = {0x56417bed, 0x6bbe, 0x4882, {0x86, 0xa0, 0x3a, 0xe8, 0xbb, 0x17, 0xf8, 0xf9}};
static EFI_GUID gEfiKmsFormatRsasha12048Guid = {0xf66447d4, 0x75a6, 0x463e, {0xa8, 0x19, 0x07, 0x7f, 0x2d, 0xda, 0x05, 0xe9}};
static EFI_GUID gEfiKmsFormatRsasha2562048Guid = {0xa477af13, 0x877d, 0x4060, {0xba, 0xa1, 0x25, 0xd1, 0xbe, 0xa0, 0x8a, 0xd3}};
static EFI_GUID gEfiKmsFormatRsasha2563072Guid = {0x4e1356c2, 0xeed, 0x463f, {0x81, 0x47, 0x99, 0x33, 0xab, 0xdb, 0xc7, 0xd5}};
static EFI_GUID gEfiKmsFormatSha1160Guid = {0x453c5e5a, 0x482d, 0x43f0, {0x87, 0xc9, 0x59, 0x41, 0xf3, 0xa3, 0x8a, 0xc2}};
static EFI_GUID gEfiKmsFormatSha256256Guid = {0x6bb4f5cd, 0x8022, 0x448d, {0xbc, 0x6d, 0x77, 0x1b, 0xae, 0x93, 0x5f, 0xc6}};
static EFI_GUID gEfiKmsFormatSha512512Guid = {0x2f240e12, 0xe14d, 0x475c, {0x83, 0xb0, 0xef, 0xff, 0x22, 0xd7, 0x7b, 0xe7}};
static EFI_GUID gEfiKmsProtocolGuid = {0xEC3A978D, 0x7C4E, 0x48FA, {0x9A, 0xBE, 0x6A, 0xD9, 0x1C, 0xC8, 0xF8, 0x11}};
static EFI_GUID gEfiLegacyRegion2ProtocolGuid = {0x70101eaf, 0x85, 0x440c, {0xb3, 0x56, 0x8e, 0xe3, 0x6f, 0xef, 0x24, 0xf0}};
static EFI_GUID gEfiLegacySpiControllerProtocolGuid = {0x39136fc7, 0x1a11, 0x49de, {0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc}};
static EFI_GUID gEfiLegacySpiFlashProtocolGuid = {0xf01bed57, 0x04bc, 0x4f3f, {0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59}};
static EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid = {0x62331b78, 0xd8d0, 0x4c8c, {0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b}};
static EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid = {0x5e3848d4, 0x0db5, 0x4fc0, {0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f}};
static EFI_GUID gEfiLoadedImageDevicePathProtocolGuid = {0xbc62157e, 0x3e33, 0x4fec, {0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf}};
static EFI_GUID gEfiLoadedImageProtocolGuid = {0x5B1B31A1, 0x9562, 0x11D2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiLoadFile2ProtocolGuid = {0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d}};
static EFI_GUID gEfiLoadFileProtocolGuid = {0x56EC3091, 0x954C, 0x11D2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiManagedNetworkProtocolGuid = {0x7ab33a91, 0xace5, 0x4326, {0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16}};
static EFI_GUID gEfiManagedNetworkServiceBindingProtocolGuid = {0xF36FF770, 0xA7E1, 0x42CF, {0x9E, 0xD2, 0x56, 0xF0, 0xF2, 0x71, 0xF4, 0x4C}};
static EFI_GUID gEfiMdePkgTokenSpaceGuid = {0x914AEBE7, 0x4635, 0x459b, {0xAA, 0x1C, 0x11, 0xE2, 0x19, 0xB0, 0x3A, 0x10}};
static EFI_GUID gEfiMemoryAttributesTableGuid = {0xdcfa911d, 0x26eb, 0x469f, {0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20}};
static EFI_GUID gEfiMemoryOverwriteControlDataGuid = {0xe20939be, 0x32d4, 0x41be, {0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29}};
static EFI_GUID gEfiMemoryOverwriteRequestControlLockGuid = {0xBB983CCF, 0x151D, 0x40E1, {0xA0, 0x7B, 0x4A, 0x17, 0xBE, 0x16, 0x82, 0x92}};
static EFI_GUID gEfiMetronomeArchProtocolGuid = {0x26BACCB2, 0x6F42, 0x11D4, {0xBC, 0xE7, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}};
static EFI_GUID gEfiMmAccessProtocolGuid = {0xc2702b74, 0x800c, 0x4131, {0x87, 0x46, 0x8f, 0xb5, 0xb8, 0x9c, 0xe4, 0xac}};
static EFI_GUID gEfiMmBaseProtocolGuid = {0xf4ccbfb7, 0xf6e0, 0x47fd, {0x9d, 0xd4, 0x10, 0xa8, 0xf1, 0x50, 0xc1, 0x91}};
static EFI_GUID gEfiMmCommunicationProtocolGuid = {0xc68ed8e2, 0x9dc6, 0x4cbd, {0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32}};
static EFI_GUID gEfiMmConfigurationProtocolGuid = {0x26eeb3de, 0xb689, 0x492e, {0x80, 0xf0, 0xbe, 0x8b, 0xd7, 0xda, 0x4b, 0xa7}};
static EFI_GUID gEfiMmControlProtocolGuid = {0x843dc720, 0xab1e, 0x42cb, {0x93, 0x57, 0x8a, 0x0, 0x78, 0xf3, 0x56, 0x1b}};
static EFI_GUID gEfiMmCpuIoProtocolGuid = {0x3242a9d8, 0xce70, 0x4aa0, {0x95, 0x5d, 0x5e, 0x7b, 0x14, 0x0d, 0xe4, 0xd2}};
static EFI_GUID gEfiMmCpuProtocolGuid = {0xeb346b97, 0x975f, 0x4a9f, {0x8b, 0x22, 0xf8, 0xe9, 0x2b, 0xb3, 0xd5, 0x69}};
static EFI_GUID gEfiMmEndOfDxeProtocolGuid = {0x24e70042, 0xd5c5, 0x4260, {0x8c, 0x39, 0xa, 0xd3, 0xaa, 0x32, 0xe9, 0x3d}};
static EFI_GUID gEfiMmGpiDispatchProtocolGuid = {0x25566b03, 0xb577, 0x4cbf, {0x95, 0x8c, 0xed, 0x66, 0x3e, 0xa2, 0x43, 0x80}};
static EFI_GUID gEfiMmIoTrapDispatchProtocolGuid = {0x58dc368d, 0x7bfa, 0x4e77, {0xab, 0xbc, 0xe, 0x29, 0x41, 0x8d, 0xf9, 0x30}};
static EFI_GUID gEfiMmMpProtocolGuid = {0x5d5450d7, 0x990c, 0x4180, {0xa8, 0x3, 0x8e, 0x63, 0xf0, 0x60, 0x83, 0x7}};
static EFI_GUID gEfiMmPciRootBridgeIoProtocolGuid = {0x8bc1714d, 0xffcb, 0x41c3, {0x89, 0xdc, 0x6c, 0x74, 0xd0, 0x6d, 0x98, 0xea}};
static EFI_GUID gEfiMmPeriodicTimerDispatchProtocolGuid = {0x4cec368e, 0x8e8e, 0x4d71, {0x8b, 0xe1, 0x95, 0x8c, 0x45, 0xfc, 0x8a, 0x53}};
static EFI_GUID gEfiMmPowerButtonDispatchProtocolGuid = {0x1b1183fa, 0x1823, 0x46a7, {0x88, 0x72, 0x9c, 0x57, 0x87, 0x55, 0x40, 0x9d}};
static EFI_GUID gEfiMmReadyToLockProtocolGuid = {0x47b7fa8c, 0xf4bd, 0x4af6, {0x82, 0x00, 0x33, 0x30, 0x86, 0xf0, 0xd2, 0xc8}};
static EFI_GUID gEfiMmRscHandlerProtocolGuid = {0x2ff29fa7, 0x5e80, 0x4ed9, {0xb3, 0x80, 0x1, 0x7d, 0x3c, 0x55, 0x4f, 0xf4}};
static EFI_GUID gEfiMmStandbyButtonDispatchProtocolGuid = {0x7300c4a1, 0x43f2, 0x4017, {0xa5, 0x1b, 0xc8, 0x1a, 0x7f, 0x40, 0x58, 0x5b}};
static EFI_GUID gEfiMmStatusCodeProtocolGuid = {0x6afd2b77, 0x98c1, 0x4acd, {0xa6, 0xf9, 0x8a, 0x94, 0x39, 0xde, 0xf, 0xb1}};
static EFI_GUID gEfiMmSwDispatchProtocolGuid = {0x18a3c6dc, 0x5eea, 0x48c8, {0xa1, 0xc1, 0xb5, 0x33, 0x89, 0xf9, 0x89, 0x99}};
static EFI_GUID gEfiMmSxDispatchProtocolGuid = {0x456d2859, 0xa84b, 0x4e47, {0xa2, 0xee, 0x32, 0x76, 0xd8, 0x86, 0x99, 0x7d}};
static EFI_GUID gEfiMmUsbDispatchProtocolGuid = {0xee9b8d90, 0xc5a6, 0x40a2, {0xbd, 0xe2, 0x52, 0x55, 0x8d, 0x33, 0xcc, 0xa1}};
static EFI_GUID gEfiMonotonicCounterArchProtocolGuid = {0x1DA97072, 0xBDDC, 0x4B30, {0x99, 0xF1, 0x72, 0xA0, 0xB5, 0x6F, 0xFF, 0x2A}};
static EFI_GUID gEfiMpServiceProtocolGuid = {0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08}};
static EFI_GUID gEfiMpsTableGuid = {0xEB9D2D2F, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiMtftp4ProtocolGuid = {0x78247C57, 0x63DB, 0x4708, {0x99, 0xC2, 0xA8, 0xB4, 0xA9, 0xA6, 0x1F, 0x6B}};
static EFI_GUID gEfiMtftp4ServiceBindingProtocolGuid = {0x2FE800BE, 0x8F01, 0x4AA6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F}};
static EFI_GUID gEfiMtftp6ProtocolGuid = {0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51}};
static EFI_GUID gEfiMtftp6ServiceBindingProtocolGuid = {0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23}};
static EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid = {0xE18541CD, 0xF755, 0x4F73, {0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29}};
static EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid_31 = {0x1ACED566, 0x76ED, 0x4218, {0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89}};
static EFI_GUID gEfiNvdimmLabelProtocolGuid = {0xd40b6b80, 0x97d5, 0x4282, {0xbb, 0x1d, 0x22, 0x3a, 0x16, 0x91, 0x80, 0x58}};
static EFI_GUID gEfiNvmExpressPassThruProtocolGuid = {0x52c78312, 0x8edc, 0x4233, {0x98, 0xf2, 0x1a, 0x1a, 0xa5, 0xe3, 0x88, 0xa5}};
static EFI_GUID gEfiPaddingNoneGuid = {0x3629ddb1, 0x228c, 0x452e, {0xb6, 0x16, 0x09, 0xed, 0x31, 0x6a, 0x97, 0x00}};
static EFI_GUID gEfiPaddingRsaesOaepGuid = {0xc1e63ac4, 0xd0cf, 0x4ce6, {0x83, 0x5b, 0xee, 0xd0, 0xe6, 0xa8, 0xa4, 0x5b}};
static EFI_GUID gEfiPaddingRsaesPkcs1V1P5Guid = {0xe1c1d0a9, 0x40b1, 0x4632, {0xbd, 0xcc, 0xd9, 0xd6, 0xe5, 0x29, 0x56, 0x31}};
static EFI_GUID gEfiPaddingRsassaPkcs1V1P5Guid = {0x9317ec24, 0x7cb0, 0x4d0e, {0x8b, 0x32, 0x2e, 0xd9, 0x20, 0x9c, 0xd8, 0xaf}};
static EFI_GUID gEfiPaddingRsassaPssGuid = {0x7b2349e0, 0x522d, 0x4f8e, {0xb9, 0x27, 0x69, 0xd9, 0x7c, 0x9e, 0x79, 0x5f}};
static EFI_GUID gEfiPartitionInfoProtocolGuid = {0x8cf2f62c, 0xbc9b, 0x4821, {0x80, 0x8d, 0xec, 0x9e, 0xc4, 0x21, 0xa1, 0xa0}};
static EFI_GUID gEfiPartTypeLegacyMbrGuid = {0x024DEE41, 0x33E7, 0x11D3, {0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F}};
static EFI_GUID gEfiPartTypeSystemPartGuid = {0xC12A7328, 0xF81F, 0x11D2, {0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B}};
static EFI_GUID gEfiPartTypeUnusedGuid = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
static EFI_GUID gEfiPcAnsiGuid = {0xE0C14753, 0xF9BE, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiPcdProtocolGuid = {0x13a3f0f6, 0x264a, 0x3ef0, {0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34}};
static EFI_GUID gEfiPciBusErrorSectionGuid = {0xc5753963, 0x3b84, 0x4095, {0xbf, 0x78, 0xed, 0xda, 0xd3, 0xf9, 0xc9, 0xdd}};
static EFI_GUID gEfiPciCfg2PpiGuid = {0x57a449a, 0x1fdc, 0x4c06, {0xbf, 0xc9, 0xf5, 0x3f, 0x6a, 0x99, 0xbb, 0x92}};
static EFI_GUID gEfiPciDevErrorSectionGuid = {0xeb5e4685, 0xca66, 0x4769, {0xb6, 0xa2, 0x26, 0x06, 0x8b, 0x00, 0x13, 0x26}};
static EFI_GUID gEfiPcieErrorSectionGuid = {0xd995e954, 0xbbc1, 0x430f, {0xad, 0x91, 0xb4, 0x4d, 0xcb, 0x3c, 0x6f, 0x35}};
static EFI_GUID gEfiPciEnumerationCompleteProtocolGuid = {0x30cfe3e7, 0x3de1, 0x4586, {0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93}};
static EFI_GUID gEfiPciHostBridgeResourceAllocationProtocolGuid = {0xCF8034BE, 0x6768, 0x4d8b, {0xb7, 0x39, 0x7c, 0xce, 0x68, 0x3a, 0x9f, 0xbe}};
static EFI_GUID gEfiPciHotPlugInitProtocolGuid = {0xaa0e8bc1, 0xdabc, 0x46b0, {0xa8, 0x44, 0x37, 0xb8, 0x16, 0x9b, 0x2b, 0xea}};
static EFI_GUID gEfiPciHotPlugRequestProtocolGuid = {0x19CB87AB, 0x2CB9, 0x4665, {0x83, 0x60, 0xDD, 0xCF, 0x60, 0x54, 0xF7, 0x9D}};
static EFI_GUID gEfiPciIoProtocolGuid = {0x4CF5B200, 0x68B8, 0x4CA5, {0x9E, 0xEC, 0xB2, 0x3E, 0x3F, 0x50, 0x02, 0x9A}};
static EFI_GUID gEfiPciOverrideProtocolGuid = {0xb5b35764, 0x460c, 0x4a06, {0x99, 0xfc, 0x77, 0xa1, 0x7c, 0x1b, 0x5c, 0xeb}};
static EFI_GUID gEfiPciPlatformProtocolGuid = {0x07d75280, 0x27d4, 0x4d69, {0x90, 0xd0, 0x56, 0x43, 0xe2, 0x38, 0xb3, 0x41}};
static EFI_GUID gEfiPciRootBridgeIoProtocolGuid = {0x2F707EBB, 0x4A1A, 0x11D4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiPeiBootInRecoveryModePpiGuid = {0x17ee496a, 0xd8e4, 0x4b9a, {0x94, 0xd1, 0xce, 0x82, 0x72, 0x30, 0x8, 0x50}};
static EFI_GUID gEfiPeiCapsulePpiGuid = {0x3acf33ee, 0xd892, 0x40f4, {0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d}};
static EFI_GUID gEfiPeiCoreFvLocationPpiGuid = {0x52888eae, 0x5b10, 0x47d0, {0xa8, 0x7f, 0xb8, 0x22, 0xab, 0xa0, 0xca, 0xf4}};
static EFI_GUID gEfiPeiCpuIoPpiInstalledGuid = {0xe6af1f7b, 0xfc3f, 0x46da, {0xa8, 0x28, 0xa3, 0xb4, 0x57, 0xa4, 0x42, 0x82}};
static EFI_GUID gEfiPeiDecompressPpiGuid = {0x1a36e4e7, 0xfab6, 0x476a, {0x8e, 0x75, 0x69, 0x5a, 0x5, 0x76, 0xfd, 0xd7}};
static EFI_GUID gEfiPeiDeviceRecoveryModulePpiGuid = {0x0DE2CE25, 0x446A, 0x45a7, {0xBF, 0xC9, 0x37, 0xDA, 0x26, 0x34, 0x4B, 0x37}};
static EFI_GUID gEfiPeiFirmwareVolumeInfo2PpiGuid = {0xea7ca24b, 0xded5, 0x4dad, {0xa3, 0x89, 0xbf, 0x82, 0x7e, 0x8f, 0x9b, 0x38}};
static EFI_GUID gEfiPeiFirmwareVolumeInfoPpiGuid = {0x49edb1c1, 0xbf21, 0x4761, {0xbb, 0x12, 0xeb, 0x0, 0x31, 0xaa, 0xbb, 0x39}};
static EFI_GUID gEfiPeiGraphicsPpiGuid = {0x6ecd1463, 0x4a4a, 0x461b, {0xaf, 0x5f, 0x5a, 0x33, 0xe3, 0xb2, 0x16, 0x2b}};
static EFI_GUID gEfiPeiI2cMasterPpiGuid = {0xb3bfab9b, 0x9f9c, 0x4e8b, {0xad, 0x37, 0x7f, 0x8c, 0x51, 0xfc, 0x62, 0x80}};
static EFI_GUID gEfiPeiLoadedImagePpiGuid = {0xc1fcd448, 0x6300, 0x4458, {0xb8, 0x64, 0x28, 0xdf, 0x1, 0x53, 0x64, 0xbc}};
static EFI_GUID gEfiPeiLoadFilePpiGuid = {0xb9e0abfe, 0x5979, 0x4914, {0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6}};
static EFI_GUID gEfiPeiMasterBootModePpiGuid = {0x7408d748, 0xfc8c, 0x4ee6, {0x92, 0x88, 0xc4, 0xbe, 0xc0, 0x92, 0xa4, 0x10}};
static EFI_GUID gEfiPeiMemoryDiscoveredPpiGuid = {0xf894643d, 0xc449, 0x42d1, {0x8e, 0xa8, 0x85, 0xbd, 0xd8, 0xc6, 0x5b, 0xde}};
static EFI_GUID gEfiPeiMpServicesPpiGuid = {0xee16160a, 0xe8be, 0x47a6, {0x82, 0xa, 0xc6, 0x90, 0xd, 0xb0, 0x25, 0xa}};
static EFI_GUID gEfiPeiPcdPpiGuid = {0x1f34d25, 0x4de2, 0x23ad, {0x3f, 0xf3, 0x36, 0x35, 0x3f, 0xf3, 0x23, 0xf1}};
static EFI_GUID gEfiPeiReadOnlyVariable2PpiGuid = {0x2ab86ef5, 0xecb5, 0x4134, {0xb5, 0x56, 0x38, 0x54, 0xca, 0x1f, 0xe1, 0xb4}};
static EFI_GUID gEfiPeiRecoveryModulePpiGuid = {0xFB6D9542, 0x612D, 0x4f45, {0x87, 0x2f, 0x5c, 0xff, 0x52, 0xe9, 0x3d, 0xcf}};
static EFI_GUID gEfiPeiReset2PpiGuid = {0x6cc45765, 0xcce4, 0x42fd, {0xbc, 0x56, 0x1, 0x1a, 0xaa, 0xc6, 0xc9, 0xa8}};
static EFI_GUID gEfiPeiResetPpiGuid = {0xef398d58, 0x9dfd, 0x4103, {0xbf, 0x94, 0x78, 0xc6, 0xf4, 0xfe, 0x71, 0x2f}};
static EFI_GUID gEfiPeiRscHandlerPpiGuid = {0x65d394, 0x9951, 0x4144, {0x82, 0xa3, 0xa, 0xfc, 0x85, 0x79, 0xc2, 0x51}};
static EFI_GUID gEfiPeiS3Resume2PpiGuid = {0x6D582DBC, 0xDB85, 0x4514, {0x8F, 0xCC, 0x5A, 0xDF, 0x62, 0x27, 0xB1, 0x47}};
static EFI_GUID gEfiPeiSecurity2PpiGuid = {0xdcd0be23, 0x9586, 0x40f4, {0xb6, 0x43, 0x6, 0x52, 0x2c, 0xed, 0x4e, 0xde}};
static EFI_GUID gEfiPeiSmbus2PpiGuid = {0x9ca93627, 0xb65b, 0x4324, {0xa2, 0x2, 0xc0, 0xb4, 0x61, 0x76, 0x45, 0x43}};
static EFI_GUID gEfiPeiStallPpiGuid = {0x1f4c6f90, 0xb06b, 0x48d8, {0xa2, 0x01, 0xba, 0xe5, 0xf1, 0xcd, 0x7d, 0x56}};
static EFI_GUID gEfiPeiStatusCodePpiGuid = {0x229832d3, 0x7a30, 0x4b36, {0xb8, 0x27, 0xf4, 0xc, 0xb7, 0xd4, 0x54, 0x36}};
static EFI_GUID gEfiPeiVirtualBlockIo2PpiGuid = {0x26cc0fad, 0xbeb3, 0x478a, {0x91, 0xb2, 0xc, 0x18, 0x8f, 0x72, 0x61, 0x98}};
static EFI_GUID gEfiPeiVirtualBlockIoPpiGuid = {0x695d8aa1, 0x42ee, 0x4c46, {0x80, 0x5c, 0x6e, 0xa6, 0xbc, 0xe7, 0x99, 0xe3}};
static EFI_GUID gEfiPersistentVirtualCdGuid = {0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D}};
static EFI_GUID gEfiPersistentVirtualDiskGuid = {0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F, 0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9}};
static EFI_GUID gEfiPkcs7VerifyProtocolGuid = {0x47889fb2, 0xd671, 0x4fab, {0xa0, 0xca, 0xdf, 0x0e, 0x44, 0xdf, 0x70, 0xd6}};
static EFI_GUID gEfiPlatformDriverOverrideProtocolGuid = {0x6b30c738, 0xa391, 0x11d4, {0x9a, 0x3b, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}};
static EFI_GUID gEfiPlatformMemory2ErrorSectionGuid = {0x61EC04FC, 0x48E6, 0xD813, {0x25, 0xC9, 0x8D, 0xAA, 0x44, 0x75, 0x0B, 0x12}};
static EFI_GUID gEfiPlatformMemoryErrorSectionGuid = {0xa5bc1114, 0x6f64, 0x4ede, {0xb8, 0x63, 0x3e, 0x83, 0xed, 0x7c, 0x83, 0xb1}};
static EFI_GUID gEfiPlatformToDriverConfigurationClpGuid = {0x345ecc0e, 0xcb6, 0x4b75, {0xbb, 0x57, 0x1b, 0x12, 0x9c, 0x47, 0x33, 0x3e}};
static EFI_GUID gEfiPlatformToDriverConfigurationProtocolGuid = {0x642cd590, 0x8059, 0x4c0a, {0xa9, 0x58, 0xc5, 0xec, 0x7, 0xd2, 0x3c, 0x4b}};
static EFI_GUID gEfiProcessorGenericErrorSectionGuid = {0x9876ccad, 0x47b4, 0x4bdb, {0xb6, 0x5e, 0x16, 0xf1, 0x93, 0xc4, 0xf3, 0xdb}};
static EFI_GUID gEfiProcessorSpecificErrorSectionGuid = {0xdc3ea0b0, 0xa144, 0x4797, {0xb9, 0x5b, 0x53, 0xfa, 0x24, 0x2b, 0x6e, 0x1d}};
static EFI_GUID gEfiPropertiesTableGuid = {0x880aaca3, 0x4adc, 0x4a04, {0x90, 0x79, 0xb7, 0x47, 0x34, 0x8, 0x25, 0xe5}};
static EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid = {0x245DCA21, 0xFB7B, 0x11D3, {0x8F, 0x01, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiPxeBaseCodeProtocolGuid = {0x03C4E603, 0xAC28, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiRamDiskProtocolGuid = {0xab38a0df, 0x6873, 0x44a9, {0x87, 0xe6, 0xd4, 0xeb, 0x56, 0x14, 0x84, 0x49}};
static EFI_GUID gEfiRealTimeClockArchProtocolGuid = {0x27CFAC87, 0x46CC, 0x11D4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiRegexSyntaxTypeEcma262Guid = {0x9A473A4A, 0x4CEB, 0xB95A, {0x41, 0x5E, 0x5B, 0xA0, 0xBC, 0x63, 0x9B, 0x2E}};
static EFI_GUID gEfiRegexSyntaxTypePerlGuid = {0x63E60A51, 0x497D, 0xD427, {0xC4, 0xA5, 0xB8, 0xAB, 0xDC, 0x3A, 0xAE, 0xB6}};
static EFI_GUID gEfiRegexSyntaxTypePosixExtendedGuid = {0x5F05B20F, 0x4A56, 0xC231, {0xFA, 0x0B, 0xA7, 0xB1, 0xF1, 0x10, 0x04, 0x1D}};
static EFI_GUID gEfiRegularExpressionProtocolGuid = {0xB3F79D9A, 0x436C, 0xDC11, {0xB0, 0x52, 0xCD, 0x85, 0xDF, 0x52, 0x4C, 0xE6}};
static EFI_GUID gEfiResetArchProtocolGuid = {0x27CFAC88, 0x46CC, 0x11D4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiResetNotificationProtocolGuid = {0x9da34ae0, 0xeaf9, 0x4bbf, {0x8e, 0xc3, 0xfd, 0x60, 0x22, 0x6c, 0x44, 0xbe}};
static EFI_GUID gEfiRestProtocolGuid = {0x0db48a36, 0x4e54, 0xea9c, {0x9b, 0x09, 0x1e, 0xa5, 0xbe, 0x3a, 0x66, 0x0b}};
static EFI_GUID gEfiRngAlgorithmRaw = {0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61}};
static EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid = {0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e}};
static EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid = {0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96}};
static EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid = {0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7}};
static EFI_GUID gEfiRngAlgorithmX9313DesGuid = {0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46}};
static EFI_GUID gEfiRngAlgorithmX931AesGuid = {0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9}};
static EFI_GUID gEfiRngProtocolGuid = {0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44}};
static EFI_GUID gEfiRscHandlerProtocolGuid = {0x86212936, 0xe76, 0x41c8, {0xa0, 0x3a, 0x2a, 0xf2, 0xfc, 0x1c, 0x39, 0xe2}};
static EFI_GUID gEfiRuntimeArchProtocolGuid = {0xb7dfb4e1, 0x052f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33}};
static EFI_GUID gEfiS3SaveStateProtocolGuid = {0xe857caf6, 0xc046, 0x45dc, {0xbe, 0x3f, 0xee, 0x7, 0x65, 0xfb, 0xa8, 0x87}};
static EFI_GUID gEfiS3SmmSaveStateProtocolGuid = {0x320afe62, 0xe593, 0x49cb, {0xa9, 0xf1, 0xd4, 0xc2, 0xf4, 0xaf, 0x1, 0x4c}};
static EFI_GUID gEfiSasDevicePathGuid = {0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d}};
static EFI_GUID gEfiScsiIoProtocolGuid = {0x932F47e6, 0x2362, 0x4002, {0x80, 0x3E, 0x3C, 0xD5, 0x4B, 0x13, 0x8F, 0x85}};
static EFI_GUID gEfiScsiPassThruProtocolGuid = {0xA59E8FCF, 0xBDA0, 0x43BB, {0x90, 0xB1, 0xD3, 0x73, 0x2E, 0xCA, 0xA8, 0x77}};
static EFI_GUID gEfiSdMmcPassThruProtocolGuid = {0x716ef0d9, 0xff83, 0x4f69, {0x81, 0xe9, 0x51, 0x8b, 0xd3, 0x9a, 0x8e, 0x70}};
static EFI_GUID gEfiSecHobDataPpiGuid = {0x3ebdaf20, 0x6667, 0x40d8, {0xb4, 0xee, 0xf5, 0x99, 0x9a, 0xc1, 0xb7, 0x1f}};
static EFI_GUID gEfiSecPlatformInformation2PpiGuid = {0x9e9f374b, 0x8f16, 0x4230, {0x98, 0x24, 0x58, 0x46, 0xee, 0x76, 0x6a, 0x97}};
static EFI_GUID gEfiSecPlatformInformationPpiGuid = {0x6f8c2b35, 0xfef4, 0x448d, {0x82, 0x56, 0xe1, 0x1b, 0x19, 0xd6, 0x10, 0x77}};
static EFI_GUID gEfiSecurity2ArchProtocolGuid = {0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68}};
static EFI_GUID gEfiSecurityArchProtocolGuid = {0xA46423E3, 0x4617, 0x49F1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39}};
static EFI_GUID gEfiSecurityPolicyProtocolGuid = {0x78E4D245, 0xCD4D, 0x4A05, {0xA2, 0xBA, 0x47, 0x43, 0xE8, 0x6C, 0xFC, 0xAB}};
static EFI_GUID gEfiSerialIoProtocolGuid = {0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD}};
static EFI_GUID gEfiShellDynamicCommandProtocolGuid = {0x3c7200e9, 0x005f, 0x4ea4, {0x87, 0xde, 0xa3, 0xdf, 0xac, 0x8a, 0x27, 0xc3}};
static EFI_GUID gEfiShellParametersProtocolGuid = {0x752f3136, 0x4e16, 0x4fdc, {0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca}};
static EFI_GUID gEfiShellProtocolGuid = {0x6302d008, 0x7f9b, 0x4f30, {0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e}};
static EFI_GUID gEfiSimpleFileSystemProtocolGuid = {0x964E5B22, 0x6459, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiSimpleNetworkProtocolGuid = {0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiSimplePointerProtocolGuid = {0x31878C87, 0x0B75, 0x11D5, {0x9A, 0x4F, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiSimpleTextInProtocolGuid = {0x387477C1, 0x69C7, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiSimpleTextInputExProtocolGuid = {0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa}};
static EFI_GUID gEfiSimpleTextOutProtocolGuid = {0x387477C2, 0x69C7, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}};
static EFI_GUID gEfiSioControlProtocolGuid = {0xb91978df, 0x9fc1, 0x427d, {0xbb, 0x5, 0x4c, 0x82, 0x84, 0x55, 0xca, 0x27}};
static EFI_GUID gEfiSioPpiGuid = {0x23a464ad, 0xcb83, 0x48b8, {0x94, 0xab, 0x1a, 0x6f, 0xef, 0xcf, 0xe5, 0x22}};
static EFI_GUID gEfiSioProtocolGuid = {0x215fdd18, 0xbd50, 0x4feb, {0x89, 0xb, 0x58, 0xca, 0xb, 0x47, 0x39, 0xe9}};
static EFI_GUID gEfiSmartCardEdgeProtocolGuid = {0xd317f29b, 0xa325, 0x4712, {0x9b, 0xf1, 0xc6, 0x19, 0x54, 0xdc, 0x19, 0x8c}};
static EFI_GUID gEfiSmartCardReaderProtocolGuid = {0x2a4d1adf, 0x21dc, 0x4b81, {0xa4, 0x2f, 0x8b, 0x8e, 0xe2, 0x38, 0x00, 0x60}};
static EFI_GUID gEfiSmbios3TableGuid = {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCF, 0x20, 0xE3, 0x94}};
static EFI_GUID gEfiSmbiosProtocolGuid = {0x3583ff6, 0xcb36, 0x4940, {0x94, 0x7e, 0xb9, 0xb3, 0x9f, 0x4a, 0xfa, 0xf7}};
static EFI_GUID gEfiSmbiosTableGuid = {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiSmbusHcProtocolGuid = {0xe49d33ed, 0x513d, 0x4634, {0xb6, 0x98, 0x6f, 0x55, 0xaa, 0x75, 0x1c, 0x1b}};
static EFI_GUID gEfiSmmAccess2ProtocolGuid = {0xc2702b74, 0x800c, 0x4131, {0x87, 0x46, 0x8f, 0xb5, 0xb8, 0x9c, 0xe4, 0xac}};
static EFI_GUID gEfiSmmBase2ProtocolGuid = {0xf4ccbfb7, 0xf6e0, 0x47fd, {0x9d, 0xd4, 0x10, 0xa8, 0xf1, 0x50, 0xc1, 0x91}};
static EFI_GUID gEfiSmmCommunicationProtocolGuid = {0xc68ed8e2, 0x9dc6, 0x4cbd, {0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32}};
static EFI_GUID gEfiSmmConfigurationProtocolGuid = {0x26eeb3de, 0xb689, 0x492e, {0x80, 0xf0, 0xbe, 0x8b, 0xd7, 0xda, 0x4b, 0xa7}};
static EFI_GUID gEfiSmmControl2ProtocolGuid = {0x843dc720, 0xab1e, 0x42cb, {0x93, 0x57, 0x8a, 0x0, 0x78, 0xf3, 0x56, 0x1b}};
static EFI_GUID gEfiSmmCpuIo2ProtocolGuid = {0x3242a9d8, 0xce70, 0x4aa0, {0x95, 0x5d, 0x5e, 0x7b, 0x14, 0x0d, 0xe4, 0xd2}};
static EFI_GUID gEfiSmmCpuProtocolGuid = {0xeb346b97, 0x975f, 0x4a9f, {0x8b, 0x22, 0xf8, 0xe9, 0x2b, 0xb3, 0xd5, 0x69}};
static EFI_GUID gEfiSmmEndOfDxeProtocolGuid = {0x24e70042, 0xd5c5, 0x4260, {0x8c, 0x39, 0xa, 0xd3, 0xaa, 0x32, 0xe9, 0x3d}};
static EFI_GUID gEfiSmmGpiDispatch2ProtocolGuid = {0x25566b03, 0xb577, 0x4cbf, {0x95, 0x8c, 0xed, 0x66, 0x3e, 0xa2, 0x43, 0x80}};
static EFI_GUID gEfiSmmIoTrapDispatch2ProtocolGuid = {0x58dc368d, 0x7bfa, 0x4e77, {0xab, 0xbc, 0xe, 0x29, 0x41, 0x8d, 0xf9, 0x30}};
static EFI_GUID gEfiSmmPciRootBridgeIoProtocolGuid = {0x8bc1714d, 0xffcb, 0x41c3, {0x89, 0xdc, 0x6c, 0x74, 0xd0, 0x6d, 0x98, 0xea}};
static EFI_GUID gEfiSmmPeriodicTimerDispatch2ProtocolGuid = {0x4cec368e, 0x8e8e, 0x4d71, {0x8b, 0xe1, 0x95, 0x8c, 0x45, 0xfc, 0x8a, 0x53}};
static EFI_GUID gEfiSmmPowerButtonDispatch2ProtocolGuid = {0x1b1183fa, 0x1823, 0x46a7, {0x88, 0x72, 0x9c, 0x57, 0x87, 0x55, 0x40, 0x9d}};
static EFI_GUID gEfiSmmReadyToLockProtocolGuid = {0x47b7fa8c, 0xf4bd, 0x4af6, {0x82, 0x00, 0x33, 0x30, 0x86, 0xf0, 0xd2, 0xc8}};
static EFI_GUID gEfiSmmRscHandlerProtocolGuid = {0x2ff29fa7, 0x5e80, 0x4ed9, {0xb3, 0x80, 0x1, 0x7d, 0x3c, 0x55, 0x4f, 0xf4}};
static EFI_GUID gEfiSmmSmramMemoryGuid = {0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d}};
static EFI_GUID gEfiSmmStandbyButtonDispatch2ProtocolGuid = {0x7300c4a1, 0x43f2, 0x4017, {0xa5, 0x1b, 0xc8, 0x1a, 0x7f, 0x40, 0x58, 0x5b}};
static EFI_GUID gEfiSmmStatusCodeProtocolGuid = {0x6afd2b77, 0x98c1, 0x4acd, {0xa6, 0xf9, 0x8a, 0x94, 0x39, 0xde, 0xf, 0xb1}};
static EFI_GUID gEfiSmmSwDispatch2ProtocolGuid = {0x18a3c6dc, 0x5eea, 0x48c8, {0xa1, 0xc1, 0xb5, 0x33, 0x89, 0xf9, 0x89, 0x99}};
static EFI_GUID gEfiSmmSxDispatch2ProtocolGuid = {0x456d2859, 0xa84b, 0x4e47, {0xa2, 0xee, 0x32, 0x76, 0xd8, 0x86, 0x99, 0x7d}};
static EFI_GUID gEfiSmmUsbDispatch2ProtocolGuid = {0xee9b8d90, 0xc5a6, 0x40a2, {0xbd, 0xe2, 0x52, 0x55, 0x8d, 0x33, 0xcc, 0xa1}};
static EFI_GUID gEfiSpiConfigurationProtocolGuid = {0x85a6d3e6, 0xb65b, 0x4afc, {0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8}};
static EFI_GUID gEfiSpiHcProtocolGuid = {0xc74e5db2, 0xfa96, 0x4ae2, {0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d}};
static EFI_GUID gEfiSpiNorFlashProtocolGuid = {0xb57ec3fe, 0xf833, 0x4ba6, {0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b}};
static EFI_GUID gEfiSpiSmmConfigurationProtocolGuid = {0x995c6eca, 0x171b, 0x45fd, {0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59}};
static EFI_GUID gEfiSpiSmmHcProtocolGuid = {0xe9f02217, 0x2093, 0x4470, {0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb}};
static EFI_GUID gEfiSpiSmmNorFlashProtocolGuid = {0xaab18f19, 0xfe14, 0x4666, {0x86, 0x04, 0x87, 0xff, 0x6d, 0x66, 0x2c, 0x9a}};
static EFI_GUID gEfiStatusCodeDataTypeStringGuid = {0x92D11080, 0x496F, 0x4D95, {0xBE, 0x7E, 0x03, 0x74, 0x88, 0x38, 0x2B, 0x0A}};
static EFI_GUID gEfiStatusCodeRuntimeProtocolGuid = {0xD2B2B828, 0x0826, 0x48A7, {0xB3, 0xDF, 0x98, 0x3C, 0x00, 0x60, 0x24, 0xF0}};
static EFI_GUID gEfiStatusCodeSpecificDataGuid = {0x335984BD, 0xE805, 0x409A, {0xB8, 0xF8, 0xD2, 0x7E, 0xCE, 0x5F, 0xF7, 0xA6}};
static EFI_GUID gEfiStorageSecurityCommandProtocolGuid = {0xc88b0b6d, 0x0dfc, 0x49a7, {0x9c, 0xb4, 0x49, 0x7, 0x4b, 0x4c, 0x3a, 0x78}};
static EFI_GUID gEfiSupplicantProtocolGuid = {0x54fcc43e, 0xaa89, 0x4333, {0x9a, 0x85, 0xcd, 0xea, 0x24, 0x5, 0x1e, 0x9e}};
static EFI_GUID gEfiSupplicantServiceBindingProtocolGuid = {0x45bcd98e, 0x59ad, 0x4174, {0x95, 0x46, 0x34, 0x4a, 0x7, 0x48, 0x58, 0x98}};
static EFI_GUID gEfiSystemResourceTableGuid = {0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80}};
static EFI_GUID gEfiTapeIoProtocolGuid = {0x1E93E633, 0xD65A, 0x459E, {0xAB, 0x84, 0x93, 0xD9, 0xEC, 0x26, 0x6D, 0x18}};
static EFI_GUID gEfiTcg2FinalEventsTableGuid = {0x1e2ed096, 0x30e2, 0x4254, {0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25}};
static EFI_GUID gEfiTcg2ProtocolGuid = {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f}};
static EFI_GUID gEfiTcgProtocolGuid = {0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd}};
static EFI_GUID gEfiTcp4ProtocolGuid = {0x65530BC7, 0xA359, 0x410F, {0xB0, 0x10, 0x5A, 0xAD, 0xC7, 0xEC, 0x2B, 0x62}};
static EFI_GUID gEfiTcp4ServiceBindingProtocolGuid = {0x00720665, 0x67EB, 0x4A99, {0xBA, 0xF7, 0xD3, 0xC3, 0x3A, 0x1C, 0x7C, 0xC9}};
static EFI_GUID gEfiTcp6ProtocolGuid = {0x46e44855, 0xbd60, 0x4ab7, {0xab, 0x0d, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77}};
static EFI_GUID gEfiTcp6ServiceBindingProtocolGuid = {0xec20eb79, 0x6c1a, 0x4664, {0x9a, 0x0d, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64}};
static EFI_GUID gEfiTemporaryRamDonePpiGuid = {0xceab683c, 0xec56, 0x4a2d, {0xa9, 0x6, 0x40, 0x53, 0xfa, 0x4e, 0x9c, 0x16}};
static EFI_GUID gEfiTemporaryRamSupportPpiGuid = {0xdbe23aa9, 0xa345, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89}};
static EFI_GUID gEfiTimerArchProtocolGuid = {0x26BACCB3, 0x6F42, 0x11D4, {0xBC, 0xE7, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}};
static EFI_GUID gEfiTimestampProtocolGuid = {0xafbfde41, 0x2e6e, 0x4262, {0xba, 0x65, 0x62, 0xb9, 0x23, 0x6e, 0x54, 0x95}};
static EFI_GUID gEfiTlsConfigurationProtocolGuid = {0x1682fe44, 0xbd7a, 0x4407, {0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d}};
static EFI_GUID gEfiTlsProtocolGuid = {0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51, 0x43, 0x90}};
static EFI_GUID gEfiTlsServiceBindingProtocolGuid = {0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d}};
static EFI_GUID gEfiTrEEProtocolGuid = {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f}};
static EFI_GUID gEfiUartDevicePathGuid = {0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4}};
static EFI_GUID gEfiUdp4ProtocolGuid = {0x3AD9DF29, 0x4501, 0x478D, {0xB1, 0xF8, 0x7F, 0x7F, 0xE7, 0x0E, 0x50, 0xF3}};
static EFI_GUID gEfiUdp4ServiceBindingProtocolGuid = {0x83F01464, 0x99BD, 0x45E5, {0xB3, 0x83, 0xAF, 0x63, 0x05, 0xD8, 0xE9, 0xE6}};
static EFI_GUID gEfiUdp6ProtocolGuid = {0x4f948815, 0xb4b9, 0x43cb, {0x8a, 0x33, 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55}};
static EFI_GUID gEfiUdp6ServiceBindingProtocolGuid = {0x66ed4721, 0x3c98, 0x4d3e, {0x81, 0xe3, 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54}};
static EFI_GUID gEfiUfsDeviceConfigProtocolGuid = {0xb81bfab0, 0xeb3, 0x4cf9, {0x84, 0x65, 0x7f, 0xa9, 0x86, 0x36, 0x16, 0x64}};
static EFI_GUID gEfiUgaDrawProtocolGuid = {0x982C298B, 0xF4FA, 0x41CB, {0xB8, 0x38, 0x77, 0xAA, 0x68, 0x8F, 0xB8, 0x39}};
static EFI_GUID gEfiUgaIoProtocolGuid = {0x61A4D49E, 0x6F68, 0x4F1B, {0xB9, 0x22, 0xA8, 0x6E, 0xED, 0x0B, 0x07, 0xA2}};
static EFI_GUID gEfiUnicodeCollation2ProtocolGuid = {0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49}};
static EFI_GUID gEfiUnicodeCollationProtocolGuid = {0x1D85CD7F, 0xF43D, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiUsb2HcProtocolGuid = {0x3E745226, 0x9818, 0x45B6, {0xA2, 0xAC, 0xD7, 0xCD, 0x0E, 0x8B, 0xA2, 0xBC}};
static EFI_GUID gEfiUsbFunctionIoProtocolGuid = {0x32d2963a, 0xfe5d, 0x4f30, {0xb6, 0x33, 0x6e, 0x5d, 0xc5, 0x58, 0x3, 0xcc}};
static EFI_GUID gEfiUsbHcProtocolGuid = {0xF5089266, 0x1AA0, 0x4953, {0x97, 0xD8, 0x56, 0x2F, 0x8A, 0x73, 0xB5, 0x19}};
static EFI_GUID gEfiUsbIoProtocolGuid = {0x2B2F68D6, 0x0CD2, 0x44CF, {0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75}};
static EFI_GUID gEfiUserCredential2ProtocolGuid = {0xe98adb03, 0xb8b9, 0x4af8, {0xba, 0x20, 0x26, 0xe9, 0x11, 0x4c, 0xbc, 0xe5}};
static EFI_GUID gEfiUserCredentialClassFingerprintGuid = {0x32cba21f, 0xf308, 0x4cbc, {0x9a, 0xb5, 0xf5, 0xa3, 0x69, 0x9f, 0x4, 0x4a}};
static EFI_GUID gEfiUserCredentialClassHandprintGuid = {0x5917ef16, 0xf723, 0x4bb9, {0xa6, 0x4b, 0xd8, 0xc5, 0x32, 0xf4, 0xd8, 0xb5}};
static EFI_GUID gEfiUserCredentialClassPasswordGuid = {0xf8e5058c, 0xccb6, 0x4714, {0xb2, 0x20, 0x3f, 0x7e, 0x3a, 0x64, 0xb, 0xd1}};
static EFI_GUID gEfiUserCredentialClassSecureCardGuid = {0x8a6b4a83, 0x42fe, 0x45d2, {0xa2, 0xef, 0x46, 0xf0, 0x6c, 0x7d, 0x98, 0x52}};
static EFI_GUID gEfiUserCredentialClassSmartCardGuid = {0x5f03ba33, 0x8c6b, 0x4c24, {0xaa, 0x2e, 0x14, 0xa2, 0x65, 0x7b, 0xd4, 0x54}};
static EFI_GUID gEfiUserCredentialClassUnknownGuid = {0x5cf32e68, 0x7660, 0x449b, {0x80, 0xe6, 0x7e, 0xa3, 0x6e, 0x3, 0xf6, 0xa8}};
static EFI_GUID gEfiUserCredentialProtocolGuid = {0x71ee5e94, 0x65b9, 0x45d5, {0x82, 0x1a, 0x3a, 0x4d, 0x86, 0xcf, 0xe6, 0xbe}};
static EFI_GUID gEfiUserInfoAccessSetupAdminGuid = {0x85b75607, 0xf7ce, 0x471e, {0xb7, 0xe4, 0x2a, 0xea, 0x5f, 0x72, 0x32, 0xee}};
static EFI_GUID gEfiUserInfoAccessSetupNormalGuid = {0x1db29ae0, 0x9dcb, 0x43bc, {0x8d, 0x87, 0x5d, 0xa1, 0x49, 0x64, 0xdd, 0xe2}};
static EFI_GUID gEfiUserInfoAccessSetupRestrictedGuid = {0xbdb38125, 0x4d63, 0x49f4, {0x82, 0x12, 0x61, 0xcf, 0x5a, 0x19, 0xa, 0xf8}};
static EFI_GUID gEfiUserManagerProtocolGuid = {0x6fd5b00c, 0xd426, 0x4283, {0x98, 0x87, 0x6c, 0xf5, 0xcf, 0x1c, 0xb1, 0xfe}};
static EFI_GUID gEfiVariableArchProtocolGuid = {0x1E5668E2, 0x8481, 0x11D4, {0xBC, 0xF1, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}};
static EFI_GUID gEfiVariableWriteArchProtocolGuid = {0x6441F818, 0x6362, 0x4E44, {0xB5, 0x70, 0x7D, 0xBA, 0x31, 0xDD, 0x24, 0x53}};
static EFI_GUID gEfiVectorHandoffInfoPpiGuid = {0x3cd652b4, 0x6d33, 0x4dce, {0x89, 0xdb, 0x83, 0xdf, 0x97, 0x66, 0xfc, 0xca}};
static EFI_GUID gEfiVectorHandoffTableGuid = {0x996ec11c, 0x5397, 0x4e73, {0xb5, 0x8f, 0x82, 0x7e, 0x52, 0x90, 0x6d, 0xef}};
static EFI_GUID gEfiVirtualCdGuid = {0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB}};
static EFI_GUID gEfiVirtualDiskGuid = {0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E}};
static EFI_GUID gEfiVlanConfigProtocolGuid = {0x9e23d768, 0xd2f3, 0x4366, {0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74}};
static EFI_GUID gEfiVT100Guid = {0xDFA66065, 0xB419, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiVT100PlusGuid = {0x7BAEC70B, 0x57E0, 0x4C76, {0x8E, 0x87, 0x2F, 0x9E, 0x28, 0x08, 0x83, 0x43}};
static EFI_GUID gEfiVTUTF8Guid = {0xAD15A0D6, 0x8BEC, 0x4ACF, {0xA0, 0x73, 0xD0, 0x1D, 0xE7, 0x7E, 0x2D, 0x88}};
static EFI_GUID gEfiWatchdogTimerArchProtocolGuid = {0x665E3FF5, 0x46CC, 0x11D4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}};
static EFI_GUID gEfiWiFi2ProtocolGuid = {0x1b0fb9bf, 0x699d, 0x4fdd, {0xa7, 0xc3, 0x25, 0x46, 0x68, 0x1b, 0xf6, 0x3b}};
static EFI_GUID gEfiWiFiProtocolGuid = {0xda55bc9, 0x45f8, 0x4bb4, {0x87, 0x19, 0x52, 0x24, 0xf1, 0x8a, 0x4d, 0x45}};
static EFI_GUID gGetPcdInfoPpiGuid = {0x4d8b155b, 0xc059, 0x4c8f, {0x89, 0x26, 0x6, 0xfd, 0x43, 0x31, 0xdb, 0x8a}};
static EFI_GUID gGetPcdInfoProtocolGuid = {0x5be40f57, 0xfa68, 0x4610, {0xbb, 0xbf, 0xe9, 0xc5, 0xfc, 0xda, 0xd3, 0x65}};
static EFI_GUID gPcdPpiGuid = {0x6e81c58, 0x4ad7, 0x44bc, {0x83, 0x90, 0xf1, 0x2, 0x65, 0xf7, 0x24, 0x80}};
static EFI_GUID gPcdProtocolGuid = {0x11B34006, 0xD85B, 0x4D0A, {0xA2, 0x90, 0xD5, 0xA5, 0x71, 0x31, 0x0E, 0xF7}};
static EFI_GUID gPeiAprioriFileNameGuid = {0x1b45cc0a, 0x156a, 0x428a, {0XAF, 0x62, 0x49, 0x86, 0x4d, 0xa0, 0xe6, 0xe6}};
static EFI_GUID gPeiCapsulePpiGuid = {0x3acf33ee, 0xd892, 0x40f4, {0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d}};
static EFI_GUID gTianoCustomDecompressGuid = {0xA31280AD, 0x481E, 0x41B6, {0x95, 0xE8, 0x12, 0x7F, 0x4C, 0x98, 0x47, 0x79}};
static EFI_GUID gWindowsUxCapsuleGuid = {0x3b8c8162, 0x188c, 0x46a4, {0xae, 0xc9, 0xbe, 0x43, 0xf1, 0xd6, 0x56, 0x97}};
#define BlockIo2Protocol gEfiBlockIo2ProtocolGuid
#define BlockIoProtocol gEfiBlockIoProtocolGuid
#define BusSpecificDriverOverrideProtocol gEfiBusSpecificDriverOverrideProtocolGuid
#define ComponentName2Protocol gEfiComponentName2ProtocolGuid
#define ComponentNameProtocol gEfiComponentNameProtocolGuid
#define DeviceIoProtocol gEfiDeviceIoProtocolGuid
#define DevicePathFromTextProtocol gEfiDevicePathFromTextProtocolGuid
#define DevicePathProtocol gEfiDevicePathProtocolGuid
#define DevicePathToTextProtocol gEfiDevicePathToTextProtocolGuid
#define DevicePathUtilitiesProtocol gEfiDevicePathUtilitiesProtocolGuid
#define DiskIo2Protocol gEfiDiskIo2ProtocolGuid
#define DiskIoProtocol gEfiDiskIoProtocolGuid
#define DriverBindingProtocol gEfiDriverBindingProtocolGuid
#define DriverFamilyOverrideProtocol gEfiDriverFamilyOverrideProtocolGuid
#define EdidActiveProtocol gEfiEdidActiveProtocolGuid
#define EdidDiscoveredProtocol gEfiEdidDiscoveredProtocolGuid
#define EdidOverrideProtocol gEfiEdidOverrideProtocolGuid
#define EfiGlobalVariable gEfiGlobalVariableGuid
#define FileSystemInfo gEfiFileSystemInfoGuid
#define FileSystemProtocol gEfiSimpleFileSystemProtocolGuid
#define FileSystemVolumeLabelInfo gEfiFileSystemVolumeLabelInfoIdGuid
#define GenericFileInfo gEfiFileInfoGuid
#define GraphicsOutputProtocol gEfiGraphicsOutputProtocolGuid
#define HashProtocol gEfiHashProtocolGuid
#define LoadedImageProtocol gEfiLoadedImageProtocolGuid
#define LoadFileProtocol gEfiLoadFileProtocolGuid
#define NetworkInterfaceIdentifierProtocol gEfiNetworkInterfaceIdentifierProtocolGuid
#define PcAnsiProtocol gEfiPcAnsiGuid
#define PciIoProtocol gEfiPciIoProtocolGuid
#define PlatformDriverOverrideProtocol gEfiPlatformDriverOverrideProtocolGuid
#define PxeBaseCodeProtocol gEfiPxeBaseCodeProtocolGuid
#define PxeCallbackProtocol gEfiPxeBaseCodeCallbackProtocolGuid
#define SerialIoProtocol gEfiSerialIoProtocolGuid
#define SimpleNetworkProtocol gEfiSimpleNetworkProtocolGuid
#define TextInProtocol gEfiSimpleTextInProtocolGuid
#define TextOutProtocol gEfiSimpleTextOutProtocolGuid
#define UiProtocol gEFiUiInterfaceProtocolGuid
#define UnicodeCollationProtocol gEfiUnicodeCollationProtocolGuid
#define Vt100Protocol gEfiVT100Guid
#pragma GCC diagnostic pop

Some files were not shown because too many files have changed in this diff Show More