408 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
793ccfd5ba ci: add CHANGELOG.md in artifacts
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Has been cancelled
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 03:22:30 +00:00
66362ed387 chore: add git-cliff
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 03:17:00 +00:00
11e7d8c2dd ci: add "push: never" to devcontainers/ci
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 02:26:13 +00:00
e1e9ce050d ci: fix limine in ci build
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 02:00:47 +00:00
92610b6678 ci: fix ci
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 01:55:00 +00:00
15a9a21448 ci: fix "touch: cannot touch '/run/user/1000/pulse/native': No such file or directory"
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Has been cancelled
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 00:37:57 +00:00
d4c4016c7c ci: potential fix for Dev Container issues
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 00:35:44 +00:00
19055409cd ci: experimental change to workflows to use dev container
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-06 00:26:30 +00:00
839dfb74b2 build(kernel): fix i386 build
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 23:34:20 +00:00
0bfb45020f build(kernel): fix compiling issues on arm
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 23:19:02 +00:00
9e746c52bc feat(kernel/api): implement arm syscall wrappers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 23:18:18 +00:00
3740b65263 fix(userspace/libc): add libgcc link to fix softfloat
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 23:17:15 +00:00
77e51a6f2c feat(userspace/libc): add experimental __aeabi_dcmpun() function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 18:58:32 +00:00
42b8b6895f fix(userspace/libc): fix wrong implementation of ioctl()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 18:54:18 +00:00
9da2650486 build(kernel): fix compiling issues on i386
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 17:39:42 +00:00
e01f488768 feat(kernel/api): implement i386 syscall wrappers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 17:38:59 +00:00
958a3ed263 feat(userspace/apps/test): update utest
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Deploy Documentation to GitHub Pages (push) Has been cancelled
Build OS / Analyze (c-cpp) (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
Build OS / Build arm (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 04:23:19 +00:00
a0e3993a3f feat(userspace/libc): implement <math.h> header
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 04:21:06 +00:00
edeecf7831 fix(userspace/apps/test): adjust fflush(stdout) calls for better output control
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 04:19:34 +00:00
90fb9c7952 test(userspace/apps/test): expand math function tests for accuracy
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 04:18:40 +00:00
0a52ef4f68 fix(userspace/apps/test): update expected results for rounding and special functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 03:53:59 +00:00
5e0a80fa1c feat(userspace/libc): implementation <fenv.h> header
FIXME: testing required!
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 03:23:19 +00:00
784f3c3df9 chore: standardize indentation for CMake files
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-05 01:22:45 +02:00
68acf428a2 fix(userspace/libc): disable debug info in memory allocation functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-03 18:26:00 +00:00
9105c63465 refactor(userspace/apps/test): ♻️ move all functions in one file
it's just too much...

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-03 18:25:05 +00:00
659805960b fix(userspace/libc): wrong puts() implementation
The implementation didn't fully followed the POSIX.1-2024 standard "The puts() function shall write the string pointed to by s, followed by a <newline>, to the standard output stream stdout. The terminating null byte shall not be written."

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-03 12:08:39 +00:00
451c5405e0 fix(userspace/apps/test): fix noreturn compiler warning
fix "warning: 'noreturn' function does return"

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-03 00:58:19 +00:00
bd02b976a2 fix(kernel/tty): temporal removal of ICANON checking
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 23:57:46 +00:00
9bffe3e013 chore(vscode): rename preLaunchTask from launch-qemu to QEMU
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 23:33:28 +00:00
84298fc4eb fix(kernel/driver): set unused file system operation pointers to nullptr
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 23:31:30 +00:00
87a2dc9444 fix(kernel/driver): node device & offset were not set for new created files under /dev
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 23:29:13 +00:00
426a84a1a9 docs(kernel): short doc for __check_op macro
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 23:14:40 +00:00
8eed8909da chore(vscode): update launch configuration to include libc_test
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 22:47:43 +00:00
09d0af1ea6 refactor(userspace/libs): rename libdemo to libexample
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 22:02:02 +00:00
7b85636f8f fix(drivers): remove drivers that are now in kernel
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:37:52 +00:00
95585fce5f fix(kernel/driver): remove unused device handling code in daemon
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:37:10 +00:00
bf1e3432d7 feat(kernel/drivers): migrate drivers to the kernel
make the drivers builtin

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:37:01 +00:00
f824df9aad feat(kernel/driver): implement built-in driver support
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:34:16 +00:00
426499090e feat(kernel/driver): add CreateDeviceFile function in the API
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:32:00 +00:00
1af2cf657d feat(kernel/driver): add CreateDeviceFile method
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:30:15 +00:00
f31d11f7ad fix(kernel/pci): fix MapPCIAddresses when BAR size of zero
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:28:28 +00:00
851a8c140f feat(kernel/driver): add ReloadDriver method to manage driver reloading
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:27:20 +00:00
ae2617dca2 refactor(driver/api): delegate memory allocation and deallocation to DriverManager
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-02 21:26:00 +00:00
adba9cc348 refactor(driver/api): fix formatting
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-01 23:33:55 +00:00
232e06f8f3 refactor(kernel/pci): simplify PCI device initialization by delegating to PCIManager
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-01 23:32:54 +00:00
aea8a7bb08 feat(kernel/pci): add device initialization method for PCI devices
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-01 23:32:14 +00:00
65ab83b42b fix(kernel/pci): map BAR address using PWT and PCD flags
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-01 23:31:31 +00:00
d3f6d51ed2 build(vscode): add separated tasks for building bootloader, kernel, drivers, userspace, and image
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-28 00:41:17 +00:00
ca8dc6429b fix(kernel): fix empty initialization of std::string (str = "")
_size is 0 which fails the memcpy checks

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-27 18:13:51 +00:00
cfb5d9a0f4 build(tools): fix gdb error 'Scripting in the "Python" language is not supported in this copy of GDB.'
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-26 23:20:10 +00:00
8dab45ecfd build(devcontainer): improve Dev Container development
The toolchain and qemu can be built inside the container + running the qemu inside the container

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-26 23:10:17 +00:00
88a5f06325 build(tools): rewrite makefile to be more efficient and easy to understand
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-26 23:07:36 +00:00
aab84cd3ab chore(devcontainer): rename dev container (libc_test)
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-26 23:04:57 +00:00
a3719eef3e feat(initrd): add /etc/hosts file
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-26 15:21:54 +00:00
0769a82f4b feat(userspace/libc): update math functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-26 02:10:06 +00:00
f978f2487e feat(userspace/libc): add math stub functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-25 16:17:37 +00:00
8859bfc438 chore(vscode): add Dev Container
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-25 16:16:41 +00:00
5202601c4f feat(userspace/libs/libm): add stub libm
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-25 16:13:42 +00:00
78141b28c7 feat(userspace/apps/test/libc_test): rewrite a lot of the code and improve debugging with vscode using .devcontainer
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-25 14:10:12 +00:00
3f2584ac09 chore(vscode): add 'kernel' scope to conventional commits
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-24 02:10:14 +02:00
a2ce579a61 fix(userspace/libc): update vscode stub macro with improved formatting
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-24 02:09:31 +02:00
0958cdf7f8 fix(kernel): add TZ environment variable to init process
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-24 02:08:42 +02:00
7f3b2b4dbb fix(userspace/libc): fix tzset() function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-22 03:26:49 +02:00
f6f46d1bbe fix(userspace/libc): fix gmtime_r, localtime_r and mktime implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-22 03:22:47 +02:00
c12ee67592 fix(userspace/libc): handle NULL input in getenv function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-22 02:52:11 +02:00
74ff9579f3 fix(userspace/libc): fopen should set buffer_pos to -1
This change is a fix for fread() because it needs to pass the if statement: "if (stream->buffer_pos >= stream->buffer_size)"

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-22 02:43:06 +02:00
d7cbeb9eba fix(userspace/libc): modify __libc_init and crt0 to initialize "environ"
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-22 02:41:41 +02:00
4d333f94bc feat(userspace/apps/test/utest): add TestProcess function for executing test programs
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:58:30 +02:00
e003af38ff chore(vscode): add userspace/apps/sys/init to conventional commit scopes
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:56:09 +02:00
d1c504f9a6 feat(userspace/apps/sys/init): handle termination signals for graceful shutdown
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:55:29 +02:00
d46ed57dd7 chore(vscode): add more conventional commit scopes for userspace
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:54:45 +02:00
a6d372aaad feat(userspace/libs/libdemo): add template library
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:53:41 +02:00
b3e0b30147 refactor(tests): remove obsolete SIMD and web test files
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:47:12 +02:00
93e57f5dbe feat(userspace/libc): add stub termios implementation
Stub implementation! This needs a rewrite!

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:45:20 +02:00
db5a42289a feat(userspace/libc): implement feof() and ferror() functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:43:00 +02:00
77136acccd feat(userspace/libc): implement <time.h> header
Not tested enough!

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:42:33 +02:00
258ac6e2f6 chore(vscode): add recommended extensions for improved development experience
ms-vscode.cpptools maziac.asm-code-lens editorconfig.editorconfig vivaxy.vscode-conventional-commits ms-vscode.hexeditor webfreak.debug ibm.output-colorizer gruntfuggly.todo-tree naumovs.color-highlight seven1bit.vscode-ext-ansi-color-highlight jeff-hykin.better-cpp-syntax aaron-bond.better-comments

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:40:21 +02:00
fbe4b94805 chore(vscode): add conventional commit scopes for kernel
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:38:52 +02:00
2c2e7d9de3 build(userspace): update vscode launch configuration and Makefiles for utest and libc_test
Easier to debug

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:37:48 +02:00
9dfa750444 refactor(kernel/syscalls): simplify argument handling in HandleNativeSyscalls
Easier to debug

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:35:57 +02:00
4240183fa1 fix(userspace/libc): cast status to int in __check_errno for proper error handling
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-21 02:33:40 +02:00
42f26787fb feat(userspace/libc): implement getdelim and getline functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 02:20:26 +02:00
8d08ab933a feat(userspace/libc): implement fstatat, lstat & stat
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 02:17:19 +02:00
c83c542f5b feat(userspace/libc): implement fstat()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 02:12:02 +02:00
08319ef4c7 docs(syscalls): add documentation for FBIOGET_SCREEN_INFO ioctl
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 02:09:09 +02:00
f4168e2815 refactor(userspace/libc): implement pthread_sigmask, sigaddset, sigfillset & sigprocmask
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 02:07:40 +02:00
123d11e4e3 feat(userspace/libc): implement system() function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 02:07:04 +02:00
b1a107fb65 refactor(userspace/libc): replace syscall2 with call_kill in kill function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 02:00:26 +02:00
d375acd0ec fix(userspace/libc): include <ctype.h> in stdlib.c
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 01:53:21 +02:00
5e6e63ab1a feat(userspace/libc): implement <ctype.h> header
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 01:52:37 +02:00
ab4bc55270 feat(userspace/libc): implement atoi, strtol, and strtoll functions in <stdlib.h>
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 01:49:41 +02:00
e5acf4a99e feat(userspace/libc): implement getpid, getppid & getuid
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 01:49:12 +02:00
5089cfa81b feat(userspace/libc): implement <pwd.h> header
Implemented everything except endpwent() and setpwent()

NOT TESTED!

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-20 01:45:04 +02:00
b5fce27037 feat(userspace/libc): implement getchar() and getc()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 21:57:51 +02:00
0238f62894 fix(userspace/libc): fix error handling in ioctl function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 21:03:53 +02:00
ce59b6ea03 feat(userspace/libc): extend termios header with input/output speed and winsize structure
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 20:59:48 +02:00
9dcb5abe89 feat(userspace/libc): add termios header file for terminal I/O control
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 20:43:37 +02:00
4ac29bbce1 feat(userspace/libc): define file descriptor macros for standard input/output
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 20:42:56 +02:00
155f3bfab5 docs(kernel/api): add documentation for FBIOGET_SCREEN_INFO
Add documentation for FBIOGET_SCREEN_INFO macro

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 19:47:10 +02:00
e960f9fcc8 chore(userspace/libc): update vscode workspace config
Add conventionalCommits.scopes with "userspace/libc"

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 18:55:28 +02:00
4bb8ce6d00 feat(userspace/libc): complete <string.h> implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 18:54:20 +02:00
2ae18af9a0 feat(userspace/apps/test/libc_test): add more tests
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-19 18:53:54 +02:00
e61b5824db refactor(userspace/apps/test/libc_test): remove deprecated string test files
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-15 15:35:28 +02:00
0f9a1915d1 feat(userspace/libc): implement all <string.h> functions
Implement all string.h functions except some which require locale which is not implemented yet

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 22:15:20 +02:00
6dfefc90c4 feat(userspace/libc): implement strcpy function
Add strcpy implementation in string.c

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 20:07:20 +02:00
c688bd7a97 feat: synchronize syscalls.h
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 19:59:59 +02:00
e927d93a48 feat(kernel): add stub device /dev/fb0
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 19:57:29 +02:00
d9235c6f90 userspace/libc: implement qsort, realloc and reallocarray functions in stdlib
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:19:14 +02:00
afa87ec5f3 userspace/libc: implement strcoll()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:18:40 +02:00
22d01c7a51 userspace/libc: add <sys/socket.h> for socket programming support
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:18:15 +02:00
dfe9bbdbfa userspace/libc: implement read, pread, write & pwrite
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:17:47 +02:00
92ef18b412 userspace/libc: implement alphasort, fdopendir, opendir, posix_getdents, readdir & scandir
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:17:06 +02:00
d0a8d9dd62 userspace/libc: add <sys/uio.h> header for vector I/O operations
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:15:40 +02:00
f3e145e6f7 userspace/libc: add <netinet/in.h> header for IPv4 and IPv6 support
FIXME: not sure if this is implemented correctly

ref: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_in.h.html
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:15:18 +02:00
d9433256ab userspace/libc: add <arpa/inet.h>
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:13:48 +02:00
ade1c77361 userspace/test: add web server test program
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-14 02:11:30 +02:00
3e656854bc userspace/test: implement more tests in libc_test
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-13 01:14:11 +02:00
6c3eefa85d userspace/libc: add stub uname function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:53:44 +02:00
2384791793 userspace/libc: add stub gethostname function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:53:13 +02:00
97af4d855f userspace/libc: implement <sys/fcntl>
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:52:39 +02:00
b0f0982fd4 userspace/libc: update function signatures in fcntl.h
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:52:01 +02:00
bd1d117283 userspace/libc: add ioctl function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:51:14 +02:00
a1b040360c userspace/apps/sys: add uname command
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:50:27 +02:00
8f7938a1e5 userspace/libc: implement vfprintf function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:47:45 +02:00
b05868d120 userspace/libc: implement fprintf function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:43:43 +02:00
24fd486764 userspace/libc: implement strncpy function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-02-12 02:42:51 +02:00
23a17fae00 userspace/init: dummy code
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Successful in 1h46m32s
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 4m27s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Failing after 6m13s
Build OS / Build amd64 (push) Failing after 14m44s
Build OS / Build i386 (push) Failing after 16m28s
Build OS / Build aarch64 (push) Failing after 11m17s
Build OS / Build arm (push) Failing after 15m17s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-28 12:26:53 +02:00
d7bccb6948 userspace: add sh program
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-28 12:25:36 +02:00
833d8d497a userspace/libc: implement sigaction(), sigemptyset(), signal() & strcspn()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-28 12:25:05 +02:00
1b55332027 userspace/libc_test: add test functions for various libc components
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-28 11:42:28 +02:00
cbe651d2da userspace/libc_test: add native build target and default toolchain configuration
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-28 11:37:45 +02:00
9c9f5549d7 userspace/libc_test: add VSCode snippets and workspace configuration
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-28 11:37:10 +02:00
655a2d88f5 chore: add newline at end of c_boilerplates.code-snippets
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-28 11:36:54 +02:00
cd49a219df userspace/libc: include stdio.h in dirent.c
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-27 23:59:29 +02:00
48067d8f58 userspace/libc: implement close() & dirfd()
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-27 23:58:54 +02:00
c2412fe710 userspace/libc_test: add return statement to main function
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-27 23:31:34 +02:00
2f71bccef2 userspace/libc: implement std more functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-27 23:30:07 +02:00
f5a813380b userspace/utest: comment out build and linking commands in Makefile
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-27 23:28:22 +02:00
b54a32ba7a userspace: add stub libc test program
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-27 23:20:54 +02:00
1c5c0b524e userspace: update Makefiles
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-26 23:28:10 +02:00
62e482facb fix: correct project name references in license headers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-25 00:20:34 +02:00
1824c99ca0 userspace/libc: flush stdout & stderr on exit
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 9m48s
Build OS / Build Cross-Compiler & Toolchain (push) Successful in 1h57m16s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Failing after 6m20s
Build OS / Build amd64 (push) Failing after 6m19s
Build OS / Build aarch64 (push) Failing after 6m20s
Build OS / Build arm (push) Failing after 6m17s
Build OS / Build i386 (push) Failing after 19m15s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-25 00:16:58 +02:00
e8b61e6d7f userspace/libc: fix stack alignment
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-25 00:08:46 +02:00
69bc044b09 userspace: include crt1.c to streamline startup code
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-25 00:07:09 +02:00
c86d24030e kernel: refactor FPU state structure for improved clarity and consistency
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 23:57:49 +02:00
4ced264c3c userspace: simplify SIMD test application assembly code
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 23:57:15 +02:00
a25c5f4a96 userspace: add SIMD test application
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 22:40:38 +02:00
c0acbf8790 workflows: comment out gnu-efi compilation for now because it breaks workflows
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 4m22s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 2h9m52s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
Build OS / Build arm (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 19:04:23 +02:00
7ce73ab813 kernel: refactor aarch64 boot code
Some checks failed
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Blocked by required conditions
Build OS / Build amd64 (push) Blocked by required conditions
Build OS / Build i386 (push) Blocked by required conditions
Build OS / Build aarch64 (push) Blocked by required conditions
Build OS / Build arm (push) Blocked by required conditions
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 4m9s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 56m7s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 15:27:11 +02:00
0ab1833034 kernel: update linker script for AArch64
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 15:26:41 +02:00
495a0ea609 kernel: move UART code in each arch subdir
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 15:26:21 +02:00
72232d8bd2 kernel: update CPU structures with __packed attribute for alignment
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 15:25:39 +02:00
6bd705f06a build: add MIDR_EL1 union for AArch64 CPU identification
https://developer.arm.com/documentation/ddi0601/2024-12/AArch64-Registers/MIDR-EL1--Main-ID-Register?lang=en
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 15:25:04 +02:00
0912d4b383 build: add Bootloader clean target to Makefile
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-23 21:47:27 +02:00
4350393610 build: add Makefile templates for Bootloader firmware across architectures
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-23 21:47:21 +02:00
a8ff50541a build: add initial Bootloader implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-23 21:43:03 +02:00
a4c5ab7ef3 chore: add .editorconfig files for consistent coding styles
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-17 19:59:38 +02:00
e147e1eff5 docs: update README.md
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-15 07:18:30 +02:00
c09bdee89a build: refine .gitignore rules for tools directory
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-13 16:47:15 +02:00
3fa7acb116 build: add support for GRUB in the build process
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-13 16:47:06 +02:00
749a1b1810 kernel: update boot code and linker script for aarch64
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-13 09:22:01 +02:00
210e06429c vscode: update debug configurations
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-13 09:20:42 +02:00
137f16bc55 build: update debug configuration for aarch64
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-13 09:20:07 +02:00
995ef471ab build: update QEMU configuration for aarch64 to use raspi4b
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-13 06:50:48 +02:00
58f3442c6d build: use --no-install-recommends for apt installs in workflows
Some checks failed
Build OS / Build amd64 (push) Failing after 7m32s
Build OS / Build i386 (push) Failing after 9m41s
Build OS / Build arm (push) Failing after 8m45s
Build OS / Build aarch64 (push) Failing after 14m10s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 7m54s
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 7m28s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-11 07:14:32 +02:00
3af04bce80 refactor: fix release building for aarch64 and arm
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-11 07:11:28 +02:00
75c8dbd31b refactor: fix softfloat on aarch64 and arm
Some checks failed
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Blocked by required conditions
Build OS / Build amd64 (push) Blocked by required conditions
Build OS / Build i386 (push) Blocked by required conditions
Build OS / Build aarch64 (push) Blocked by required conditions
Build OS / Build arm (push) Blocked by required conditions
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 9m56s
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-11 06:48:48 +02:00
fbe9fbfbd1 kernel: add arm architecture support
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 5m35s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Has been cancelled
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
Build OS / Build arm (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-10 18:55:34 +02:00
e6933acfb0 kernel: add aarch64 architecture support
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-10 17:26:26 +02:00
07abdd9f6c workflows: move obsolete CodeQL and documentation workflows to makefile.yml
Some checks failed
Build OS / Build Cross-Compiler & Toolchain (push) Successful in 2h54m6s
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 3m8s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Failing after 2m37s
Build OS / Build amd64 (push) Failing after 14m7s
Build OS / Build i386 (push) Failing after 13m9s
Build OS / Build aarch64 (push) Failing after 5m33s
Build OS / Build arm (push) Failing after 5m29s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-08 17:11:46 +02:00
9cb66f395b workflows: add ARM build support
Some checks failed
Build OS / Build amd64 (push) Blocked by required conditions
Build OS / Build i386 (push) Blocked by required conditions
Build OS / Build aarch64 (push) Blocked by required conditions
Build OS / Build arm (push) Blocked by required conditions
Deploy Documentation / Deploy Documentation to GitHub Pages (push) Failing after 5m4s
CodeQL Advanced / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Failing after 4m42s
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-08 12:02:12 +02:00
eb602e12c2 toolchain: update architecture support and improve toolchain configuration
Added arm and aarch64 support
tools/Makefile has been refactored

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-08 11:59:30 +02:00
61b1e95629 kernel: Fix boot on i386
Some checks failed
CodeQL Advanced / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Has been cancelled
Deploy Documentation / Deploy Documentation to GitHub Pages (push) Has been cancelled
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-07 17:58:51 +02:00
2bb997597e refactor: Fix build on i386
Some checks failed
CodeQL Advanced / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Has been cancelled
Deploy Documentation / Deploy Documentation to GitHub Pages (push) Has been cancelled
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-07 17:49:37 +02:00
463d16f8bc refactor: streamline source file discovery in Makefile and update OSARCH handling in config.mk
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-07 13:45:59 +02:00
6cf3c62c83 chore: remove SonarCloud workflow configuration
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 21:44:56 +02:00
616 changed files with 72320 additions and 26140 deletions

127
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,127 @@
FROM mcr.microsoft.com/devcontainers/cpp:1-ubuntu-24.04
ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="none"
COPY ./reinstall-cmake.sh /tmp/
RUN <<EOF
if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then
chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE};
fi
rm -f /tmp/reinstall-cmake.sh
EOF
# Update system and set noninteractive env
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update
# Required packages for building gcc & binutils
RUN apt-get -y install --no-install-recommends \
build-essential \
bison \
flex \
libgmp-dev \
libmpfr-dev \
texinfo \
file \
python3-dev
# Required packages for building qemu
RUN apt-get -y install --no-install-recommends \
git \
libglib2.0-dev \
libfdt-dev \
libpixman-1-dev \
zlib1g-dev \
ninja-build \
libaio-dev \
libbluetooth-dev \
libcapstone-dev \
libbrlapi-dev \
libbz2-dev \
libcap-ng-dev \
libcurl4-gnutls-dev \
libgtk-3-dev \
libibverbs-dev \
libjpeg8-dev \
libncurses5-dev \
libnuma-dev \
librbd-dev \
librdmacm-dev \
libsasl2-dev \
libsdl2-dev \
libseccomp-dev \
libsnappy-dev \
libssh-dev \
libvde-dev \
libvdeplug-dev \
libvte-2.91-dev \
libxen-dev \
liblzo2-dev \
valgrind \
xfslibs-dev \
libnfs-dev \
libiscsi-dev \
python3-venv \
libslirp-dev \
ovmf
# Required packages for building test apps in userspace
RUN apt-get -y install --no-install-recommends \
mingw-w64 \
libtool \
libltdl-dev
# Required packages for building the OS and misc
RUN apt-get -y install --no-install-recommends \
grub2-common \
xorriso \
mtools \
grub-common \
grub-efi-amd64-bin \
grub-efi-amd64-signed \
grub-gfxpayload-lists \
grub-pc-bin \
grub-pc \
grub2-common \
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
git config --global core.autocrlf input
git config --global init.defaultbranch master
EOF
# Set display environment variable for QEMU
ENV DISPLAY=:0
ENV NO_AT_BRIDGE=1
# Set PATH
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

@ -0,0 +1,45 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/cpp
{
"name": "Fennix",
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"ms-azuretools.vscode-docker",
"eamodio.gitlens",
"EditorConfig.EditorConfig",
"naumovs.color-highlight",
"Gruntfuggly.todo-tree",
"ms-vscode.hexeditor",
"vivaxy.vscode-conventional-commits",
"webfreak.debug",
"maziac.asm-code-lens",
"Seven1bit.vscode-ext-ansi-color-highlight",
"ms-vsliveshare.vsliveshare",
"maziac.hex-hover-converter",
"ms-vscode.makefile-tools"
]
}
},
// 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"
},
{
"source": "/run/user/1000/pulse/native",
"target": "/run/user/1000/pulse/native",
"type": "bind"
}
],
"runArgs": [
"--privileged",
"--network=host"
]
}

View File

@ -0,0 +1,59 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
set -e
CMAKE_VERSION=${1:-"none"}
if [ "${CMAKE_VERSION}" = "none" ]; then
echo "No CMake version specified, skipping CMake reinstallation"
exit 0
fi
# Cleanup temporary directory and associated files when exiting the script.
cleanup() {
EXIT_CODE=$?
set +e
if [[ -n "${TMP_DIR}" ]]; then
echo "Executing cleanup of tmp files"
rm -Rf "${TMP_DIR}"
fi
exit $EXIT_CODE
}
trap cleanup EXIT
echo "Installing CMake..."
apt-get -y purge --auto-remove cmake
mkdir -p /opt/cmake
architecture=$(dpkg --print-architecture)
case "${architecture}" in
arm64)
ARCH=aarch64 ;;
amd64)
ARCH=x86_64 ;;
*)
echo "Unsupported architecture ${architecture}."
exit 1
;;
esac
CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh"
CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt"
TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX)
echo "${TMP_DIR}"
cd "${TMP_DIR}"
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O
sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}"
sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license
ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
ln -s /opt/cmake/bin/ctest /usr/local/bin/ctest

26
.editorconfig Normal file
View File

@ -0,0 +1,26 @@
# EditorConfig is awesome: https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
[Makefile]
indent_style = tab
[.github/**]
indent_style = space
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

@ -1,86 +0,0 @@
name: "CodeQL Advanced"
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: '27 20 * * 0'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
permissions:
security-events: write
packages: read
actions: read
contents: read
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
- language: c-cpp
build-mode: manual
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check for cache
id: check-cache
run: |
if [ -z "${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}" ]; then
echo "No cache found, cancelling job."
exit 1
fi
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 0
- name: Install Packages
run: |
sudo apt update
sudo apt -y install rustc xorriso mtools genisoimage ovmf nasm doxygen make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Kernel prepare
- name: Cache cross
id: cache-cross
uses: actions/cache@v3
with:
path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Build OS
run: |
make build_userspace
make build_drivers
make build_kernel
make build_userspace
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

View File

@ -1,34 +0,0 @@
name: Deploy Documentation
on:
push:
branches: [ master ]
pull_request:
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: Update System
run: sudo apt update
- name: Install Doxygen
run: sudo apt -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

View File

@ -22,71 +22,104 @@ jobs:
path: tools/cross path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }} key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Update System - name: Prepare Environment for Dev Container
if: steps.cache-cross.outputs.cache-hit != 'true'
run: sudo apt update
- name: Install GCC Dependencies
if: steps.cache-cross.outputs.cache-hit != 'true'
run: sudo apt -y install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo libzstd-dev libisl-dev m4 automake gettext gperf dejagnu guile-3.0 guile-3.0-dev expect tcl autogen tex-common sphinx-common git ssh diffutils patch autoconf2.69 libtool wget dpkg
- name: Check autoconf
if: steps.cache-cross.outputs.cache-hit != 'true'
run: | run: |
if [ "$(autoconf --version | head -n 1 | awk '{print $NF}')" != "2.69" ]; then sudo mkdir -p /tmp/.X11-unix
echo "Autoconf version is not 2.69, performing additional steps..." sudo mkdir -p /run/user/1000/pulse
wget https://launchpad.net/ubuntu/+archive/primary/+files/autoconf_2.69-11.1_all.deb sudo touch /run/user/1000/pulse/native
sudo dpkg --force-all -i ./autoconf_2.69-11.1_all.deb
- name: Run make ci-setup in dev container
if: steps.cache-cross.outputs.cache-hit != 'true'
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: |
/usr/bin/make ci-setup
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
needs: [buildcompiler]
permissions:
security-events: write
packages: read
actions: read
contents: read
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
- language: c-cpp
build-mode: manual
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check for cache
id: check-cache
run: |
if [ -z "${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}" ]; then
echo "No cache found, cancelling job."
exit 1
fi fi
- name: Check automake - name: Initialize CodeQL
if: steps.cache-cross.outputs.cache-hit != 'true' uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- if: matrix.build-mode == 'manual'
shell: bash
run: | run: |
if [ "$(automake --version | head -n 1 | awk '{print $NF}')" != "1.15.1" ]; then echo 'If you are using a "manual" build mode for one or more of the' \
echo "Automake version is not 1.15.1, performing additional steps..." 'languages you are analyzing, replace this with the commands to build' \
wget https://ftp.gnu.org/gnu/automake/automake-1.15.1.tar.gz 'your code, for example:'
tar -xzf automake-1.15.1.tar.gz echo ' make bootstrap'
cd automake-1.15.1 echo ' make release'
./configure exit 0
make
sudo make install
fi
- name: Clone All - name: Install Packages
if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools __clone_all_no_qemu
- name: Compile Binutils
if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools do_binutils
- name: Compile GCC
if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools do_gcc
- name: Clean Up
if: steps.cache-cross.outputs.cache-hit != 'true'
run: | run: |
cd tools sudo apt update
rm -rf binutils-gdb gcc sudo apt --no-install-recommends -y install rustc xorriso mtools genisoimage ovmf nasm doxygen make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo
make --quiet -C tools do_limine
make --quiet prepare
compile64: - name: Cache cross
name: Build amd64 id: cache-cross
uses: actions/cache@v4
with:
path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Build OS
run: |
make build_userspace
make build_drivers
make build_kernel
make build_userspace
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
compile:
name: Build OS
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [buildcompiler] needs: [buildcompiler]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
fetch-depth: 0
- name: Update & Install Required Packages
run: |
sudo apt update
sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Kernel prepare
- name: Cache cross Folder - name: Cache cross Folder
id: cache-cross id: cache-cross
@ -95,124 +128,98 @@ jobs:
path: tools/cross path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }} key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Configure config.mk - name: Prepare Environment for Dev Container
run: sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./config.mk && cat config.mk | grep OSARCH
- name: Compile Debug and Release ISO
run: | run: |
make build sudo mkdir -p /tmp/.X11-unix
mv Fennix.iso Fennix-debug.iso sudo mkdir -p /run/user/1000/pulse
make clean sudo touch /run/user/1000/pulse/native
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
make build
mv Fennix.iso Fennix-release.iso
- name: Upload Artifact (Fennix-debug.iso) - name: Build AMD64 Debug
if: always()
uses: devcontainers/ci@v0.3
with:
push: never
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 uses: actions/upload-artifact@v4
with: with:
name: Fennix-amd64-debug name: artifacts
path: Fennix-debug.iso path: artifacts/
- name: Upload Artifact (Fennix-release.iso) nightly:
uses: actions/upload-artifact@v4 if: always()
with: name: Upload Nightly Build to GitHub Releases
name: Fennix-amd64-release
path: Fennix-release.iso
compile32:
name: Build i386
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [buildcompiler] needs: [compile]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
fetch-depth: 0
- name: Update & Install Required Packages - name: Download All Builds
run: | uses: actions/download-artifact@v4
sudo apt update
sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Kernel prepare
- name: Cache cross Folder - name: Update Nightly
id: cache-cross run: gh release upload nightly artifacts/* -R ${{github.repository}} --clobber
uses: actions/cache@v4
with:
path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Configure config.mk env:
run: sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./config.mk && cat config.mk | grep OSARCH GH_TOKEN: ${{ github.token }}
- name: Compile Debug and Release ISO
run: |
make build
mv Fennix.iso Fennix-debug.iso
make clean
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
make build
mv Fennix.iso Fennix-release.iso
- name: Upload Artifact (Fennix-debug.iso)
uses: actions/upload-artifact@v4
with:
name: Fennix-i386-debug
path: Fennix-debug.iso
- name: Upload Artifact (Fennix-release.iso)
uses: actions/upload-artifact@v4
with:
name: Fennix-i386-release
path: Fennix-release.iso
compilearm64:
name: Build aarch64
runs-on: ubuntu-latest
needs: [buildcompiler]
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Update & Install Required Packages
run: |
sudo apt update
sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Kernel prepare
- name: Cache cross Folder
id: cache-cross
uses: actions/cache@v4
with:
path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Configure config.mk
run: sed -i 's/.*OSARCH = .*/OSARCH = aarch64/' ./config.mk && cat config.mk | grep OSARCH
- name: Compile Debug and Release ISO
run: |
make build
mv Fennix.iso Fennix-debug.iso
make clean
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
make build
mv Fennix.iso Fennix-release.iso
- name: Upload Artifact (Fennix-debug.iso)
uses: actions/upload-artifact@v4
with:
name: Fennix-aarch64-debug
path: Fennix-debug.iso
- name: Upload Artifact (Fennix-release.iso)
uses: actions/upload-artifact@v4
with:
name: Fennix-aarch64-release
path: Fennix-release.iso

View File

@ -1,67 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow helps you trigger a SonarCloud analysis of your code and populates
# GitHub Code Scanning alerts with the vulnerabilities found.
# Free for open source project.
# 1. Login to SonarCloud.io using your GitHub account
# 2. Import your project on SonarCloud
# * Add your GitHub organization first, then add your repository as a new project.
# * Please note that many languages are eligible for automatic analysis,
# which means that the analysis will start automatically without the need to set up GitHub Actions.
# * This behavior can be changed in Administration > Analysis Method.
#
# 3. Follow the SonarCloud in-product tutorial
# * a. Copy/paste the Project Key and the Organization Key into the args parameter below
# (You'll find this information in SonarCloud. Click on "Information" at the bottom left)
#
# * b. Generate a new token and add it to your Github repository's secrets using the name SONAR_TOKEN
# (On SonarCloud, click on your avatar on top-right > My account > Security
# or go directly to https://sonarcloud.io/account/security/)
# Feel free to take a look at our documentation (https://docs.sonarcloud.io/getting-started/github/)
# or reach out to our community forum if you need some help (https://community.sonarsource.com/c/help/sc/9)
name: SonarCloud analysis
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
workflow_dispatch:
permissions:
pull-requests: read # allows SonarCloud to decorate PRs with analysis results
jobs:
Analysis:
runs-on: ubuntu-latest
steps:
- name: Analyze with SonarCloud
# You can pin the exact commit or the version.
# uses: SonarSource/sonarcloud-github-action@v2.2.0
uses: SonarSource/sonarcloud-github-action@4006f663ecaf1f8093e8e4abb9227f6041f52216
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on Sonarcloud.io, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret)
with:
# Additional arguments for the SonarScanner CLI
args:
# Unique keys of your project and organization. You can find them in SonarCloud > Information (bottom-left menu)
# mandatory
-Dsonar.projectKey=EnderIce2_Fennix
-Dsonar.organization=enderice2
# Comma-separated paths to directories containing main source files.
#-Dsonar.sources= # optional, default is project base directory
# Comma-separated paths to directories containing test source files.
#-Dsonar.tests= # optional. For more info about Code Coverage, please refer to https://docs.sonarcloud.io/enriching/test-coverage/overview/
# Adds more detail to both client and server-side analysis logs, activating DEBUG mode for the scanner, and adding client-side environment variables and system properties to the server-side log of analysis report processing.
#-Dsonar.verbose= # optional, default is false
# When you need the analysis to take place in a directory other than the one from which it was launched, default is .
projectBaseDir: .

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

23
.gitignore vendored
View File

@ -1,23 +1,10 @@
iso_tmp_data iso_tmp_data
initrd_tmp_data artifacts
initrd/usr/include/* tmp_rootfs
!initrd/usr/include/.gitkeep rootfs/usr/include/*
tools/* !rootfs/usr/include/.gitkeep
!tools/ExtMemDbg
!tools/stage2_eltorito
!tools/*.md
!tools/README.md
!tools/website
!tools/Makefile
!tools/*.c
!tools/*.patch
!tools/*.cpp
!tools/*.cfg
!tools/acpi
!tools/doxygen
!tools/.gdbinit
doxygen-doc doxygen-doc
initrd.tar rootfs.tar.gz
.dccache .dccache
*.log *.log
*.log.* *.log.*

130
.vscode/launch.json vendored
View File

@ -2,55 +2,141 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Launch QEMU & debug the kernel", "name": "Debug Kernel (x64)",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/../Kernel/fennix.elf", "program": "${workspaceFolder}/../Kernel/fennix.elf",
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"args": [],
"targetArchitecture": "x64", "targetArchitecture": "x64",
"MIMode": "gdb", "MIMode": "gdb",
"miDebuggerServerAddress": "/tmp/gdb-fennix", "miDebuggerServerAddress": "/tmp/gdb-fennix",
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gdb", "miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gdb",
"miDebuggerArgs": "",
"externalConsole": false, "externalConsole": false,
"additionalSOLibSearchPath": "${workspaceFolder}",
"internalConsoleOptions": "neverOpen", "internalConsoleOptions": "neverOpen",
"customLaunchSetupCommands": [
// {
// "text": "target remote localhost:1234",
// "description": "Connect to QEMU remote debugger"
// }
],
"setupCommands": [ "setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{ {
"text": "set breakpoint pending on", "text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load." "description": "Make breakpoint pending on future shared library load."
}, },
{ {
"text": "file ${workspaceFolder}/../Kernel/fennix.elf", "text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "Load binary" "description": "/bin/utest (0x00400000)",
"ignoreFailures": true
}, },
{ {
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/utest", "text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "Load /bin/utest", "description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true "ignoreFailures": true
}, },
{ {
"text": "source ${workspaceFolder}/../tools/.gdbinit" "text": "source ${workspaceFolder}/../tools/.gdbinit"
} }
], ],
"preLaunchTask": "launch-qemu" "preLaunchTask": "QEMU"
},
{
"name": "Debug Kernel (x86)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/../Kernel/fennix.elf",
"cwd": "${workspaceFolder}",
"targetArchitecture": "x86",
"MIMode": "gdb",
"miDebuggerServerAddress": "/tmp/gdb-fennix",
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/i386-fennix-gdb",
"externalConsole": false,
"internalConsoleOptions": "neverOpen",
"setupCommands": [
{
"text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "/bin/utest (0x00400000)",
"ignoreFailures": true
},
{
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true
},
{
"text": "source ${workspaceFolder}/../tools/.gdbinit"
}
],
"preLaunchTask": "QEMU"
},
{
"name": "Debug Kernel (arm64)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/../Kernel/fennix.elf",
"cwd": "${workspaceFolder}",
"targetArchitecture": "arm64",
"MIMode": "gdb",
"miDebuggerServerAddress": "/tmp/gdb-fennix",
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-fennix-gdb",
"externalConsole": false,
"internalConsoleOptions": "neverOpen",
"setupCommands": [
{
"text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "/bin/utest (0x00400000)",
"ignoreFailures": true
},
{
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true
},
{
"text": "source ${workspaceFolder}/../tools/.gdbinit"
}
],
"preLaunchTask": "QEMU"
},
{
"name": "Debug Kernel (arm)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/../Kernel/fennix.elf",
"cwd": "${workspaceFolder}",
"targetArchitecture": "arm",
"MIMode": "gdb",
"miDebuggerServerAddress": "/tmp/gdb-fennix",
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/arm-fennix-gdb",
"externalConsole": false,
"internalConsoleOptions": "neverOpen",
"setupCommands": [
{
"text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
"description": "/bin/utest (0x00400000)",
"ignoreFailures": true
},
{
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
"description": "/bin/libc_test (0x00600000)",
"ignoreFailures": true
},
{
"text": "source ${workspaceFolder}/../tools/.gdbinit"
}
],
"preLaunchTask": "QEMU"
}, },
{ {
"type": "gdb", "type": "gdb",
"request": "attach", "request": "attach",
"name": "Launch QEMU & attach to gdbserver", "name": "Launch QEMU & attach to gdbserver (x64)",
"executable": "${workspaceFolder}/../Kernel/fennix.elf", "executable": "${workspaceFolder}/../Kernel/fennix.elf",
"target": "/tmp/gdb-fennix", "target": "/tmp/gdb-fennix",
"remote": true, "remote": true,
@ -63,7 +149,7 @@
], ],
"internalConsoleOptions": "neverOpen", "internalConsoleOptions": "neverOpen",
"printCalls": false, "printCalls": false,
"preLaunchTask": "launch-qemu" "preLaunchTask": "QEMU"
}, },
] ]
} }

View File

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

478
.vscode/tasks.json vendored
View File

@ -2,13 +2,240 @@
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"label": "launch-qemu", "label": "Clean",
"type": "shell", "type": "shell",
"command": "make -C ../ build && make -C ../ vscode_debug_only", "command": "make clean",
"isBackground": true, "isBackground": false,
"problemMatcher": [], "hide": false,
"group": { "group": {
"kind": "build", "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
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Build Kernel",
"type": "shell",
"command": "make -C ../ build_kernel",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Bootloader"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Build Drivers",
"type": "shell",
"command": "make -C ../ build_drivers",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Kernel"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Build Userspace",
"type": "shell",
"command": "make -C ../ build_userspace",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Drivers"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "Build Image",
"type": "shell",
"command": "make -C ../ build_image",
"isBackground": false,
"hide": true,
"dependsOn": [
"Build Userspace"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
},
{
"label": "QEMU",
"type": "shell",
"command": "make",
"args": [
"-C",
"../",
"vscode_debug_only"
],
"isBackground": true,
// "problemMatcher": "$tsc-watch",
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "CPU Reset",
}
}
],
"dependsOn": [
"Build Image"
],
"group": {
"kind": "test",
"isDefault": true "isDefault": true
}, },
"presentation": { "presentation": {
@ -23,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"
]
}
}
} }
] ]
} }

13
Bootloader/.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# EditorConfig is awesome: https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
[Makefile]
indent_style = tab

10
Bootloader/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
gnu-efi
include/*
!include/stdbool.h
!include/types.h
*.o
*.su
*.EFI
*.map
*.bin
*.elf

View File

@ -0,0 +1,96 @@
{
"Lynx Bootloader C++ Header": {
"isFileTemplate": true,
"scope": "c,cpp",
"prefix": [
"head",
],
"body": [
"/*",
"\tThis file is part of Lynx Bootloader.",
"",
"\tLynx Bootloader is free software: you can redistribute it and/or",
"\tmodify it under the terms of the GNU General Public License as",
"\tpublished by the Free Software Foundation, either version 3 of",
"\tthe License, or (at your option) any later version.",
"",
"\tLynx Bootloader is distributed in the hope that it will be useful,",
"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of",
"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"\tGNU General Public License for more details.",
"",
"\tYou should have received a copy of the GNU General Public License",
"\talong with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.",
"*/",
"",
"#pragma once",
"",
"$0",
"",
"$1",
""
],
"description": "Create kernel header."
},
"Lynx Bootloader C Header": {
"isFileTemplate": true,
"scope": "c,cpp",
"prefix": [
"headc",
],
"body": [
"/*",
"\tThis file is part of Lynx Bootloader.",
"",
"\tLynx Bootloader is free software: you can redistribute it and/or",
"\tmodify it under the terms of the GNU General Public License as",
"\tpublished by the Free Software Foundation, either version 3 of",
"\tthe License, or (at your option) any later version.",
"",
"\tLynx Bootloader is distributed in the hope that it will be useful,",
"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of",
"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"\tGNU General Public License for more details.",
"",
"\tYou should have received a copy of the GNU General Public License",
"\talong with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.",
"*/",
"",
"#ifndef __LYNX_BOOTLOADER_${1:header}_H__",
"#define __LYNX_BOOTLOADER_${1:header}_H__",
"",
"#include <types.h>",
"",
"$0",
"",
"#endif // !__LYNX_BOOTLOADER_${1:header}_H__",
""
],
"description": "Create kernel header."
},
"License": {
"isFileTemplate": true,
"prefix": [
"license",
],
"body": [
"/*",
"\tThis file is part of Lynx Bootloader.",
"",
"\tLynx Bootloader is free software: you can redistribute it and/or",
"\tmodify it under the terms of the GNU General Public License as",
"\tpublished by the Free Software Foundation, either version 3 of",
"\tthe License, or (at your option) any later version.",
"",
"\tLynx Bootloader is distributed in the hope that it will be useful,",
"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of",
"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"\tGNU General Public License for more details.",
"",
"\tYou should have received a copy of the GNU General Public License",
"\talong with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.",
"*/"
],
"description": "Create kernel license."
}
}

184
Bootloader/.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,184 @@
{
"configurations": [
{
"name": "Fennix x64 (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/include/**"
],
"defines": [
"DEBUG=\"1\""
],
"forcedInclude": [
"${workspaceFolder}/.vscode/preinclude.h"
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// Compiler flags
"-fno-pic",
"-fno-pie",
"-mno-red-zone",
"-march=core2",
"-pipe",
"-mcmodel=kernel",
"-fno-builtin",
"-m64",
"-fcoroutines",
// Warnings
"-Wall",
"-Wextra",
"-Wfloat-equal",
"-Wpointer-arith",
"-Wcast-align",
"-Wredundant-decls",
"-Winit-self",
"-Wswitch-default",
"-Wstrict-overflow=5",
"-Wconversion",
// C++ flags
"-fno-rtti",
"-fno-exceptions",
// Linker flags
"-T${workspaceFolder}/arch/amd64/linker.ld",
"-Wl,-static,--no-dynamic-linker,-ztext",
"-nostdlib",
"-nodefaultlibs",
"-nolibc",
"-zmax-page-size=0x1000",
"-shared",
// Debug flags
"-ggdb3",
"-O0",
"-fdiagnostics-color=always",
"-fverbose-asm",
"-fstack-usage",
"-fstack-check",
"-fsanitize=undefined",
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
},
{
"name": "Fennix x32 (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/include/**"
],
"forcedInclude": [
"${workspaceFolder}/.vscode/preinclude.h"
],
"defines": [
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-fennix-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "gcc-x86",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// Compiler flags
"-fno-pic",
"-fno-pie",
"-mno-80387",
"-mno-mmx",
"-mno-3dnow",
"-mno-red-zone",
"-march=pentium",
"-pipe",
"-msoft-float",
"-fno-builtin",
"-m32",
"-fcoroutines",
// Warnings
"-Wall",
"-Wextra",
"-Wfloat-equal",
"-Wpointer-arith",
"-Wcast-align",
"-Wredundant-decls",
"-Winit-self",
"-Wswitch-default",
"-Wstrict-overflow=5",
"-Wconversion",
// C++ flags
"-fno-rtti",
"-fno-exceptions",
// Linker flags
"-T${workspaceFolder}/arch/i386/linker.ld",
"-Wl,-static,--no-dynamic-linker,-ztext",
"-nostdlib",
"-nodefaultlibs",
"-nolibc",
"-zmax-page-size=0x1000",
"-shared",
// Debug flags
"-ggdb3",
"-O0",
"-fdiagnostics-color=always",
"-fverbose-asm",
"-fstack-usage",
"-fstack-check",
"-fsanitize=undefined",
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
},
{
"name": "Fennix Arm (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/include/**"
],
"forcedInclude": [
"${workspaceFolder}/.vscode/preinclude.h"
],
"defines": [
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/arm-fennix-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "linux-gcc-arm",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
},
{
"name": "Fennix Aarch64 (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/include/**"
],
"forcedInclude": [
"${workspaceFolder}/.vscode/preinclude.h"
],
"defines": [
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-fennix-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "linux-gcc-arm64",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
}
],
"version": 4
}

1
Bootloader/.vscode/launch.json vendored Symbolic link
View File

@ -0,0 +1 @@
../../.vscode/launch.json

11
Bootloader/.vscode/preinclude.h vendored Normal file
View File

@ -0,0 +1,11 @@
#undef __linux__
#undef __WIN32__
#undef __WIN64__
#undef _WIN32
#undef _WIN64
#undef __APPLE__
#undef __clang__
#define __vscode__ 1
#define __kernel__ 1
#define GIT_COMMIT "0000000000000000000000000000000000000000"
#define GIT_COMMIT_SHORT "0000000"

23
Bootloader/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,23 @@
{
"C_Cpp.errorSquiggles": "enabled",
"C_Cpp.autocompleteAddParentheses": true,
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
"C_Cpp.clang_format_style": "Visual Studio",
"C_Cpp.default.intelliSenseMode": "gcc-x64",
"C_Cpp.default.cStandard": "c17",
"C_Cpp.default.cppStandard": "c++20",
"C_Cpp.intelliSenseMemoryLimit": 16384,
"editor.smoothScrolling": true,
"editor.cursorSmoothCaretAnimation": "on",
"C_Cpp.codeAnalysis.clangTidy.checks.disabled": [
"clang-analyzer-security.insecureAPI.strcpy",
"clang-diagnostic-unknown-warning-option",
"clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling",
"clang-diagnostic-implicit-exception-spec-mismatch",
"clang-diagnostic-unknown-attributes",
"clang-diagnostic-user-defined-literals",
"clang-diagnostic-non-pod-varargs",
"clang-diagnostic-non-pod-varargs",
"clang-diagnostic-non-pod-varargs"
]
}

1
Bootloader/.vscode/tasks.json vendored Symbolic link
View File

@ -0,0 +1 @@
../../.vscode/tasks.json

56
Bootloader/Makefile Normal file
View File

@ -0,0 +1,56 @@
GNUEFI_RELEASE_VERSION=3.0.18
GIT_COMMIT = $(shell git rev-parse HEAD)
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
export CC := $(__CONF_CC)
export CXX := $(__CONF_CXX)
export LD := $(__CONF_LD)
export AS := $(__CONF_AS)
export AR := $(__CONF_AR)
export NM := $(__CONF_NM)
export OBJCOPY := $(__CONF_OBJCOPY)
export OBJDUMP := $(__CONF_OBJDUMP)
export GDB := $(__CONF_GDB)
default:
$(error Do not run this Makefile directly!)
prepare:
ifeq ("$(wildcard ./gnu-efi)", "")
wget https://freefr.dl.sourceforge.net/project/gnu-efi/gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
tar -xf gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
rm gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
mv ./gnu-efi-$(GNUEFI_RELEASE_VERSION) ./gnu-efi
cp -a ./gnu-efi/inc/. ./include
endif
# echo "PREPARE > Compiling gnu-efi for x86_64"
# make -C gnu-efi all ARCH=x86_64 \
# AR=$(TOOLCHAIN_AMD64_PREFIX)ar \
# AS=$(TOOLCHAIN_AMD64_PREFIX)as \
# CC=$(TOOLCHAIN_AMD64_PREFIX)gcc \
# LD=$(TOOLCHAIN_AMD64_PREFIX)ld
# echo "PREPARE > Compiling gnu-efi for arm"
# make -C gnu-efi all ARCH=arm \
# AR=$(TOOLCHAIN_ARM_PREFIX)ar \
# AS=$(TOOLCHAIN_ARM_PREFIX)as \
# CC=$(TOOLCHAIN_ARM_PREFIX)gcc \
# LD=$(TOOLCHAIN_ARM_PREFIX)ld \
# CFLAGS="-I$(CURDIR)/gnu-efi/inc"
# echo "PREPARE > Compiling gnu-efi for aarch64"
# make -C gnu-efi all ARCH=aarch64 \
# AR=$(TOOLCHAIN_AARCH64_PREFIX)ar \
# AS=$(TOOLCHAIN_AARCH64_PREFIX)as \
# CC=$(TOOLCHAIN_AARCH64_PREFIX)gcc \
# LD=$(TOOLCHAIN_AARCH64_PREFIX)ld
build:
$(MAKE) -C common build
$(MAKE) -C firmware build
# $(MAKE) -C uefi build
clean:
$(MAKE) -C common clean
$(MAKE) -C firmware clean
# $(MAKE) -C uefi clean
rm -f boot.bin

13
Bootloader/README.md Normal file
View File

@ -0,0 +1,13 @@
# Lynx Bootloader
> [!CAUTION]
> The project is in early stages of development and is not yet ready for production use.
>
> Use at your own risk.
## Introduction
### [bios](bios)
### [uefi](uefi)

View File

@ -0,0 +1,19 @@
define find-sources
$(shell find ./ -type f -name '$1' -print0 | xargs -0)
endef
BMP_SOURCES := $(call find-sources,*.bmp)
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)
default:
$(error Do not run this Makefile directly!)
build:
clean:

21
Bootloader/common/main.c Normal file
View File

@ -0,0 +1,21 @@
/*
This file is part of Lynx Bootloader.
Lynx Bootloader 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.
Lynx Bootloader 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 Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
*/
int main()
{
return 0;
}

View File

@ -0,0 +1,8 @@
default:
$(error Do not run this Makefile directly!)
build:
$(MAKE) -C $(OSARCH) build
clean:
$(MAKE) -C $(OSARCH) clean

View File

@ -0,0 +1,64 @@
define find-sources
$(shell find ./ -type f -name '$1' $(shell echo $(foreach board,$(filter-out $(BOARD_TYPE),$(AVAILABLE_BOARDS)), -not -path \"./$(board)/*\")) -print0 | xargs -0)
endef
S_SOURCES := $(call find-sources,*.S)
s_SOURCES := $(call find-sources,*.s)
C_SOURCES := $(call find-sources,*.c)
define find-common-sources
$(shell find ../../common -type f -name '$1' -print0 | xargs -0)
endef
C_COMMON_SOURCES := $(call find-common-sources,*.c)
OBJ = $(s_SOURCES:.s=.o) $(S_SOURCES:.S=.o) $(C_SOURCES:.c=.o) $(C_COMMON_SOURCES:.c=.o)
LDFLAGS = -static -nostdlib -nodefaultlibs -nolibc \
-Wl,-static,--no-dynamic-linker,-ztext \
-zmax-page-size=0x1000 \
-Wl,-Map boot.map -fno-pic -fno-pie
CFLAGS := \
$(INCLUDE_DIR) \
-D__kernel__='1' \
-DGIT_COMMIT='"$(GIT_COMMIT)"' \
-DGIT_COMMIT_SHORT='"$(GIT_COMMIT_SHORT)"' \
-fno-pic -fno-pie -fno-builtin -I../../include
CFLAGS += -mcmodel=large
LDFLAGS += -T$(BOARD_TYPE)/linker.ld
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
# CFLAGS += -fsanitize=undefined
CFLAGS += -fstack-check -fverbose-asm
LDFLAGS += -ggdb3 -O0
ASFLAGS += -g --gstabs+ --gdwarf-5 -D
endif # DEBUG
default:
$(error Do not run this Makefile directly!)
build: boot.bin
boot.bin: $(OBJ)
$(info Linking $@)
$(CC) $(LDFLAGS) $(OBJ) -o tmp.elf
$(OBJCOPY) tmp.elf -O binary ../../boot.bin
# rm tmp.elf
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(CFLAGS) -fstack-protector-all -std=c17 -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) $(ASFLAGS) -c $< -o $@
%.o: %.s
$(info Compiling $<)
$(AS) $(ASFLAGS) -c $< -o $@
clean:
rm -f $(OBJ) boot.map

View File

@ -0,0 +1 @@
./raspi4

View File

@ -0,0 +1,49 @@
/*
This file is part of Lynx Bootloader.
Lynx Bootloader 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.
Lynx Bootloader 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 Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
*/
.section ".text.boot"
.extern __bss_start
.extern __bss_end
.extern __bss_size
.global _start
_start:
/* Keep only the main core */
mrs x1, mpidr_el1
and x1, x1, #3
cbz x1, 2f
/* Halt */
1: wfe
b 1b
/* Initialize the stack */
2: ldr x1, =_start
mov sp, x1
/* Clear the BSS */
ldr x1, =__bss_start
ldr w2, =__bss_size
3: cbz w2, 4f
str xzr, [x1], #8
sub w2, w2, #1
cbnz w2, 3b
/* Start the kernel */
4: bl _aarch64_start
b 1b

View File

@ -0,0 +1,32 @@
/*
This file is part of Lynx Bootloader.
Lynx Bootloader 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.
Lynx Bootloader 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 Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
*/
#include <types.h>
uintptr_t __stack_chk_guard = 0;
__noreturn __no_stack_protector void __stack_chk_fail(void)
{
while (1)
;
}
int main();
__attribute__((section(".bootstrap.text"))) void _aarch64_start(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3)
{
main();
}

View File

@ -0,0 +1,70 @@
/*
This file is part of Lynx Bootloader.
Lynx Bootloader 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.
Lynx Bootloader 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 Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
*/
OUTPUT_FORMAT("elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_start)
SECTIONS
{
. = 0x80000;
__start = .;
__text_start = .;
.text :
{
KEEP(*(.text.boot))
*(.text)
}
. = ALIGN(4096);
__text_end = .;
__rodata_start = .;
.rodata :
{
*(.rodata)
}
. = ALIGN(4096);
__rodata_end = .;
__data_start = .;
.data :
{
*(.data)
}
. = ALIGN(4096);
__data_end = .;
__bss_start = .;
.bss :
{
bss = .;
*(.bss)
}
. = ALIGN(4096);
__bss_end = .;
__bss_size = __bss_end - __bss_start; /* SIZEOF(.bss); */
__end = .;
/DISCARD/ :
{
*(.comment*)
*(.gnu*)
*(.note*)
*(.eh_frame*)
}
}

View File

@ -0,0 +1,6 @@
default:
$(error Do not run this Makefile directly!)
build:
clean:

View File

@ -0,0 +1,6 @@
default:
$(error Do not run this Makefile directly!)
build:
clean:

View File

@ -0,0 +1,6 @@
default:
$(error Do not run this Makefile directly!)
build:
clean:

View File

@ -1,25 +1,26 @@
/* /*
This file is part of Fennix Drivers. This file is part of Lynx Bootloader.
Fennix Drivers is free software: you can redistribute it and/or Lynx Bootloader is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. the License, or (at your option) any later version.
Fennix Drivers is distributed in the hope that it will be useful, Lynx Bootloader is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>. along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
*/ */
#pragma once #ifndef __STDBOOL_H__
#define __STDBOOL_H__
#include <types.h>
EXTERNC int cxx_Panic(); typedef int bool;
EXTERNC int cxx_Probe(); #define true 1
EXTERNC int cxx_Initialize(); #define false 0
EXTERNC int cxx_Finalize();
#endif /* __STDBOOL_H__ */

496
Bootloader/include/types.h Normal file
View File

@ -0,0 +1,496 @@
/*
This file is part of Lynx Bootloader.
Lynx Bootloader 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.
Lynx Bootloader 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 Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_TYPES_H__
#define __FENNIX_KERNEL_TYPES_H__
#include <stdbool.h>
/**
* It doesn't do anything.
*
* Used to specify a function that is dependent on the architecture.
* It's architecture specific variant is defined in arch/<arch>/...
*/
#define arch
#ifdef __cplusplus
#define EXTERNC extern "C"
#define START_EXTERNC \
EXTERNC \
{
#define END_EXTERNC \
}
#else // __cplusplus
#define EXTERNC
#define START_EXTERNC
#define END_EXTERNC
#endif // __cplusplus
#ifdef __cplusplus
#define NULL 0
#else // __cplusplus
#define NULL ((void *)0)
#endif // __cplusplus
#define asm __asm__
#define asmv __asm__ volatile
#define inf_loop while (1)
#define ilp inf_loop; /* Used for debugging */
#ifdef __cplusplus
#define foreach for
#define in :
#define forItr(itr, container) \
for (auto itr = container.begin(); \
itr != container.end(); ++itr)
#define r_cst(t, v) reinterpret_cast<t>(v)
#define c_cst(t, v) const_cast<t>(v)
#define s_cst(t, v) static_cast<t>(v)
#define d_cst(t, v) dynamic_cast<t>(v)
#endif // __cplusplus
#define UNUSED(x) (void)(x)
#define CONCAT(x, y) x##y
#ifndef __va_list__
typedef __builtin_va_list va_list;
#endif
#define va_start(v, l) __builtin_va_start(v, l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v, l) __builtin_va_arg(v, l)
#define ALIGN_UP(x, align) ((__typeof__(x))(((uintptr_t)(x) + ((align) - 1)) & (~((align) - 1))))
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align) - 1))))
#define offsetof(type, member) __builtin_offsetof(type, member)
#define RGB_TO_HEX(r, g, b) ((r << 16) | (g << 8) | (b))
#define MAX(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#define MIN(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
#define ROUND_UP(x, y) (((x) + (y) - 1) & ~((y) - 1))
#define ROUND_DOWN(x, y) ((x) & ~((y) - 1))
#define VPOKE(type, address) (*((volatile type *)(address)))
#define POKE(type, address) (*((type *)(address)))
#ifndef __SIG_ATOMIC_TYPE__
#define __SIG_ATOMIC_TYPE__ int
#endif
typedef __INT8_TYPE__ int8_t;
typedef __INT16_TYPE__ int16_t;
typedef __INT32_TYPE__ int32_t;
typedef __INT64_TYPE__ int64_t;
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __INT_LEAST8_TYPE__ int_least8_t;
typedef __INT_LEAST16_TYPE__ int_least16_t;
typedef __INT_LEAST32_TYPE__ int_least32_t;
typedef __INT_LEAST64_TYPE__ int_least64_t;
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
typedef __INT_FAST8_TYPE__ int_fast8_t;
typedef __INT_FAST16_TYPE__ int_fast16_t;
typedef __INT_FAST32_TYPE__ int_fast32_t;
typedef __INT_FAST64_TYPE__ int_fast64_t;
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
typedef __INTPTR_TYPE__ intptr_t;
typedef __UINTPTR_TYPE__ uintptr_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __SIZE_TYPE__ size_t;
#ifndef __cplusplus
typedef __WCHAR_TYPE__ wchar_t;
#endif
typedef __WINT_TYPE__ wint_t;
typedef __SIG_ATOMIC_TYPE__ sig_atomic_t;
// TODO: ssize_t
typedef intptr_t ssize_t;
#if defined(__amd64__) || defined(__aarch64__)
typedef int64_t off_t;
typedef int64_t off64_t;
typedef uint32_t mode_t;
typedef uint64_t dev_t;
typedef uint64_t ino64_t;
typedef uint64_t ino_t;
typedef uint32_t nlink_t;
typedef int64_t blksize_t;
typedef int64_t blkcnt_t;
typedef int64_t blkcnt64_t;
typedef int64_t time_t;
typedef uint32_t uid_t;
typedef uint32_t gid_t;
typedef int64_t clock_t;
typedef int32_t pid_t;
#elif defined(__i386__) || defined(__arm__)
typedef int32_t off_t;
typedef long long off64_t;
typedef uint32_t mode_t;
typedef int32_t dev_t;
typedef int32_t ino64_t;
typedef int32_t ino_t;
typedef uint32_t nlink_t;
typedef int blksize_t;
typedef int32_t blkcnt_t;
typedef int32_t blkcnt64_t;
typedef int32_t time_t;
typedef uint32_t uid_t;
typedef uint32_t gid_t;
typedef long clock_t;
typedef int pid_t;
#endif
#ifdef __cplusplus
template <typename T>
class ptr_t
{
T ptr;
public:
ptr_t() : ptr(nullptr) {}
ptr_t(T p) : ptr(p) {}
ptr_t(int p) : ptr((T)(uintptr_t)p) {}
ptr_t(const ptr_t<T> &other) : ptr(other.ptr) {}
operator T() { return ptr; }
operator uintptr_t() { return (uintptr_t)ptr; }
operator bool() { return (void *)(uintptr_t)ptr != nullptr; }
ptr_t<T> &operator=(const ptr_t<T> &other)
{
ptr = other.ptr;
return *this;
}
ptr_t<T> &operator+=(uintptr_t offset)
{
ptr = (T)((uintptr_t)ptr + offset);
return *this;
}
ptr_t<T> &operator-=(uintptr_t offset)
{
ptr = (T)((uintptr_t)ptr - offset);
return *this;
}
bool operator==(const ptr_t<T> &other) const { return ptr == other.ptr; }
bool operator==(auto other) const { return (uintptr_t)ptr == (uintptr_t)other; }
bool operator!=(const ptr_t<T> &other) const { return ptr != other.ptr; }
bool operator!=(auto other) const { return (uintptr_t)ptr != (uintptr_t)other; }
bool operator>(const ptr_t<T> &other) const { return ptr > other.ptr; }
bool operator>(auto other) const { return (uintptr_t)ptr > (uintptr_t)other; }
bool operator<(const ptr_t<T> &other) const { return ptr < other.ptr; }
bool operator<(auto other) const { return (uintptr_t)ptr < (uintptr_t)other; }
bool operator>=(const ptr_t<T> &other) const { return ptr >= other.ptr; }
bool operator>=(auto other) const { return (uintptr_t)ptr >= (uintptr_t)other; }
bool operator<=(const ptr_t<T> &other) const { return ptr <= other.ptr; }
bool operator<=(auto other) const { return (uintptr_t)ptr <= (uintptr_t)other; }
ptr_t<T> operator+(auto offset) const { return ptr_t<T>((void *)((uintptr_t)ptr + offset)); }
ptr_t<T> operator-(auto offset) const { return ptr_t<T>((void *)((uintptr_t)ptr - offset)); }
T operator->() { return ptr; }
T operator*() { return *ptr; }
};
#endif // __cplusplus
#define INT8_MAX __INT8_MAX__
#define INT8_MIN (-INT8_MAX - 1)
#define UINT8_MAX __UINT8_MAX__
#define INT16_MAX __INT16_MAX__
#define INT16_MIN (-INT16_MAX - 1)
#define UINT16_MAX __UINT16_MAX__
#define INT32_MAX __INT32_MAX__
#define INT32_MIN (-INT32_MAX - 1)
#define UINT32_MAX __UINT32_MAX__
#define INT64_MAX __INT64_MAX__
#define INT64_MIN (-INT64_MAX - 1)
#define UINT64_MAX __UINT64_MAX__
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
#define INT_FAST8_MAX __INT_FAST8_MAX__
#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
#define INT_FAST16_MAX __INT_FAST16_MAX__
#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
#define INT_FAST32_MAX __INT_FAST32_MAX__
#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
#define INT_FAST64_MAX __INT_FAST64_MAX__
#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
#define INTPTR_MAX __INTPTR_MAX__
#define INTPTR_MIN (-INTPTR_MAX - 1)
#define UINTPTR_MAX __UINTPTR_MAX__
#define INTMAX_MAX __INTMAX_MAX__
#define INTMAX_MIN (-INTMAX_MAX - 1)
#define UINTMAX_MAX __UINTMAX_MAX__
#define PTRDIFF_MAX __PTRDIFF_MAX__
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__
#define SIZE_MAX __SIZE_MAX__
#define WCHAR_MAX __WCHAR_MAX__
#define WCHAR_MIN __WCHAR_MIN__
#define WINT_MAX __WINT_MAX__
#define WINT_MIN __WINT_MIN__
#if defined(__amd64__)
#define BREAK __asm__ __volatile__("int $0x3" \
: \
: \
: "memory");
#elif defined(__i386__)
#define BREAK __asm__ __volatile__("int $0x3" \
: \
: \
: "memory");
#elif defined(__aarch64__)
#define BREAK __asm__ __volatile__("brk #0" \
: \
: \
: "memory");
#endif
#ifdef __INT48_TYPE__
typedef __INT48_TYPE__ int48_t;
typedef __UINT48_TYPE__ uint48_t;
typedef int48_t int_least48_t;
typedef uint48_t uint_least48_t;
typedef int48_t int_fast48_t;
typedef uint48_t uint_fast48_t;
#else // __INT48_TYPE__
typedef __INT64_TYPE__ int48_t;
typedef __UINT64_TYPE__ uint48_t;
typedef int48_t int_least48_t;
typedef uint48_t uint_least48_t;
typedef int48_t int_fast48_t;
typedef uint48_t uint_fast48_t;
#endif // __INT48_TYPE__
#define b4(x) ((x & 0x0F) << 4 | (x & 0xF0) >> 4)
#define b8(x) ((x) & 0xFF)
#define b16(x) __builtin_bswap16(x)
#define b32(x) __builtin_bswap32(x)
#define b48(x) (((((x) & 0x0000000000ff) << 40) | \
(((x) & 0x00000000ff00) << 24) | \
(((x) & 0x000000ff0000) << 8) | \
(((x) & 0x0000ff000000) >> 8) | \
(((x) & 0x00ff00000000) >> 24) | \
(((x) & 0xff0000000000) >> 40)))
#define b64(x) __builtin_bswap64(x)
/* https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html */
/** No optimization (the default); generates
* unoptimized code but has the fastest compilation time.
*/
#define O0 __attribute__((optimize("O0")))
/** Moderate optimization;
* optimizes reasonably well but does not degrade
* compilation time significantly. */
#define O1 __attribute__((optimize("O1")))
/** Full optimization; generates highly
* optimized code and has the slowest compilation time.
*/
#define O2 __attribute__((optimize("O2")))
/** Full optimization as in -O2;
* also uses more aggressive automatic inlining of
* subprograms within a unit (Inlining of Subprograms)
* and attempts to vectorize loops. */
#define O3 __attribute__((optimize("O3")))
/** Optimize space usage (code and data)
* of resulting program.
*/
#define Os __attribute__((optimize("Os")))
/** Disregard strict standards compliance.
* -Ofast enables all -O3 optimizations.
* It also enables optimizations that are not valid for
* all standard-compliant programs.
*/
#define Ofast __attribute__((optimize("Ofast")))
/** Optimize for size.
* -Oz enables all -Os optimizations that do not typically
* increase code size.
*/
#define Oz __attribute__((optimize("Oz")))
/** Optimize for debugging.
* -Og enables optimizations that do not interfere with
* debugging.
*/
#define Og __attribute__((optimize("Og")))
#define __unused __attribute__((unused))
#define __packed __attribute__((packed))
#define __naked __attribute__((naked))
#define __aligned(x) __attribute__((aligned(x)))
#define __section(x) __attribute__((section(x)))
#define __noreturn __attribute__((noreturn))
#define __weak __attribute__((weak))
#define __alias(x) __attribute__((alias(x)))
#define __always_inline __attribute__((always_inline))
#define __noinline __attribute__((noinline))
#define __pure __attribute__((pure))
#define __const __attribute__((const))
#define __malloc __attribute__((malloc))
#define __returns_twice __attribute__((returns_twice))
#define __used __attribute__((used))
#define __deprecated __attribute__((deprecated))
#define __deprecated_msg(x) __attribute__((deprecated(x)))
#define __weakref(x) __attribute__((weakref(x)))
#define __weakrefalias(x) __attribute__((weakref(#x)))
#define __visibility(x) __attribute__((visibility(x)))
#define __constructor __attribute__((constructor))
#define __destructor __attribute__((destructor))
#define __cleanup(x) __attribute__((cleanup(x)))
#define __fallthrough __attribute__((fallthrough))
#define __nonnull(x) __attribute__((nonnull x))
#define __nonnull_all __attribute__((nonnull))
#define __returns_nonnull __attribute__((returns_nonnull))
#define __sentinel __attribute__((sentinel))
#define __sentinel_all __attribute__((sentinel(0)))
#define __format(x, y, z) __attribute__((format(x, y, z)))
#define __format_arg(x) __attribute__((format_arg(x)))
#define __nonnull_params(x) __attribute__((nonnull x))
#define __nonnull_all __attribute__((nonnull))
#define __warn_unused_result __attribute__((warn_unused_result))
#define __no_stack_protector __attribute__((no_stack_protector))
#define __no_instrument_function __attribute__((no_instrument_function))
#define __no_debug __attribute__((no_debug))
#define __target(x) __attribute__((target(x)))
#define __min_vector_width(x) __attribute__((min_vector_width(x)))
// sanitizer
#define __no_sanitize(x) __attribute__((no_sanitize(x)))
#define __no_sanitize_address __attribute__((no_sanitize_address))
#define __no_sanitize_thread __attribute__((no_sanitize_thread))
#define __no_sanitize_undefined __attribute__((no_sanitize_undefined))
#define __no_sanitize_coverage __attribute__((no_sanitize_coverage))
#define __synchronize __sync_synchronize()
#define __sync __synchronize
#define __unreachable __builtin_unreachable()
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define NoSecurityAnalysis __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_sanitize_thread
#define nsa NoSecurityAnalysis
#define NIF __no_instrument_function
#define int3 \
__asm__ __volatile__("int3" \
: \
: \
: "memory")
#define StackPush(stack, type, value) \
*((type *)--stack) = value
#define StackPop(stack, type) \
*((type *)stack++)
#define ReturnLogError(ret, format, ...) \
{ \
trace(format, ##__VA_ARGS__); \
return ret; \
} \
while (0) \
__builtin_unreachable()
#define AssertReturnError(condition, ret) \
do \
{ \
if (__builtin_expect(!!(!(condition)), 0)) \
{ \
error("\"%s\" failed!", #condition); \
return ret; \
} \
} while (0)
#endif // !__FENNIX_KERNEL_TYPES_H__

137
Bootloader/uefi/Makefile Normal file
View File

@ -0,0 +1,137 @@
BOOT_FILENAME = BOOTX64.EFI
GNUEFI_RELEASE_VERSION=3.0.18
GIT_COMMIT = $(shell git rev-parse HEAD)
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
HEADERS := $(sort $(dir $(wildcard ../include/*)))
INCLUDE_DIR = -I../include
define find-sources
$(shell find ./ -type f -name '$1' -print0 | xargs -0)
endef
BMP_SOURCES := $(call find-sources,*.bmp)
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)
LDFLAGS = -static -nostdlib -nodefaultlibs -nolibc \
-Wl,-static,--no-dynamic-linker,-ztext \
-zmax-page-size=0x1000 \
-Wl,-Map kernel.map -fno-pic -fno-pie
# Disable all warnings by adding "-w" in WARNCFLAG and if you want to treat the warnings as errors, add "-Werror"
# -Wconversion this may be re-added later
WARNCFLAG = -Wall -Wextra \
-Wfloat-equal -Wpointer-arith -Wcast-align \
-Wredundant-decls -Winit-self -Wswitch-default \
-Wstrict-overflow=5 -Wno-error=cpp -Werror \
-Wno-unused-parameter -Wno-error=format
CFLAG_STACK_PROTECTOR := -fstack-protector-all
# https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
CFLAGS := \
$(INCLUDE_DIR) \
-D__kernel__='1' \
-DKERNEL_NAME='"$(OSNAME)"' \
-DKERNEL_ARCH='"$(OSARCH)"' \
-DKERNEL_VERSION='"$(KERNEL_VERSION)"' \
-DGIT_COMMIT='"$(GIT_COMMIT)"' \
-DGIT_COMMIT_SHORT='"$(GIT_COMMIT_SHORT)"' \
-fno-pic -fno-pie -fno-builtin
ifeq ($(OSARCH), amd64)
CFLAGS += -march=core2 -mcmodel=kernel -m64 -mno-red-zone
LDFLAGS += -T../linker.ld
else ifeq ($(OSARCH), i386)
CFLAGS += -march=pentium -m32 -mno-red-zone
LDFLAGS += -T../linker.ld
else ifeq ($(OSARCH), arm)
CFLAGS += -march=armv7-a -mfloat-abi=softfp -ggdb3
LDFLAGS += -T../linker.ld
WARNCFLAG += -w
else ifeq ($(OSARCH), aarch64)
CFLAGS += -march=armv9.4-a -mtune=cortex-a72 -mlittle-endian -mcmodel=large
LDFLAGS += -T../linker.ld
endif # OSARCH
# -finstrument-functions for __cyg_profile_func_enter & __cyg_profile_func_exit. Used for profiling and debugging.
ifeq ($(DEBUG), 1)
# CFLAGS += --coverage
# CFLAGS += -pg
# CFLAGS += -finstrument-functions
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage -fsanitize=undefined
ifeq ($(OSARCH), amd64)
CFLAGS += -fverbose-asm
endif # amd64
ifeq ($(OSARCH), arm)
CFLAGS += -fstack-check -fverbose-asm
endif # arm
ifeq ($(OSARCH), aarch64)
CFLAGS += -fstack-check -fverbose-asm
endif # aarch64
LDFLAGS += -ggdb3 -O0
ASFLAGS += -g --gstabs+ --gdwarf-5 -D
WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable
endif # DEBUG
default:
$(error Do not run this Makefile directly!)
build: $(BOOT_FILENAME)
$(BOOT_FILENAME): $(OBJ)
$(info Linking $@)
$(LD) -shared -Bsymbolic -L../gnu-efi/x86_64/lib -L../gnu-efi/x86_64/gnuefi -T../gnu-efi/gnuefi/elf_x86_64_efi.lds ../gnu-efi/x86_64/gnuefi/crt0-efi-x86_64.o $(OBJ) -o tmp.so -lgnuefi -lefi
objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target efi-app-x86_64 --subsystem=10 tmp.so BOOTX64.EFI
rm tmp.so
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) -I../include -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CC) -I../include -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) $(ASFLAGS) -c $< -o $@
%.o: %.s
$(info Compiling $<)
$(AS) $(ASFLAGS) -c $< -o $@
%.o: %.psf
ifeq ($(OSARCH), amd64)
$(OBJCOPY) -O elf64-x86-64 -I binary $< $@
else ifeq ($(OSARCH), i386)
$(OBJCOPY) -O elf32-i386 -I binary $< $@
else ifeq ($(OSARCH), arm)
$(OBJCOPY) -O elf32-littlearm -I binary $< $@
else ifeq ($(OSARCH), aarch64)
$(OBJCOPY) -O elf64-littleaarch64 -I binary $< $@
endif
$(NM) $@
%.o: %.bmp
ifeq ($(OSARCH), amd64)
$(OBJCOPY) -O elf64-x86-64 -I binary $< $@
else ifeq ($(OSARCH), i386)
$(OBJCOPY) -O elf32-i386 -I binary $< $@
else ifeq ($(OSARCH), arm)
$(OBJCOPY) -O elf32-littlearm -I binary $< $@
else ifeq ($(OSARCH), aarch64)
$(OBJCOPY) -O elf64-littlearch64 -I binary $< $@
endif
$(NM) $@
clean:
rm -f kernel.map kernel_dump.map kernel_dump_intel.map $(OBJ) $(STACK_USAGE_OBJ) $(GCNO_OBJ) $(BOOT_FILENAME)

27
Bootloader/uefi/main.c Normal file
View File

@ -0,0 +1,27 @@
/*
This file is part of Lynx Bootloader.
Lynx Bootloader 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.
Lynx Bootloader 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 Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
*/
#include <efi.h>
#include <efilib.h>
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
InitializeLib(ImageHandle, SystemTable);
SystemTable->BootServices->SetWatchdogTimer(0, 0, 0, NULL);
Print(L"Lynx Bootloader © EnderIce2 2025\n");
return EFI_SUCCESS;
}

1883
CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

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 function and global declaration names with an uppercase letter.
- Start local variable names with a lowercase letter. - Start local variable names with a lowercase letter.
- Maintain consistent formatting and commenting guidelines. - 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. 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 0x7
- [CPUID](https://en.wikipedia.org/wiki/CPUID) - [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 ## Network
- [Beej's Guide to Network Programming](https://web.archive.org/web/20051210132103/http://users.pcnet.ro/dmoroian/beej/Beej.html) - [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) - [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 ## UART
- [Interfacing the Serial / RS232 Port V5.0](http://www.senet.com.au/~cpeacock) - [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! Special thanks to all contributors and the creators of the referenced projects and resources!

13
Drivers/.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# EditorConfig is awesome: https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
[Makefile]
indent_style = tab

View File

@ -1,118 +1,137 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "Fennix x64 (Linux, GCC, debug)", "name": "Fennix x64 (Linux, GCC, debug)",
"includePath": [ "includePath": [
"${workspaceFolder}/include", "${workspaceFolder}/include",
"${workspaceFolder}/include/**" "${workspaceFolder}/include/**"
], ],
"defines": [ "defines": [
"__debug_vscode__", "__debug_vscode__",
"KERNEL_NAME=\"Fennix\"", "KERNEL_NAME=\"Fennix\"",
"KERNEL_VERSION=\"1.0\"", "KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"", "GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"", "GIT_COMMIT_SHORT=\"0000000\"",
"DEBUG=\"1\"" "DEBUG=\"1\""
], ],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc", "compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "c++20", "cppStandard": "c++20",
"intelliSenseMode": "gcc-x64", "intelliSenseMode": "gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools", "configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [ "compilerArgs": [
// Compiler flags // Compiler flags
"-fPIC", "-fPIC",
"-fPIE", "-fPIE",
"-pie", "-pie",
"-mno-80387", "-mno-80387",
"-mno-mmx", "-mno-mmx",
"-mno-3dnow", "-mno-3dnow",
"-mno-red-zone", "-mno-red-zone",
"-mno-sse", "-mno-sse",
"-mno-sse2", "-mno-sse2",
"-march=x86-64", "-march=x86-64",
"-pipe", "-pipe",
"-ffunction-sections", "-ffunction-sections",
"-msoft-float", "-msoft-float",
"-fno-builtin", "-fno-builtin",
// C++ flags
// C++ flags "-fexceptions",
"-fexceptions", // Linker flags
"-fPIC",
// Linker flags "-fPIE",
"-fPIC", "-pie",
"-fPIE", "-Wl,-eDriverEntry",
"-pie", "-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment",
"-Wl,-eDriverEntry", "-nostdlib",
"-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment", "-nodefaultlibs",
"-nostdlib", "-nolibc",
"-nodefaultlibs", "-zmax-page-size=0x1000",
"-nolibc", "-static",
"-zmax-page-size=0x1000", // VSCode flags
"-static", "-ffreestanding",
"-nostdinc",
// VSCode flags "-nostdinc++"
"-ffreestanding", ]
"-nostdinc", },
"-nostdinc++" {
] "name": "Fennix x32 (Linux, GCC, debug)",
}, "includePath": [
{ "${workspaceFolder}/include/**"
"name": "Fennix x32 (Linux, GCC, debug)", ],
"includePath": [ "defines": [
"${workspaceFolder}/include/**" "__debug_vscode__",
], "KERNEL_NAME=\"Fennix\"",
"defines": [ "KERNEL_VERSION=\"1.0\"",
"__debug_vscode__", "GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"KERNEL_NAME=\"Fennix\"", "GIT_COMMIT_SHORT=\"0000000\"",
"KERNEL_VERSION=\"1.0\"", "DEBUG=\"1\""
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"", ],
"GIT_COMMIT_SHORT=\"0000000\"", "compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc",
"DEBUG=\"1\"" "cStandard": "c17",
], "cppStandard": "c++20",
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc", "intelliSenseMode": "gcc-x86",
"cStandard": "c17", "configurationProvider": "ms-vscode.makefile-tools",
"cppStandard": "c++20", "compilerArgs": [
"intelliSenseMode": "gcc-x86", // Compiler flags
"configurationProvider": "ms-vscode.makefile-tools", "-fPIC",
"compilerArgs": [ "-fPIE",
// Compiler flags "-pie",
"-fPIC", "-mno-80387",
"-fPIE", "-mno-mmx",
"-pie", "-mno-3dnow",
"-mno-80387", "-mno-red-zone",
"-mno-mmx", "-mno-sse",
"-mno-3dnow", "-mno-sse2",
"-mno-red-zone", "-march=i386",
"-mno-sse", "-pipe",
"-mno-sse2", "-ffunction-sections",
"-march=i386", "-msoft-float",
"-pipe", "-fno-builtin",
"-ffunction-sections", // C++ flags
"-msoft-float", "-fexceptions",
"-fno-builtin", // Linker flags
"-fPIC",
// C++ flags "-fPIE",
"-fexceptions", "-pie",
"-Wl,-eDriverEntry",
// Linker flags "-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment",
"-fPIC", "-nostdlib",
"-fPIE", "-nodefaultlibs",
"-pie", "-nolibc",
"-Wl,-eDriverEntry", "-zmax-page-size=0x1000",
"-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment", "-static",
"-nostdlib", // VSCode flags
"-nodefaultlibs", "-ffreestanding",
"-nolibc", "-nostdinc",
"-zmax-page-size=0x1000", "-nostdinc++"
"-static", ]
},
// VSCode flags {
"-ffreestanding", "name": "Fennix Aarch64 (Linux, GCC, debug)",
"-nostdinc", "includePath": [
"-nostdinc++" "${workspaceFolder}/include",
] "${workspaceFolder}/include/**"
} ],
], "defines": [
"version": 4 "__debug_vscode__",
"KERNEL_NAME=\"Fennix\"",
"KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"",
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-fennix-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "linux-gcc-arm64",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
}
],
"version": 4
} }

View File

@ -43,26 +43,47 @@ endif
export DRIVER_LDFLAGS export DRIVER_LDFLAGS
export DRIVER_CFLAGS 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: build:
cp -rf ../Kernel/include/interface/* include/ cp -rf ../Kernel/include/interface/* include/
mkdir -p out mkdir -p out
make -C library build $(MAKE) -C library build
make -C audio build ifneq ($(filter amd64 i386,$(OSARCH)),)
make -C input build $(MAKE) -C audio build
make -C misc build $(MAKE) -C input build
make -C network build $(MAKE) -C misc build
make -C storage build $(MAKE) -C network build
make -C filesystem build $(MAKE) -C storage build
$(MAKE) -C filesystem build
endif
$(MAKE) copy_driver_signatures
prepare: prepare:
$(info Nothing to prepare) $(info Nothing to prepare)
clean: clean:
rm -rf out rm -rf out
make -C library clean $(MAKE) -C library clean
make -C audio clean ifneq ($(filter amd64 i386,$(OSARCH)),)
make -C input clean $(MAKE) -C audio clean
make -C misc clean $(MAKE) -C input clean
make -C network clean $(MAKE) -C misc clean
make -C storage clean $(MAKE) -C network clean
make -C filesystem clean $(MAKE) -C storage clean
$(MAKE) -C filesystem clean
endif

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,881 +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 <errno.h>
#include <audio.h>
#include <regs.h>
#include <base.h>
#include <pci.h>
#include <io.h>
#include <fs.h>
#define DescriptorListLength 0x20
enum AudioVolumeValues
{
AV_Maximum = 0x0,
AV_Minimum = 0x3F,
};
enum AudioEncodingValues
{
AE_PCMs8,
AE_PCMu8,
AE_PCMs16le,
AE_PCMs20le,
AE_PCMs24le,
AE_PCMs32le,
AE_PCMu16le,
AE_PCMu20le,
AE_PCMu24le,
AE_PCMu32le,
AE_PCMs16be,
AE_PCMs20be,
AE_PCMs24be,
AE_PCMs32be,
AE_PCMu16be,
AE_PCMu20be,
AE_PCMu24be,
AE_PCMu32be,
};
enum NativeAudioMixerRegisters
{
/**
* @brief Reset Register
* @note Length: word
*/
NAM_Reset = 0x00,
/**
* @brief Master Volume Register
* @note Length: word
*/
NAM_MasterVolume = 0x02,
/**
* @brief Microphone Volume Register
* @note Length: word
*/
NAM_MicrophoneVolume = 0x0E,
/**
* @brief PCM Out Volume Register
* @note Length: word
*/
NAM_PCMOutVolume = 0x18,
/**
* @brief Select Record Input Register
* @note Length: word
*/
NAM_SelectRecordInput = 0x1A,
/**
* @brief Record Gain Register
* @note Length: word
*/
NAM_RecordGain = 0x1C,
/**
* @brief Record Gain Microphone Register
* @note Length: word
*/
NAM_RecordGainMicrophone = 0x1E,
};
enum NativeAudioBusMasterRegisters
{
/**
* @brief Register box for PCM IN
* @note Length: below
*/
NABM_PCMInBox = 0x00,
/**
* @brief Register box for PCM OUT
* @note Length: below
*/
NABM_PCMOutBox = 0x10,
/**
* @brief Register box for Microphone
* @note Length: below
*/
NABM_MicrophoneBox = 0x20,
/**
* @brief Global Control Register
* @note Length: dword
*/
NABM_GlobalControl = 0x2C, /* 0x30 */
/**
* @brief Global Status Register
* @note Length: dword
*/
NABM_GlobalStatus = 0x30, /* 0x34 */
};
enum NativeAudioBusMasterBoxOffsets
{
/**
* @brief Physical Address of Buffer Descriptor List
* @note Length: dword
*/
NABMBOFF_BufferDescriptorList = 0x00,
/**
* @brief Number of Actual Processed Buffer Descriptor Entry
* @note Length: byte
*/
NABMBOFF_BufferDescriptorEntry = 0x04,
/**
* @brief Number of all Descriptor Entries
* @note Length: byte
*/
NABMBOFF_DescriptorEntries = 0x05,
/**
* @brief Status of transferring Data
* @note Length: word
*/
NABMBOFF_Status = 0x06,
/**
* @brief Number of transferred Samples in Actual Processed Entry
* @note Length: word
*/
NABMBOFF_TransferredSamples = 0x08,
/**
* @brief Number of next processed Buffer Entry
* @note Length: byte
*/
NABMBOFF_NextProcessedBufferEntry = 0x0A,
/**
* @brief Transfer Control
* @note Length: byte
*/
NABMBOFF_TransferControl = 0x0B,
};
enum OutputPulseCodeModulationRegisters
{
/**
* @brief Physical Address of Buffer Descriptor List
* @note Length: dword
*/
PCMOUT_BufferDescriptorList = (int)NABM_PCMOutBox + (int)NABMBOFF_BufferDescriptorList,
/**
* @brief Number of Actual Processed Buffer Descriptor Entry
* @note Length: byte
*/
PCMOUT_BufferDescriptorEntry = (int)NABM_PCMOutBox + (int)NABMBOFF_BufferDescriptorEntry,
/**
* @brief Number of all Descriptor Entries
* @note Length: byte
*/
PCMOUT_DescriptorEntries = (int)NABM_PCMOutBox + (int)NABMBOFF_DescriptorEntries,
/**
* @brief Status of transferring Data
* @note Length: word
*/
PCMOUT_Status = (int)NABM_PCMOutBox + (int)NABMBOFF_Status,
/**
* @brief Number of transferred Samples in Actual Processed Entry
* @note Length: word
*/
PCMOUT_TransferredSamples = (int)NABM_PCMOutBox + (int)NABMBOFF_TransferredSamples,
/**
* @brief Number of next processed Buffer Entry
* @note Length: byte
*/
PCMOUT_NextProcessedBufferEntry = (int)NABM_PCMOutBox + (int)NABMBOFF_NextProcessedBufferEntry,
/**
* @brief Transfer Control
* @note Length: byte
*/
PCMOUT_TransferControl = (int)NABM_PCMOutBox + (int)NABMBOFF_TransferControl,
};
enum TransferControlRegisters
{
/**
* @brief DMA controller control
*
* 0 = Pause transfer
* 1 = Transfer sound data
*/
TC_DMAControllerControl = 0x01,
/**
* @brief Reset
*
* 0 = Remove reset condition
* 1 = Reset this NABM register box, this bit is cleared by card when is reset complete
*/
TC_TransferReset = 0x02,
/**
* @brief Last Buffer Entry Interrupt enable
*
* 0 = Disable interrupt
* 1 = Enable interrupt
*/
TC_LastBufferEntryInterruptEnable = 0x04,
/**
* @brief IOC Interrupt enable
*
* 0 = Disable interrupt
* 1 = Enable interrupt
*/
TC_IOCInterruptEnable = 0x08,
/**
* @brief Fifo ERROR Interrupt enable
*
* 0 = Disable interrupt
* 1 = Enable interrupt
*/
TC_FifoERRORInterruptEnable = 0x10,
};
enum GlobalControlRegisters
{
/**
* @brief Global Interrupt Enable
*
* 0 = Disable Interrupts
* 1 = Enable Interrupts
*/
GC_GlobalInterruptEnable = 0x01,
/**
* @brief Cold reset
*
* 0 = Device is in reset and can not be used
* 1 = Resume to operational state
*/
GC_ColdReset = 0x02,
/**
* @brief Warm reset
*/
GC_WarmReset = 0x04,
/**
* @brief Shut down
*
* 0 = Device is powered
* 1 = Shut down
*/
GC_ShutDown = 0x08,
/**
* @brief Channels for PCM Output
*
* 00 = 2 channels
* 01 = 4 channels
* 10 = 6 channels
* 11 = Reserved
*/
GC_ChannelsForPCMOutput = 0x30,
/**
* @brief PCM Output mode
*
* 00 = 16 bit samples
* 01 = 20 bit samples
*/
GC_PCMOutputMode = 0xC0,
};
struct BufferDescriptorList
{
/**
* @brief Physical Address to sound data in memory
* @note Length: dword
*/
uint32_t Address;
/**
* @brief Number of samples in this buffer
* @note Length: word
*/
uint16_t SampleCount;
/**
* @brief Flags
* @note Length: word
*
* Bit 15 = Interrupt fired when data from this entry is transferred
* Bit 14 = Last entry of buffer, stop playing
* Other bits = Reserved
*/
uint16_t Flags;
} __attribute__((packed));
uint16_t MixerVolume(uint8_t Left, uint8_t Right, bool Mute)
{
return ((uint16_t)((Right & 0x3F) |
((Left & 0x3F) << 0x8) |
(Mute & 1 << 0xF)));
}
class AC97Device
{
private:
PCIHeader0 *Header;
BufferDescriptorList *DescriptorList = nullptr;
uint16_t MixerAddress;
uint16_t BusMasterAddress;
AudioEncodingValues Encoding = AE_PCMs16le;
char Channels = 2;
uint8_t Volume = AV_Maximum;
bool Mute = false;
int SampleRate = 48000;
char SampleSize = 2;
public:
size_t write(uint8_t *Buffer, size_t Size)
{
if (Buffer == nullptr)
{
KernelLog("Invalid buffer.");
return -EINVAL;
}
if ((Size == 0) || (Size % (SampleSize * Channels)))
{
KernelLog("Invalid buffer length.");
return -EINVAL;
}
int TotalBDLToFill = (int)((Size + PAGE_SIZE - 1) >> 12);
while (Size > 0)
{
bool ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl);
if (ActiveDMA)
{
int RemainingBDL = 0;
do
{
int CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
int LastBDL = inb(BusMasterAddress + PCMOUT_DescriptorEntries);
RemainingBDL = LastBDL - CurrentBDL;
if (RemainingBDL < 0)
RemainingBDL += DescriptorListLength;
RemainingBDL += 1;
if (RemainingBDL >= DescriptorListLength - 1)
{
long SampleCount = DescriptorList[(CurrentBDL + 1) % DescriptorListLength].SampleCount / Channels;
if (SampleCount > 0)
Sleep(SampleCount * 1000 / SampleRate);
}
} while (RemainingBDL >= DescriptorListLength - 1 &&
!(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl));
}
uint8_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
uint8_t LastBDL = inb(BusMasterAddress + PCMOUT_DescriptorEntries);
uint8_t NextBDL = LastBDL % DescriptorListLength;
ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl);
if (ActiveDMA)
{
NextBDL = (uint8_t)((LastBDL + 1) % DescriptorListLength);
if (NextBDL == CurrentBDL)
continue;
}
do
{
size_t Wrote = (PAGE_SIZE > Size) ? size_t(Size)
: size_t(PAGE_SIZE);
if (Wrote == 0)
{
KernelLog("Wrote 0 bytes.");
break;
}
memcpy((void *)((uint64_t)DescriptorList[NextBDL].Address), Buffer, Wrote);
DescriptorList[NextBDL].Flags = 0;
Buffer += Wrote;
Size -= (unsigned int)Wrote;
DescriptorList[NextBDL].SampleCount = uint16_t(Wrote / SampleSize);
TotalBDLToFill--;
NextBDL = (uint8_t)((NextBDL + 1) % DescriptorListLength);
} while (TotalBDLToFill-- && NextBDL != CurrentBDL);
outb(BusMasterAddress + PCMOUT_DescriptorEntries, NextBDL - 1);
ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl);
if (!ActiveDMA)
{
// Start DMA
outb(BusMasterAddress + PCMOUT_TransferControl,
inb(BusMasterAddress + PCMOUT_TransferControl) | TC_DMAControllerControl);
}
}
return Size;
}
int ioctl(AudioIoctl, void *)
{
// if (Data->AudioCallback.Adjust._Volume)
// {
// Volume = (uint8_t)(0x3F - (0x3F * Data->AudioCallback.Adjust.Volume / 100));
// outw(BAR.MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute));
// // outw(BAR.MixerAddress + NAM_PCMOutVolume, MixerVolume(Volume, Volume, Mute));
// }
// else if (Data->AudioCallback.Adjust._Encoding)
// {
// fixme("Encoding changing not supported yet.");
// }
// else if (Data->AudioCallback.Adjust._SampleRate)
// {
// switch (Data->AudioCallback.Adjust.SampleRate)
// {
// case 0:
// {
// SampleRate = 8000;
// break;
// }
// case 1:
// {
// SampleRate = 11025;
// break;
// }
// case 2:
// {
// SampleRate = 16000;
// break;
// }
// case 3:
// {
// SampleRate = 22050;
// break;
// }
// case 4:
// {
// SampleRate = 32000;
// break;
// }
// case 5:
// {
// SampleRate = 44100;
// break;
// }
// case 6:
// {
// SampleRate = 48000;
// break;
// }
// case 7:
// {
// SampleRate = 88200;
// break;
// }
// case 8:
// {
// SampleRate = 96000;
// break;
// }
// default:
// {
// SampleRate = 16000;
// error("Invalid sample rate. Defaulting to 16000.");
// break;
// }
// }
// }
// else if (Data->AudioCallback.Adjust._Channels)
// {
// switch (Data->AudioCallback.Adjust.Channels)
// {
// case 0:
// {
// Channels = 1; // Mono
// break;
// }
// case 1:
// {
// Channels = 2; // Stereo
// break;
// }
// default:
// {
// Channels = 2;
// error("Invalid channel count. Defaulting to 2.");
// break;
// }
// }
// }
return 0;
}
void OnInterruptReceived(TrapFrame *)
{
uint16_t Status = inw(MixerAddress + PCMOUT_Status);
if (Status & TC_IOCInterruptEnable)
{
DebugLog("IOC");
outw(MixerAddress + PCMOUT_Status, TC_IOCInterruptEnable);
uint16_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
uint16_t LastBDL = (CurrentBDL + 2) & (DescriptorListLength - 1);
outb(BusMasterAddress + PCMOUT_DescriptorEntries, LastBDL);
KernelLog("FIXME: CurrentBDL: %d, LastBDL: %d", CurrentBDL, LastBDL);
}
else if (Status & TC_LastBufferEntryInterruptEnable)
{
DebugLog("Last buffer entry");
// Stop DMA
uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl));
TransferControl &= ~TC_DMAControllerControl;
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl);
outw(MixerAddress + PCMOUT_Status, TC_LastBufferEntryInterruptEnable);
}
else if (Status & TC_FifoERRORInterruptEnable)
{
KernelLog("FIFO error");
outw(MixerAddress + PCMOUT_Status, TC_FifoERRORInterruptEnable);
}
else
{
DebugLog("Unknown interrupt status %#x", Status);
outw(MixerAddress + PCMOUT_Status, 0xFFFF);
}
}
void Panic()
{
uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl));
TransferControl &= ~(TC_LastBufferEntryInterruptEnable |
TC_IOCInterruptEnable |
TC_FifoERRORInterruptEnable);
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl);
uint32_t GlobalControl = inl((uint16_t)(BusMasterAddress + NABM_GlobalControl));
GlobalControl &= ~GC_GlobalInterruptEnable;
GlobalControl |= GC_ShutDown;
outl((uint16_t)(BusMasterAddress + NABM_GlobalControl), GlobalControl);
}
AC97Device(PCIHeader0 *_Header)
: Header(_Header)
{
/* Native Audio Mixer Base Address */
uint32_t PCIBAR0 = Header->BAR0;
/* Native Audio Bus Master Base Address */
uint32_t PCIBAR1 = Header->BAR1;
// uint8_t Type = PCIBAR0 & 1;
MixerAddress = (uint16_t)(PCIBAR0 & (~3));
BusMasterAddress = PCIBAR1 & (~15);
uint16_t OutputPCMTransferControl = BusMasterAddress + PCMOUT_TransferControl;
/* DescriptorList address MUST be physical. */
DescriptorList = (BufferDescriptorList *)AllocateMemory(TO_PAGES(sizeof(BufferDescriptorList) * DescriptorListLength));
memset(DescriptorList, 0, sizeof(BufferDescriptorList) * DescriptorListLength);
uint16_t DLSampleCount = (uint16_t)(PAGE_SIZE / SampleSize);
for (int i = 0; i < DescriptorListLength; i++)
{
DescriptorList[i].Address = (uint32_t)(uintptr_t)AllocateMemory(TO_PAGES(sizeof(uint16_t *)));
DescriptorList[i].SampleCount = DLSampleCount;
DescriptorList[i].Flags = 0;
DebugLog("DescriptorList[%d] = { Address: %#lx, SampleCount: %d, Flags: %#lx }",
i,
DescriptorList[i].Address,
DescriptorList[i].SampleCount,
DescriptorList[i].Flags);
}
outw(MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute));
outw(MixerAddress + NAM_PCMOutVolume, MixerVolume(Volume, Volume, Mute));
Volume = 0x3F - (0x3F * /* VOL 50% */ 50 / 100);
outw(MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute));
outb(OutputPCMTransferControl, inb(OutputPCMTransferControl) | TC_TransferReset);
while (inb(OutputPCMTransferControl) & TC_TransferReset)
;
uint32_t GlobalControl = inl(BusMasterAddress + NABM_GlobalControl);
GlobalControl = (GlobalControl & ~((0x3U) << 0x16)); /* PCM 16-bit mode */
GlobalControl = (GlobalControl & ~((0x3U) << 20)); /* 2 channels */
GlobalControl |= GC_GlobalInterruptEnable;
GlobalControl &= ~GC_ShutDown;
outl(BusMasterAddress + PCMOUT_BufferDescriptorList,
(uint32_t)(uint64_t)DescriptorList);
outl(BusMasterAddress + NABM_GlobalControl, GlobalControl);
uint8_t TransferControl = inb(OutputPCMTransferControl);
TransferControl |= TC_IOCInterruptEnable |
TC_FifoERRORInterruptEnable;
outb(OutputPCMTransferControl, TransferControl);
// Stop DMA
outb(OutputPCMTransferControl, inb(OutputPCMTransferControl) & ~TC_DMAControllerControl);
}
~AC97Device()
{
outw(MixerAddress + NAM_MasterVolume, MixerVolume(AV_Maximum, AV_Maximum, true));
outw(MixerAddress + NAM_PCMOutVolume, MixerVolume(AV_Maximum, AV_Maximum, true));
// Stop DMA
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl),
inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl)) & ~TC_DMAControllerControl);
// Disable interrupts
uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl));
TransferControl &= ~(TC_LastBufferEntryInterruptEnable |
TC_IOCInterruptEnable |
TC_FifoERRORInterruptEnable);
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl);
// Disable global control
uint32_t GlobalControl = inl((uint16_t)(BusMasterAddress + NABM_GlobalControl));
GlobalControl &= ~GC_GlobalInterruptEnable;
GlobalControl |= GC_ShutDown;
outl((uint16_t)(BusMasterAddress + NABM_GlobalControl), GlobalControl);
}
};
AC97Device *Drivers[4] = {nullptr};
dev_t AudioID[4] = {(dev_t)-1};
#define OIR(x) OIR_##x
#define CREATE_OIR(x) \
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
CREATE_OIR(0);
CREATE_OIR(1);
CREATE_OIR(2);
CREATE_OIR(3);
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
int __fs_Close(struct Inode *) { return 0; }
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
{
return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
}
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
{
return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp);
}
const struct InodeOperations AudioOps = {
.Lookup = nullptr,
.Create = nullptr,
.Remove = nullptr,
.Rename = nullptr,
.Read = __fs_Read,
.Write = __fs_Write,
.Truncate = nullptr,
.Open = __fs_Open,
.Close = __fs_Close,
.Ioctl = __fs_Ioctl,
.ReadDir = nullptr,
.MkDir = nullptr,
.RmDir = nullptr,
.SymLink = nullptr,
.ReadLink = nullptr,
.Seek = nullptr,
.Stat = nullptr,
};
PCIArray *Devices;
EXTERNC int cxx_Panic()
{
PCIArray *ctx = Devices;
short Count = 0;
while (ctx != nullptr)
{
if (Drivers[Count] != nullptr)
Drivers[Count]->Panic();
Count++;
ctx = (PCIArray *)ctx->Next;
}
return 0;
}
EXTERNC int cxx_Probe()
{
uint16_t VendorIDs[] = {0x8086, PCI_END};
uint16_t DeviceIDs[] = {0x2415, PCI_END};
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
if (Devices == nullptr)
{
KernelLog("No AC'97 device found.");
return -ENODEV;
}
PCIArray *ctx = Devices;
bool Found = false;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count++ > sizeof(Drivers) / sizeof(AC97Device *))
break;
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
uint8_t Type = PCIBAR0 & 1;
if (Type != 1)
{
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
PCIBaseAddress->Header.VendorID,
PCIBaseAddress->Header.DeviceID,
PCIBaseAddress->Header.ProgIF);
continue;
}
Found = true;
ctx = (PCIArray *)ctx->Next;
}
if (!Found)
{
KernelLog("No valid AC'97 device found.");
return -EINVAL;
}
return 0;
}
EXTERNC int cxx_Initialize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count > sizeof(Drivers) / sizeof(AC97Device *))
break;
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
uint8_t Type = PCIBAR0 & 1;
if (Type != 1)
{
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
PCIBaseAddress->Header.VendorID,
PCIBaseAddress->Header.DeviceID,
PCIBaseAddress->Header.ProgIF);
continue;
}
InitializePCI(ctx->Device);
Drivers[Count] = new AC97Device((PCIHeader0 *)ctx->Device->Header);
/* FIXME: bad code */
switch (Count)
{
case 0:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0));
break;
case 1:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1));
break;
case 2:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2));
break;
case 3:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3));
break;
default:
break;
}
dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps);
AudioID[Count] = ret;
Count++;
ctx = (PCIArray *)ctx->Next;
}
return 0;
}
EXTERNC int cxx_Finalize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count++ > sizeof(Drivers) / sizeof(AC97Device *))
break;
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
uint8_t Type = PCIBAR0 & 1;
if (Type != 1)
{
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
PCIBaseAddress->Header.VendorID,
PCIBaseAddress->Header.DeviceID,
PCIBaseAddress->Header.ProgIF);
continue;
}
delete Drivers[Count++];
ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE;
ctx = (PCIArray *)ctx->Next;
}
for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++)
{
if (AudioID[i] != (dev_t)-1)
UnregisterDevice(AudioID[i]);
}
return 0;
}

View File

@ -1,31 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <base.h>
#include "ac97.hpp"
int DriverEntry() { return cxx_Initialize(); }
int DriverFinal() { return cxx_Finalize(); }
int DriverPanic() { return cxx_Panic(); }
int DriverProbe() { return cxx_Probe(); }
DriverInfo("ac97",
"Audio Codec '97 Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,263 +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 <errno.h>
#include <audio.h>
#include <regs.h>
#include <base.h>
#include <pci.h>
#include <io.h>
#include <fs.h>
#include "hda.hpp"
class HDADevice
{
private:
PCIHeader0 *Header;
bool Initialized = false;
ControllerRegisters *CTL;
uint32_t *CORB;
uint64_t *RIRB;
public:
bool IsInitialized() { return Initialized; }
size_t write(uint8_t *, size_t Size)
{
return Size;
}
int ioctl(AudioIoctl, void *)
{
return 0;
}
void OnInterruptReceived(TrapFrame *)
{
}
void Panic()
{
}
HDADevice(PCIHeader0 *_Header)
: Header(_Header),
CORB((uint32_t *)(uintptr_t)AllocateMemory(1)),
RIRB((uint64_t *)AllocateMemory(1))
{
CTL = (ControllerRegisters *)(uintptr_t)Header->BAR0;
KernelLog("Unimplemented HDA driver");
return;
Initialized = true;
}
~HDADevice()
{
if (!Initialized)
return;
}
};
HDADevice *Drivers[4] = {nullptr};
dev_t AudioID[4] = {(dev_t)-1};
#define OIR(x) OIR_##x
#define CREATE_OIR(x) \
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
CREATE_OIR(0);
CREATE_OIR(1);
CREATE_OIR(2);
CREATE_OIR(3);
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
int __fs_Close(struct Inode *) { return 0; }
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
{
return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
}
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
{
return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp);
}
const struct InodeOperations AudioOps = {
.Lookup = nullptr,
.Create = nullptr,
.Remove = nullptr,
.Rename = nullptr,
.Read = __fs_Read,
.Write = __fs_Write,
.Truncate = nullptr,
.Open = __fs_Open,
.Close = __fs_Close,
.Ioctl = __fs_Ioctl,
.ReadDir = nullptr,
.MkDir = nullptr,
.RmDir = nullptr,
.SymLink = nullptr,
.ReadLink = nullptr,
.Seek = nullptr,
.Stat = nullptr,
};
PCIArray *Devices;
EXTERNC int cxx_Panic()
{
PCIArray *ctx = Devices;
short Count = 0;
while (ctx != nullptr)
{
if (Drivers[Count] != nullptr)
Drivers[Count]->Panic();
Count++;
ctx = (PCIArray *)ctx->Next;
}
return 0;
}
EXTERNC int cxx_Probe()
{
uint16_t VendorIDs[] = {0x8086, /* Intel */
0x15AD, /* VMware */
PCI_END};
uint16_t DeviceIDs[] = {0x9D71 /* Sunrise Point-LP HD Audio */,
0x2668 /* ICH6 */,
0x293E /* ICH9 */,
PCI_END};
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
if (Devices == nullptr)
{
KernelLog("No HDA device found.");
return -ENODEV;
}
PCIArray *ctx = Devices;
bool Found = false;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count++ > sizeof(Drivers) / sizeof(HDADevice *))
break;
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
uint8_t Type = PCIBAR0 & 1;
if (Type == 1)
{
KernelLog("Device %x:%x.%d BAR0 is I/O.",
PCIBaseAddress->Header.VendorID,
PCIBaseAddress->Header.DeviceID,
PCIBaseAddress->Header.ProgIF);
continue;
}
Found = true;
ctx = (PCIArray *)ctx->Next;
}
if (!Found)
{
KernelLog("No valid HDA device found.");
return -EINVAL;
}
return 0;
}
EXTERNC int cxx_Initialize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count > sizeof(Drivers) / sizeof(HDADevice *))
break;
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
uint8_t Type = PCIBAR0 & 1;
if (Type == 1)
{
KernelLog("Device %x:%x.%d BAR0 is I/O.",
PCIBaseAddress->Header.VendorID,
PCIBaseAddress->Header.DeviceID,
PCIBaseAddress->Header.ProgIF);
continue;
}
InitializePCI(ctx->Device);
Drivers[Count] = new HDADevice((PCIHeader0 *)ctx->Device->Header);
if (Drivers[Count]->IsInitialized())
{
dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps);
AudioID[Count] = ret;
Count++;
}
ctx = (PCIArray *)ctx->Next;
}
if (Count == 0)
{
KernelLog("No valid HDA device found.");
return -EINVAL;
}
return 0;
}
EXTERNC int cxx_Finalize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count++ > sizeof(Drivers) / sizeof(HDADevice *))
break;
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
uint8_t Type = PCIBAR0 & 1;
if (Type == 1)
{
KernelLog("Device %x:%x.%d BAR0 is I/O.",
PCIBaseAddress->Header.VendorID,
PCIBaseAddress->Header.DeviceID,
PCIBaseAddress->Header.ProgIF);
continue;
}
delete Drivers[Count++];
ctx = (PCIArray *)ctx->Next;
}
for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++)
{
if (AudioID[i] != (dev_t)-1)
UnregisterDevice(AudioID[i]);
}
return 0;
}

View File

@ -1,31 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <base.h>
#include "hda.hpp"
int DriverEntry() { return cxx_Initialize(); }
int DriverFinal() { return cxx_Finalize(); }
int DriverPanic() { return cxx_Panic(); }
int DriverProbe() { return cxx_Probe(); }
DriverInfo("hda",
"Intel High Definition Audio Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,45 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <base.h>
int DriverEntry()
{
return 0;
}
int DriverFinal()
{
return 0;
}
int DriverPanic()
{
return 0;
}
int DriverProbe()
{
/* Nothing to do */
return 0;
}
DriverInfo("fat",
"File Allocation Table Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -103,6 +103,7 @@ typedef union
uint8_t Raw; uint8_t Raw;
} PS2_OUTPUT_PORT; } PS2_OUTPUT_PORT;
#ifndef __kernel__
void PIC_EOI(uint8_t IRQ); void PIC_EOI(uint8_t IRQ);
void IRQ_MASK(uint8_t IRQ); void IRQ_MASK(uint8_t IRQ);
void IRQ_UNMASK(uint8_t IRQ); void IRQ_UNMASK(uint8_t IRQ);
@ -114,11 +115,11 @@ uint8_t PS2ReadStatus();
uint8_t PS2ReadAfterACK(); uint8_t PS2ReadAfterACK();
void PS2ClearOutputBuffer(); void PS2ClearOutputBuffer();
int PS2ACKTimeout(); int PS2ACKTimeout();
#endif // !__kernel__
#define WaitOutput PS2Wait(DriverID, true) #define WaitOutput PS2Wait(DriverID, true)
#define WaitInput PS2Wait(DriverID, false) #define WaitInput PS2Wait(DriverID, false)
#define PS2_KBD_CMD_SET_LEDS 0xED #define PS2_KBD_CMD_SET_LEDS 0xED
#define PS2_KBD_CMD_ECHO 0xEE #define PS2_KBD_CMD_ECHO 0xEE
#define PS2_KBD_CMD_SCAN_CODE_SET 0xF0 #define PS2_KBD_CMD_SCAN_CODE_SET 0xF0
@ -189,7 +190,6 @@ typedef union
uint8_t Raw; uint8_t Raw;
} PS2_KBD_TYPEMATIC; } PS2_KBD_TYPEMATIC;
#define PS2_MOUSE_CMD_SET_SCALING_1_1 0xE6 #define PS2_MOUSE_CMD_SET_SCALING_1_1 0xE6
#define PS2_MOUSE_CMD_SET_SCALING_2_1 0xE7 #define PS2_MOUSE_CMD_SET_SCALING_2_1 0xE7
#define PS2_MOUSE_CMD_SET_RESOLUTION 0xE8 #define PS2_MOUSE_CMD_SET_RESOLUTION 0xE8

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

@ -69,7 +69,10 @@ typedef enum
BLOCK_TYPE_FLOPPY = DEVICE_TYPE_BLOCK + 128, BLOCK_TYPE_FLOPPY = DEVICE_TYPE_BLOCK + 128,
} DeviceType; } DeviceType;
#ifndef __kernel__
EXTERNC dev_t CreateDeviceFile(const char *name, mode_t mode, const struct InodeOperations *Operations);
EXTERNC dev_t RegisterDevice(DeviceType Type, const struct InodeOperations *Operations); EXTERNC dev_t RegisterDevice(DeviceType Type, const struct InodeOperations *Operations);
EXTERNC int UnregisterDevice(dev_t Device); EXTERNC int UnregisterDevice(dev_t Device);
#endif // !__kernel__
#endif // !__FENNIX_API_DEVICE_H__ #endif // !__FENNIX_API_DEVICE_H__

File diff suppressed because it is too large Load Diff

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 */ /** Other: X */
#define S_IXOTH 0001 #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_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
@ -146,10 +136,10 @@ static_assert(sizeof(blkcnt_t) == 8, "blkcnt_t must be 64 bits");
#else #else
static_assert(sizeof(dev_t) == 4, "dev_t must be 32 bits"); static_assert(sizeof(dev_t) == 4, "dev_t must be 32 bits");
static_assert(sizeof(ino_t) == 4, "ino_t must be 32 bits"); static_assert(sizeof(ino_t) == 4, "ino_t must be 32 bits");
static_assert(sizeof(mode_t) == 2, "mode_t must be 16 bits"); static_assert(sizeof(mode_t) == 4, "mode_t must be 32 bits");
static_assert(sizeof(nlink_t) == 2, "nlink_t must be 16 bits"); static_assert(sizeof(nlink_t) == 4, "nlink_t must be 32 bits");
static_assert(sizeof(uid_t) == 2, "uid_t must be 16 bits"); static_assert(sizeof(uid_t) == 4, "uid_t must be 32 bits");
static_assert(sizeof(gid_t) == 2, "gid_t must be 16 bits"); static_assert(sizeof(gid_t) == 4, "gid_t must be 32 bits");
static_assert(sizeof(off_t) == 4, "off_t must be 32 bits"); static_assert(sizeof(off_t) == 4, "off_t must be 32 bits");
static_assert(sizeof(time_t) == 4, "time_t must be 32 bits"); static_assert(sizeof(time_t) == 4, "time_t must be 32 bits");
static_assert(sizeof(blksize_t) == 4, "blksize_t must be 32 bits"); static_assert(sizeof(blksize_t) == 4, "blksize_t must be 32 bits");
@ -332,11 +322,29 @@ struct InodeOperations
int (*Stat)(struct Inode *Node, struct kstat *Stat); int (*Stat)(struct Inode *Node, struct kstat *Stat);
} __attribute__((packed)); } __attribute__((packed));
#define I_FLAG_ROOT 0x1
#define I_FLAG_MOUNTPOINT 0x2
#define I_FLAG_CACHE_KEEP 0x4
struct FileSystemInfo; 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 struct SuperBlockOperations
{ {
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result); int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
@ -347,8 +355,8 @@ struct SuperBlockOperations
* *
* Write all pending changes to the disk. * Write all pending changes to the disk.
* *
* @param Info Inode to synchronize. If NULL, synchronize all inodes. * @param Info Inode to synchronize.
* @param Node Inode to synchronize. * @param Node Inode to synchronize. If NULL, synchronize all inodes.
* *
* @return Zero on success, otherwise an error code. * @return Zero on success, otherwise an error code.
*/ */
@ -364,20 +372,62 @@ struct SuperBlockOperations
* @return Zero on success, otherwise an error code. * @return Zero on success, otherwise an error code.
*/ */
int (*Destroy)(struct FileSystemInfo *Info); 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)); } __attribute__((packed));
struct FileSystemInfo struct FileSystemInfo
{ {
const char *Name; const char *Name;
const char *RootName;
int Flags; int Flags;
int Capabilities;
struct SuperBlockOperations SuperOps; struct SuperBlockOperations SuperOps;
struct InodeOperations Ops; struct InodeOperations Ops;
void *PrivateData; void *PrivateData;
} __attribute__((packed)); } __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); dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
int UnregisterFileSystem(dev_t Device); int UnregisterFileSystem(dev_t Device);
#endif // !__kernel__
#endif // !__FENNIX_API_FILESYSTEM_H__ #endif // !__FENNIX_API_FILESYSTEM_H__

View File

@ -239,6 +239,8 @@ typedef struct
}; };
} InputReport; } InputReport;
#ifndef __kernel__
EXTERNC int ReportInputEvent(InputReport *Report); EXTERNC int ReportInputEvent(InputReport *Report);
#endif // !__kernel__
#endif // !__FENNIX_API_INPUT_H__ #endif // !__FENNIX_API_INPUT_H__

View File

@ -75,7 +75,7 @@ extern "C"
: "dN"(Port), "a"(Data)); : "dN"(Port), "a"(Data));
} }
static inline uint8_t mmioin8(uint64_t Address) static inline uint8_t mmioin8(uintptr_t Address)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
@ -85,7 +85,7 @@ extern "C"
return Result; return Result;
} }
static inline uint16_t mmioin16(uint64_t Address) static inline uint16_t mmioin16(uintptr_t Address)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
@ -95,7 +95,7 @@ extern "C"
return Result; return Result;
} }
static inline uint32_t mmioin32(uint64_t Address) static inline uint32_t mmioin32(uintptr_t Address)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
@ -105,17 +105,17 @@ extern "C"
return Result; return Result;
} }
static inline uint64_t mmioin64(uint64_t Address) static inline uintptr_t mmioin64(uintptr_t Address)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
uint64_t Result = *(volatile uint64_t *)Address; uintptr_t Result = *(volatile uintptr_t *)Address;
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
return Result; return Result;
} }
static inline void mmioout8(uint64_t Address, uint8_t Data) static inline void mmioout8(uintptr_t Address, uint8_t Data)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
@ -124,7 +124,7 @@ extern "C"
: "memory"); : "memory");
} }
static inline void mmioout16(uint64_t Address, uint16_t Data) static inline void mmioout16(uintptr_t Address, uint16_t Data)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
@ -133,7 +133,7 @@ extern "C"
: "memory"); : "memory");
} }
static inline void mmioout32(uint64_t Address, uint32_t Data) static inline void mmioout32(uintptr_t Address, uint32_t Data)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
@ -142,11 +142,11 @@ extern "C"
: "memory"); : "memory");
} }
static inline void mmioout64(uint64_t Address, uint64_t Data) static inline void mmioout64(uintptr_t Address, uintptr_t Data)
{ {
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
*(volatile uint64_t *)Address = Data; *(volatile uintptr_t *)Address = Data;
__asm__ volatile("" :: __asm__ volatile("" ::
: "memory"); : "memory");
} }
@ -175,10 +175,10 @@ extern "C"
: "memory"); : "memory");
} }
static inline void mmoutq(void *Address, uint64_t Value) static inline void mmoutq(void *Address, uintptr_t Value)
{ {
__asm__ volatile("mov %1, %0" __asm__ volatile("mov %1, %0"
: "=m"((*(uint64_t *)(Address))) : "=m"((*(uintptr_t *)(Address)))
: "r"(Value) : "r"(Value)
: "memory"); : "memory");
} }
@ -213,12 +213,12 @@ extern "C"
return Result; return Result;
} }
static inline uint64_t mminq(void *Address) static inline uintptr_t mminq(void *Address)
{ {
uint64_t Result; uintptr_t Result;
__asm__ volatile("mov %1, %0" __asm__ volatile("mov %1, %0"
: "=r"(Result) : "=r"(Result)
: "m"((*(uint64_t *)(Address))) : "m"((*(uintptr_t *)(Address)))
: "memory"); : "memory");
return Result; return Result;
} }

View File

@ -171,11 +171,13 @@ extern "C"
{ {
#endif #endif
#ifndef __kernel__
PCIArray *GetPCIDevices(uint16_t Vendors[], uint16_t Devices[]); PCIArray *GetPCIDevices(uint16_t Vendors[], uint16_t Devices[]);
void InitializePCI(PCIDevice *Device); void InitializePCI(PCIDevice *Device);
uint32_t GetBAR(uint8_t Index, PCIDevice *Device); uint32_t GetBAR(uint8_t Index, PCIDevice *Device);
uint8_t iLine(PCIDevice *Device); uint8_t iLine(PCIDevice *Device);
uint8_t iPin(PCIDevice *Device); uint8_t iPin(PCIDevice *Device);
#endif // !__kernel__
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -15,13 +15,44 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>. along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef __FENNIX_API_SYSCALLS_LIST_H__ #ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__
#define __FENNIX_API_SYSCALLS_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 #pragma region Syscall Wrappers
#define scarg __UINTPTR_TYPE__ #define scarg __UINTPTR_TYPE__
#ifdef __arm__
#ifdef __thumb__
#define __thumb_r7
#define __arm_call(...)
#warning "arm thumb code not implemented"
#else /* __thumb__ */
#define __thumb_r7 __asm__("r7")
#define __arm_call(...) \
__asm__ __volatile__("svc 0" \
: "=r"(r0) \
: __VA_ARGS__ \
: "memory")
#endif /* __thumb__ */
#ifdef __thumb2__
#define __r7_operand "rI"(r7)
#else /* __thumb2__ */
#define __r7_operand "r"(r7)
#endif /* __thumb2__ */
#endif /* __arm__ */
/** /**
* @brief Syscall wrapper with 0 arguments * @brief Syscall wrapper with 0 arguments
* *
@ -33,10 +64,30 @@
static inline scarg syscall0(scarg syscall) static inline scarg syscall0(scarg syscall)
{ {
scarg ret; scarg ret;
#if defined(__amd64__)
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: "=a"(ret) : "=a"(ret)
: "a"(syscall) : "a"(syscall)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__i386__)
__asm__ __volatile__("int $0x30"
: "=a"(ret)
: "a"(syscall)
: "memory");
#elif defined(__arm__)
register scarg r7 __thumb_r7 = syscall;
register scarg r0 __asm__("r0");
__arm_call(__r7_operand);
#elif defined(__aarch64__)
register scarg x8 __asm__("x8") = syscall;
register scarg x0 __asm__("x0");
__asm__ __volatile__("svc 0"
: "=r"(x0)
: "r"(x8)
: "memory", "cc");
#else
#error "Unsupported architecture"
#endif
return ret; return ret;
} }
@ -52,10 +103,30 @@ static inline scarg syscall0(scarg syscall)
static inline scarg syscall1(scarg syscall, scarg arg1) static inline scarg syscall1(scarg syscall, scarg arg1)
{ {
scarg ret; scarg ret;
#if defined(__amd64__)
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: "=a"(ret) : "=a"(ret)
: "a"(syscall), "D"(arg1) : "a"(syscall), "D"(arg1)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__i386__)
__asm__ __volatile__("int $0x30"
: "=a"(ret)
: "a"(syscall), "b"(arg1)
: "memory");
#elif defined(__arm__)
register scarg r7 __thumb_r7 = syscall;
register scarg r0 __asm__("r0") = arg1;
__arm_call(__r7_operand, "0"(r0));
#elif defined(__aarch64__)
register scarg x8 __asm__("x8") = syscall;
register scarg x0 __asm__("x0") = arg1;
__asm__ __volatile__("svc 0"
: "=r"(ret)
: "r"(x8), "0"(x0)
: "memory", "cc");
#else
#error "Unsupported architecture"
#endif
return ret; return ret;
} }
@ -72,10 +143,32 @@ static inline scarg syscall1(scarg syscall, scarg arg1)
static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2) static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
{ {
scarg ret; scarg ret;
#if defined(__amd64__)
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: "=a"(ret) : "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2) : "a"(syscall), "D"(arg1), "S"(arg2)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__i386__)
__asm__ __volatile__("int $0x30"
: "=a"(ret)
: "a"(syscall), "b"(arg1), "c"(arg2)
: "memory");
#elif defined(__arm__)
register scarg r7 __thumb_r7 = syscall;
register scarg r0 __asm__("r0") = arg1;
register scarg r1 __asm__("r1") = arg2;
__arm_call(__r7_operand, "0"(r0), "r"(r1));
#elif defined(__aarch64__)
register scarg x8 __asm__("x8") = syscall;
register scarg x0 __asm__("x0") = arg1;
register scarg x1 __asm__("x1") = arg2;
__asm__ __volatile__("svc 0"
: "=r"(ret)
: "r"(x8), "0"(x0), "r"(x1)
: "memory", "cc");
#else
#error "Unsupported architecture"
#endif
return ret; return ret;
} }
@ -93,10 +186,34 @@ static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3) static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
{ {
scarg ret; scarg ret;
#if defined(__amd64__)
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: "=a"(ret) : "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__i386__)
__asm__ __volatile__("int $0x30"
: "=a"(ret)
: "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3)
: "memory");
#elif defined(__arm__)
register scarg r7 __thumb_r7 = syscall;
register scarg r0 __asm__("r0") = arg1;
register scarg r1 __asm__("r1") = arg2;
register scarg r2 __asm__("r2") = arg3;
__arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2));
#elif defined(__aarch64__)
register scarg x8 __asm__("x8") = syscall;
register scarg x0 __asm__("x0") = arg1;
register scarg x1 __asm__("x1") = arg2;
register scarg x2 __asm__("x2") = arg3;
__asm__ __volatile__("svc 0"
: "=r"(ret)
: "r"(x8), "0"(x0), "r"(x1), "r"(x2)
: "memory", "cc");
#else
#error "Unsupported architecture"
#endif
return ret; return ret;
} }
@ -115,11 +232,37 @@ static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4) static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4)
{ {
scarg ret; scarg ret;
#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4; register scarg r10 __asm__("r10") = arg4;
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: "=a"(ret) : "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__i386__)
__asm__ __volatile__("int $0x30"
: "=a"(ret)
: "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4)
: "memory");
#elif defined(__arm__)
register scarg r7 __thumb_r7 = syscall;
register scarg r0 __asm__("r0") = arg1;
register scarg r1 __asm__("r1") = arg2;
register scarg r2 __asm__("r2") = arg3;
register scarg r3 __asm__("r3") = arg4;
__arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2), "r"(r3));
#elif defined(__aarch64__)
register scarg x8 __asm__("x8") = syscall;
register scarg x0 __asm__("x0") = arg1;
register scarg x1 __asm__("x1") = arg2;
register scarg x2 __asm__("x2") = arg3;
register scarg x3 __asm__("x3") = arg4;
__asm__ __volatile__("svc 0"
: "=r"(ret)
: "r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3)
: "memory", "cc");
#else
#error "Unsupported architecture"
#endif
return ret; return ret;
} }
@ -139,12 +282,40 @@ static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5) static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5)
{ {
scarg ret; scarg ret;
#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4; register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5; register scarg r8 __asm__("r8") = arg5;
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: "=a"(ret) : "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__i386__)
__asm__ __volatile__("int $0x30"
: "=a"(ret)
: "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4), "D"(arg5)
: "memory");
#elif defined(__arm__)
register scarg r7 __thumb_r7 = syscall;
register scarg r0 __asm__("r0") = arg1;
register scarg r1 __asm__("r1") = arg2;
register scarg r2 __asm__("r2") = arg3;
register scarg r3 __asm__("r3") = arg4;
register scarg r4 __asm__("r4") = arg5;
__arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
#elif defined(__aarch64__)
register scarg x8 __asm__("x8") = syscall;
register scarg x0 __asm__("x0") = arg1;
register scarg x1 __asm__("x1") = arg2;
register scarg x2 __asm__("x2") = arg3;
register scarg x3 __asm__("x3") = arg4;
register scarg x4 __asm__("x4") = arg5;
__asm__ __volatile__("svc 0"
: "=r"(ret)
: "r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4)
: "memory", "cc");
#else
#error "Unsupported architecture"
#endif
return ret; return ret;
} }
@ -165,6 +336,7 @@ static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5, scarg arg6) static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5, scarg arg6)
{ {
scarg ret; scarg ret;
#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4; register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5; register scarg r8 __asm__("r8") = arg5;
register scarg r9 __asm__("r9") = arg6; register scarg r9 __asm__("r9") = arg6;
@ -172,6 +344,35 @@ static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
: "=a"(ret) : "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
#elif defined(__i386__)
__asm__ __volatile__("int $0x30"
: "=a"(ret)
: "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4), "D"(arg5), "g"(arg6)
: "memory");
#elif defined(__arm__)
register scarg r7 __thumb_r7 = syscall;
register scarg r0 __asm__("r0") = arg1;
register scarg r1 __asm__("r1") = arg2;
register scarg r2 __asm__("r2") = arg3;
register scarg r3 __asm__("r3") = arg4;
register scarg r4 __asm__("r4") = arg5;
register scarg r5 __asm__("r5") = arg6;
__arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
#elif defined(__aarch64__)
register scarg x8 __asm__("x8") = syscall;
register scarg x0 __asm__("x0") = arg1;
register scarg x1 __asm__("x1") = arg2;
register scarg x2 __asm__("x2") = arg3;
register scarg x3 __asm__("x3") = arg4;
register scarg x4 __asm__("x4") = arg5;
register scarg x5 __asm__("x5") = arg6;
__asm__ __volatile__("svc 0"
: "=r"(ret)
: "r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5)
: "memory", "cc");
#else
#error "Unsupported architecture"
#endif
return ret; return ret;
} }
@ -202,18 +403,18 @@ typedef enum
typedef enum typedef enum
{ {
__SYS_O_RDONLY = 0x1, __SYS_O_RDONLY = O_RDONLY,
__SYS_O_WRONLY = 0x2, __SYS_O_WRONLY = O_WRONLY,
__SYS_O_RDWR = 0x3, __SYS_O_RDWR = O_RDWR,
__SYS_O_APPEND = 0x4, __SYS_O_APPEND = O_APPEND,
__SYS_O_CREAT = 0x8, __SYS_O_CREAT = O_CREAT,
__SYS_O_DSYNC = 0x10, __SYS_O_DSYNC = O_DSYNC,
__SYS_O_EXCL = 0x20, __SYS_O_EXCL = O_EXCL,
__SYS_O_NOCTTY = 0x40, __SYS_O_NOCTTY = O_NOCTTY,
__SYS_O_NONBLOCK = 0x80, __SYS_O_NONBLOCK = O_NONBLOCK,
__SYS_O_RSYNC = 0x100, __SYS_O_RSYNC = O_RSYNC,
__SYS_O_SYNC = 0x200, __SYS_O_SYNC = O_SYNC,
__SYS_O_TRUNC = 0x400 __SYS_O_TRUNC = O_TRUNC
} syscall_open_flags_t; } syscall_open_flags_t;
typedef enum typedef enum
@ -411,6 +612,36 @@ static_assert((int)__SYS_SIG_IGN == (int)___SYS_SIG_IGN, "SIG_IGN values do not
typedef int __SYS_clockid_t; typedef int __SYS_clockid_t;
typedef unsigned int __SYS_socklen_t; typedef unsigned int __SYS_socklen_t;
typedef struct FramebufferScreenInfo
{
__UINT32_TYPE__ Width;
__UINT32_TYPE__ Height;
__UINT32_TYPE__ Pitch;
__UINT32_TYPE__ Bpp;
__UINT32_TYPE__ Size;
} FramebufferScreenInfo;
/**
* @brief Get framebuffer screen info
*
* @code
* struct FramebufferScreenInfo info;
* int ioctl(fd, FBIOGET_SCREEN_INFO, &info);
* @endcode
*
* @param fd File descriptor of the framebuffer device
* @param info Pointer to the framebuffer screen info structure
*/
#define FBIOGET_SCREEN_INFO 0xf0
struct kutsname
{
char sysname[65];
char release[65];
char version[65];
char machine[65];
};
/** /**
* @brief List of syscalls * @brief List of syscalls
* *
@ -443,6 +674,8 @@ typedef enum
*/ */
SYS_API_VERSION = 0, SYS_API_VERSION = 0,
SYS_DEBUG_REPORT = 1,
/* I/O */ /* I/O */
/** /**
@ -599,6 +832,25 @@ typedef enum
* - #EINVAL if the request is invalid * - #EINVAL if the request is invalid
*/ */
SYS_IOCTL, 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 */ /* File Status */
@ -1388,6 +1640,22 @@ typedef enum
* - #EACCES if permission is denied * - #EACCES if permission is denied
*/ */
SYS_RENAME, 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 * @brief Max number of syscalls
@ -1431,6 +1699,9 @@ typedef enum
/** @copydoc SYS_IOCTL */ /** @copydoc SYS_IOCTL */
#define call_ioctl(fd, request, argp) syscall3(SYS_IOCTL, (scarg)fd, (scarg)request, (scarg)argp) #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 */ /* File Status */
/** @copydoc SYS_STAT */ /** @copydoc SYS_STAT */
@ -1538,7 +1809,7 @@ typedef enum
/* Time */ /* Time */
/** @copydoc SYS_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 */ /** @copydoc SYS_CLOCK_GETTIME */
#define call_clock_gettime(clockid, tp) syscall2(SYS_CLOCK_GETTIME, (scarg)clockid, (scarg)tp) #define call_clock_gettime(clockid, tp) syscall2(SYS_CLOCK_GETTIME, (scarg)clockid, (scarg)tp)
@ -1569,4 +1840,7 @@ typedef enum
/** @copydoc SYS_RENAME */ /** @copydoc SYS_RENAME */
#define call_rename(oldpath, newpath) syscall2(SYS_RENAME, (scarg)oldpath, (scarg)newpath) #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

@ -71,7 +71,7 @@ typedef uint32_t uid_t;
typedef uint32_t gid_t; typedef uint32_t gid_t;
typedef int64_t clock_t; typedef int64_t clock_t;
typedef int32_t pid_t; typedef int32_t pid_t;
#elif defined(__LP32__) #else
typedef int32_t off_t; typedef int32_t off_t;
typedef long long off64_t; typedef long long off64_t;
typedef __INT32_TYPE__ mode_t; typedef __INT32_TYPE__ mode_t;

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,39 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_DRIVER_AIP_H__
#define __FENNIX_DRIVER_AIP_H__
#include <types.h>
#include <aip.h>
#include <regs.h>
extern uint8_t Device1ID[];
extern uint8_t Device2ID[];
void PS2KbdInterruptHandler(TrapFrame *);
int InitializeKeyboard();
int FinalizeKeyboard();
int DetectPS2Keyboard();
void PS2MouseInterruptHandler(TrapFrame *);
int InitializeMouse();
int FinalizeMouse();
int DetectPS2Mouse();
int DetectUART();
#endif // !__FENNIX_DRIVER_AIP_H__

View File

@ -1,235 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include "aip.h"
#include <errno.h>
#include <base.h>
bool IsKeyboard(uint8_t ID)
{
/* Common keyboard IDs */
return ID == 0xAB || ID == 0xAC || ID == 0x5D ||
ID == 0x2B || ID == 0x47 || ID == 0x60;
}
bool IsMouse(uint8_t ID)
{
/* Common mouse IDs */
return ID == 0x00 || ID == 0x03 || ID == 0x04;
}
const char *GetPS2DeviceName(uint8_t ID, uint8_t SubID)
{
switch (ID)
{
case 0x00:
return "Standard PS/2 Mouse";
case 0x03:
return "Mouse with scroll wheel";
case 0x04:
return "Mouse 5 buttons";
case 0xAB:
{
switch (SubID)
{
case 0x83: /* Normal */
case 0x41: /* Translated */
case 0xC1: /* Normal + Translated */
return "Standard PS/2 Keyboard";
case 0x84:
case 0x54:
return "IBM Thinkpad/Spacesaver Keyboard";
case 0x85:
return "NCD N-97/122-Key Host Connect(ed) Keyboard";
case 0x86:
return "122-Key Keyboard";
case 0x90:
return "Japanese \"G\" Keyboard";
case 0x91:
return "Japanese \"P\" Keyboard";
case 0x92:
return "Japanese \"A\" Keyboard";
default:
return "Unknown PS/2 Keyboard";
}
}
case 0xAC:
{
switch (SubID)
{
case 0xA1:
return "NCD Sun Keyboard";
default:
return "Unknown NCD Sun Keyboard";
}
}
case 0x5D:
case 0x2B:
return "Trust Keyboard";
case 0x47:
case 0x60:
return "NMB SGI Keyboard";
default:
return "Unknown PS/2 Device";
}
}
uint8_t Device1ID[2] = {0x00, 0x00};
uint8_t Device2ID[2] = {0x00, 0x00};
bool DualChannel = false;
int DriverEntry()
{
PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
PS2WriteCommand(PS2_CMD_DISABLE_PORT_2);
PS2ClearOutputBuffer();
PS2WriteCommand(PS2_CMD_READ_CONFIG);
PS2_CONFIGURATION cfg = {.Raw = PS2ReadData()};
DualChannel = cfg.Port2Clock;
if (DualChannel)
KernelLog("Dual channel PS/2 controller detected");
cfg.Port1Interrupt = 1;
cfg.Port2Interrupt = 1;
cfg.Port1Translation = 1;
PS2WriteCommand(PS2_CMD_WRITE_CONFIG);
PS2WriteData(cfg.Raw);
PS2WriteCommand(PS2_CMD_TEST_CONTROLLER);
uint8_t test = PS2ReadData();
if (test != PS2_TEST_PASSED)
{
KernelLog("PS/2 controller self test failed (%#x)", test);
return -EFAULT;
}
PS2WriteCommand(PS2_CMD_WRITE_CONFIG);
PS2WriteData(cfg.Raw);
// bool port2avail = false;
// if (DualChannel)
// {
// PS2WriteCommand(PS2_CMD_ENABLE_PORT_1);
// PS2WriteCommand(PS2_CMD_READ_CONFIG);
// cfg.Raw = PS2ReadData();
// port2avail = cfg.Port2Clock;
// PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
// }
PS2WriteCommand(PS2_CMD_TEST_PORT_1);
test = PS2ReadData();
if (test != 0x00)
{
KernelLog("PS/2 Port 1 self test failed (%#x)", test);
return -EFAULT;
}
if (DualChannel)
{
PS2WriteCommand(PS2_CMD_TEST_PORT_2);
test = PS2ReadData();
if (test != 0x00)
{
KernelLog("PS/2 Port 2 self test failed (%#x)", test);
return -EFAULT;
}
}
PS2WriteCommand(PS2_CMD_ENABLE_PORT_1);
if (DualChannel)
PS2WriteCommand(PS2_CMD_ENABLE_PORT_2);
int errK = InitializeKeyboard();
int errM = 0;
if (DualChannel)
errM = InitializeMouse();
/** A device may fail, but if the other one works,
* we can still use it.
*/
if (errK != 0 && errM != 0)
return -ENODEV;
return 0;
}
int DriverFinal()
{
FinalizeKeyboard();
FinalizeMouse();
PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
PS2WriteCommand(PS2_CMD_DISABLE_PORT_2);
return 0;
}
int DriverPanic()
{
PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
PS2WriteCommand(PS2_CMD_DISABLE_PORT_2);
return 0;
}
void __intStub() {}
int DriverProbe()
{
RegisterInterruptHandler(1, __intStub);
RegisterInterruptHandler(12, __intStub);
int kbd = DetectPS2Keyboard();
int mouse = DetectPS2Mouse();
int uart = DetectUART();
UnregisterAllInterruptHandlers(__intStub);
if (kbd != 0 && mouse != 0 && uart != 0)
return -ENODEV;
if (kbd == 0)
{
if (!IsKeyboard(Device1ID[0]))
{
KernelLog("PS/2 Port 1 is not a keyboard");
// return -EINVAL;
}
}
if (mouse == 0)
{
if (!IsMouse(Device2ID[0]))
{
KernelLog("PS/2 Port 2 is not a mouse");
// return -EINVAL;
}
}
KernelPrint("PS/2 Port 1: %s (0x%X 0x%X)",
GetPS2DeviceName(Device1ID[0], Device1ID[1]),
Device1ID[0], Device1ID[1]);
KernelPrint("PS/2 Port 2: %s (0x%X 0x%X)",
GetPS2DeviceName(Device2ID[0], Device2ID[1]),
Device2ID[0], Device2ID[1]);
return 0;
}
DriverInfo("aip",
"Advanced Integrated Peripheral Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -1,244 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include "aip.h"
#include <errno.h>
#include <base.h>
#include <fs.h>
#include <input.h>
dev_t MouseDevID = -1;
bool PacketReady = false;
bool FourPackets = false;
bool MouseButton45 = false;
uint8_t Cycle = 0;
PS2_MOUSE_PACKET Packet = {0};
InputReport mir = {0};
void PS2MouseInterruptHandler(TrapFrame *)
{
uint8_t data = PS2ReadData();
if (data == PS2_MOUSE_RESP_ACK ||
data == PS2_MOUSE_RESP_RESEND)
return;
if (!PacketReady)
{
switch (Cycle)
{
case 0:
{
if ((data & 0b00001000 /* Always 1 */) == 0)
return;
Packet.Base.Raw = data;
Cycle++;
break;
}
case 1:
{
Packet.XMovement = data;
Cycle++;
break;
}
case 2:
{
Packet.YMovement = data;
if (FourPackets)
Cycle++;
else
{
Cycle = 0;
PacketReady = true;
}
break;
}
case 3:
{
Packet.ZMovement.Raw = data;
Cycle = 0;
PacketReady = true;
break;
}
default:
break;
}
return;
}
/* https://stackoverflow.com/a/3208376/9352057 */
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
((byte) & 0x80 ? '1' : '0'), \
((byte) & 0x40 ? '1' : '0'), \
((byte) & 0x20 ? '1' : '0'), \
((byte) & 0x10 ? '1' : '0'), \
((byte) & 0x08 ? '1' : '0'), \
((byte) & 0x04 ? '1' : '0'), \
((byte) & 0x02 ? '1' : '0'), \
((byte) & 0x01 ? '1' : '0')
DebugLog("PS/2 Mouse Packet: [" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN "] LB:%d RB:%d MB:%d A1:%d XS:%d YS:%d XO:%d YO:%d | X:%03d Y:%03d | Z:%d B4:%d B5:%d A0:%d A0:%d",
BYTE_TO_BINARY(Packet.Base.Raw),
BYTE_TO_BINARY(Packet.XMovement),
BYTE_TO_BINARY(Packet.YMovement),
BYTE_TO_BINARY(Packet.ZMovement.Raw),
Packet.Base.LeftButton, Packet.Base.RightButton, Packet.Base.MiddleButton,
Packet.Base.Always1,
Packet.Base.XSign, Packet.Base.YSign,
Packet.Base.XOverflow, Packet.Base.YOverflow,
Packet.XMovement, Packet.YMovement,
Packet.ZMovement.Z, Packet.ZMovement.Button4, Packet.ZMovement.Button5,
Packet.ZMovement.Always0, Packet.ZMovement.Always0_2);
int X, Y;
X = Packet.XMovement - (Packet.Base.XSign ? 256 : 0);
Y = Packet.YMovement - (Packet.Base.YSign ? 256 : 0);
if (Packet.Base.XOverflow)
X = 0;
if (Packet.Base.YOverflow)
Y = 0;
mir.Type = INPUT_TYPE_MOUSE;
mir.Device = MouseDevID;
mir.Mouse.LeftButton = Packet.Base.LeftButton;
mir.Mouse.RightButton = Packet.Base.RightButton;
mir.Mouse.MiddleButton = Packet.Base.MiddleButton;
mir.Mouse.Button4 = Packet.ZMovement.Button4;
mir.Mouse.Button5 = Packet.ZMovement.Button5;
mir.Mouse.X = X;
mir.Mouse.Y = -Y;
mir.Mouse.Z = Packet.ZMovement.Z;
ReportInputEvent(&mir);
PacketReady = false;
}
void MouseSampleRate(uint8_t SampleRate)
{
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_SET_SAMPLE_RATE);
PS2ReadData();
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(SampleRate);
PS2ReadData();
}
int __fs_ms_Ioctl(struct Inode *, unsigned long, void *)
{
return 0;
}
const struct InodeOperations MouseOps = {
.Ioctl = __fs_ms_Ioctl,
};
int InitializeMouse()
{
PS2WriteData(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_RESET);
uint8_t test = PS2ReadData();
if (test != PS2_MOUSE_RESP_TEST_PASSED &&
test != PS2_MOUSE_RESP_ACK)
{
KernelLog("PS/2 mouse reset failed! (%#x)", test);
return -EFAULT;
}
RegisterInterruptHandler(12, PS2MouseInterruptHandler);
MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps);
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS);
PS2ReadData();
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_ENABLE_DATA_REPORTING);
MouseSampleRate(200);
MouseSampleRate(100);
MouseSampleRate(80);
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
uint8_t Device2ID = PS2ReadData();
KernelLog("PS/2 Mouse ID: %#x", Device2ID);
MouseSampleRate(200);
MouseSampleRate(200);
MouseSampleRate(80);
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
Device2ID = PS2ReadData();
KernelLog("PS/2 Mouse ID: %#x", Device2ID);
if (Device2ID >= 3 && Device2ID <= 4)
FourPackets = true;
if (Device2ID == 4)
MouseButton45 = true;
return 0;
}
int FinalizeMouse()
{
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
UnregisterDevice(MouseDevID);
return 0;
}
int DetectPS2Mouse()
{
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
if (PS2ACKTimeout() != 0)
KernelLog("PS/2 mouse failed to disable data reporting!");
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
if (PS2ACKTimeout() != 0)
KernelLog("PS/2 mouse failed to read ID!");
uint8_t recByte;
int timeout = 1000000;
while (timeout--)
{
recByte = PS2ReadData();
if (recByte != PS2_ACK)
break;
}
Device2ID[0] = recByte;
timeout = 1000000;
while (timeout--)
{
recByte = PS2ReadData();
if (recByte != PS2_ACK)
break;
}
Device2ID[1] = recByte;
KernelLog("PS2 Mouse Device: 0x%X 0x%X", Device2ID[0], Device2ID[1]);
return 0;
}

View File

@ -1,646 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include "aip.h"
#include <errno.h>
#include <base.h>
#include <fs.h>
#include <input.h>
#include <io.h>
#define SERIAL_ENABLE_DLAB 0x80
#define SERIAL_BUFFER_EMPTY 0x20
enum Ports
{
COM1 = 0x3F8,
COM2 = 0x2F8,
COM3 = 0x3E8,
COM4 = 0x2E8,
COM5 = 0x5F8,
COM6 = 0x4F8,
COM7 = 0x5E8,
COM8 = 0x4E8,
LPT1 = 0x378,
LPT2 = 0x278,
LPT3 = 0x3BC
};
enum SerialSpeed
{
RATE_50_HI = 0x09,
RATE_50_LO = 0x00,
RATE_300_HI = 0x01,
RATE_300_LO = 0x80,
RATE_600_HI = 0x00,
RATE_600_LO = 0xC0,
RATE_2400_HI = 0x00,
RATE_2400_LO = 0x30,
RATE_4800_HI = 0x00,
RATE_4800_LO = 0x18,
RATE_9600_HI = 0x00,
RATE_9600_LO = 0x0C,
RATE_19200_HI = 0x00,
RATE_19200_LO = 0x06,
RATE_38400_HI = 0x00,
RATE_38400_LO = 0x03,
RATE_57600_HI = 0x00,
RATE_57600_LO = 0x02,
RATE_115200_HI = 0x00,
RATE_115200_LO = 0x01
};
/*
. Table of Registers .
/---------------------------------------------------------------------\
| Base Address | DLAB | R/W | Abr | Register Name |
|---------------------------------------------------------------------|
| +0 | =0 | W | - | Transmitter Holding Buffer |
| | =0 | R | - | Receiver Buffer |
| | =1 | R/W | - | Divisor Latch Low Byte |
| +1 | =0 | R/W | IER | Interrupt Enable Register |
| | =1 | R/W | - | Divisor Latch High Byte |
| +2 | - | R | IIR | Interrupt Identification Register |
| | - | W | FCR | FIFO Control Register |
| +3 | - | R/W | LCR | Line Control Register |
| +4 | - | R/W | MCR | Modem Control Register |
| +5 | - | R | LSR | Line Status Register |
| +6 | - | R | MSR | Modem Status Register |
| +7 | - | R/W | - | Scratch Register |
\---------------------------------------------------------------------/
Source:
Interfacing the Serial / RS232 Port V5.0
Table 5 : Table of Registers
*/
/** Interrupt Enable Register */
typedef union
{
struct
{
/* Enable Received Data Available Interrupt */
uint8_t InterruptOnReceive : 1;
/* Enable Transmitter Holding Register Empty Interrupt */
uint8_t InterruptOnTransmitter : 1;
/* Enable Receiver Line Status Interrupt */
uint8_t LineStatusInterrupt : 1;
/* Enable Modem Status Interrupt */
uint8_t ModemStatusInterrupt : 1;
/* Enables Sleep Mode (16750) */
uint8_t SleepMode : 1;
/* Enables Low Power Mode (16750) */
uint8_t LowPowerMode : 1;
/* Reserved */
uint8_t __reserved : 2;
};
uint8_t raw;
} IER;
/** Interrupt Identification Register */
typedef union
{
struct
{
/* Interrupt pending */
uint8_t InterruptPending : 1;
/**
* Interrupt Status
*
* 00b = Modem Status Interrupt
* 01b = Transmitter Holding Register Empty Interrupt
* 10b = Received Data Available Interrupt
* 11b = Receiver Line Status Interrupt
*/
uint8_t InterruptStatus : 2;
/**
* 16550 Time-out Interrupt Pending
*
* @note Reserved on 8250, 16450
*/
uint8_t TimeOutIP : 1;
/** Reserved */
uint8_t __reserved : 1;
/** 64 Byte Fifo Enabled (16750 only) */
uint8_t FIFO64 : 1;
/**
* Enable FIFO
*
* 00b = No FIFO
* 01b = FIFO Enabled but Unusable
* 11b = FIFO Enabled
*/
uint8_t FIFO : 2;
};
uint8_t raw;
} IIR;
/** First In / First Out Control Register */
typedef union
{
struct
{
/** Enable FIFO's */
uint8_t FIFO : 1;
/** Clear Receive FIFO */
uint8_t ClearRX : 1;
/** Clear Transmit FIFO */
uint8_t ClearTX : 1;
/** DMA Mode Select.
*
* Change status of RXRDY & TXRDY pins from mode 1 to mode 2.
*/
uint8_t DMAMode : 1;
/** Reserved */
uint8_t __reserved : 1;
/** Enable 64 Byte FIFO (16750 only) */
uint8_t FIFO64 : 1;
/** Interrupt Trigger Level
*
* 00b = 1 Byte
* 01b = 4 Bytes
* 10b = 8 Bytes
* 11b = 14 Bytes
*/
uint8_t TriggerLevel : 2;
};
uint8_t raw;
} FCR;
/** Line Control Register */
typedef union
{
struct
{
/** Word Length
*
* 00b = 5 bits
* 01b = 6 bits
* 10b = 7 bits
* 11b = 8 bits
*/
uint8_t WordLength : 2;
/** Length of Stop Bit
*
* 0b = One Stop Bit
* 1b = 2 Stop bits for words of length 6,7 or 8 bits or 1.5 Stop Bits for Word lengths of 5 bits.
*/
uint8_t StopBit : 1;
/** Parity Select
*
* 0b = No Parity
* 001b = Odd Parity
* 011b = Even Parity
* 101b = High Parity (Sticky)
* 111b = Low Parity (Sticky)
*/
uint8_t Parity : 3;
/** Set Break Enable */
uint8_t SetBreak : 1;
/**
* Divisor Latch Access
*
* 0b = Access to Receiver buffer, Transmitter buffer & Interrupt Enable Register
* 1b = Divisor Latch Access Bit
*/
uint8_t DLAB : 1;
};
uint8_t raw;
} LCR;
/** Modem Control Register */
typedef union
{
struct
{
/** Force Data Terminal Ready */
uint8_t DataTerminalReady : 1;
/** Force Request to Send */
uint8_t RequestToSend : 1;
/** Auxiliary Output 1 */
uint8_t Out1 : 1;
/** Auxiliary Output 2 */
uint8_t Out2 : 1;
/** Loopback Mode */
uint8_t Loopback : 1;
/** Autoflow Control Enabled (16750 only) */
uint8_t Autoflow : 1;
/** Reserved */
uint8_t __reserved : 2;
};
uint8_t raw;
} MCR;
/** Line Status Register */
typedef union
{
struct
{
/** Data Ready */
uint8_t DataReady : 1;
/** Overrun Error */
uint8_t OverrunError : 1;
/** Parity Error */
uint8_t ParityError : 1;
/** Framing Error */
uint8_t FramingError : 1;
/** Break Interrupt */
uint8_t BreakInterrupt : 1;
/** Empty Transmitter Holding Register */
uint8_t EmptyTransmitterHolding : 1;
/** Empty Data Holding Registers */
uint8_t EmptyDataHolding : 1;
/** Error in Received FIFO */
uint8_t ErrorReceivedFIFO : 1;
};
uint8_t raw;
} LSR;
/** Modem Status Register */
typedef union
{
struct
{
/** Delta Clear to Send */
uint8_t DeltaClearToSend : 1;
/** Delta Data Set Ready */
uint8_t DeltaDataSetReady : 1;
/** Trailing Edge Ring Indicator */
uint8_t TrailingEdgeRingIndicator : 1;
/** Delta Data Carrier Detect */
uint8_t DeltaDataCarrierDetect : 1;
/** Clear To Send */
uint8_t ClearToSend : 1;
/** Data Set Ready */
uint8_t DataSetReady : 1;
/** Ring Indicator */
uint8_t RingIndicator : 1;
/** Carrier Detect */
uint8_t CarrierDetect : 1;
};
uint8_t raw;
} MSR;
union UARTs
{
struct
{
uint8_t com1 : 1;
uint8_t com2 : 1;
uint8_t com3 : 1;
uint8_t com4 : 1;
uint8_t com5 : 1;
uint8_t com6 : 1;
uint8_t com7 : 1;
uint8_t com8 : 1;
uint8_t lpt1 : 1;
uint8_t lpt2 : 1;
uint8_t lpt3 : 1;
uint8_t __reserved : 5;
};
uint16_t raw;
} uart;
bool IsDataReady(uint16_t Port)
{
LSR lsr;
lsr.raw = inb(Port + 5);
return lsr.DataReady;
}
bool IsTransmitEmpty(uint16_t Port)
{
LSR lsr;
lsr.raw = inb(Port + 5);
return lsr.EmptyTransmitterHolding;
}
char ReadSerial(uint16_t Port)
{
while (!IsDataReady(Port))
Yield();
return inb(Port);
}
void WriteSerial(uint16_t Port, char Character)
{
while (!IsTransmitEmpty(Port))
Yield();
outb(Port, Character);
}
void ReportSerialReceived(uint8_t Data)
{
DebugLog("%c", Data);
}
void UartCOM24(TrapFrame *)
{
LSR lsr2, lsr4;
do
{
lsr2.raw = inb(COM2 + 5);
if (lsr2.DataReady)
ReportSerialReceived(inb(COM2));
lsr4.raw = inb(COM4 + 5);
if (lsr4.DataReady)
ReportSerialReceived(inb(COM4));
} while (lsr2.DataReady || lsr4.DataReady);
}
void UartCOM13(TrapFrame *)
{
LSR lsr1, lsr3;
do
{
lsr1.raw = inb(COM1 + 5);
if (lsr1.DataReady)
ReportSerialReceived(inb(COM1));
lsr3.raw = inb(COM3 + 5);
if (lsr3.DataReady)
ReportSerialReceived(inb(COM3));
} while (lsr1.DataReady || lsr3.DataReady);
}
bool InitializePort(uint16_t Port)
{
ECS;
LCR lcr = {0};
IER ier = {0};
FCR fcr = {0};
MCR mcr = {0};
outb(Port + 3, lcr.raw);
outb(Port + 1, ier.raw);
lcr.DLAB = 1;
outb(Port + 3, lcr.raw);
outb(Port + 0, RATE_115200_LO);
outb(Port + 1, RATE_115200_HI);
lcr.DLAB = 0;
lcr.WordLength = 0b11;
outb(Port + 3, lcr.raw);
fcr.FIFO = 1;
fcr.ClearRX = 1;
fcr.ClearTX = 1;
fcr.TriggerLevel = 0b11;
outb(Port + 2, fcr.raw);
mcr.DataTerminalReady = 1;
mcr.RequestToSend = 1;
mcr.Out2 = 1;
mcr.Loopback = 1;
outb(Port + 4, mcr.raw);
/* Test the serial port */
outb(Port + 0, 0x48);
uint8_t result = inb(Port + 0);
if (result != 0x48)
{
/* FIXME: DETECT BAUD RATE
Do multiple test to check if the output is garbage.
If so, reduce the baud rate until it works. */
LCS;
KernelPrint("Port %#X test failed!", Port);
return false;
}
/* Set normal operation mode */
mcr.DataTerminalReady = 1;
mcr.RequestToSend = 1;
mcr.Out1 = 1;
mcr.Out2 = 1;
mcr.Loopback = 0;
outb(Port + 4, mcr.raw);
/* Enable interrupts on receive */
ier.InterruptOnReceive = 1;
outb(Port + 1, ier.raw);
RegisterInterruptHandler(3, UartCOM24);
RegisterInterruptHandler(4, UartCOM13);
LCS;
KernelPrint("Port %#X initialized", Port);
return true;
}
int DetectUART()
{
uart.com1 = inb(COM1) != 0xFF ? true : false;
uart.com2 = inb(COM2) != 0xFF ? true : false;
uart.com3 = inb(COM3) != 0xFF ? true : false;
uart.com4 = inb(COM4) != 0xFF ? true : false;
uart.com5 = inb(COM5) != 0xFF ? true : false;
uart.com6 = inb(COM6) != 0xFF ? true : false;
uart.com7 = inb(COM7) != 0xFF ? true : false;
uart.com8 = inb(COM8) != 0xFF ? true : false;
uart.lpt1 = inb(LPT1) != 0xFF ? true : false;
uart.lpt2 = inb(LPT2) != 0xFF ? true : false;
uart.lpt3 = inb(LPT3) != 0xFF ? true : false;
if (uart.com1 == true)
if (InitializePort(COM1) == false)
uart.com1 = false;
if (uart.com2 == true)
if (InitializePort(COM2) == false)
uart.com1 = false;
if (uart.com3 == true)
if (InitializePort(COM3) == false)
uart.com1 = false;
if (uart.com4 == true)
if (InitializePort(COM4) == false)
uart.com1 = false;
if (uart.com5 == true)
if (InitializePort(COM5) == false)
uart.com1 = false;
if (uart.com6 == true)
if (InitializePort(COM6) == false)
uart.com1 = false;
if (uart.com7 == true)
if (InitializePort(COM7) == false)
uart.com1 = false;
if (uart.com8 == true)
if (InitializePort(COM8) == false)
uart.com1 = false;
if (uart.lpt1 == true)
KernelPrint("LPT1 is present");
if (uart.lpt2 == true)
KernelPrint("LPT2 is present");
if (uart.lpt3 == true)
KernelPrint("LPT3 is present");
return 0;
}
// static int once = 0;
// static uint8_t com4 = 0xFF;
// if (!once++)
// com4 = inb(0x2E8);
// if (com4 == 0xFF)
// CPU::Halt(true);
// char UserInputBuffer[256]{'\0'};
// int BackSpaceLimit = 0;
// while (true)
// {
// while ((inb(0x2E8 + 5) & 1) == 0)
// CPU::Pause();
// char key = inb(0x2E8);
// // debug("key: %d", key);
// if (key == '\x7f') /* Backspace (DEL) */
// {
// if (BackSpaceLimit <= 0)
// continue;
// char keyBuf[5] = {'\b', '\x1b', '[', 'K', '\0'};
// ExPrint(keyBuf);
// backspace(UserInputBuffer);
// BackSpaceLimit--;
// continue;
// }
// else if (key == '\x0d') /* Enter (CR) */
// {
// UserInput(UserInputBuffer);
// BackSpaceLimit = 0;
// UserInputBuffer[0] = '\0';
// continue;
// }
// else if (key == '\x1b') /* Escape */
// {
// char tmp[16]{'\0'};
// append(tmp, key);
// while ((inb(0x2E8 + 5) & 1) == 0)
// CPU::Pause();
// char key = inb(0x2E8);
// append(tmp, key);
// if (key == '[')
// {
// // 27 91
// // < 68
// // > 67
// // down 66
// // up 65
// while ((inb(0x2E8 + 5) & 1) == 0)
// CPU::Pause();
// key = inb(0x2E8);
// append(tmp, key);
// switch (key)
// {
// case 'A':
// key = KEY_D_UP;
// break;
// case 'B':
// key = KEY_D_DOWN;
// break;
// case 'C':
// key = KEY_D_RIGHT;
// break;
// case 'D':
// key = KEY_D_LEFT;
// break;
// default:
// {
// for (size_t i = 0; i < strlen(tmp); i++)
// {
// if ((int)sizeof(UserInputBuffer) <= BackSpaceLimit)
// continue;
// append(UserInputBuffer, tmp[i]);
// BackSpaceLimit++;
// char keyBuf[2] = {(char)tmp[i], '\0'};
// ExPrint(keyBuf);
// }
// continue;
// }
// }
// ArrowInput(key);
// continue;
// }
// }
// if ((int)sizeof(UserInputBuffer) <= BackSpaceLimit)
// continue;
// append(UserInputBuffer, key);
// BackSpaceLimit++;
// char keyBuf[2] = {(char)key, '\0'};
// ExPrint(keyBuf);
// }

View File

@ -36,7 +36,15 @@ CFLAGS += -pipe -fno-builtin -fPIC
endif endif
CRT_CFLAGS := -fPIC -fPIE -pie -mno-red-zone -std=c++20 -I$(INCLUDE_DIR) CRT_CFLAGS := -fPIC -fPIE -pie -std=c++20 -I$(INCLUDE_DIR)
ifeq ($(OSARCH), amd64)
CRT_CFLAGS += -mno-red-zone
else ifeq ($(OSARCH), i386)
CRT_CFLAGS += -mno-red-zone
else ifeq ($(OSARCH), aarch64)
CRT_CFLAGS +=
endif
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage

View File

@ -73,7 +73,11 @@ DefineFunction(void, KernelPrint, const char *format, ...)
{ {
__builtin_va_list args; __builtin_va_list args;
__builtin_va_start(args, format); __builtin_va_start(args, format);
#if defined(__amd64__) || defined(__i386__)
__KernelPrint(DriverID, (long)format, (long)args); __KernelPrint(DriverID, (long)format, (long)args);
#elif defined(__aarch64__)
__KernelPrint(DriverID, (long)format, (long)__builtin_va_arg(args, void *));
#endif
__builtin_va_end(args); __builtin_va_end(args);
} }
@ -81,7 +85,11 @@ DefineFunction(void, KernelLog, const char *format, ...)
{ {
__builtin_va_list args; __builtin_va_list args;
__builtin_va_start(args, format); __builtin_va_start(args, format);
#if defined(__amd64__) || defined(__i386__)
__KernelLog(DriverID, (long)format, (long)args); __KernelLog(DriverID, (long)format, (long)args);
#elif defined(__aarch64__)
__KernelLog(DriverID, (long)format, (long)__builtin_va_arg(args, void *));
#endif
__builtin_va_end(args); __builtin_va_end(args);
} }

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,878 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <driver.h>
#include <errno.h>
#include <fs.h>
#include <input.h>
#include <regs.h>
#include <base.h>
#include <aip.h>
#include <io.h>
enum RPCMessages
{
MSG_OPEN,
MSG_SENDSIZE,
MSG_SENDPAYLOAD,
MSG_RECVSIZE,
MSG_RECVPAYLOAD,
MSG_RECVSTATUS,
MSG_CLOSE,
};
enum RPCStatus
{
STATUS_SUCCESS = 0x1,
STATUS_DORECV = 0x2,
STATUS_CPT = 0x10,
STATUS_HB = 0x80,
};
typedef struct
{
union
{
uint32_t ax;
uint32_t magic;
};
union
{
uint32_t bx;
size_t size;
};
union
{
uint32_t cx;
uint16_t command;
};
union
{
uint32_t dx;
uint16_t port;
};
uint32_t si;
uint32_t di;
} VMwareCommand;
#define VMWARE_MAGIC 0x564D5868
#define VMWARE_PORT 0x5658
#define VMWARE_PORTHB 0x5659
#define VMWARE_HYPERVISOR_HB 0x00000000
#define VMWARE_HYPERVISOR_OUT 0x00000001
#define CMD_GETVERSION 0xA
#define CMD_MESSAGE 0x1E
#define CMD_ABSPOINTER_DATA 0x27
#define CMD_ABSPOINTER_STATUS 0x28
#define CMD_ABSPOINTER_COMMAND 0x29
#define ABSPOINTER_ENABLE 0x45414552
#define ABSPOINTER_RELATIVE 0xF5
#define ABSPOINTER_ABSOLUTE 0x53424152
#define MESSAGE_RPCI 0x49435052
#define MESSAGE_TCLO 0x4f4c4354
#define FLAG_COOKIE 0x80000000
#define ToMsg(x) ((x) << 16 | CMD_MESSAGE)
#define HighWord(x) ((x & 0xFFFF0000) >> 16)
#define MESSAGE_HB_MSG 0
#define MESSAGE_OPEN_CHANNEL ToMsg(MSG_OPEN)
#define MESSAGE_CLOSE_CHANNEL ToMsg(MSG_CLOSE)
#define MESSAGE_SEND_SIZE ToMsg(MSG_SENDSIZE)
#define MESSAGE_SEND_PAYLOAD ToMsg(MSG_SENDPAYLOAD)
#define MESSAGE_RECV_SIZE ToMsg(MSG_RECVSIZE)
#define MESSAGE_RECV_PAYLOAD ToMsg(MSG_RECVPAYLOAD)
#define MESSAGE_RECV_STATUS ToMsg(MSG_RECVSTATUS)
#define VM_PORT(cmd, in_ebx, isi, idi, \
flags, magic, \
ax, bx, cx, dx, si, di) \
__asm__ __volatile__("movw $0x5658, %%dx\n" \
"inl %%dx, %%eax\n" \
: "=a"(ax), \
"=b"(bx), \
"=c"(cx), \
"=d"(dx), \
"=S"(si), \
"=D"(di) \
: "a"(magic), \
"b"(in_ebx), \
"c"(cmd), \
"d"(flags), \
"S"(isi), \
"D"(idi) : "memory")
#define VM_PORT_HB_OUT(cmd, in_ecx, isi, idi, \
flags, magic, bp, \
ax, bx, cx, dx, si, di) \
__asm__ __volatile__("push %%rbp\n" \
"mov %12, %%rbp\n" \
"movw $0x5659, %%dx\n" \
"rep outsb\n" \
"pop %%rbp\n" \
: "=a"(ax), \
"=b"(bx), \
"=c"(cx), \
"=d"(dx), \
"=S"(si), \
"=D"(di) \
: "a"(magic), \
"b"(cmd), \
"c"(in_ecx), \
"d"(flags), \
"S"(isi), \
"D"(idi), \
"r"(bp) : "memory", "cc")
#define VM_PORT_HB_IN(cmd, in_ecx, isi, idi, \
flags, magic, bp, \
ax, bx, cx, dx, si, di) \
__asm__ __volatile__("push %%rbp\n" \
"mov %12, %%rbp\n" \
"movw $0x5659, %%dx\n" \
"rep insb\n" \
"pop %%rbp\n" \
: "=a"(ax), \
"=b"(bx), \
"=c"(cx), \
"=d"(dx), \
"=S"(si), \
"=D"(di) \
: "a"(magic), \
"b"(cmd), \
"c"(in_ecx), \
"d"(flags), \
"S"(isi), \
"D"(idi), \
"r"(bp) : "memory", "cc")
/* TODO:
- use vmcall or vmmcall instead of "out" and "in" if available
*/
typedef struct
{
int TCLOChannel;
uint16_t ChannelID;
uint32_t CookieHigh;
uint32_t CookieLow;
} ToolboxContext;
dev_t MouseDevID = -1;
int __strcmp(const char *l, const char *r)
{
for (; *l == *r && *l; l++, r++)
;
return *(unsigned char *)l - *(unsigned char *)r;
}
void __cpuid(uint32_t Function,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
asmv("cpuid"
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
: "a"(Function));
}
bool __CheckHypervisorBit()
{
uint32_t eax, ebx, ecx, edx;
__cpuid(0x1, &eax, &ebx, &ecx, &edx);
if (!(ecx & (1 << 31)))
return false; /* Hypervisor not detected */
return true;
}
bool __VMwareBackdoorHypervisors()
{
const char hv[13] = {0};
uint32_t eax, ebx, ecx, edx;
__cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
*(uint32_t *)hv = ebx;
*(uint32_t *)(hv + 4) = ecx;
*(uint32_t *)(hv + 8) = edx;
if (__strcmp(hv, "VMwareVMware") != 0 &&
__strcmp(hv, "KVMKVMKVM") != 0 &&
__strcmp(hv, "TCGTCGTCGTCG") != 0)
{
return false;
}
return true;
}
bool IsVMwareBackdoorAvailable()
{
if (!__CheckHypervisorBit())
return false;
if (!__VMwareBackdoorHypervisors())
return false;
struct
{
union
{
uint32_t ax;
uint32_t magic;
};
union
{
uint32_t bx;
size_t size;
};
union
{
uint32_t cx;
uint16_t command;
};
union
{
uint32_t dx;
uint16_t port;
};
uint32_t si;
uint32_t di;
} cmd;
cmd.si = cmd.di = 0;
cmd.bx = ~0x564D5868;
cmd.command = 0xA;
cmd.magic = 0x564D5868;
cmd.port = 0x5658;
asmv("in %%dx, %0"
: "+a"(cmd.ax), "+b"(cmd.bx),
"+c"(cmd.cx), "+d"(cmd.dx),
"+S"(cmd.si), "+D"(cmd.di));
if (cmd.bx != 0x564D5868 ||
cmd.ax == 0xFFFFFFFF)
return false;
return true;
}
static int OpenMessageChannel(ToolboxContext *ctx, uint32_t Protocol)
{
uintptr_t ax, bx, cx, dx, si = 0, di = 0;
VM_PORT(MESSAGE_OPEN_CHANNEL,
(Protocol | FLAG_COOKIE), si, di,
0, VMWARE_MAGIC,
ax, bx, cx, dx, si, di);
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
{
KernelLog("Failed to open message channel %#lx", Protocol);
return -EINVAL;
}
DebugLog("Opened message channel %d (Protocol: %#lx)",
HighWord(dx), Protocol);
ctx->ChannelID = (uint16_t)HighWord(dx);
ctx->CookieHigh = si;
ctx->CookieLow = di;
return 0;
}
static void MessageClose(ToolboxContext *ctx)
{
uintptr_t ax, bx, cx, dx,
si = ctx->CookieHigh,
di = ctx->CookieLow;
VM_PORT(MESSAGE_CLOSE_CHANNEL,
0, si, di,
ctx->ChannelID << 16,
VMWARE_MAGIC,
ax, bx, cx, dx, si, di);
DebugLog("Closed message channel %d", ctx->ChannelID);
}
static uintptr_t MessageSendHB(ToolboxContext *ctx,
const char *Message)
{
uintptr_t ax, bx, cx, dx,
si = (uintptr_t)Message,
di = ctx->CookieLow,
bp = ctx->CookieHigh;
uint32_t ChannelID = ctx->ChannelID << 16;
size_t Size = StringLength(Message);
VM_PORT_HB_OUT((STATUS_SUCCESS << 16) | MESSAGE_HB_MSG,
Size, si, di,
VMWARE_HYPERVISOR_HB | ChannelID | VMWARE_HYPERVISOR_OUT,
VMWARE_MAGIC, bp,
ax, bx, cx, dx, si, di);
return bx;
}
static uintptr_t MessageSendLB(ToolboxContext *ctx,
const char *Message)
{
uintptr_t ax, bx,
cx = STATUS_SUCCESS << 16,
dx, si, di;
size_t Size = StringLength(Message);
while (Size &&
(HighWord(cx) & STATUS_SUCCESS))
{
uint32_t TotalBytes = MIN((uint32_t)Size, (uint32_t)4);
uint32_t Word = 0;
MemoryCopy(&Word, Message, TotalBytes);
Message += TotalBytes;
si = ctx->CookieHigh;
di = ctx->CookieLow;
VM_PORT(MESSAGE_SEND_PAYLOAD,
Word, si, di,
ctx->ChannelID << 16,
VMWARE_MAGIC,
ax, bx, cx, dx, si, di);
}
return cx;
}
static uintptr_t MessageReceiveHB(ToolboxContext *ctx,
char *Buffer,
size_t BufferSize)
{
uintptr_t ax, bx, cx, dx,
si = ctx->CookieHigh,
di = (uintptr_t)Buffer,
bp = ctx->CookieLow;
uint32_t ChannelID = ctx->ChannelID << 16;
VM_PORT_HB_IN((STATUS_SUCCESS << 16) | MESSAGE_HB_MSG,
BufferSize, si, di,
VMWARE_HYPERVISOR_HB | ChannelID | VMWARE_HYPERVISOR_OUT,
VMWARE_MAGIC, bp,
ax, bx, cx, dx, si, di);
return bx;
}
static uintptr_t MessageReceiveLB(ToolboxContext *ctx,
char *Buffer,
size_t BufferSize)
{
uintptr_t ax, bx,
cx = STATUS_SUCCESS << 16,
dx, si, di;
while (BufferSize)
{
uint32_t TotalBytes = MIN((uint32_t)BufferSize, (uint32_t)4);
si = ctx->CookieHigh;
di = ctx->CookieLow;
VM_PORT(MESSAGE_RECV_PAYLOAD,
STATUS_SUCCESS, si, di,
ctx->ChannelID << 16,
VMWARE_MAGIC,
ax, bx, cx, dx, si, di);
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
break;
MemoryCopy(Buffer, &bx, TotalBytes);
Buffer += TotalBytes;
BufferSize -= TotalBytes;
}
return cx;
}
static int MessageSend(ToolboxContext *ctx,
const char *Message)
{
uintptr_t ax, bx, cx, dx, si, di;
size_t Size = StringLength(Message);
int Retries = 0;
while (Retries < 2)
{
Retries++;
si = ctx->CookieHigh;
di = ctx->CookieLow;
VM_PORT(MESSAGE_SEND_SIZE,
Size, si, di,
ctx->ChannelID << 16,
VMWARE_MAGIC,
ax, bx, cx, dx, si, di);
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
{
KernelLog("Failed to send message size for \"%s\": %d",
Message, cx);
return -EINVAL;
}
bool HighBand = (HighWord(cx) & STATUS_HB) != 0;
if (HighBand)
bx = MessageSendHB(ctx, Message);
else
bx = MessageSendLB(ctx, Message);
int status = HighWord(bx);
if ((status & STATUS_SUCCESS) != 0)
{
DebugLog("Message \"%s\" sent", Message);
return 0;
}
else if ((status & STATUS_CPT) == 0)
{
KernelLog("Checkpoint occurred for message \"%s\"", Message);
continue;
}
else
break;
}
KernelLog("Failed to send message \"%s\": %#lx", Message, bx);
return -EINVAL;
}
static int MessageReceive(ToolboxContext *ctx,
char **Buffer,
size_t *BufferSize)
{
uintptr_t ax, bx, cx, dx, si, di;
int Retries = 0;
*Buffer = NULL;
*BufferSize = 0;
char *ReplyBuf = NULL;
size_t ReplyBufPages = 0;
size_t ReplySize = 0;
while (Retries < 2)
{
Retries++;
si = ctx->CookieHigh;
di = ctx->CookieLow;
VM_PORT(MESSAGE_RECV_SIZE,
0, si, di,
ctx->ChannelID << 16,
VMWARE_MAGIC,
ax, bx, cx, dx, si, di);
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
{
KernelLog("Failed to receive message size: %d", cx);
return -EINVAL;
}
else if ((HighWord(cx) & STATUS_DORECV) == 0)
{
DebugLog("No message to receive");
return -EAGAIN;
}
ReplySize = bx;
if (ReplyBuf != NULL)
FreeMemory(ReplyBuf, ReplyBufPages);
ReplyBufPages = ReplySize / 0x1000 + 1;
ReplyBuf = AllocateMemory(ReplyBufPages);
bool HighBand = (HighWord(cx) & STATUS_HB) != 0;
if (HighBand)
bx = MessageReceiveHB(ctx, ReplyBuf, ReplySize);
else
bx = MessageReceiveLB(ctx, ReplyBuf, ReplySize);
if ((HighWord(bx) & STATUS_SUCCESS) == 0)
{
if ((HighWord(bx) & STATUS_CPT) == 0)
{
KernelLog("Checkpoint occurred for message payload");
continue;
}
KernelLog("Failed to receive message payload: %d", HighWord(bx));
FreeMemory(ReplyBuf, ReplyBufPages);
return -EINVAL;
}
ReplyBuf[ReplySize] = '\0';
si = ctx->CookieHigh;
di = ctx->CookieLow;
VM_PORT(MESSAGE_RECV_STATUS,
STATUS_SUCCESS, si, di,
ctx->ChannelID << 16,
VMWARE_MAGIC,
ax, bx, cx, dx, si, di);
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
{
if ((HighWord(cx) & STATUS_CPT) == 0)
{
KernelLog("Retrying message receive");
continue;
}
KernelLog("Failed to receive message status: %d", HighWord(cx));
FreeMemory(ReplyBuf, ReplyBufPages);
return -EINVAL;
}
break;
}
if (ReplyBuf == NULL)
{
KernelLog("Failed to receive message");
return -EINVAL;
}
*Buffer = ReplyBuf;
*BufferSize = ReplySize;
DebugLog("Received message \"%s\"", ReplyBuf);
return 0;
}
static int SendRPCI(ToolboxContext *, const char *Request)
{
ToolboxContext rpci_ctx = {0};
int status = OpenMessageChannel(&rpci_ctx, MESSAGE_RPCI);
if (status < 0)
{
KernelLog("Failed to open RPCI channel: %d", status);
return status;
}
status = MessageSend(&rpci_ctx, Request);
if (status < 0)
{
KernelLog("Failed to send RPCI request: %d", status);
return status;
}
MessageClose(&rpci_ctx);
return 0;
}
int MsgEqual(const char *haystack, const char *needle)
{
return strstr(haystack, needle) == haystack;
}
static int DisplayGetSize(ToolboxContext *ctx)
{
if (ctx->TCLOChannel != -1)
MessageClose(ctx);
OpenMessageChannel(ctx, MESSAGE_TCLO);
char EmptyBuffer[256] = {'\0'};
MessageSend(ctx, EmptyBuffer);
while (true)
{
/* FIXME: buf memory leak */
char *buf;
size_t len;
int status = MessageReceive(ctx, &buf, &len);
if (status == -EAGAIN)
{
Sleep(1000);
continue;
}
else if (status < 0)
{
KernelLog("Failed to receive message");
return 1;
}
buf[StringLength(buf)] = '\0';
if (MsgEqual(buf, "reset"))
{
if (MessageSend(ctx, "OK ATR toolbox") < 0)
return 1;
}
else if (MsgEqual(buf, "ping"))
{
if (MessageSend(ctx, "OK ") < 0)
return 1;
}
else if (MsgEqual(buf, "Capabilities_Register"))
{
SendRPCI(ctx, "tools.capability.resolution_set 1");
SendRPCI(ctx, "tools.capability.resolution_server toolbox 1");
SendRPCI(ctx, "tools.capability.display_topology_set 1");
SendRPCI(ctx, "tools.capability.color_depth_set 1");
SendRPCI(ctx, "tools.capability.resolution_min 0 0");
SendRPCI(ctx, "tools.capability.unity 1");
if (MessageSend(ctx, "OK ") < 0)
return 1;
}
else if (MsgEqual(buf, "Resolution_Set"))
{
DebugLog("%s", buf);
if (MessageSend(ctx, "OK ") < 0)
return 1;
MessageClose(ctx);
return 0;
}
else
{
if (MessageSend(ctx, "ERROR Unknown command") < 0)
return 1;
}
}
}
pid_t dst_id = -1;
pid_t dst_pid = -1;
ToolboxContext *tb_ctx = NULL;
void DisplayScaleThread()
{
/* sizeof ToolboxContext */
tb_ctx = AllocateMemory(1);
Sleep(2000);
while (true)
{
if (DisplayGetSize(tb_ctx) != 0)
KernelLog("Failed to scale display");
Sleep(1000);
}
}
void CommandSend(VMwareCommand *cmd)
{
cmd->magic = VMWARE_MAGIC;
cmd->port = VMWARE_PORT;
asm volatile("in %%dx, %0"
: "+a"(cmd->ax), "+b"(cmd->bx),
"+c"(cmd->cx), "+d"(cmd->dx),
"+S"(cmd->si), "+D"(cmd->di));
}
void Absolute()
{
VMwareCommand cmd = {0};
/* Enable */
cmd.bx = ABSPOINTER_ENABLE;
cmd.command = CMD_ABSPOINTER_COMMAND;
CommandSend(&cmd);
/* Status */
cmd.bx = 0;
cmd.command = CMD_ABSPOINTER_STATUS;
CommandSend(&cmd);
/* Read data (1) */
cmd.bx = 1;
cmd.command = CMD_ABSPOINTER_DATA;
CommandSend(&cmd);
/* Enable absolute */
cmd.bx = ABSPOINTER_ABSOLUTE;
cmd.command = CMD_ABSPOINTER_COMMAND;
CommandSend(&cmd);
}
void Relative()
{
VMwareCommand cmd = {0};
cmd.bx = ABSPOINTER_RELATIVE;
cmd.command = CMD_ABSPOINTER_COMMAND;
CommandSend(&cmd);
}
InputReport ir = {0};
void InterruptHandler(TrapFrame *)
{
uint8_t Data = inb(0x60);
(void)Data;
VMwareCommand cmd = {0};
cmd.bx = 0;
cmd.command = CMD_ABSPOINTER_STATUS;
CommandSend(&cmd);
if (cmd.ax == 0xFFFF0000)
{
KernelLog("VMware mouse is not connected?");
Relative();
Absolute();
return;
}
if ((cmd.ax & 0xFFFF) < 4)
return;
cmd.bx = 4;
cmd.command = CMD_ABSPOINTER_DATA;
CommandSend(&cmd);
int Buttons = (cmd.ax & 0xFFFF);
/**
* How should I handle this?
* (cmd.[bx,cx] * Width) / 0xFFFF
* Maybe TODO: Width and Height API?
*/
uintptr_t AbsoluteX = cmd.bx;
uintptr_t AbsoluteY = cmd.cx;
ir.Type = INPUT_TYPE_MOUSE;
ir.Device = MouseDevID;
ir.Mouse.X = AbsoluteX;
ir.Mouse.Y = AbsoluteY;
ir.Mouse.Z = (int8_t)cmd.dx;
ir.Mouse.Absolute = 1;
ir.Mouse.LeftButton = Buttons & 0x20;
ir.Mouse.RightButton = Buttons & 0x10;
ir.Mouse.MiddleButton = Buttons & 0x08;
// ir.Mouse.Button4 = 0x0;
// ir.Mouse.Button5 = 0x0;
// ir.Mouse.Button6 = 0x0;
// ir.Mouse.Button7 = 0x0;
// ir.Mouse.Button8 = 0x0;
ReportInputEvent(&ir);
}
int __fs_Ioctl(struct Inode *, unsigned long Request, void *)
{
switch (Request)
{
case 0x1:
Relative();
break;
case 0x2:
Absolute();
break;
default:
return -EINVAL;
}
return 0;
}
const struct InodeOperations MouseOps = {
.Ioctl = __fs_Ioctl,
};
bool ToolboxSupported = false;
int DriverEntry()
{
ToolboxContext tb_ctx = {0};
/* Test if it's supported */
int status = OpenMessageChannel(&tb_ctx, MESSAGE_TCLO);
if (status == 0)
{
ToolboxSupported = true;
MessageClose(&tb_ctx);
dst_id = CreateKernelThread(0, "VMware Display Scale",
(void *)DisplayScaleThread, NULL);
dst_pid = GetCurrentProcess();
}
PS2WriteCommand(PS2_CMD_ENABLE_PORT_2);
PS2WriteCommand(PS2_CMD_READ_CONFIG);
PS2_CONFIGURATION config = {.Raw = PS2ReadData()};
config.Port2Interrupt = 1;
PS2WriteCommand(PS2_CMD_WRITE_CONFIG);
PS2WriteData(config.Raw);
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS);
PS2ReadData();
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_ENABLE_DATA_REPORTING);
PS2ReadData();
Absolute();
/**
* If we have another driver using the PS/2 mouse, we need to
* override its interrupt handler.
*/
OverrideInterruptHandler(12, InterruptHandler);
MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps);
return 0;
}
int DriverFinal()
{
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
Relative();
UnregisterDevice(MouseDevID);
if (ToolboxSupported)
{
KillThread(dst_id, dst_pid, 0);
if (tb_ctx->TCLOChannel != -1)
MessageClose(tb_ctx);
FreeMemory(tb_ctx, 1);
}
return 0;
}
int DriverPanic()
{
Relative();
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
return 0;
}
int DriverProbe()
{
if (!IsVMwareBackdoorAvailable())
return -ENODEV;
return 0;
}
DriverInfo("vmware",
"VMware Tools Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,512 +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 <netools.h>
#include <errno.h>
#include <regs.h>
#include <base.h>
#include <pci.h>
#include <network.h>
#include <io.h>
#include "e1000.hpp"
class E1000Device
{
private:
PCIHeader0 *Header;
uint16_t DeviceID;
bool Initialized = false;
bool EEPROMAvailable;
struct BARData
{
uint8_t Type;
uint16_t IOBase;
uint64_t MemoryBase;
} BAR;
#define E1000_NUM_RX_DESC 32
#define E1000_NUM_TX_DESC 8
RXDescriptor *RX[E1000_NUM_RX_DESC];
TXDescriptor *TX[E1000_NUM_TX_DESC];
uint16_t RXCurrent;
uint16_t TXCurrent;
const int BaseBufferSize = 8192;
const int AdditionalBytes = 16;
uint32_t CurrentPacket;
void WriteCMD(uint16_t Address, uint32_t Value)
{
if (BAR.Type == 0)
mmoutl((void *)(BAR.MemoryBase + Address), Value);
else
{
outl(BAR.IOBase, Address);
outl(BAR.IOBase + 4, Value);
}
}
uint32_t ReadCMD(uint16_t Address)
{
if (BAR.Type == 0)
return mminl((void *)(BAR.MemoryBase + Address));
else
{
outl(BAR.IOBase, Address);
return inl(BAR.IOBase + 0x4);
}
}
uint32_t ReadEEPROM(uint8_t Address)
{
uint16_t Data = 0;
uint32_t temp = 0;
if (EEPROMAvailable)
{
WriteCMD(REG::EEPROM, (1) | ((uint32_t)(Address) << 8));
while (!((temp = ReadCMD(REG::EEPROM)) & (1 << 4)))
;
}
else
{
WriteCMD(REG::EEPROM, (1) | ((uint32_t)(Address) << 2));
while (!((temp = ReadCMD(REG::EEPROM)) & (1 << 1)))
;
}
Data = (uint16_t)((temp >> 16) & 0xFFFF);
return Data;
}
void InitializeRX()
{
DebugLog("Initializing RX...");
uintptr_t Ptr = (uintptr_t)AllocateMemory(TO_PAGES(sizeof(RXDescriptor) *
E1000_NUM_RX_DESC +
AdditionalBytes));
for (int i = 0; i < E1000_NUM_RX_DESC; i++)
{
RX[i] = (RXDescriptor *)(Ptr + i * 16);
RX[i]->Address = (uint64_t)AllocateMemory(TO_PAGES(BaseBufferSize + AdditionalBytes));
RX[i]->Status = 0;
}
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
WriteCMD(REG::TXDESCLO, (uint32_t)(Ptr >> 32));
WriteCMD(REG::TXDESCHI, (uint32_t)(Ptr & 0xFFFFFFFF));
WriteCMD(REG::RXDESCLO, (uint32_t)Ptr);
WriteCMD(REG::RXDESCHI, 0);
WriteCMD(REG::RXDESCLEN, E1000_NUM_RX_DESC * 16);
WriteCMD(REG::RXDESCHEAD, 0);
WriteCMD(REG::RXDESCTAIL, E1000_NUM_RX_DESC - 1);
RXCurrent = 0;
WriteCMD(REG::RCTRL, RCTL::EN | RCTL::SBP | RCTL::UPE |
RCTL::MPE | RCTL::LBM_NONE |
RTCL::RDMTS_HALF | RCTL::BAM |
RCTL::SECRC | RCTL::BSIZE_8192);
}
void InitializeTX()
{
DebugLog("Initializing TX...");
uintptr_t Ptr = (uintptr_t)AllocateMemory(TO_PAGES(sizeof(TXDescriptor) *
E1000_NUM_RX_DESC +
AdditionalBytes));
for (short i = 0; i < E1000_NUM_TX_DESC; i++)
{
TX[i] = (TXDescriptor *)((uintptr_t)Ptr + i * 16);
TX[i]->Address = 0;
TX[i]->Command = 0;
TX[i]->Status = TSTA::DD;
}
WriteCMD(REG::TXDESCHI, (uint32_t)((uint64_t)Ptr >> 32));
WriteCMD(REG::TXDESCLO, (uint32_t)((uint64_t)Ptr & 0xFFFFFFFF));
WriteCMD(REG::TXDESCLEN, E1000_NUM_TX_DESC * 16);
WriteCMD(REG::TXDESCHEAD, 0);
WriteCMD(REG::TXDESCTAIL, 0);
TXCurrent = 0;
WriteCMD(REG::TCTRL, TCTL::EN_ | TCTL::PSP |
(15 << TCTL::CT_SHIFT) |
(64 << TCTL::COLD_SHIFT) |
TCTL::RTLC);
WriteCMD(REG::TCTRL, 0b0110000000000111111000011111010);
WriteCMD(REG::TIPG, 0x0060200A);
}
public:
dev_t ID;
bool IsInitialized() { return Initialized; }
size_t write(uint8_t *Buffer, size_t Size)
{
TX[TXCurrent]->Address = (uint64_t)Buffer;
TX[TXCurrent]->Length = (uint16_t)Size;
TX[TXCurrent]->Command = CMD::EOP | CMD::IFCS | CMD::RS;
TX[TXCurrent]->Status = 0;
uint16_t OldTXCurrent = TXCurrent;
TXCurrent = (uint16_t)((TXCurrent + 1) % E1000_NUM_TX_DESC);
WriteCMD(REG::TXDESCTAIL, TXCurrent);
while (!(TX[OldTXCurrent]->Status & 0xFF))
Yield();
return Size;
}
MediaAccessControl GetMAC()
{
MediaAccessControl mac;
if (EEPROMAvailable)
{
uint32_t temp;
temp = ReadEEPROM(0);
mac.Address[0] = temp & 0xff;
mac.Address[1] = (uint8_t)(temp >> 8);
temp = ReadEEPROM(1);
mac.Address[2] = temp & 0xff;
mac.Address[3] = (uint8_t)(temp >> 8);
temp = ReadEEPROM(2);
mac.Address[4] = temp & 0xff;
mac.Address[5] = (uint8_t)(temp >> 8);
}
else
{
uint8_t *BaseMac8 = (uint8_t *)(BAR.MemoryBase + 0x5400);
uint32_t *BaseMac32 = (uint32_t *)(BAR.MemoryBase + 0x5400);
if (BaseMac32[0] != 0)
for (int i = 0; i < 6; i++)
mac.Address[i] = BaseMac8[i];
else
{
KernelLog("No MAC address found.");
return MediaAccessControl();
}
}
return mac;
}
int ioctl(NetIoctl req, void *arg)
{
switch (req)
{
case IOCTL_NET_GET_MAC:
{
MediaAccessControl mac = GetMAC();
*((uint48_t *)arg) = mac.ToHex(); /* UNTESTED */
return 0;
}
default:
return -EINVAL;
}
return 0;
}
void OnInterruptReceived(TrapFrame *)
{
WriteCMD(REG::IMASK, 0x1);
uint32_t status = ReadCMD(0xC0);
UNUSED(status);
while ((RX[RXCurrent]->Status & 0x1))
{
uint8_t *data = (uint8_t *)RX[RXCurrent]->Address;
uint16_t dataSz = RX[RXCurrent]->Length;
// ReportNetworkPacket(ID, data, dataSz);
/* FIXME: Implement */
KernelLog("FIXME: Received packet");
(void)data;
(void)dataSz;
RX[RXCurrent]->Status = 0;
uint16_t OldRXCurrent = RXCurrent;
RXCurrent = (uint16_t)((RXCurrent + 1) % E1000_NUM_RX_DESC);
WriteCMD(REG::RXDESCTAIL, OldRXCurrent);
}
}
void Panic()
{
WriteCMD(REG::IMASK, 0x00000000);
WriteCMD(REG::ITR, 0x00000000);
WriteCMD(REG::IAM, 0x00000000);
}
E1000Device(PCIHeader0 *_Header, uint16_t _DeviceID)
: Header(_Header),
DeviceID(_DeviceID)
{
uint32_t PCIBAR0 = Header->BAR0;
uint32_t PCIBAR1 = Header->BAR1;
BAR.Type = PCIBAR0 & 1;
BAR.IOBase = (uint16_t)(PCIBAR0 & (~3));
BAR.MemoryBase = PCIBAR1 & (~15);
switch (DeviceID)
{
case 0x100E:
{
KernelLog("Found Intel 82540EM Gigabit Ethernet Controller.");
/* Detect EEPROM */
WriteCMD(REG::EEPROM, 0x1);
for (int i = 0; i < 1000 && !EEPROMAvailable; i++)
if (ReadCMD(REG::EEPROM) & 0x10)
EEPROMAvailable = true;
else
EEPROMAvailable = false;
if (!GetMAC().Valid())
{
KernelLog("Failed to get MAC");
return;
}
/* Start link */
uint32_t cmdret = ReadCMD(REG::CTRL);
WriteCMD(REG::CTRL, cmdret | ECTRL::SLU);
for (int i = 0; i < 0x80; i++)
WriteCMD((uint16_t)(0x5200 + i * 4), 0);
WriteCMD(REG::IMASK, 0x1F6DC);
WriteCMD(REG::IMASK, 0xFF & ~4);
ReadCMD(0xC0);
InitializeRX();
InitializeTX();
break;
}
default:
{
KernelLog("Unimplemented E1000 device.");
return;
}
}
Initialized = true;
}
~E1000Device()
{
if (!Initialized)
return;
switch (DeviceID)
{
case 0x100E:
{
// Clearing Enable bit in Receive Control Register
uint32_t cmdret = ReadCMD(REG::RCTRL);
WriteCMD(REG::RCTRL, cmdret & ~RCTL::EN);
// Masking Interrupt Mask, Interrupt Throttling Rate & Interrupt Auto-Mask
WriteCMD(REG::IMASK, 0x00000000);
WriteCMD(REG::ITR, 0x00000000);
WriteCMD(REG::IAM, 0x00000000);
// Clearing SLU bit in Device Control Register
cmdret = ReadCMD(REG::CTRL);
WriteCMD(REG::CTRL, cmdret & ~ECTRL::SLU);
// Clear the Interrupt Cause Read register by reading it
ReadCMD(REG::ICR);
// Powering down the device (?)
WriteCMD(REG::CTRL, PCTRL::POWER_DOWN);
/* TODO: Stop link; further testing required */
break;
}
default:
{
KernelLog("Unimplemented E1000 device.");
return;
}
}
}
};
E1000Device *Drivers[4] = {nullptr};
dev_t NetID[4] = {(dev_t)-1};
#define OIR(x) OIR_##x
#define CREATE_OIR(x) \
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
CREATE_OIR(0);
CREATE_OIR(1);
CREATE_OIR(2);
CREATE_OIR(3);
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
int __fs_Close(struct Inode *) { return 0; }
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
{
return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
}
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
{
return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp);
}
const struct InodeOperations NetOps = {
.Lookup = nullptr,
.Create = nullptr,
.Remove = nullptr,
.Rename = nullptr,
.Read = __fs_Read,
.Write = __fs_Write,
.Truncate = nullptr,
.Open = __fs_Open,
.Close = __fs_Close,
.Ioctl = __fs_Ioctl,
.ReadDir = nullptr,
.MkDir = nullptr,
.RmDir = nullptr,
.SymLink = nullptr,
.ReadLink = nullptr,
.Seek = nullptr,
.Stat = nullptr,
};
PCIArray *Devices;
EXTERNC int cxx_Panic()
{
PCIArray *ctx = Devices;
short Count = 0;
while (ctx != nullptr)
{
if (Drivers[Count] != nullptr)
Drivers[Count]->Panic();
Count++;
ctx = (PCIArray *)ctx->Next;
}
return 0;
}
EXTERNC int cxx_Probe()
{
uint16_t VendorIDs[] = {0x8086, /* Intel */
PCI_END};
uint16_t DeviceIDs[] = {0x100E, /* 82540EM */
0x100F, /* 82545EM */
0x10D3, /* 82574L */
0x10EA, /* I217-LM */
0x153A, /* 82577LM */
PCI_END};
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
if (Devices == nullptr)
{
KernelLog("No E1000 device found.");
return -ENODEV;
}
return 0;
}
EXTERNC int cxx_Initialize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count > sizeof(Drivers) / sizeof(E1000Device *))
break;
InitializePCI(ctx->Device);
Drivers[Count] = new E1000Device((PCIHeader0 *)ctx->Device->Header,
ctx->Device->Header->DeviceID);
if (Drivers[Count]->IsInitialized())
{
dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps);
NetID[Count] = ret;
Drivers[Count]->ID = ret;
/* FIXME: bad code */
switch (Count)
{
case 0:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0));
break;
case 1:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1));
break;
case 2:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2));
break;
case 3:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3));
break;
default:
break;
}
Count++;
}
ctx = (PCIArray *)ctx->Next;
}
if (Count == 0)
{
KernelLog("No valid E1000 device found.");
return -EINVAL;
}
return 0;
}
EXTERNC int cxx_Finalize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count++ > sizeof(Drivers) / sizeof(E1000Device *))
break;
delete Drivers[Count++];
ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE;
ctx = (PCIArray *)ctx->Next;
}
for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++)
{
if (NetID[i] != (dev_t)-1)
UnregisterDevice(NetID[i]);
}
return 0;
}

View File

@ -1,31 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <base.h>
#include "e1000.hpp"
int DriverEntry() { return cxx_Initialize(); }
int DriverFinal() { return cxx_Finalize(); }
int DriverPanic() { return cxx_Panic(); }
int DriverProbe() { return cxx_Probe(); }
DriverInfo("e1000",
"Intel(R) PRO/1000 Network Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,31 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <base.h>
#include "rtl8139.hpp"
int DriverEntry() { return cxx_Initialize(); }
int DriverFinal() { return cxx_Finalize(); }
int DriverPanic() { return cxx_Panic(); }
int DriverProbe() { return cxx_Probe(); }
DriverInfo("rtl8139",
"Realtek RTL8139 Network Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -1,325 +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 <netools.h>
#include <errno.h>
#include <regs.h>
#include <base.h>
#include <pci.h>
#include <network.h>
#include <io.h>
#include "rtl8139.hpp"
class RTL8139Device
{
private:
PCIHeader0 *Header;
bool Initialized = false;
struct BARData
{
uint8_t Type;
uint16_t IOBase;
uint64_t MemoryBase;
} BAR;
const int BaseBufferSize = 8192;
const int WRAPBytes = 1500;
const int AdditionalBytes = 16;
const int BufferSize = BaseBufferSize +
WRAPBytes +
AdditionalBytes;
uint8_t *RXBuffer = nullptr;
int TXCurrent = 0;
uint16_t CurrentPacket = 0;
uint8_t TSAD[4] = {0x20, 0x24, 0x28, 0x2C};
uint8_t TSD[4] = {0x10, 0x14, 0x18, 0x1C};
public:
dev_t ID;
bool IsInitialized() { return Initialized; }
size_t write(uint8_t *Buffer, size_t Size)
{
outl(TSAD[TXCurrent], (uint32_t)(reinterpret_cast<uint64_t>(Buffer)));
outl(TSD[TXCurrent++], (uint32_t)Size);
if (TXCurrent > 3)
TXCurrent = 0;
return Size;
}
MediaAccessControl GetMAC()
{
return MediaAccessControl();
}
int ioctl(NetIoctl req, void *)
{
switch (req)
{
case IOCTL_NET_GET_MAC:
{
return -ENOSYS;
}
default:
return -EINVAL;
}
return 0;
}
void OnInterruptReceived(TrapFrame *)
{
/* Acknowledge interrupt */
uint16_t status = inw(RegISR);
DebugLog("%#lx", status);
/* Read status */
if (status & RecOK)
{
/* Get the current packet */
uint16_t *data = (uint16_t *)(RXBuffer + CurrentPacket);
uint16_t dataSz = *(data + 1);
data += 2;
// ReportNetworkPacket(ID, data, dataSz);
/* FIXME: Implement */
KernelLog("FIXME: Received packet");
(void)data;
(void)dataSz;
/* Update CAPR */
#define RX_READ_PTR_MASK (~0x3)
CurrentPacket = (uint16_t)((CurrentPacket + dataSz + 4 + 3) & RX_READ_PTR_MASK);
if (CurrentPacket > BufferSize)
CurrentPacket -= uint16_t(BufferSize);
outw(RegCAPR, CurrentPacket - 0x10);
}
/* Clear interrupt */
outw(RegISR, (RecOK | RecBad | SendOK | SendBad));
}
void Panic()
{
}
RTL8139Device(PCIHeader0 *_Header)
: Header(_Header)
{
uint32_t PCIBAR0 = Header->BAR0;
uint32_t PCIBAR1 = Header->BAR1;
BAR.Type = PCIBAR0 & 1;
BAR.IOBase = (uint16_t)(PCIBAR0 & (~3));
BAR.MemoryBase = PCIBAR1 & (~15);
RXBuffer = (uint8_t *)AllocateMemory(TO_PAGES(BufferSize));
/* Power on */
outb(RegCONFIG1, 0x0);
/* Software Reset */
outb(RegCMD, 0x10);
while (inb(RegCMD) & 0x10)
Yield();
/* Initialize receive buffer */
outl(RegRBSTART, (uint32_t)(reinterpret_cast<uintptr_t>(RXBuffer)));
/* Configure interrupt mask register */
outw(RegIMR, (RecOK | RecBad | SendOK | SendBad));
outl(regRCR, (RcAB | RcAM | RcAPM | RcAAP) | RcWRAP);
/* Enable receive and transmit */
outb(RegCMD, 0xC); /* 0xC = RE and TE bit */
uint32_t MAC1 = inl(RegMAC);
uint16_t MAC2 = inw(RegMAR);
MediaAccessControl mac = {
mac.Address[0] = (uint8_t)MAC1,
mac.Address[1] = (uint8_t)(MAC1 >> 8),
mac.Address[2] = (uint8_t)(MAC1 >> 16),
mac.Address[3] = (uint8_t)(MAC1 >> 24),
mac.Address[4] = (uint8_t)MAC2,
mac.Address[5] = (uint8_t)(MAC2 >> 8)};
Initialized = true;
}
~RTL8139Device()
{
if (!Initialized)
return;
/* FIXME: Shutdown code */
}
};
RTL8139Device *Drivers[4] = {nullptr};
dev_t NetID[4] = {(dev_t)-1};
#define OIR(x) OIR_##x
#define CREATE_OIR(x) \
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
CREATE_OIR(0);
CREATE_OIR(1);
CREATE_OIR(2);
CREATE_OIR(3);
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
int __fs_Close(struct Inode *) { return 0; }
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
{
return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
}
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
{
return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp);
}
const struct InodeOperations NetOps = {
.Lookup = nullptr,
.Create = nullptr,
.Remove = nullptr,
.Rename = nullptr,
.Read = __fs_Read,
.Write = __fs_Write,
.Truncate = nullptr,
.Open = __fs_Open,
.Close = __fs_Close,
.Ioctl = __fs_Ioctl,
.ReadDir = nullptr,
.MkDir = nullptr,
.RmDir = nullptr,
.SymLink = nullptr,
.ReadLink = nullptr,
.Seek = nullptr,
.Stat = nullptr,
};
PCIArray *Devices;
EXTERNC int cxx_Panic()
{
PCIArray *ctx = Devices;
short Count = 0;
while (ctx != nullptr)
{
if (Drivers[Count] != nullptr)
Drivers[Count]->Panic();
Count++;
ctx = (PCIArray *)ctx->Next;
}
return 0;
}
EXTERNC int cxx_Probe()
{
uint16_t VendorIDs[] = {0x10EC, /* Realtek */
PCI_END};
uint16_t DeviceIDs[] = {0x8139, /* RTL8139 */
PCI_END};
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
if (Devices == nullptr)
{
KernelLog("No RTL8139 device found.");
return -ENODEV;
}
return 0;
}
EXTERNC int cxx_Initialize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count > sizeof(Drivers) / sizeof(RTL8139Device *))
break;
InitializePCI(ctx->Device);
Drivers[Count] = new RTL8139Device((PCIHeader0 *)ctx->Device->Header);
if (Drivers[Count]->IsInitialized())
{
dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps);
NetID[Count] = ret;
Drivers[Count]->ID = ret;
/* FIXME: bad code */
switch (Count)
{
case 0:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0));
break;
case 1:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1));
break;
case 2:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2));
break;
case 3:
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3));
break;
default:
break;
}
Count++;
}
ctx = (PCIArray *)ctx->Next;
}
if (Count == 0)
{
KernelLog("No valid RTL8139 device found.");
return -EINVAL;
}
return 0;
}
EXTERNC int cxx_Finalize()
{
PCIArray *ctx = Devices;
size_t Count = 0;
while (ctx != nullptr)
{
if (Count++ > sizeof(Drivers) / sizeof(RTL8139Device *))
break;
delete Drivers[Count++];
ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE;
ctx = (PCIArray *)ctx->Next;
}
for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++)
{
if (NetID[i] != (dev_t)-1)
UnregisterDevice(NetID[i]);
}
return 0;
}

View File

@ -1,7 +1,9 @@
build: MAKE_TARGETS := build clean
make -C ahci build DIRECTORIES := $(sort $(dir $(wildcard ./*/)))
make -C ata build
clean: .PHONY: $(MAKE_TARGETS) $(DIRECTORIES)
make -C ahci clean
make -C ata clean $(MAKE_TARGETS): $(DIRECTORIES)
$(DIRECTORIES):
$(MAKE) -C $@ $(MAKECMDGOALS)

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <base.h>
#include "ahci.hpp"
int DriverEntry() { return cxx_Initialize(); }
int DriverFinal() { return cxx_Finalize(); }
int DriverPanic() { return cxx_Panic(); }
int DriverProbe() { return cxx_Probe(); }
DriverInfo("ahci",
"Advanced Host Controller Interface Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -1,35 +0,0 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
FILENAME = $(notdir $(shell pwd)).drv
build: $(FILENAME)
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)

View File

@ -1,76 +0,0 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <regs.h>
#include <base.h>
#include <io.h>
bool IsATAPresent()
{
outb(0x1F0 + 2, 0);
outb(0x1F0 + 3, 0);
outb(0x1F0 + 4, 0);
outb(0x1F0 + 5, 0);
outb(0x1F0 + 7, 0xEC);
if (inb(0x1F0 + 7) == 0 || inb(0x1F0 + 1) != 0)
return false;
return true;
}
void MasterInterruptHandler(TrapFrame *)
{
}
void SlaveInterruptHandler(TrapFrame *)
{
}
int DriverEntry()
{
RegisterInterruptHandler(14, MasterInterruptHandler);
RegisterInterruptHandler(15, SlaveInterruptHandler);
return 0;
}
int DriverFinal()
{
UnregisterInterruptHandler(14, MasterInterruptHandler);
UnregisterInterruptHandler(15, SlaveInterruptHandler);
return 0;
}
int DriverPanic()
{
return 0;
}
int DriverProbe()
{
if (!IsATAPresent())
return -ENODEV;
return 0;
}
DriverInfo("ata",
"Advanced Technology Attachment Driver",
"EnderIce2",
0, 0, 1,
"GPLv3");

View File

@ -0,0 +1,14 @@
{
"folders": [
{
"path": "./Bootloader"
}
],
"settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false,
}
}

View File

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

View File

@ -7,25 +7,25 @@
"settings": { "settings": {
"terminal.integrated.cwd": "../", "terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true, "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.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always", "git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false "C_Cpp.autoAddFileAssociations": false,
"conventionalCommits.scopes": [
"kernel/api",
"kernel/syscalls",
"vscode",
"kernel",
"kernel/pci",
"kernel/driver",
"kernel/drivers",
"kernel/elf",
"kernel/scheduler",
"kernel/tty",
"kernel/std",
"kernel/vfs",
"kernel/memory",
"kernel/efi",
"kernel/bootstrap"
]
} }
} }

View File

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

View File

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

View File

@ -6,9 +6,14 @@
], ],
"settings": { "settings": {
"debug.allowBreakpointsEverywhere": true, "debug.allowBreakpointsEverywhere": true,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master", "git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always", "git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false "C_Cpp.autoAddFileAssociations": false,
"conventionalCommits.scopes": [
"rootfs",
"tools",
"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`.

17
Kernel/.editorconfig Normal file
View File

@ -0,0 +1,17 @@
# EditorConfig is awesome: https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
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

@ -137,6 +137,33 @@
"-nostdinc++" "-nostdinc++"
] ]
}, },
{
"name": "Fennix Arm (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/include/**",
"${workspaceFolder}/include_std",
"${workspaceFolder}/include_std/**",
"${workspaceFolder}/arch/aarch64/include"
],
"forcedInclude": [
"${workspaceFolder}/.vscode/preinclude.h"
],
"defines": [
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/arm-fennix-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "linux-gcc-arm",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
},
{ {
"name": "Fennix Aarch64 (Linux, GCC, debug)", "name": "Fennix Aarch64 (Linux, GCC, debug)",
"includePath": [ "includePath": [
@ -158,38 +185,6 @@
"intelliSenseMode": "linux-gcc-arm64", "intelliSenseMode": "linux-gcc-arm64",
"configurationProvider": "ms-vscode.makefile-tools", "configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [ "compilerArgs": [
// Compiler flags
"-pipe",
"-fno-builtin",
"-msoft-float",
"-fPIC",
"-Wstack-protector",
"-fcoroutines",
// Warnings
"-Wall",
"-Wextra",
"-Wfloat-equal",
"-Wpointer-arith",
"-Wcast-align",
"-Wredundant-decls",
"-Winit-self",
"-Wswitch-default",
"-Wstrict-overflow=5",
"-Wconversion",
// C++ flags
"-fno-rtti",
"-fno-exceptions",
// Linker flags
"-T${workspaceFolder}/arch/aarch64/linker.ld",
"-fPIC",
// Debug flags
"-ggdb3",
"-O0",
"-fdiagnostics-color=always",
"-fverbose-asm",
"-fstack-usage",
"-fstack-check",
"-fsanitize=undefined",
// VSCode flags // VSCode flags
"-ffreestanding", "-ffreestanding",
"-nostdinc", "-nostdinc",

16
Kernel/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
"recommendations": [
"ms-vscode.cpptools",
"maziac.asm-code-lens",
"editorconfig.editorconfig",
"vivaxy.vscode-conventional-commits",
"ms-vscode.hexeditor",
"webfreak.debug",
"ibm.output-colorizer",
"gruntfuggly.todo-tree",
"naumovs.color-highlight",
"seven1bit.vscode-ext-ansi-color-highlight",
"jeff-hykin.better-cpp-syntax",
"aaron-bond.better-comments"
]
}

View File

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

View File

@ -6,26 +6,18 @@ GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
HEADERS := $(sort $(dir $(wildcard ./include/*))) $(sort $(dir $(wildcard ./include_std/*))) HEADERS := $(sort $(dir $(wildcard ./include/*))) $(sort $(dir $(wildcard ./include_std/*)))
INCLUDE_DIR = -I./include -I./include_std INCLUDE_DIR = -I./include -I./include_std
BMP_SOURCES := $(shell find ./ -type f -name '*.bmp') define find-sources
PSF_SOURCES := $(shell find ./ -type f -name '*.psf') $(shell find ./ -type f -name '$1' $(shell echo $(foreach arch,$(filter-out $(OSARCH),$(AVAILABLE_ARCHS)), -not -path \"./arch/$(arch)/*\")) -print0 | xargs -0)
ifeq ($(OSARCH), amd64) endef
S_SOURCES := $(shell find ./ -type f -name '*.S' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*")
s_SOURCES := $(shell find ./ -type f -name '*.s' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*")
C_SOURCES := $(shell find ./ -type f -name '*.c' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*")
CXX_SOURCES := $(shell find ./ -type f -name '*.cpp' -not -path "./arch/i386/*" -not -path "./arch/aarch64/*")
else ifeq ($(OSARCH), i386)
S_SOURCES := $(shell find ./ -type f -name '*.S' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*")
s_SOURCES := $(shell find ./ -type f -name '*.s' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*")
C_SOURCES := $(shell find ./ -type f -name '*.c' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*")
CXX_SOURCES := $(shell find ./ -type f -name '*.cpp' -not -path "./arch/amd64/*" -not -path "./arch/aarch64/*")
else ifeq ($(OSARCH), aarch64)
S_SOURCES := $(shell find ./ -type f -name '*.S' -not -path "./arch/amd64/*" -not -path "./arch/i386/*")
s_SOURCES := $(shell find ./ -type f -name '*.s' -not -path "./arch/amd64/*" -not -path "./arch/i386/*")
C_SOURCES := $(shell find ./ -type f -name '*.c' -not -path "./arch/amd64/*" -not -path "./arch/i386/*")
CXX_SOURCES := $(shell find ./ -type f -name '*.cpp' -not -path "./arch/amd64/*" -not -path "./arch/i386/*")
endif # OSARCH
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) 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 = $(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) STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CXX_SOURCES:.cpp=.gcno) GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CXX_SOURCES:.cpp=.gcno)
@ -40,7 +32,7 @@ WARNCFLAG = -Wall -Wextra \
-Wfloat-equal -Wpointer-arith -Wcast-align \ -Wfloat-equal -Wpointer-arith -Wcast-align \
-Wredundant-decls -Winit-self -Wswitch-default \ -Wredundant-decls -Winit-self -Wswitch-default \
-Wstrict-overflow=5 -Wno-error=cpp -Werror \ -Wstrict-overflow=5 -Wno-error=cpp -Werror \
-Wno-unused-parameter -Wno-unused-parameter -Wno-error=format
CFLAG_STACK_PROTECTOR := -fstack-protector-all CFLAG_STACK_PROTECTOR := -fstack-protector-all
@ -53,16 +45,20 @@ CFLAGS := \
-DKERNEL_VERSION='"$(KERNEL_VERSION)"' \ -DKERNEL_VERSION='"$(KERNEL_VERSION)"' \
-DGIT_COMMIT='"$(GIT_COMMIT)"' \ -DGIT_COMMIT='"$(GIT_COMMIT)"' \
-DGIT_COMMIT_SHORT='"$(GIT_COMMIT_SHORT)"' \ -DGIT_COMMIT_SHORT='"$(GIT_COMMIT_SHORT)"' \
-fno-pic -fno-pie -mno-red-zone -fno-builtin -fno-pic -fno-pie -fno-builtin
ifeq ($(OSARCH), amd64) ifeq ($(OSARCH), amd64)
CFLAGS += -march=core2 -mcmodel=kernel -m64 CFLAGS += -march=core2 -mcmodel=kernel -m64 -mno-red-zone
LDFLAGS += -Tarch/amd64/linker.ld LDFLAGS += -Tarch/amd64/linker.ld
else ifeq ($(OSARCH), i386) else ifeq ($(OSARCH), i386)
CFLAGS += -march=pentium -m32 CFLAGS += -march=pentium -m32 -mno-red-zone
LDFLAGS += -Tarch/i386/linker.ld LDFLAGS += -Tarch/i386/linker.ld
else ifeq ($(OSARCH), arm)
CFLAGS += -march=armv7-a -mfloat-abi=softfp -ggdb3
LDFLAGS += -Tarch/arm/linker.ld
WARNCFLAG += -w
else ifeq ($(OSARCH), aarch64) else ifeq ($(OSARCH), aarch64)
CFLAGS += CFLAGS += -march=armv9.4-a -mtune=cortex-a72 -mlittle-endian -mcmodel=large
LDFLAGS += -Tarch/aarch64/linker.ld LDFLAGS += -Tarch/aarch64/linker.ld
endif # OSARCH endif # OSARCH
@ -72,11 +68,15 @@ ifeq ($(DEBUG), 1)
# CFLAGS += -pg # CFLAGS += -pg
# CFLAGS += -finstrument-functions # CFLAGS += -finstrument-functions
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage -fsanitize=undefined CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage -fsanitize=undefined
CXXFLAGS += -fdiagnostics-all-candidates
ifeq ($(OSARCH), amd64) ifeq ($(OSARCH), amd64)
CFLAGS += -fverbose-asm CFLAGS += -fverbose-asm
endif # amd64 endif # amd64
ifneq ($(OSARCH), aarch64) ifeq ($(OSARCH), arm)
CFLAGS += -fstack-check CFLAGS += -fstack-check -fverbose-asm
endif # arm
ifeq ($(OSARCH), aarch64)
CFLAGS += -fstack-check -fverbose-asm
endif # aarch64 endif # aarch64
LDFLAGS += -ggdb3 -O0 LDFLAGS += -ggdb3 -O0
ASFLAGS += -g --gstabs+ --gdwarf-5 -D ASFLAGS += -g --gstabs+ --gdwarf-5 -D
@ -112,7 +112,7 @@ $(KERNEL_FILENAME): $(OBJ)
# https://gcc.gnu.org/projects/cxx-status.html # https://gcc.gnu.org/projects/cxx-status.html
%.o: %.cpp $(HEADERS) %.o: %.cpp $(HEADERS)
$(info Compiling $<) $(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 %.o: %.S
$(info Compiling $<) $(info Compiling $<)
@ -127,16 +127,20 @@ ifeq ($(OSARCH), amd64)
$(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@ $(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@
else ifeq ($(OSARCH), i386) else ifeq ($(OSARCH), i386)
$(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@ $(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@
else ifeq ($(OSARCH), arm)
$(__CONF_OBJCOPY) -O elf32-littlearm -I binary $< $@
else ifeq ($(OSARCH), aarch64) else ifeq ($(OSARCH), aarch64)
$(__CONF_OBJCOPY) -O elf64-littleaarch64 -I binary $< $@ $(__CONF_OBJCOPY) -O elf64-littleaarch64 -I binary $< $@
endif endif
$(__CONF_NM) $@ $(__CONF_NM) $@
%.o: %.bmp %.o: %.png
ifeq ($(OSARCH), amd64) ifeq ($(OSARCH), amd64)
$(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@ $(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@
else ifeq ($(OSARCH), i386) else ifeq ($(OSARCH), i386)
$(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@ $(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@
else ifeq ($(OSARCH), arm)
$(__CONF_OBJCOPY) -O elf32-littlearm -I binary $< $@
else ifeq ($(OSARCH), aarch64) else ifeq ($(OSARCH), aarch64)
$(__CONF_OBJCOPY) -O elf64-littlearch64 -I binary $< $@ $(__CONF_OBJCOPY) -O elf64-littlearch64 -I binary $< $@
endif endif

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)) - [ ] ~~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. - [ ] Implementation of logging (beside serial) with log rotation.
- [x] Implement a better task manager. (replace struct P/TCB with classes) - [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. - [ ] Colors in crash screen are not following the kernel color scheme.
- [x] ~~Find a way to add intrinsics.~~ (not feasible, use inline assembly) - [x] ~~Find a way to add intrinsics.~~ (not feasible, use inline assembly)
- [ ] Rework PSF1 font loader. - [ ] Rework PSF1 font loader.

View File

@ -1,36 +0,0 @@
/* Based on this tutorial:
https://github.com/s-matyukevich/raspberry-pi-os */
.section ".text.boot", "a"
.extern _bss_start
.extern _bss_end
.extern arm64Entry
memzero:
str xzr, [x0], #8
subs x1, x1, #8
b.gt memzero
ret
.global _start
_start:
mrs x0, mpidr_el1
and x0, x0, #0xFF
cbz x0, _start2
b CPU_Loop
_start2:
adr x0, _bss_start
adr x1, _bss_end
sub x1, x1, x0
bl memzero
mov sp, #0x200000
bl arm64Entry
Halt:
wfe
b Halt
CPU_Loop:
b CPU_Loop

View File

@ -0,0 +1,49 @@
/*
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/>.
*/
.section ".bootstrap.boot", "a"
.extern _kernel_bss_start
.extern _kernel_bss_end
.extern _kernel_bss_size
.global _start
_start:
/* Keep only the main core */
mrs x1, mpidr_el1
and x1, x1, #3
cbz x1, 2f
/* Halt */
1: wfe
b 1b
/* Initialize the stack */
2: ldr x1, =_start
mov sp, x1
/* Clear the BSS */
ldr x1, =_kernel_bss_start
ldr w2, =_kernel_bss_size
3: cbz w2, 4f
str xzr, [x1], #8
sub w2, w2, #1
cbnz w2, 3b
/* Start the kernel */
4: bl _aarch64_start
b 1b

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