Compare commits

...

44 Commits

Author SHA1 Message Date
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
138 changed files with 25892 additions and 12336 deletions

View File

@ -120,6 +120,18 @@ License information can be found in the [LICENSES.md](LICENSES.md) file.
## UART
- [Interfacing the Serial / RS232 Port V5.0](http://www.senet.com.au/~cpeacock)
## UEFI
- [U-Boot EFI Commands](https://docs.u-boot.org/en/latest/usage/cmd/efi.html)
- [UEFI Specification 2.10](https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf)
- [UEFI Boot Process Overview](https://gist.github.com/Velocet/d394281d96191e235ff46a8aa2018d80)
- [Rust OS Development: UEFI](https://blog.malware.re/2023/09/01/rust-os-part2/index.html)
- [GUIDs Database](https://github.com/DSecurity/efiSeek/blob/master/data/guids-db.ini)
## BGRT
- [BGRT on OSDev](https://wiki.osdev.org/BGRT)
- [BMP File Structure @ Gdansk University of Technology](http://www.ue.eti.pg.gda.pl/fpgalab/zadania.spartan3/zad_vga_struktura_pliku_bmp_en.html)
- [BGRT @ Purdue University](https://engineering.purdue.edu/ece264/16au/hw/HW13)
---
Special thanks to all contributors and the creators of the referenced projects and resources!

View File

@ -44,10 +44,20 @@ export DRIVER_LDFLAGS
export DRIVER_CFLAGS
copy_driver_signatures:
@echo "const char *trusted_drivers[] = {" > $(OUTPUT_DIR)../../Kernel/drivers/trusted.c
@find $(OUTPUT_DIR) -name "*.drv" -exec sha512sum {} \; | awk '{gsub(/.*\//, "", $$2); gsub(/\./, "_", $$2); sub(/_drv$$/, "_drv", $$2); print "\"" $$1 "\"," }' >> $(OUTPUT_DIR)../../Kernel/drivers/trusted.c
@echo "};" >> $(OUTPUT_DIR)../../Kernel/drivers/trusted.c
@echo "const __SIZE_TYPE__ trusted_drivers_count = sizeof(trusted_drivers) / sizeof(trusted_drivers[0]);" >> $(OUTPUT_DIR)../../Kernel/drivers/trusted.c
@TMP_FILE="$(OUTPUT_DIR)../../Kernel/drivers/trusted.c.tmp"; \
OUT_FILE="$(OUTPUT_DIR)../../Kernel/drivers/trusted.c"; \
mkdir -p $(OUTPUT_DIR)../../Kernel/drivers/; \
echo "const char *trusted_drivers[] = {" > $$TMP_FILE; \
find $(OUTPUT_DIR) -name "*.drv" -exec sha512sum {} \; | awk '{gsub(/.*\//, "", $$2); gsub(/\./, "_", $$2); sub(/_drv$$/, "_drv", $$2); print "\"" $$1 "\"," }' >> $$TMP_FILE; \
echo "};" >> $$TMP_FILE; \
echo "const __SIZE_TYPE__ trusted_drivers_count = sizeof(trusted_drivers) / sizeof(trusted_drivers[0]);" >> $$TMP_FILE; \
if [ ! -f $$OUT_FILE ] || ! cmp -s $$TMP_FILE $$OUT_FILE; then \
mv $$TMP_FILE $$OUT_FILE; \
printf '\033[0;32m[trusted.c updated]\033[0m\n'; \
else \
rm $$TMP_FILE; \
printf '\033[0;33m[trusted.c unchanged]\033[0m\n'; \
fi
build:
cp -rf ../Kernel/include/interface/* include/

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

@ -322,11 +322,29 @@ struct InodeOperations
int (*Stat)(struct Inode *Node, struct kstat *Stat);
} __attribute__((packed));
#define I_FLAG_ROOT 0x1
#define I_FLAG_MOUNTPOINT 0x2
#define I_FLAG_CACHE_KEEP 0x4
struct FileSystemInfo;
struct FileSystemDevice
{
struct
{
/**
* @brief Inode
*
* If the device is a block device, this will be NULL.
*/
struct Inode *node;
struct InodeOperations *ops;
} inode;
/**
* @brief Block Device
*
* If the device is a block device, this will be non-NULL.
*/
struct BlockDevice *Block;
};
struct SuperBlockOperations
{
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
@ -337,8 +355,8 @@ struct SuperBlockOperations
*
* Write all pending changes to the disk.
*
* @param Info Inode to synchronize. If NULL, synchronize all inodes.
* @param Node Inode to synchronize.
* @param Info Inode to synchronize.
* @param Node Inode to synchronize. If NULL, synchronize all inodes.
*
* @return Zero on success, otherwise an error code.
*/
@ -354,13 +372,50 @@ struct SuperBlockOperations
* @return Zero on success, otherwise an error code.
*/
int (*Destroy)(struct FileSystemInfo *Info);
/**
* Probe the filesystem.
*
* Check if the filesystem is supported by the driver.
*
* @param Device Device to probe.
*
* @return Zero on success, otherwise an error code.
*/
int (*Probe)(struct FileSystemDevice *Device);
/**
* Mount the filesystem.
*
* Mount the filesystem on the given device.
*
* @param FS Filesystem to mount.
* @param Root Pointer to the root inode.
* @param Device Device to mount. This pointer will be undefined after the function returns!
*
* @return Zero on success, otherwise an error code.
*/
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, struct FileSystemDevice *Device);
/**
* Unmount the filesystem.
*
* Unmount the filesystem from the given device.
*
* @param FS Filesystem to unmount.
*
* @return Zero on success, otherwise an error code.
*/
int (*Unmount)(struct FileSystemInfo *FS);
} __attribute__((packed));
struct FileSystemInfo
{
const char *Name;
const char *RootName;
int Flags;
int Capabilities;
struct SuperBlockOperations SuperOps;
struct InodeOperations Ops;
@ -368,6 +423,9 @@ struct FileSystemInfo
} __attribute__((packed));
#ifndef __kernel__
dev_t RegisterMountPoint(FileSystemInfo *fsi, Inode *Root);
int UnregisterMountPoint(dev_t Device);
dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
int UnregisterFileSystem(dev_t Device);
#endif // !__kernel__

View File

@ -23,7 +23,9 @@
"kernel/tty",
"kernel/std",
"kernel/vfs",
"kernel/memory"
"kernel/memory",
"kernel/efi",
"kernel/bootstrap"
]
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -68,8 +68,10 @@ Multiboot_start:
je x32Hang
mov %cr4, %ecx
or $0x00000010, %ecx /* PSE */
or $0x00000020, %ecx /* PAE */
or $0x10, %ecx /* PSE */
or $0x20, %ecx /* PAE */
or $0x200, %ecx /* OSFXSR */
or $0x400, %ecx /* OSXMMEXCPT */
mov %ecx, %cr4
call LoadGDT32
@ -82,12 +84,14 @@ Multiboot_start:
rdmsr
or $0x800, %eax /* LME */
or $0x100, %eax /* LMA */
or $0x1, %eax /* SCE */
or $0x1, %eax /* SCE */
wrmsr
mov %cr0, %ecx
and $~0x4, %ecx /* EM */
or $0x2, %ecx /* MP */
or $0x80000000, %ecx /* PG */
or $0x1, %ecx /* PE */
or $0x1, %ecx /* PE */
mov %ecx, %cr0
lgdt [GDT64.Ptr]

View File

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

View File

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

View File

@ -27,7 +27,7 @@
namespace KernelConsole
{
int TermColors[] = {
static int TermColors[] = {
[TerminalColor::BLACK] = 0x000000,
[TerminalColor::RED] = 0xAA0000,
[TerminalColor::GREEN] = 0x00AA00,
@ -38,7 +38,7 @@ namespace KernelConsole
[TerminalColor::GREY] = 0xAAAAAA,
};
int TermBrightColors[] = {
static int TermBrightColors[] = {
[TerminalColor::BLACK] = 0x858585,
[TerminalColor::RED] = 0xFF5555,
[TerminalColor::GREEN] = 0x55FF55,
@ -123,7 +123,8 @@ namespace KernelConsole
ConsoleTerminal *term = CurrentTerminal.load();
ConsoleTerminal::Blinker &blinker = term->Blink;
TerminalCell *cell = term->Term->GetCell(Renderer.Cursor.X + Renderer.Cursor.Y * term->Term->GetWinsize()->ws_row);
size_t cellIndex = Renderer.Cursor.Y * term->Term->GetWinsize()->ws_col + Renderer.Cursor.X;
TerminalCell *cell = term->Term->GetCell(cellIndex);
uint32_t bgColor = cell->attr.Bright ? TermBrightColors[cell->attr.Background] : TermColors[cell->attr.Background];
Renderer.Paint(Renderer.Cursor.X, Renderer.Cursor.Y, blinker.Character, Enable ? blinker.Color : bgColor, bgColor);
}
@ -155,15 +156,15 @@ namespace KernelConsole
bool SetTheme(std::string Theme)
{
FileNode *rn = fs->GetByPath("/sys/cfg/term", thisProcess->Info.RootNode);
Node rn = fs->Lookup(thisProcess->Info.RootNode, "/sys/cfg/term");
if (rn == nullptr)
return false;
kstat st{};
rn->Stat(&st);
kstat st;
fs->Stat(rn, &st);
char *sh = new char[st.Size];
rn->Read(sh, st.Size, 0);
fs->Read(rn, sh, st.Size, 0);
ini_t *ini = ini_load(sh, NULL);
int themeSection, c0, c1, c2, c3, c4, c5, c6, c7, colorsIdx;
@ -369,16 +370,16 @@ namespace KernelConsole
void LateInit()
{
FileNode *rn = fs->GetByPath("/sys/cfg/term", thisProcess->Info.RootNode);
Node rn = fs->Lookup(thisProcess->Info.RootNode, "/sys/cfg/term");
if (rn == nullptr)
return;
{
kstat st;
rn->Stat(&st);
fs->Stat(rn, &st);
std::string cfg;
cfg.reserve(st.Size);
rn->Read(cfg.data(), st.Size, 0);
cfg.resize(st.Size);
fs->Read(rn, cfg.data(), st.Size, 0);
LoadConsoleConfig(cfg);
}

View File

@ -191,11 +191,11 @@ namespace v0
/* --------- */
dev_t RegisterFileSystem(dev_t DriverID, FileSystemInfo *Info, struct Inode *Root)
dev_t RegisterFileSystem(dev_t DriverID, FileSystemInfo *Info)
{
dbg_api("%d, %#lx, %#lx", DriverID, Info, Root);
dbg_api("%d, %#lx", DriverID, Info);
return fs->RegisterFileSystem(Info, Root);
return fs->RegisterFileSystem(Info);
}
int UnregisterFileSystem(dev_t DriverID, dev_t Device)
@ -333,7 +333,7 @@ namespace v0
void PS2Wait(dev_t DriverID, const bool Output)
{
dbg_api("%d, %d", DriverID, Output);
// dbg_api("%d, %d", DriverID, Output);
#if defined(__amd64__) || defined(__i386__)
int Timeout = 100000;
@ -379,7 +379,7 @@ namespace v0
uint8_t PS2ReadData(dev_t DriverID)
{
dbg_api("%d", DriverID);
// dbg_api("%d", DriverID);
#if defined(__amd64__) || defined(__i386__)
WaitOutput;
@ -710,6 +710,20 @@ namespace v0
return DriverManager->ReportInputEvent(DriverID, Report);
}
dev_t RegisterBlockDevice(dev_t DriverID, struct BlockDevice *Device)
{
dbg_api("%d, %#lx", DriverID, Device);
return DriverManager->RegisterBlockDevice(DriverID, Device);
}
int UnregisterBlockDevice(dev_t DriverID, dev_t DeviceID)
{
dbg_api("%d, %d", DriverID, DeviceID);
return DriverManager->UnregisterBlockDevice(DriverID, DeviceID);
}
}
struct APISymbols
@ -777,6 +791,8 @@ static struct APISymbols APISymbols_v0[] = {
{"__RegisterDevice", (void *)v0::RegisterDevice},
{"__UnregisterDevice", (void *)v0::UnregisterDevice},
{"__ReportInputEvent", (void *)v0::ReportInputEvent},
{"__RegisterBlockDevice", (void *)v0::RegisterBlockDevice},
{"__UnregisterBlockDevice", (void *)v0::UnregisterBlockDevice},
};
long __KernelUndefinedFunction(long arg0, long arg1, long arg2, long arg3,

View File

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

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

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

View File

@ -38,12 +38,12 @@ extern const __SIZE_TYPE__ trusted_drivers_count;
namespace Driver
{
bool Manager::IsDriverTrusted(FileNode *File)
bool Manager::IsDriverTrusted(Node File)
{
kstat st;
File->Stat(&st);
fs->Stat(File, &st);
std::unique_ptr<uint8_t[]> ptr(new uint8_t[st.Size]);
File->Read(ptr.get(), st.Size, 0);
fs->Read(File, ptr.get(), st.Size, 0);
uint8_t *sha = sha512_sum(ptr.get(), st.Size);
char hash_str[129];
for (int j = 0; j < 64; j++)
@ -102,7 +102,8 @@ namespace Driver
}
const char *DriverDirectory = Config.DriverDirectory;
FileNode *drvDirNode = fs->GetByPath(DriverDirectory, nullptr);
Node root = fs->GetRoot(0);
Node drvDirNode = fs->Lookup(root, DriverDirectory);
if (!drvDirNode)
{
error("Failed to open driver directory %s", DriverDirectory);
@ -110,7 +111,7 @@ namespace Driver
return;
}
for (const auto &drvNode : drvDirNode->Children)
for (const auto &drvNode : fs->ReadDirectory(drvDirNode))
{
debug("Checking driver %s", drvNode->Path.c_str());
if (!drvNode->IsRegularFile())
@ -273,12 +274,12 @@ namespace Driver
}
}
int Manager::LoadDriverFile(DriverObject &Drv, FileNode *File)
int Manager::LoadDriverFile(DriverObject &Drv, Node File)
{
trace("Loading driver %s in memory", File->Name.c_str());
Elf_Ehdr ELFHeader{};
File->Read(&ELFHeader, sizeof(Elf_Ehdr), 0);
fs->Read(File, &ELFHeader, sizeof(Elf_Ehdr), 0);
AssertReturnError(ELFHeader.e_ident[EI_CLASS] == ELFCLASS64, -ENOEXEC);
AssertReturnError(ELFHeader.e_ident[EI_DATA] == ELFDATA2LSB, -ENOEXEC);
@ -295,7 +296,7 @@ namespace Driver
Elf_Phdr phdr{};
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
File->Read(&phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
fs->Read(File, &phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
if (phdr.p_type == PT_LOAD || phdr.p_type == PT_DYNAMIC)
{
if (segSize < phdr.p_vaddr + phdr.p_memsz)
@ -306,7 +307,7 @@ namespace Driver
if (phdr.p_type == PT_INTERP)
{
char interp[17];
File->Read(interp, sizeof(interp), phdr.p_offset);
fs->Read(File, interp, sizeof(interp), phdr.p_offset);
if (strncmp(interp, "/boot/fennix.elf", sizeof(interp)) != 0)
{
error("Interpreter is not /boot/fennix.elf");
@ -326,13 +327,13 @@ namespace Driver
Elf_Shdr shstrtab{};
Elf_Shdr shdr{};
__DriverInfo driverInfo{};
File->Read(&shstrtab, sizeof(Elf_Shdr), ELFHeader.e_shoff + (ELFHeader.e_shstrndx * ELFHeader.e_shentsize));
fs->Read(File, &shstrtab, sizeof(Elf_Shdr), ELFHeader.e_shoff + (ELFHeader.e_shstrndx * ELFHeader.e_shentsize));
for (Elf_Half i = 0; i < ELFHeader.e_shnum; i++)
{
if (i == ELFHeader.e_shstrndx)
continue;
File->Read(&shdr, ELFHeader.e_shentsize, ELFHeader.e_shoff + (i * ELFHeader.e_shentsize));
fs->Read(File, &shdr, ELFHeader.e_shentsize, ELFHeader.e_shoff + (i * ELFHeader.e_shentsize));
switch (shdr.sh_type)
{
@ -350,11 +351,11 @@ namespace Driver
}
char symName[16];
File->Read(symName, sizeof(symName), shstrtab.sh_offset + shdr.sh_name);
fs->Read(File, symName, sizeof(symName), shstrtab.sh_offset + shdr.sh_name);
if (strcmp(symName, ".driver.info") != 0)
continue;
File->Read(&driverInfo, sizeof(__DriverInfo), shdr.sh_offset);
fs->Read(File, &driverInfo, sizeof(__DriverInfo), shdr.sh_offset);
/* Perform relocations */
driverInfo.Name = (const char *)(Drv.BaseAddress + (uintptr_t)driverInfo.Name);
@ -367,13 +368,13 @@ namespace Driver
{
Elf_Sym symEntry{};
uintptr_t symOffset = sht_symtab.sh_offset + (h * sizeof(Elf_Sym));
File->Read(&symEntry, sizeof(Elf_Sym), symOffset);
fs->Read(File, &symEntry, sizeof(Elf_Sym), symOffset);
if (symEntry.st_name == 0)
continue;
char symName[16];
File->Read(symName, sizeof(symName), sht_strtab.sh_offset + symEntry.st_name);
fs->Read(File, symName, sizeof(symName), sht_strtab.sh_offset + symEntry.st_name);
switch (symEntry.st_shndx)
{
@ -405,7 +406,7 @@ namespace Driver
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
File->Read(&phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
fs->Read(File, &phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
switch (phdr.p_type)
{
@ -421,7 +422,7 @@ namespace Driver
phdr.p_filesz, phdr.p_memsz);
if (phdr.p_filesz > 0)
File->Read(dest, phdr.p_filesz, phdr.p_offset);
fs->Read(File, (void *)dest, phdr.p_filesz, phdr.p_offset);
if (phdr.p_memsz - phdr.p_filesz > 0)
{
@ -620,7 +621,8 @@ namespace Driver
delete Drv.DeviceOperations;
/* Reload the driver */
FileNode *drvNode = fs->GetByPath(Drv.Path.c_str(), nullptr);
Node root = fs->GetRoot(0);
Node drvNode = fs->Lookup(root, Drv.Path);
if (!drvNode)
{
error("Failed to open driver file %s", Drv.Path.c_str());
@ -684,7 +686,7 @@ namespace Driver
newDrvObj.Initialized = true;
}
Manager::Manager() { this->InitializeDaemonFS(); }
Manager::Manager() { this->InitializeDeviceDirectory(); }
Manager::~Manager()
{

View File

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

View File

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

View File

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

View File

@ -52,7 +52,7 @@ void *FbBeforePanic = nullptr;
size_t FbPagesBeforePanic = 0;
FontRenderer CrashFontRenderer;
int ExTermColors[] = {
static int ExTermColors[] = {
[TerminalColor::BLACK] = 0x000000,
[TerminalColor::RED] = 0xAA0000,
[TerminalColor::GREEN] = 0x00AA00,
@ -63,7 +63,7 @@ int ExTermColors[] = {
[TerminalColor::GREY] = 0xAAAAAA,
};
int ExTermBrightColors[] = {
static int ExTermBrightColors[] = {
[TerminalColor::BLACK] = 0x858585,
[TerminalColor::RED] = 0xFF5555,
[TerminalColor::GREEN] = 0x55FF55,
@ -408,8 +408,7 @@ nsa __noreturn void HandleBufferOverflow()
CPU::Stop();
}
EXTERNC nsa __noreturn void HandleAssertionFailed(const char *File, int Line,
const char *Expression)
EXTERNC nsa __noreturn void HandleAssertionFailed(const char *File, int Line, const char *Expression)
{
DisplayAssertionFailed(File, Line, Expression);
CPU::Stop();

View File

@ -571,6 +571,7 @@ nsa void DisplayCrashScreen(CPU::ExceptionFrame *Frame)
DisplayTopOverlay();
DisplayMainScreen(Frame);
DisplayStackScreen(Frame);
InitializeKeyboards();
DisplayBottomOverlay();

View File

@ -185,17 +185,13 @@ namespace SymbolResolver
if (strlen(name) == 0)
continue;
SymbolTable tbl{};
SymbolTable tbl;
tbl.Address = sym->st_value;
tbl.FunctionName = new char[strlen(name) + 1];
strcpy(tbl.FunctionName, name);
this->SymTable.push_back(tbl);
this->SymbolTableExists = true;
// debug("Symbol %d: %#lx %s(%#lx)",
// i, tbl.Address,
// tbl.FunctionName,
// name);
// debug("Symbol %d: %#lx %s(%#lx)", i, tbl.Address, tbl.FunctionName, name);
}
}
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

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

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

View File

@ -15,34 +15,22 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_FILESYSTEM_INITRD_H__
#define __FENNIX_KERNEL_FILESYSTEM_INITRD_H__
#include <efi.h>
#include <types.h>
#include <convert.h>
#include <filesystem.hpp>
namespace vfs
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
{
class Initrd
{
public:
struct InitrdHeader
{
uint32_t nfiles;
};
if (Guid1 == NULL || Guid2 == NULL)
return FALSE;
struct InitrdFileHeader
{
uint8_t magic;
char name[64];
uint32_t offset;
uint32_t length;
};
Initrd(uintptr_t Address);
~Initrd();
};
return (Guid1->Data1 == Guid2->Data1 &&
Guid1->Data2 == Guid2->Data2 &&
Guid1->Data3 == Guid2->Data3 &&
memcmp(Guid1->Data4, Guid2->Data4, sizeof(Guid1->Data4)) == 0);
}
#endif // !__FENNIX_KERNEL_FILESYSTEM_INITRD_H__
VOID InitializeLib(IN EFI_HANDLE, IN EFI_SYSTEM_TABLE *)
{
/* Does nothing */
}

View File

@ -25,7 +25,7 @@
namespace Execute
{
BinaryType GetBinaryType(FileNode *Node)
BinaryType GetBinaryType(Node &Node)
{
debug("Checking binary type of %s", Node->Path.c_str());
BinaryType type;
@ -34,13 +34,13 @@ namespace Execute
ReturnLogError((BinaryType)-ENOENT, "Node is null");
Elf_Ehdr ehdr;
Node->Read(&ehdr, sizeof(Elf_Ehdr), 0);
fs->Read(Node, &ehdr, sizeof(Elf_Ehdr), 0);
mach_header mach;
Node->Read(&mach, sizeof(mach_header), 0);
fs->Read(Node, &mach, sizeof(mach_header), 0);
IMAGE_DOS_HEADER mz;
Node->Read(&mz, sizeof(IMAGE_DOS_HEADER), 0);
fs->Read(Node, &mz, sizeof(IMAGE_DOS_HEADER), 0);
/* Check ELF header. */
if (ehdr.e_ident[EI_MAG0] == ELFMAG0 &&
@ -64,10 +64,10 @@ namespace Execute
else if (mz.e_magic == IMAGE_DOS_SIGNATURE)
{
IMAGE_NT_HEADERS pe;
Node->Read(&pe, sizeof(IMAGE_NT_HEADERS), mz.e_lfanew);
fs->Read(Node, &pe, sizeof(IMAGE_NT_HEADERS), mz.e_lfanew);
IMAGE_OS2_HEADER ne;
Node->Read(&ne, sizeof(IMAGE_OS2_HEADER), mz.e_lfanew);
fs->Read(Node, &ne, sizeof(IMAGE_OS2_HEADER), mz.e_lfanew);
/* TODO: LE, EDOS */
if (pe.Signature == IMAGE_NT_SIGNATURE)
@ -99,14 +99,14 @@ namespace Execute
BinaryType GetBinaryType(std::string Path)
{
FileNode *node = fs->GetByPath(Path.c_str(), nullptr);
Node node = fs->Lookup(thisProcess->Info.RootNode, Path);
if (node->IsSymbolicLink())
{
char buffer[512];
node->ReadLink(buffer, sizeof(buffer));
node = fs->GetByPath(buffer, node->Parent);
fs->ReadLink(node, buffer, sizeof(buffer));
node = fs->Lookup(node->Parent, buffer);
}
debug("Checking binary type of %s (returning %p)", Path.c_str(), node);
debug("Checking binary type of %s (returning %p)", Path.c_str(), node.get());
assert(node != nullptr);
return GetBinaryType(node);
}

View File

@ -32,7 +32,7 @@ using namespace vfs;
namespace Execute
{
void ELFObject::GenerateAuxiliaryVector(Memory::VirtualMemoryArea *vma, FileNode *fd, Elf_Ehdr ELFHeader, uintptr_t EntryPoint, uintptr_t BaseAddress)
void ELFObject::GenerateAuxiliaryVector(Memory::VirtualMemoryArea *vma, Node &fd, Elf_Ehdr ELFHeader, uintptr_t EntryPoint, uintptr_t BaseAddress)
{
char *aux_platform = (char *)vma->RequestPages(1, true); /* TODO: 4KiB is too much for this */
strcpy(aux_platform, "x86_64");
@ -79,7 +79,7 @@ namespace Execute
#endif
}
void ELFObject::LoadSegments(FileNode *fd, PCB *TargetProcess, Elf_Ehdr &ELFHeader, uintptr_t &BaseAddress)
void ELFObject::LoadSegments(Node &fd, PCB *TargetProcess, Elf_Ehdr &ELFHeader, uintptr_t &BaseAddress)
{
Memory::Virtual vmm(TargetProcess->PageTable);
Memory::VirtualMemoryArea *vma = TargetProcess->vma;
@ -91,7 +91,7 @@ namespace Execute
size_t SegmentsSize = 0;
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
fd->Read(&ProgramHeader, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
fs->Read(fd, &ProgramHeader, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
if (ProgramHeader.p_type == PT_LOAD || ProgramHeader.p_type == PT_DYNAMIC)
{
@ -113,7 +113,7 @@ namespace Execute
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
fd->Read(&ProgramHeader, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
fs->Read(fd, &ProgramHeader, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
switch (ProgramHeader.p_type)
{
@ -132,7 +132,7 @@ namespace Execute
if (ProgramHeader.p_filesz > 0)
{
fd->Read(SegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
fs->Read(fd, (void *)SegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
}
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
@ -158,7 +158,7 @@ namespace Execute
if (ProgramHeader.p_filesz > 0)
{
fd->Read(DynamicSegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
fs->Read(fd, (void *)DynamicSegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
}
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
@ -212,7 +212,7 @@ namespace Execute
{
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
{
fd->Read(&ProgramHeader, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
fs->Read(fd, &ProgramHeader, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
switch (ProgramHeader.p_type)
{
case PT_LOAD:
@ -220,6 +220,9 @@ namespace Execute
if (ProgramHeader.p_memsz == 0)
continue;
if (BaseAddress == 0)
BaseAddress = ALIGN_DOWN(ProgramHeader.p_vaddr, PAGE_SIZE);
void *pAddr = vma->RequestPages(TO_PAGES(ProgramHeader.p_memsz + (ProgramHeader.p_vaddr % PAGE_SIZE)), true);
void *vAddr = (void *)ALIGN_DOWN(ProgramHeader.p_vaddr, PAGE_SIZE);
uintptr_t destOffset = ProgramHeader.p_vaddr - uintptr_t(vAddr);
@ -242,7 +245,7 @@ namespace Execute
if (ProgramHeader.p_filesz > 0)
{
debug("%d %#lx %d", ProgramHeader.p_offset, (uint8_t *)pAddr + destOffset, ProgramHeader.p_filesz);
fd->Read((uint8_t *)pAddr + destOffset, ProgramHeader.p_filesz, ProgramHeader.p_offset);
fs->Read(fd, (uint8_t *)pAddr + destOffset, ProgramHeader.p_filesz, ProgramHeader.p_offset);
}
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
@ -262,35 +265,35 @@ namespace Execute
case PT_NOTE:
{
Elf_Nhdr NoteHeader;
fd->Read(&NoteHeader, sizeof(Elf_Nhdr), ProgramHeader.p_offset);
fs->Read(fd, &NoteHeader, sizeof(Elf_Nhdr), ProgramHeader.p_offset);
switch (NoteHeader.n_type)
{
case NT_PRSTATUS:
{
Elf_Prstatus prstatus;
fd->Read(&prstatus, sizeof(Elf_Prstatus), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
fs->Read(fd, &prstatus, sizeof(Elf_Prstatus), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
debug("PRSTATUS: %#lx", prstatus.pr_reg[0]);
break;
}
case NT_PRPSINFO:
{
Elf_Prpsinfo prpsinfo;
fd->Read(&prpsinfo, sizeof(Elf_Prpsinfo), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
fs->Read(fd, &prpsinfo, sizeof(Elf_Prpsinfo), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
debug("PRPSINFO: %s", prpsinfo.pr_fname);
break;
}
case NT_PLATFORM:
{
char platform[256];
fd->Read(&platform, sizeof(platform), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
fs->Read(fd, &platform, sizeof(platform), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
debug("PLATFORM: %s", platform);
break;
}
case NT_AUXV:
{
Elf_auxv_t auxv;
fd->Read(&auxv, sizeof(Elf_auxv_t), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
fs->Read(fd, &auxv, sizeof(Elf_auxv_t), ProgramHeader.p_offset + sizeof(Elf_Nhdr));
debug("AUXV: %#lx", auxv.a_un.a_val);
break;
}
@ -308,7 +311,7 @@ namespace Execute
debug("TLS Size: %ld (%ld pages)",
tlsSize, TO_PAGES(tlsSize));
void *tlsMemory = vma->RequestPages(TO_PAGES(tlsSize));
fd->Read(tlsMemory, tlsSize, ProgramHeader.p_offset);
fs->Read(fd, tlsMemory, tlsSize, ProgramHeader.p_offset);
TargetProcess->TLS = {
.pBase = uintptr_t(tlsMemory),
.vBase = ProgramHeader.p_vaddr,
@ -343,12 +346,12 @@ namespace Execute
case PT_GNU_PROPERTY:
{
Elf_Nhdr NoteHeader;
fd->Read(&NoteHeader, sizeof(Elf_Nhdr), ProgramHeader.p_offset);
fs->Read(fd, &NoteHeader, sizeof(Elf_Nhdr), ProgramHeader.p_offset);
if (NoteHeader.n_type == NT_GNU_PROPERTY_TYPE_0)
{
char noteName[0x400];
fd->Read(noteName, NoteHeader.n_namesz, ProgramHeader.p_offset + sizeof(Elf_Nhdr));
fs->Read(fd, noteName, NoteHeader.n_namesz, ProgramHeader.p_offset + sizeof(Elf_Nhdr));
noteName[NoteHeader.n_namesz - 1] = '\0';
if (strcmp(noteName, "GNU") == 0)
@ -391,10 +394,10 @@ namespace Execute
TargetProcess->ProgramBreak->InitBrk(ProgramBreak);
}
void ELFObject::LoadExec(FileNode *fd, PCB *TargetProcess)
void ELFObject::LoadExec(Node &fd, PCB *TargetProcess)
{
Elf_Ehdr ehdr{};
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
uintptr_t entry = ehdr.e_entry;
debug("Entry point is %#lx", entry);
@ -411,12 +414,20 @@ namespace Execute
this->ip = entry;
this->IsElfValid = true;
#ifdef DEBUG
std::string sanitizedPath = fd->Path;
size_t pos = sanitizedPath.find("\x06root-0\x06");
if (pos != std::string::npos)
sanitizedPath.erase(pos, std::string("\x06root-0\x06").length());
debug("gdb: \"-exec add-symbol-file-all /workspaces/Fennix/tmp_rootfs%s %#lx\" entry:%#lx", sanitizedPath.c_str(), base, entry);
#endif
}
void ELFObject::LoadDyn(FileNode *fd, PCB *TargetProcess)
void ELFObject::LoadDyn(Node &fd, PCB *TargetProcess)
{
Elf_Ehdr ehdr{};
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
uintptr_t entry = ehdr.e_entry;
debug("Entry point is %#lx", entry);
@ -436,27 +447,43 @@ namespace Execute
this->ip = entry;
this->IsElfValid = true;
Elf_Phdr interp = ELFGetSymbolType(fd, PT_INTERP).front();
std::string interpreterPath;
interpreterPath.resize(256);
fd->Read(interpreterPath.data(), 256, interp.p_offset);
debug("Interpreter: %s", interpreterPath.c_str());
#ifdef DEBUG
std::string sanitizedPath = fd->Path;
size_t pos = sanitizedPath.find("\x06root-0\x06");
if (pos != std::string::npos)
sanitizedPath.erase(pos, std::string("\x06root-0\x06").length());
debug("gdb: \"-exec add-symbol-file-all /workspaces/Fennix/tmp_rootfs%s %#lx\" entry:%#lx", sanitizedPath.c_str(), base, entry);
#endif
FileNode *ifd = fs->GetByPath(interpreterPath.c_str(), TargetProcess->Info.RootNode);
if (ifd == nullptr)
std::vector<Elf_Phdr> interpVec = ELFGetSymbolType(fd, PT_INTERP);
if (interpVec.empty())
{
warn("Failed to open interpreter file: %s", interpreterPath.c_str());
debug("No interpreter found");
return;
}
Elf_Phdr interp = interpVec.front();
std::string interpreterPath;
interpreterPath.resize(256);
fs->Read(fd, interpreterPath.data(), 256, interp.p_offset);
debug("Interpreter: %s", interpreterPath.c_str());
eNode ret = fs->Lookup(TargetProcess->Info.RootNode, interpreterPath);
if (ret == false)
{
warn("Failed to open interpreter file: %s", ret.what());
return;
}
Node ifd = ret;
if (ifd->IsSymbolicLink())
{
char buffer[512];
ifd->ReadLink(buffer, sizeof(buffer));
ifd = fs->GetByPath(buffer, ifd->Parent);
fs->ReadLink(ifd, buffer, sizeof(buffer));
ifd = fs->Lookup(ifd->Parent, buffer);
}
debug("ifd: %p, interpreter: %s", ifd, interpreterPath.c_str());
debug("ifd: %p, interpreter: %s", ifd.get(), interpreterPath.c_str());
if (GetBinaryType(interpreterPath) != BinTypeELF)
{
warn("Interpreter %s is not an ELF file", interpreterPath.c_str());
@ -466,10 +493,10 @@ namespace Execute
LoadInterpreter(ifd, TargetProcess);
}
bool ELFObject::LoadInterpreter(FileNode *fd, PCB *TargetProcess)
bool ELFObject::LoadInterpreter(Node &fd, PCB *TargetProcess)
{
Elf_Ehdr ehdr;
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
switch (ehdr.e_type)
{
@ -490,6 +517,14 @@ namespace Execute
break;
}
#ifdef DEBUG
std::string sanitizedPath = fd->Path;
size_t pos = sanitizedPath.find("\x06root-0\x06");
if (pos != std::string::npos)
sanitizedPath.erase(pos, std::string("\x06root-0\x06").length());
debug("gdb: \"-exec add-symbol-file-all /workspaces/Fennix/tmp_rootfs%s %#lx\" entry:%#lx", sanitizedPath.c_str(), base, ehdr.e_entry);
#endif
return true;
}
case ET_CORE:
@ -516,18 +551,19 @@ namespace Execute
return;
}
FileNode *fd = fs->GetByPath(AbsolutePath.c_str(), TargetProcess->Info.RootNode);
if (fd == nullptr)
eNode ret = fs->Lookup(TargetProcess->Info.RootNode, AbsolutePath);
if (ret == false)
{
error("Failed to open %s, errno: %d", AbsolutePath.c_str(), fd);
error("Failed to open %s, errno: %s", AbsolutePath.c_str(), ret.what());
return;
}
Node fd = ret;
if (fd->IsSymbolicLink())
{
char buffer[512];
fd->ReadLink(buffer, sizeof(buffer));
fd = fs->GetByPath(buffer, fd->Parent);
fs->ReadLink(fd, buffer, sizeof(buffer));
fd = fs->Lookup(fd->Parent, buffer);
}
debug("Opened %s", AbsolutePath.c_str());
@ -541,7 +577,7 @@ namespace Execute
envc++;
Elf_Ehdr ehdr{};
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
// ELFargv = new const char *[argc + 2];
size_t argv_size = argc + 2 * sizeof(char *);

View File

@ -92,10 +92,10 @@ namespace Execute
return nullptr;
}
Elf_Sym ELFLookupSymbol(FileNode *fd, std::string Name)
Elf_Sym ELFLookupSymbol(Node fd, std::string Name)
{
Elf_Ehdr ehdr{};
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
Elf_Shdr symTable{};
Elf_Shdr stringTable{};
@ -103,13 +103,13 @@ namespace Execute
for (Elf64_Half i = 0; i < ehdr.e_shnum; i++)
{
Elf_Shdr shdr;
fd->Read(&shdr, sizeof(Elf_Shdr), ehdr.e_shoff + (i * sizeof(Elf_Shdr)));
fs->Read(fd, &shdr, sizeof(Elf_Shdr), ehdr.e_shoff + (i * sizeof(Elf_Shdr)));
switch (shdr.sh_type)
{
case SHT_SYMTAB:
symTable = shdr;
fd->Read(&stringTable, sizeof(Elf_Shdr), ehdr.e_shoff + (shdr.sh_link * sizeof(Elf_Shdr)));
fs->Read(fd, &stringTable, sizeof(Elf_Shdr), ehdr.e_shoff + (shdr.sh_link * sizeof(Elf_Shdr)));
break;
default:
break;
@ -126,11 +126,11 @@ namespace Execute
{
// Elf_Sym *sym = (Elf_Sym *)((uintptr_t)Header + symTable->sh_offset + (i * sizeof(Elf_Sym)));
Elf_Sym sym;
fd->Read(&sym, sizeof(Elf_Sym), symTable.sh_offset + (i * sizeof(Elf_Sym)));
fs->Read(fd, &sym, sizeof(Elf_Sym), symTable.sh_offset + (i * sizeof(Elf_Sym)));
// char *str = (char *)((uintptr_t)Header + stringTable->sh_offset + sym->st_name);
char str[256];
fd->Read(&str, sizeof(str), stringTable.sh_offset + sym.st_name);
fs->Read(fd, &str, sizeof(str), stringTable.sh_offset + sym.st_name);
if (strcmp(str, Name.c_str()) == 0)
return sym;

View File

@ -21,12 +21,12 @@
namespace Execute
{
std::vector<Elf_Dyn> ELFGetDynamicTag(FileNode *fd, DynamicArrayTags Tag)
std::vector<Elf_Dyn> ELFGetDynamicTag(Node &fd, DynamicArrayTags Tag)
{
std::vector<Elf_Dyn> ret;
std::vector<Elf_Phdr> phdrs = ELFGetSymbolType(fd, PT_DYNAMIC);
if (phdrs.size() < 1)
if (phdrs.empty())
{
debug("No dynamic phdrs found.");
return ret;
@ -34,10 +34,10 @@ namespace Execute
for (auto phdr : phdrs)
{
Elf_Dyn dyn{};
Elf_Dyn dyn;
for (size_t i = 0; i < phdr.p_filesz / sizeof(Elf_Dyn); i++)
{
fd->Read(&dyn, sizeof(Elf_Dyn), phdr.p_offset + (i * sizeof(Elf_Dyn)));
fs->Read(fd, &dyn, sizeof(Elf_Dyn), phdr.p_offset + (i * sizeof(Elf_Dyn)));
if (dyn.d_tag != Tag)
continue;

View File

@ -21,28 +21,26 @@
namespace Execute
{
std::vector<Elf_Shdr> ELFGetSections(FileNode *fd, const char *SectionName)
std::vector<Elf_Shdr> ELFGetSections(Node fd, const char *SectionName)
{
std::vector<Elf_Shdr> ret;
Elf_Ehdr ehdr{};
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
Elf_Ehdr ehdr;
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
Elf_Shdr *sections = new Elf_Shdr[ehdr.e_shnum];
fd->Read(sections, sizeof(Elf_Shdr) * ehdr.e_shnum, ehdr.e_shoff);
std::unique_ptr<Elf_Shdr[]> sections(new Elf_Shdr[ehdr.e_shnum]);
fs->Read(fd, sections.get(), sizeof(Elf_Shdr) * ehdr.e_shnum, ehdr.e_shoff);
char *sectionNames = new char[sections[ehdr.e_shstrndx].sh_size];
fd->Read(sectionNames, sections[ehdr.e_shstrndx].sh_size, sections[ehdr.e_shstrndx].sh_offset);
std::string sectionNames(sections[ehdr.e_shstrndx].sh_size, '\0');
fs->Read(fd, sectionNames.data(), sections[ehdr.e_shstrndx].sh_size, sections[ehdr.e_shstrndx].sh_offset);
for (Elf_Half i = 0; i < ehdr.e_shnum; ++i)
{
const char *Name = sectionNames + sections[i].sh_name;
const char *Name = sectionNames.data() + sections[i].sh_name;
if (strcmp(Name, SectionName) == 0)
ret.push_back(sections[i]);
}
delete[] sections;
delete[] sectionNames;
return ret;
}
}

View File

@ -21,15 +21,15 @@
namespace Execute
{
std::vector<Elf_Phdr> ELFGetSymbolType(FileNode *fd, SegmentTypes Tag)
std::vector<Elf_Phdr> ELFGetSymbolType(Node &fd, SegmentTypes Tag)
{
std::vector<Elf_Phdr> ret;
Elf_Ehdr ehdr{};
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
Elf_Ehdr ehdr;
fs->Read(fd, &ehdr, sizeof(Elf_Ehdr), 0);
Elf_Phdr phdr{};
fd->Read(&phdr, sizeof(Elf_Phdr), ehdr.e_phoff);
Elf_Phdr phdr;
fs->Read(fd, &phdr, sizeof(Elf_Phdr), ehdr.e_phoff);
off_t off = ehdr.e_phoff;
for (Elf_Half i = 0; i < ehdr.e_phnum; i++)
@ -38,7 +38,7 @@ namespace Execute
ret.push_back(phdr);
off += sizeof(Elf_Phdr);
fd->Read(&phdr, sizeof(Elf_Phdr), off);
fs->Read(fd, &phdr, sizeof(Elf_Phdr), off);
}
return ret;

View File

@ -35,7 +35,13 @@ namespace Execute
Tasking::TaskCompatibility Compatibility,
bool Critical)
{
FileNode *fd = fs->GetByPath(Path, nullptr);
if (Parent == nullptr)
{
debug("no parent specified, using current process");
Parent = thisProcess;
}
Node fd = fs->Lookup(Parent->Info.RootNode, Path);
if (fd == nullptr)
return -ENOENT;
@ -44,8 +50,8 @@ namespace Execute
if (fd->IsSymbolicLink())
{
char buffer[512];
fd->ReadLink(buffer, sizeof(buffer));
fd = fs->GetByPath(buffer, fd->Parent);
fs->ReadLink(fd, buffer, sizeof(buffer));
fd = fs->Lookup(fd->Parent, buffer);
if (fd == nullptr)
return -ENOENT;
}
@ -61,7 +67,7 @@ namespace Execute
const char *BaseName;
cwk_path_get_basename(Path, &BaseName, nullptr);
Elf32_Ehdr ELFHeader;
fd->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
fs->Read(fd, &ELFHeader, sizeof(Elf32_Ehdr), 0);
switch (ELFHeader.e_machine)
{
@ -108,7 +114,6 @@ namespace Execute
PCB *Process;
if (Fork)
{
assert(Parent != nullptr);
CriticalSection cs;
Process = Parent;
@ -124,17 +129,13 @@ namespace Execute
}
else
{
if (Parent == nullptr)
Parent = thisProcess;
Process = TaskManager->CreateProcess(Parent, BaseName,
TaskExecutionMode::User,
false, 0, 0);
Process = TaskManager->CreateProcess(Parent, BaseName, User, false, 0, 0);
Process->Info.Compatibility = Compatibility;
Process->Info.Architecture = Arch;
}
Process->SetWorkingDirectory(fs->GetByPath(Path, nullptr)->Parent);
Node cwdNode = fs->Lookup(Parent->Info.RootNode, Path);
Process->SetWorkingDirectory(fs->Convert(cwdNode->Parent));
Process->SetExe(Path);
ELFObject *obj = new ELFObject(Path, Process, argv, envp);
@ -148,9 +149,9 @@ namespace Execute
vfs::FileDescriptorTable *pfdt = Parent->FileDescriptors;
vfs::FileDescriptorTable *fdt = Process->FileDescriptors;
auto ForkStdio = [pfdt, fdt](FileNode *SearchNode)
auto ForkStdio = [pfdt, fdt](Node SearchNode)
{
if (unlikely(SearchNode == nullptr))
if (unlikely(SearchNode.get() == nullptr))
return false;
for (const auto &ffd : pfdt->FileMap)
@ -158,12 +159,11 @@ namespace Execute
if (ffd.second.Flags & O_CLOEXEC)
continue;
if (ffd.second.Node == SearchNode)
{
fdt->usr_open(ffd.second.Node->Path.c_str(),
ffd.second.Flags, ffd.second.Mode);
return true;
}
if (ffd.second.node.get() != SearchNode.get())
continue;
fdt->usr_open(ffd.second.node->Path.c_str(), ffd.second.Flags, ffd.second.Mode);
return true;
}
return false;
};

View File

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

View File

@ -15,12 +15,12 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <filesystem/ramfs.hpp>
#include <fs/ramfs.hpp>
#include <memory.hpp>
#include <functional>
#include <debug.h>
#include "../../kernel.h"
#include "../kernel.h"
namespace vfs
{
@ -81,7 +81,6 @@ namespace vfs
inode.Index = NextInode;
inode.Offset = 0;
inode.PrivateData = this;
inode.Flags = I_FLAG_CACHE_KEEP;
const char *basename;
size_t length;
@ -329,54 +328,54 @@ namespace vfs
}
}
O2 int __ramfs_Lookup(struct Inode *Parent, const char *Name, struct Inode **Result)
int __ramfs_Lookup(struct Inode *Parent, const char *Name, struct Inode **Result)
{
return ((vfs::RAMFS *)Parent->PrivateData)->Lookup(Parent, Name, Result);
}
O2 int __ramfs_Create(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result)
int __ramfs_Create(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result)
{
return ((vfs::RAMFS *)Parent->PrivateData)->Create(Parent, Name, Mode, Result);
}
O2 ssize_t __ramfs_Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
ssize_t __ramfs_Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
{
return ((vfs::RAMFS *)Node->PrivateData)->Read(Node, Buffer, Size, Offset);
}
O2 ssize_t __ramfs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
ssize_t __ramfs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
{
return ((vfs::RAMFS *)Node->PrivateData)->Write(Node, Buffer, Size, Offset);
}
O2 ssize_t __ramfs_Readdir(struct Inode *Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries)
ssize_t __ramfs_Readdir(struct Inode *Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries)
{
return ((vfs::RAMFS *)Node->PrivateData)->ReadDir(Node, Buffer, Size, Offset, Entries);
}
O2 int __ramfs_SymLink(Inode *Parent, const char *Name, const char *Target, Inode **Result)
int __ramfs_SymLink(Inode *Parent, const char *Name, const char *Target, Inode **Result)
{
return ((vfs::RAMFS *)Parent->PrivateData)->SymLink(Parent, Name, Target, Result);
}
O2 ssize_t __ramfs_ReadLink(Inode *Node, char *Buffer, size_t Size)
ssize_t __ramfs_ReadLink(Inode *Node, char *Buffer, size_t Size)
{
return ((vfs::RAMFS *)Node->PrivateData)->ReadLink(Node, Buffer, Size);
}
O2 int __ramfs_Stat(struct Inode *Node, kstat *Stat)
int __ramfs_Stat(struct Inode *Node, kstat *Stat)
{
return ((vfs::RAMFS *)Node->PrivateData)->Stat(Node, Stat);
}
O2 int __ramfs_DestroyInode(FileSystemInfo *Info, Inode *Node)
int __ramfs_DestroyInode(FileSystemInfo *Info, Inode *Node)
{
vfs::RAMFS::RAMFSInode *inode = (vfs::RAMFS::RAMFSInode *)Node;
delete inode;
return 0;
}
O2 int __ramfs_Destroy(FileSystemInfo *fsi)
int __ramfs_Destroy(FileSystemInfo *fsi)
{
assert(fsi->PrivateData);
delete (vfs::RAMFS *)fsi->PrivateData;
@ -384,16 +383,13 @@ O2 int __ramfs_Destroy(FileSystemInfo *fsi)
return 0;
}
bool MountRAMFS(FileNode *Parent, const char *Name, size_t Index)
bool MountAndRootRAMFS(Node Parent, const char *Name, size_t Index)
{
vfs::RAMFS *ramfs = new vfs::RAMFS;
ramfs->DeviceID = fs->EarlyReserveDevice();
ramfs->RootName.assign(Name);
FileSystemInfo *fsi = new FileSystemInfo;
fsi->Name = "ramfs";
fsi->RootName = Name;
fsi->Flags = I_FLAG_ROOT | I_FLAG_MOUNTPOINT | I_FLAG_CACHE_KEEP;
fsi->SuperOps.DeleteInode = __ramfs_DestroyInode;
fsi->SuperOps.Destroy = __ramfs_Destroy;
fsi->Ops.Lookup = __ramfs_Lookup;
@ -405,13 +401,12 @@ bool MountRAMFS(FileNode *Parent, const char *Name, size_t Index)
fsi->Ops.ReadLink = __ramfs_ReadLink;
fsi->Ops.Stat = __ramfs_Stat;
fsi->PrivateData = ramfs;
ramfs->DeviceID = fs->RegisterFileSystem(fsi);
Inode *root = nullptr;
ramfs->Create(nullptr, Name, S_IFDIR | 0755, &root);
fs->LateRegisterFileSystem(ramfs->DeviceID, fsi, root);
fs->AddRootAt(root, Index);
fs->Mount(Parent, root, Name);
fs->Mount(Parent, root, Name, fsi);
fs->AddRoot(Index, fs->Convert(root));
return true;
}

View File

@ -15,12 +15,12 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <filesystem/ustar.hpp>
#include <fs/ustar.hpp>
#include <memory.hpp>
#include <functional>
#include <debug.h>
#include "../../kernel.h"
#include "../kernel.h"
#define TMAGIC "ustar"
#define TMAGLEN 6
@ -32,7 +32,7 @@ namespace vfs
int USTAR::Lookup(struct Inode *_Parent, const char *Name, struct Inode **Result)
{
auto Parent = (USTARInode *)_Parent;
debug("looking up for %s", Name);
const char *basename;
size_t length;
cwk_path_get_basename(Name, &basename, &length);
@ -91,7 +91,6 @@ namespace vfs
inode.Index = NextInode;
inode.Offset = 0;
inode.PrivateData = this;
inode.Flags = I_FLAG_CACHE_KEEP;
const char *basename;
size_t length;
@ -217,6 +216,7 @@ namespace vfs
{
/* FIXME: FIX ALIGNMENT FOR DIRENT! */
auto Node = (USTARInode *)_Node;
debug("reading directory %s", Node->Path.c_str());
off_t realOffset = Offset;
@ -237,6 +237,7 @@ namespace vfs
ent->d_type = DT_DIR;
strcpy(ent->d_name, ".");
totalSize += reclen;
debug(".");
}
if (Offset <= 1)
@ -263,6 +264,7 @@ namespace vfs
ent->d_type = DT_DIR;
strcpy(ent->d_name, "..");
totalSize += reclen;
debug("..");
}
// off_t entriesSkipped = 0;
@ -309,10 +311,13 @@ namespace vfs
if (var->Deleted)
continue;
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + strlen(var->Name.c_str()) + 1);
reclen = (uint16_t)(offsetof(struct kdirent, d_name) + var->Name.size() + 1);
if (totalSize + reclen >= Size)
if (totalSize + reclen > Size)
{
debug("not enough space for %s (%zu + %zu = %zu > %zu)", var->Name.c_str(), totalSize, reclen, totalSize + reclen, Size);
break;
}
ent = (struct kdirent *)((uintptr_t)Buffer + totalSize);
ent->d_ino = var->Node.Index;
@ -349,7 +354,7 @@ namespace vfs
break;
}
strncpy(ent->d_name, var->Name.c_str(), strlen(var->Name.c_str()));
debug("%s", var->Name.c_str());
totalSize += reclen;
entries++;
}
@ -601,7 +606,6 @@ namespace vfs
uNode.RawDevice = 0;
uNode.Index = NextInode;
SetMode(uNode, header);
uNode.Flags = I_FLAG_CACHE_KEEP;
uNode.Offset = 0;
uNode.PrivateData = this;
@ -847,17 +851,8 @@ bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size, size_t Index)
return false;
}
ustar->DeviceID = fs->EarlyReserveDevice();
ustar->ReadArchive(Address, Size);
Inode *rootfs = nullptr;
ustar->Lookup(nullptr, "/", &rootfs);
assert(rootfs != nullptr);
FileSystemInfo *fsi = new FileSystemInfo;
fsi->Name = "ustar";
fsi->RootName = "/";
fsi->Flags = I_FLAG_ROOT | I_FLAG_MOUNTPOINT | I_FLAG_CACHE_KEEP;
fsi->SuperOps.DeleteInode = __ustar_DestroyInode;
fsi->SuperOps.Destroy = __ustar_Destroy;
fsi->Ops.Lookup = __ustar_Lookup;
@ -868,8 +863,23 @@ bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size, size_t Index)
fsi->Ops.ReadLink = __ustar_ReadLink;
fsi->Ops.Stat = __ustar_Stat;
fsi->PrivateData = ustar;
fs->LateRegisterFileSystem(ustar->DeviceID, fsi, rootfs);
fs->AddRootAt(rootfs, Index);
ustar->DeviceID = fs->RegisterFileSystem(fsi);
ustar->ReadArchive(Address, Size);
Inode *rootfs = nullptr;
ustar->Lookup(nullptr, "/", &rootfs);
assert(rootfs != nullptr);
eNode _node = fs->Convert(rootfs);
assert(_node.Error == 0);
Node node = _node;
node->fsi = fsi;
node->Flags.MountPoint = true;
node->Name = "/";
node->Path = "/";
fs->AddRoot(Index, node);
return true;
}

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

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

51
Kernel/gdb_printers.py Normal file
View File

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

View File

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

View File

@ -20,24 +20,24 @@
enum MemoryType
{
Unknown_Memory_Type,
Usable,
Reserved,
ACPIReclaimable,
ACPINVS,
BadMemory,
BootloaderReclaimable,
KernelAndModules,
Framebuffer,
Unknown
Unknown_Memory_Type,
Usable,
Reserved,
ACPIReclaimable,
ACPINVS,
BadMemory,
BootloaderReclaimable,
KernelAndModules,
Framebuffer,
Unknown
};
enum FramebufferType
{
Unknown_Framebuffer_Type,
Indexed,
RGB,
EGA
Unknown_Framebuffer_Type,
Indexed,
RGB,
EGA
};
#define MAX_FRAMEBUFFERS 16
@ -46,110 +46,137 @@ enum FramebufferType
struct BootInfo
{
struct FramebufferInfo
{
enum FramebufferType Type;
void *BaseAddress;
__UINT32_TYPE__ Width;
__UINT32_TYPE__ Height;
__SIZE_TYPE__ Pitch;
__UINT16_TYPE__ BitsPerPixel;
__UINT8_TYPE__ RedMaskSize;
__UINT8_TYPE__ RedMaskShift;
__UINT8_TYPE__ GreenMaskSize;
__UINT8_TYPE__ GreenMaskShift;
__UINT8_TYPE__ BlueMaskSize;
__UINT8_TYPE__ BlueMaskShift;
void *ExtendedDisplayIdentificationData;
__SIZE_TYPE__ EDIDSize;
} Framebuffer[MAX_FRAMEBUFFERS];
struct FramebufferInfo
{
enum FramebufferType Type;
void *BaseAddress;
__UINT32_TYPE__ Width;
__UINT32_TYPE__ Height;
__SIZE_TYPE__ Pitch;
__UINT16_TYPE__ BitsPerPixel;
__UINT8_TYPE__ RedMaskSize;
__UINT8_TYPE__ RedMaskShift;
__UINT8_TYPE__ GreenMaskSize;
__UINT8_TYPE__ GreenMaskShift;
__UINT8_TYPE__ BlueMaskSize;
__UINT8_TYPE__ BlueMaskShift;
void *ExtendedDisplayIdentificationData;
__SIZE_TYPE__ EDIDSize;
} Framebuffer[MAX_FRAMEBUFFERS];
struct MemoryInfo
{
struct MemoryEntryInfo
{
void *BaseAddress;
__SIZE_TYPE__ Length;
enum MemoryType Type;
} Entry[MAX_MEMORY_ENTRIES];
__SIZE_TYPE__ Entries;
__SIZE_TYPE__ Size;
} Memory;
struct MemoryInfo
{
struct MemoryEntryInfo
{
void *BaseAddress;
__SIZE_TYPE__ Length;
enum MemoryType Type;
} Entry[MAX_MEMORY_ENTRIES];
__SIZE_TYPE__ Entries;
__SIZE_TYPE__ Size;
} Memory;
struct ModuleInfo
{
void *Address;
char Path[256];
char CommandLine[256];
__SIZE_TYPE__ Size;
} Modules[MAX_MODULES];
struct ModuleInfo
{
void *Address;
char Path[256];
char CommandLine[256];
__SIZE_TYPE__ Size;
} Modules[MAX_MODULES];
struct RSDPInfo
{
/**
* @brief Signature
*/
__UINT8_TYPE__ Signature[8];
/**
* @brief Checksum
*/
__UINT8_TYPE__ Checksum;
/**
* @brief OEM ID
*/
__UINT8_TYPE__ OEMID[6];
/**
* @brief Revision
*/
__UINT8_TYPE__ Revision;
/**
* @brief Address of the Root System Description Table
*/
__UINT32_TYPE__ RSDTAddress;
/* END OF RSDP 1.0 */
struct RSDPInfo
{
/**
* @brief Signature
*/
__UINT8_TYPE__ Signature[8];
/**
* @brief Checksum
*/
__UINT8_TYPE__ Checksum;
/**
* @brief OEM ID
*/
__UINT8_TYPE__ OEMID[6];
/**
* @brief Revision
*/
__UINT8_TYPE__ Revision;
/**
* @brief Address of the Root System Description Table
*/
__UINT32_TYPE__ RSDTAddress;
/* END OF RSDP 1.0 */
/**
* @brief Length
*/
__UINT32_TYPE__ Length;
/**
* @brief Extended System Descriptor Table
*/
__UINT64_TYPE__ XSDTAddress;
/**
* @brief Extended checksum
*/
__UINT8_TYPE__ ExtendedChecksum;
/**
* @brief Reserved
*/
__UINT8_TYPE__ Reserved[3];
} __attribute__((packed)) * RSDP;
/**
* @brief Length
*/
__UINT32_TYPE__ Length;
/**
* @brief Extended System Descriptor Table
*/
__UINT64_TYPE__ XSDTAddress;
/**
* @brief Extended checksum
*/
__UINT8_TYPE__ ExtendedChecksum;
/**
* @brief Reserved
*/
__UINT8_TYPE__ Reserved[3];
} __attribute__((packed)) * RSDP;
struct KernelInfo
{
void *PhysicalBase;
void *VirtualBase;
void *FileBase;
char CommandLine[256];
__SIZE_TYPE__ Size;
struct KernelInfo
{
void *PhysicalBase;
void *VirtualBase;
void *FileBase;
char CommandLine[256];
__SIZE_TYPE__ Size;
struct KernelSymbolInfo
{
__UINT32_TYPE__ Num;
__UINT32_TYPE__ EntSize;
__UINT32_TYPE__ Shndx;
__UINTPTR_TYPE__ Sections;
} Symbols;
} Kernel;
struct KernelSymbolInfo
{
__UINT32_TYPE__ Num;
__UINT32_TYPE__ EntSize;
__UINT32_TYPE__ Shndx;
__UINTPTR_TYPE__ Sections;
} Symbols;
} Kernel;
struct BootloaderInfo
{
char Name[256];
char Version[64];
} Bootloader;
struct BootloaderInfo
{
char Name[256];
char Version[64];
} Bootloader;
void *SMBIOSPtr;
void *SMBIOSPtr;
struct EFIInfo
{
union
{
struct
{
__UINT8_TYPE__ Enabled : 1;
__UINT8_TYPE__ BS : 1;
__UINT8_TYPE__ IH : 1;
__UINT8_TYPE__ ST : 1;
__UINT8_TYPE__ MemoryMap : 1;
} __attribute__((packed));
__UINT8_TYPE__ raw;
} Info;
struct
{
void *BaseAddress;
__SIZE_TYPE__ DescriptorSize;
__SIZE_TYPE__ DescriptorVersion;
__SIZE_TYPE__ NumberOfEntries;
} MemoryMap;
void *ImageHandle;
void *SystemTable;
} EFI;
};
#endif // !__FENNIX_KERNEL_BOOT_INFO_H__

View File

@ -72,12 +72,11 @@
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
#define MULTIBOOT_ARCHITECTURE_I386 0
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
#define MULTIBOOT2_ARCHITECTURE_I386 0
#define MULTIBOOT2_ARCHITECTURE_MIPS32 4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
@ -96,320 +95,320 @@ typedef unsigned long long multiboot_uint64_t;
struct multiboot_header
{
/* Must be MULTIBOOT_MAGIC - see above. */
multiboot_uint32_t magic;
/* Must be MULTIBOOT_MAGIC - see above. */
multiboot_uint32_t magic;
/* ISA */
multiboot_uint32_t architecture;
/* ISA */
multiboot_uint32_t architecture;
/* Total header length. */
multiboot_uint32_t header_length;
/* Total header length. */
multiboot_uint32_t header_length;
/* The above fields plus this one must equal 0 mod 2^32. */
multiboot_uint32_t checksum;
/* The above fields plus this one must equal 0 mod 2^32. */
multiboot_uint32_t checksum;
};
struct multiboot_header_tag
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
};
struct multiboot_header_tag_information_request
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t requests[0];
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t requests[0];
};
struct multiboot_header_tag_address
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t header_addr;
multiboot_uint32_t load_addr;
multiboot_uint32_t load_end_addr;
multiboot_uint32_t bss_end_addr;
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t header_addr;
multiboot_uint32_t load_addr;
multiboot_uint32_t load_end_addr;
multiboot_uint32_t bss_end_addr;
};
struct multiboot_header_tag_entry_address
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t entry_addr;
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t entry_addr;
};
struct multiboot_header_tag_console_flags
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t console_flags;
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t console_flags;
};
struct multiboot_header_tag_framebuffer
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t width;
multiboot_uint32_t height;
multiboot_uint32_t depth;
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t width;
multiboot_uint32_t height;
multiboot_uint32_t depth;
};
struct multiboot_header_tag_module_align
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
};
struct multiboot_header_tag_relocatable
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t min_addr;
multiboot_uint32_t max_addr;
multiboot_uint32_t align;
multiboot_uint32_t preference;
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t min_addr;
multiboot_uint32_t max_addr;
multiboot_uint32_t align;
multiboot_uint32_t preference;
};
struct multiboot_color
{
multiboot_uint8_t red;
multiboot_uint8_t green;
multiboot_uint8_t blue;
multiboot_uint8_t red;
multiboot_uint8_t green;
multiboot_uint8_t blue;
};
struct multiboot_mmap_entry
{
multiboot_uint64_t addr;
multiboot_uint64_t len;
multiboot_uint64_t addr;
multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
#define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5
multiboot_uint32_t type;
multiboot_uint32_t zero;
multiboot_uint32_t type;
multiboot_uint32_t zero;
};
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
struct multiboot_tag
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t type;
multiboot_uint32_t size;
};
struct multiboot_tag_string
{
multiboot_uint32_t type;
multiboot_uint32_t size;
char string[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
char string[0];
};
struct multiboot_tag_module
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mod_start;
multiboot_uint32_t mod_end;
char cmdline[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mod_start;
multiboot_uint32_t mod_end;
char cmdline[0];
};
struct multiboot_tag_basic_meminfo
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mem_lower;
multiboot_uint32_t mem_upper;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mem_lower;
multiboot_uint32_t mem_upper;
};
struct multiboot_tag_bootdev
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t biosdev;
multiboot_uint32_t slice;
multiboot_uint32_t part;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t biosdev;
multiboot_uint32_t slice;
multiboot_uint32_t part;
};
struct multiboot_tag_mmap
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t entry_size;
multiboot_uint32_t entry_version;
struct multiboot_mmap_entry entries[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t entry_size;
multiboot_uint32_t entry_version;
struct multiboot_mmap_entry entries[0];
};
struct multiboot_vbe_info_block
{
multiboot_uint8_t external_specification[512];
multiboot_uint8_t external_specification[512];
};
struct multiboot_vbe_mode_info_block
{
multiboot_uint8_t external_specification[256];
multiboot_uint8_t external_specification[256];
};
struct multiboot_tag_vbe
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint16_t vbe_mode;
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;
multiboot_uint16_t vbe_mode;
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;
struct multiboot_vbe_info_block vbe_control_info;
struct multiboot_vbe_mode_info_block vbe_mode_info;
struct multiboot_vbe_info_block vbe_control_info;
struct multiboot_vbe_mode_info_block vbe_mode_info;
};
struct multiboot_tag_framebuffer_common
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t framebuffer_addr;
multiboot_uint32_t framebuffer_pitch;
multiboot_uint32_t framebuffer_width;
multiboot_uint32_t framebuffer_height;
multiboot_uint8_t framebuffer_bpp;
multiboot_uint64_t framebuffer_addr;
multiboot_uint32_t framebuffer_pitch;
multiboot_uint32_t framebuffer_width;
multiboot_uint32_t framebuffer_height;
multiboot_uint8_t framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
multiboot_uint8_t framebuffer_type;
multiboot_uint16_t reserved;
multiboot_uint8_t framebuffer_type;
multiboot_uint16_t reserved;
};
struct multiboot_tag_framebuffer
{
struct multiboot_tag_framebuffer_common common;
struct multiboot_tag_framebuffer_common common;
union
{
struct
{
multiboot_uint16_t framebuffer_palette_num_colors;
struct multiboot_color framebuffer_palette[0];
};
struct
{
multiboot_uint8_t framebuffer_red_field_position;
multiboot_uint8_t framebuffer_red_mask_size;
multiboot_uint8_t framebuffer_green_field_position;
multiboot_uint8_t framebuffer_green_mask_size;
multiboot_uint8_t framebuffer_blue_field_position;
multiboot_uint8_t framebuffer_blue_mask_size;
};
};
union
{
struct
{
multiboot_uint16_t framebuffer_palette_num_colors;
struct multiboot_color framebuffer_palette[0];
};
struct
{
multiboot_uint8_t framebuffer_red_field_position;
multiboot_uint8_t framebuffer_red_mask_size;
multiboot_uint8_t framebuffer_green_field_position;
multiboot_uint8_t framebuffer_green_mask_size;
multiboot_uint8_t framebuffer_blue_field_position;
multiboot_uint8_t framebuffer_blue_mask_size;
};
};
};
struct multiboot_tag_elf_sections
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t num;
multiboot_uint32_t entsize;
multiboot_uint32_t shndx;
char sections[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t num;
multiboot_uint32_t entsize;
multiboot_uint32_t shndx;
char sections[0];
};
struct multiboot_tag_apm
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint16_t version;
multiboot_uint16_t cseg;
multiboot_uint32_t offset;
multiboot_uint16_t cseg_16;
multiboot_uint16_t dseg;
multiboot_uint16_t flags;
multiboot_uint16_t cseg_len;
multiboot_uint16_t cseg_16_len;
multiboot_uint16_t dseg_len;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint16_t version;
multiboot_uint16_t cseg;
multiboot_uint32_t offset;
multiboot_uint16_t cseg_16;
multiboot_uint16_t dseg;
multiboot_uint16_t flags;
multiboot_uint16_t cseg_len;
multiboot_uint16_t cseg_16_len;
multiboot_uint16_t dseg_len;
};
struct multiboot_tag_efi32
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
};
struct multiboot_tag_efi64
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
};
struct multiboot_tag_smbios
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t major;
multiboot_uint8_t minor;
multiboot_uint8_t reserved[6];
multiboot_uint8_t tables[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t major;
multiboot_uint8_t minor;
multiboot_uint8_t reserved[6];
multiboot_uint8_t tables[0];
};
struct multiboot_tag_old_acpi
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
};
struct multiboot_tag_new_acpi
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
};
struct multiboot_tag_network
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t dhcpack[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t dhcpack[0];
};
struct multiboot_tag_efi_mmap
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t descr_size;
multiboot_uint32_t descr_vers;
multiboot_uint8_t efi_mmap[0];
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t descr_size;
multiboot_uint32_t descr_vers;
multiboot_uint8_t efi_mmap[0];
};
struct multiboot_tag_efi32_ih
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
};
struct multiboot_tag_efi64_ih
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
};
struct multiboot_tag_load_base_addr
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t load_base_addr;
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t load_base_addr;
};
#endif /* ! ASM_FILE */

View File

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

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

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

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

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

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

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

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

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

View File

@ -20,7 +20,7 @@
#include <types.h>
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include <errno.h>
#include <vector>
@ -50,15 +50,15 @@ namespace Execute
void *ELFProgramHeaders;
void GenerateAuxiliaryVector(Memory::VirtualMemoryArea *vma,
FileNode *fd, Elf_Ehdr ELFHeader,
Node &fd, Elf_Ehdr ELFHeader,
uintptr_t EntryPoint,
uintptr_t BaseAddress);
void LoadSegments(FileNode *fd, Tasking::PCB *TargetProcess, Elf_Ehdr &ELFHeader, uintptr_t &BaseAddress);
void LoadSegments(Node &fd, Tasking::PCB *TargetProcess, Elf_Ehdr &ELFHeader, uintptr_t &BaseAddress);
void LoadExec(FileNode *fd, Tasking::PCB *TargetProcess);
void LoadDyn(FileNode *fd, Tasking::PCB *TargetProcess);
bool LoadInterpreter(FileNode *fd, Tasking::PCB *TargetProcess);
void LoadExec(Node &fd, Tasking::PCB *TargetProcess);
void LoadDyn(Node &fd, Tasking::PCB *TargetProcess);
bool LoadInterpreter(Node &fd, Tasking::PCB *TargetProcess);
public:
decltype(IsElfValid) &IsValid = IsElfValid;
@ -74,7 +74,7 @@ namespace Execute
~ELFObject();
};
BinaryType GetBinaryType(FileNode *Path);
BinaryType GetBinaryType(Node &Path);
BinaryType GetBinaryType(std::string Path);
int Spawn(const char *Path, const char **argv, const char **envp,
@ -88,12 +88,12 @@ namespace Execute
char *GetELFStringTable(Elf_Ehdr *Header);
char *ELFLookupString(Elf_Ehdr *Header, uintptr_t Offset);
Elf_Sym *ELFLookupSymbol(Elf_Ehdr *Header, std::string Name);
Elf_Sym ELFLookupSymbol(FileNode *fd, std::string Name);
Elf_Sym ELFLookupSymbol(Node &fd, std::string Name);
uintptr_t ELFGetSymbolValue(Elf_Ehdr *Header, uintptr_t Table, uintptr_t Index);
std::vector<Elf_Phdr> ELFGetSymbolType(FileNode *fd, SegmentTypes Tag);
std::vector<Elf_Shdr> ELFGetSections(FileNode *fd, std::string SectionName);
std::vector<Elf_Dyn> ELFGetDynamicTag(FileNode *fd, DynamicArrayTags Tag);
std::vector<Elf_Phdr> ELFGetSymbolType(Node &fd, SegmentTypes Tag);
std::vector<Elf_Shdr> ELFGetSections(Node &fd, std::string SectionName);
std::vector<Elf_Dyn> ELFGetDynamicTag(Node &fd, DynamicArrayTags Tag);
}
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__

View File

@ -1,260 +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/>.
*/
#ifndef __FENNIX_KERNEL_FILESYSTEM_H__
#define __FENNIX_KERNEL_FILESYSTEM_H__
#include <types.h>
#include <interface/fs.h>
#include <unordered_map>
#include <lock.hpp>
#include <errno.h>
#include <atomic>
#include <string>
#include <list>
static_assert(DTTOIF(DT_FIFO) == S_IFIFO);
static_assert(IFTODT(S_IFCHR) == DT_CHR);
/**
* This macro is used to check if a filesystem operation is available.
*
* TL;DR
*
* @code
* if FileSystemInfo.Ops.op == nullptr
* return -err
* else
* return FileSystemInfo.Ops.op(this->Node, ...);
* @endcode
*
* @param op The operation to check.
* @param err The error to return if the operation is not available.
* @param ... The arguments to pass to the operation.
*
* @return The result of the operation.
*/
#define __check_op(op, err, ...) \
if (fsi->Ops.op == nullptr) \
return -err; \
else \
return fsi->Ops.op(this->Node, ##__VA_ARGS__)
#define FSROOT(num) "\x06root-" #num "\x06"
class FileNode
{
public:
std::string Name, Path;
FileNode *Parent;
std::vector<FileNode *> Children;
Inode *Node;
FileSystemInfo *fsi;
std::string GetName();
std::string GetPath();
bool IsDirectory() { return S_ISDIR(Node->Mode); }
bool IsCharacterDevice() { return S_ISCHR(Node->Mode); }
bool IsBlockDevice() { return S_ISBLK(Node->Mode); }
bool IsRegularFile() { return S_ISREG(Node->Mode); }
bool IsFIFO() { return S_ISFIFO(Node->Mode); }
bool IsSymbolicLink() { return S_ISLNK(Node->Mode); }
bool IsSocket() { return S_ISSOCK(Node->Mode); }
int Lookup(const char *Name, Inode **Node) { __check_op(Lookup, ENOTSUP, Name, Node); }
int Create(const char *Name, mode_t Mode, Inode **Node) { __check_op(Create, EROFS, Name, Mode, Node); }
int Remove(const char *Name) { __check_op(Remove, EROFS, Name); }
int Rename(const char *OldName, const char *NewName) { __check_op(Rename, EROFS, OldName, NewName); }
ssize_t Read(auto Buffer, size_t Size, off_t Offset) { __check_op(Read, ENOTSUP, (void *)Buffer, Size, Offset); }
ssize_t Write(const auto Buffer, size_t Size, off_t Offset) { __check_op(Write, EROFS, (const void *)Buffer, Size, Offset); }
int Truncate(off_t Size) { __check_op(Truncate, EROFS, Size); }
int Open(int Flags, mode_t Mode) { __check_op(Open, ENOTSUP, Flags, Mode); }
int Close() { __check_op(Close, ENOTSUP); }
int Ioctl(unsigned long Request, void *Argp) { __check_op(Ioctl, ENOTSUP, Request, Argp); }
ssize_t ReadDir(struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries) { __check_op(ReadDir, ENOTSUP, Buffer, Size, Offset, Entries); }
int MkDir(const char *Name, mode_t Mode, struct Inode **Result) { __check_op(MkDir, EROFS, Name, Mode, Result); }
int RmDir(const char *Name) { __check_op(RmDir, EROFS, Name); }
int SymLink(const char *Name, const char *Target, struct Inode **Result) { __check_op(SymLink, EROFS, Name, Target, Result); }
ssize_t ReadLink(auto Buffer, size_t Size) { __check_op(ReadLink, ENOTSUP, (char *)Buffer, Size); }
off_t Seek(off_t Offset) { __check_op(Seek, ENOTSUP, Offset); }
int Stat(struct kstat *Stat) { __check_op(Stat, ENOTSUP, Stat); }
~FileNode() = delete;
};
#undef __check_op
namespace vfs
{
struct vfsInode
{
Inode Node;
std::string Name;
std::string FriendlyName;
std::vector<Inode *> Children;
};
class Virtual
{
private:
NewLock(VirtualLock);
struct FSMountInfo
{
FileSystemInfo *fsi;
Inode *Root;
};
struct CacheNode
{
FileNode *fn;
std::atomic_int References;
};
std::unordered_map<dev_t, FSMountInfo> DeviceMap;
std::atomic_bool RegisterLock = false;
FileNode *CacheSearchReturnLast(FileNode *Parent, const char **Path);
FileNode *CacheRecursiveSearch(FileNode *Root, const char *NameOrPath, bool IsName);
FileNode *CacheLookup(FileNode *Parent, const char *Path);
FileNode *CreateCacheNode(FileNode *Parent, Inode *Node, const char *Name, mode_t Mode);
int RemoveCacheNode(FileNode *Node);
public:
vfsInode *FileSystemRoots = nullptr;
/**
* Default reserved roots:
*
* 0 - Native
* 1 - Linux
* 2 - Windows
*/
std::unordered_map<ino_t, FileNode *> FileRoots;
bool PathIsRelative(const char *Path);
bool PathIsAbsolute(const char *Path) { return !PathIsRelative(Path); }
/**
* Reserve a device number for a filesystem
*
* @note After this function is called, the filesystem must
* call LateRegisterFileSystem to release the lock
*/
dev_t EarlyReserveDevice();
/**
* Register a filesystem after the device number has been reserved
*/
int LateRegisterFileSystem(dev_t Device, FileSystemInfo *fsi, Inode *Root);
dev_t RegisterFileSystem(FileSystemInfo *fsi, Inode *Root);
int UnregisterFileSystem(dev_t Device);
void AddRoot(Inode *Root);
void AddRootAt(Inode *Root, size_t Index);
bool SetRootAt(Inode *Root, size_t Index);
void RemoveRoot(Inode *Root);
FileNode *GetRoot(size_t Index);
bool RootExists(size_t Index);
FileNode *Create(FileNode *Parent, const char *Name, mode_t Mode);
FileNode *ForceCreate(FileNode *Parent, const char *Name, mode_t Mode);
FileNode *Mount(FileNode *Parent, Inode *Node, const char *Path);
int Unmount(const char *Path);
FileNode *GetByPath(const char *Path, FileNode *Parent);
std::string GetByNode(FileNode *Node);
FileNode *CreateLink(const char *Path, FileNode *Parent, const char *Target);
FileNode *CreateLink(const char *Path, FileNode *Parent, FileNode *Target);
bool PathExists(const char *Path, FileNode *Parent);
int Remove(FileNode *Node);
void Initialize();
Virtual();
~Virtual();
};
class FileDescriptorTable
{
public:
struct Fildes
{
enum FildesType
{
FD_INODE,
FD_PIPE,
FD_SOCKET,
} Type;
mode_t Mode = 0;
int Flags = 0;
FileNode *Node = nullptr;
int References = 0;
off_t Offset = 0;
int operator==(const Fildes &other)
{
return Type == other.Type &&
Mode == other.Mode &&
Flags == other.Flags &&
Node == other.Node &&
References == other.References &&
Offset == other.Offset;
}
};
private:
FileNode *fdDir = nullptr;
void *Owner;
int AddFileDescriptor(const char *AbsolutePath, mode_t Mode, int Flags);
int RemoveFileDescriptor(int FileDescriptor);
int GetFreeFileDescriptor();
public:
std::unordered_map<int, Fildes> FileMap;
int GetFlags(int FileDescriptor);
int SetFlags(int FileDescriptor, int Flags);
void Fork(FileDescriptorTable *Parent);
int usr_open(const char *pathname, int flags, mode_t mode);
int usr_creat(const char *pathname, mode_t mode);
ssize_t usr_read(int fd, void *buf, size_t count);
ssize_t usr_write(int fd, const void *buf, size_t count);
ssize_t usr_pread(int fd, void *buf, size_t count, off_t offset);
ssize_t usr_pwrite(int fd, const void *buf, size_t count, off_t offset);
int usr_close(int fd);
off_t usr_lseek(int fd, off_t offset, int whence);
int usr_stat(const char *pathname, struct kstat *statbuf);
int usr_fstat(int fd, struct kstat *statbuf);
int usr_lstat(const char *pathname, struct kstat *statbuf);
int usr_dup(int oldfd);
int usr_dup2(int oldfd, int newfd);
int usr_ioctl(int fd, unsigned long request, void *argp);
FileDescriptorTable(void *Owner);
~FileDescriptorTable() = default;
};
}
#endif // !__FENNIX_KERNEL_FILESYSTEM_H__

86
Kernel/include/fs/fdt.hpp Normal file
View File

@ -0,0 +1,86 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <fs/node.hpp>
#include <unordered_map>
namespace vfs
{
class FileDescriptorTable
{
public:
struct Fildes
{
enum FildesType
{
FD_INODE,
FD_PIPE,
FD_SOCKET,
} Type;
mode_t Mode = 0;
int Flags = 0;
Node node = nullptr;
int References = 0;
off_t Offset = 0;
int operator==(const Fildes &other)
{
return Type == other.Type &&
Mode == other.Mode &&
Flags == other.Flags &&
node.get() == other.node.get() &&
References == other.References &&
Offset == other.Offset;
}
};
private:
Node fdDir = nullptr;
void *Owner;
int AddFileDescriptor(const char *AbsolutePath, mode_t Mode, int Flags);
int RemoveFileDescriptor(int FileDescriptor);
int GetFreeFileDescriptor();
public:
std::unordered_map<int, Fildes> FileMap;
int GetFlags(int FileDescriptor);
int SetFlags(int FileDescriptor, int Flags);
void Fork(FileDescriptorTable *Parent);
int usr_open(const char *pathname, int flags, mode_t mode);
int usr_creat(const char *pathname, mode_t mode);
ssize_t usr_read(int fd, void *buf, size_t count);
ssize_t usr_write(int fd, const void *buf, size_t count);
ssize_t usr_pread(int fd, void *buf, size_t count, off_t offset);
ssize_t usr_pwrite(int fd, const void *buf, size_t count, off_t offset);
int usr_close(int fd);
off_t usr_lseek(int fd, off_t offset, int whence);
int usr_stat(const char *pathname, kstat *statbuf);
int usr_fstat(int fd, kstat *statbuf);
int usr_lstat(const char *pathname, kstat *statbuf);
int usr_dup(int oldfd);
int usr_dup2(int oldfd, int newfd);
int usr_ioctl(int fd, unsigned long request, void *argp);
FileDescriptorTable(void *Owner);
~FileDescriptorTable() = default;
};
}

207
Kernel/include/fs/node.hpp Normal file
View File

@ -0,0 +1,207 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <interface/fs.h>
#include <errno.h>
#include <string>
#include <vector>
/**
* This macro is used to check if a filesystem operation is available.
*
* TL;DR
*
* @code
* if FileSystemInfo.Ops.op == nullptr
* return -err
* else
* return FileSystemInfo.Ops.op(this->Node, ...);
* @endcode
*
* @param op The operation to check.
* @param err The error to return if the operation is not available.
* @param ... The arguments to pass to the operation.
*
* @return The result of the operation.
*/
#define __check_op(op, err, ...) \
if (unlikely(fsi->Ops.op == nullptr)) \
return -err; \
else \
return fsi->Ops.op(this->inode, ##__VA_ARGS__)
namespace vfs
{
class NodeObject
{
public:
Inode *inode;
FileSystemInfo *fsi;
union
{
struct
{
uint8_t MountPoint : 1;
uint8_t __reserved : 7;
};
uint8_t raw;
} Flags;
int __Lookup(const char *Name, Inode **Node) { __check_op(Lookup, ENOTSUP, Name, Node); }
int __Create(const char *Name, mode_t Mode, Inode **Node) { __check_op(Create, ENOTSUP, Name, Mode, Node); }
int __Remove(const char *Name) { __check_op(Remove, ENOTSUP, Name); }
int __Rename(const char *OldName, const char *NewName) { __check_op(Rename, ENOTSUP, OldName, NewName); }
ssize_t __Read(auto Buffer, size_t Size, off_t Offset) { __check_op(Read, ENOTSUP, (void *)Buffer, Size, Offset); }
ssize_t __Write(const auto Buffer, size_t Size, off_t Offset) { __check_op(Write, ENOTSUP, (const void *)Buffer, Size, Offset); }
int __Truncate(off_t Size) { __check_op(Truncate, ENOTSUP, Size); }
int __Open(int Flags, mode_t Mode) { __check_op(Open, ENOTSUP, Flags, Mode); }
int __Close() { __check_op(Close, ENOTSUP); }
int __Ioctl(unsigned long Request, void *Argp) { __check_op(Ioctl, ENOTSUP, Request, Argp); }
ssize_t __ReadDir(struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries) { __check_op(ReadDir, ENOTSUP, Buffer, Size, Offset, Entries); }
int __MkDir(const char *Name, mode_t Mode, struct Inode **Result) { __check_op(MkDir, ENOTSUP, Name, Mode, Result); }
int __RmDir(const char *Name) { __check_op(RmDir, ENOTSUP, Name); }
int __SymLink(const char *Name, const char *Target, struct Inode **Result) { __check_op(SymLink, ENOTSUP, Name, Target, Result); }
ssize_t __ReadLink(auto Buffer, size_t Size) { __check_op(ReadLink, ENOTSUP, (char *)Buffer, Size); }
off_t __Seek(off_t Offset) { __check_op(Seek, ENOTSUP, Offset); }
int __Stat(struct kstat *Stat) { __check_op(Stat, ENOTSUP, Stat); }
~NodeObject()
{
debug("%#lx destructor called", this);
}
};
}
class NodeCache;
/**
* @brief Node is a type that represents a filesystem node.
* It is a shared pointer to a NodeCache object.
*
* If the refcount of the NodeCache object goes to zero, the data is synced to disk.
*/
typedef std::shared_ptr<NodeCache> Node;
/**
* @brief NodeResult is a type that represents the result of a filesystem operation.
* It contains a Node object and an error code.
*/
typedef struct NodeResult
{
/* Value must be the first member of the struct to allow for implicit conversion */
Node Value;
int Error;
operator bool() const { return Error == 0 && Value.get() != nullptr; }
operator Node() const { return Value; }
const char *what() const { return strerror(Error); }
} eNode;
class NodeCache : public vfs::NodeObject
{
public:
std::string Name, Path, Link;
/**
* @brief Parent of this node
*
* Maximum depth is 1, otherwise undefined behavior.
*/
Node Parent;
/**
* @brief Childrens of this node
*
* On access, children are loaded, but not children of children!
* Accessing children of children is undefined behavior.
*/
std::vector<Node> Children;
std::string GetName() { return Name; }
std::string GetPath() { return Path; }
std::string GetLink() { return Link; }
bool IsDirectory() { return S_ISDIR(inode->Mode); }
bool IsCharacterDevice() { return S_ISCHR(inode->Mode); }
bool IsBlockDevice() { return S_ISBLK(inode->Mode); }
bool IsRegularFile() { return S_ISREG(inode->Mode); }
bool IsFIFO() { return S_ISFIFO(inode->Mode); }
bool IsSymbolicLink() { return S_ISLNK(inode->Mode); }
bool IsSocket() { return S_ISSOCK(inode->Mode); }
bool IsMountPoint() { return Flags.MountPoint; }
/**
* @brief Search through the cached children of this node
*
* Searches through the cached children of this node.
*
* @param Name The name to search for
* @return 0 and a Node on success, ENOENT on failure
*/
eNode CachedSearch(std::string Name)
{
for (auto it = Children.begin(); it != Children.end(); ++it)
{
if ((*it).get() == nullptr)
{
Children.erase(it);
continue;
}
debug("comparing \"%s\" with \"%s\"", (*it)->Name.c_str(), Name.c_str());
if ((*it)->Name == Name)
{
debug("\"%s\" found", Name.c_str());
return {*it, 0};
}
}
return {nullptr, ENOENT};
}
/**
* @brief Get the allocation size of this object
*
* @return The allocated size
*/
size_t GetAllocationSize()
{
size_t size = sizeof(NodeCache);
size += Name.capacity();
size += Path.capacity();
size += Link.capacity();
size += Children.capacity();
return size;
}
~NodeCache()
{
debug("%#lx\"%s\" destructor called", this, Name.c_str());
if (this->Parent)
this->Parent->Children.erase(std::remove(this->Parent->Children.begin(), this->Parent->Children.end(), Node(this)), this->Parent->Children.end());
if (fsi->SuperOps.Synchronize)
fsi->SuperOps.Synchronize(this->fsi, this->inode);
// FIXME: recursive deletion of nodes children
}
};
#undef __check_op

View File

@ -17,7 +17,7 @@
#pragma once
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <memory.hpp>
namespace vfs
@ -147,4 +147,4 @@ namespace vfs
};
}
bool MountRAMFS(FileNode *Parent, const char *Name, size_t Index);
bool MountAndRootRAMFS(Node Parent, const char *Name, size_t Index);

View File

@ -18,7 +18,7 @@
#ifndef __FENNIX_KERNEL_FILESYSTEM_USTAR_H__
#define __FENNIX_KERNEL_FILESYSTEM_USTAR_H__
#include <filesystem.hpp>
#include <fs/vfs.hpp>
namespace vfs
{

247
Kernel/include/fs/vfs.hpp Normal file
View File

@ -0,0 +1,247 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <fs/fdt.hpp>
#include <errno.h>
#include <cwalk.h>
#include <atomic>
#include <string>
#include <list>
/* sanity checks */
static_assert(DTTOIF(DT_FIFO) == S_IFIFO);
static_assert(IFTODT(S_IFCHR) == DT_CHR);
namespace vfs
{
class Virtual
{
private:
std::unordered_map<dev_t, Node> Roots;
std::unordered_map<dev_t, FileSystemInfo *> FileSystems;
public:
#pragma region Utilities
inline bool PathIsRelative(const char *Path) { return cwk_path_is_relative(Path); }
inline bool PathIsAbsolute(const char *Path) { return !PathIsRelative(Path); }
inline bool PathIsRelative(std::string &Path) { return cwk_path_is_relative(Path.c_str()); }
inline bool PathIsAbsolute(std::string &Path) { return !PathIsRelative(Path.c_str()); }
eNode Convert(Node node) { return {node, 0}; }
/**
* @brief Converts an Inode to a Node
*
* Result of this function will be empty.
* You are responsible to populate the Node.
*
* @param inode Inode to convert
* @return eNode{Node, errno}
*/
eNode Convert(Inode *inode);
/**
* @brief Converts an Inode to a Node
*
* Result of this function will be populated using the Parent Node.
* This function will automatically assign the FSI, parents and children.
*
* @note Name and Path won't be set.
*
* @param Parent Parent Node
* @param inode Inode to convert
* @return eNode{Node, errno}
*/
eNode Convert(Node &Parent, Inode *inode);
/**
* @brief Normalizes a path
*
* If the path is relative, it will be normalized using the Parent Node.
* Example if Join is true:
* Parent = /home/user/Desktop
* Path = ../Documents
* Result = /home/user/Documents
*
* If Join is false:
* Path = /var/foo/bar/../../
* Result = /var
*
* @param Parent Parent Node
* @param Path Path to normalize
* @param Join If true, the path will be joined with the Parent Node
* @return Normalized Path
*/
std::string NormalizePath(Node &Parent, std::string Path, bool Join = false);
#pragma endregion Utilities
#pragma region Roots
bool RootExists(dev_t Index);
eNode GetRoot(dev_t Index);
ssize_t GetRoot(Node Index);
int AddRoot(dev_t Index, Node Root, bool Replace = false);
int AddRoot(dev_t Index, eNode Root, bool Replace = false) { return AddRoot(Index, Root.Value, Replace); }
#pragma endregion Roots
#pragma region Registrations
dev_t RegisterFileSystem(FileSystemInfo *fsi);
int UnregisterFileSystem(dev_t Device);
#pragma endregion Registrations
#pragma region Node Operations
eNode Lookup(Node &Parent, std::string Path);
eNode Create(Node &Parent, std::string Name, mode_t Mode, bool ErrorIfExists = true);
int Remove(Node &Parent, std::string Name);
int Remove(Node &node);
int Rename(Node &node, std::string NewName);
ssize_t Read(Node &Target, void *Buffer, size_t Size, off_t Offset);
ssize_t Write(Node &Target, const void *Buffer, size_t Size, off_t Offset);
int Truncate(Node &Target, off_t Size);
/**
* @brief Read directory entries
*
* @note This function includes "." and ".."
*
* @param Target
* @param Buffer
* @param Size
* @param Offset
* @param Entries
* @return
*/
ssize_t ReadDirectory(Node &Target, kdirent *Buffer, size_t Size, off_t Offset, off_t Entries);
/**
* @brief Read directory entries
*
* @note This function does NOT include "." and ".."
*
* @param Target
* @return
*/
std::list<Node> ReadDirectory(Node &Target);
eNode CreateLink(Node &Parent, std::string Name, std::string Target);
eNode CreateLink(Node &Parent, std::string Name, Node &Target) { return this->CreateLink(Parent, Name, Target->Path); }
int Stat(Node &Target, kstat *Stat);
int ReadLink(Node &Target, char *Buffer, size_t Size) { return Target->__ReadLink(Buffer, Size); }
off_t Seek(Node &Target, off_t Offset);
int Open(Node &Target, int Flags, mode_t Mode);
int Close(Node &Target);
int Ioctl(Node &Target, unsigned long Request, void *Argp) { return Target->__Ioctl(Request, Argp); }
#pragma endregion Node Operations
#pragma region Mounting
FileSystemInfo *Probe(FileSystemDevice *Device);
FileSystemInfo *Probe(Node &node)
{
FileSystemDevice dev;
dev.inode.node = node->inode;
dev.inode.ops = &node->fsi->Ops;
dev.Block = nullptr;
return this->Probe(&dev);
}
FileSystemInfo *Probe(BlockDevice *Device)
{
FileSystemDevice dev;
dev.inode.node = nullptr;
dev.inode.ops = nullptr;
dev.Block = Device;
return this->Probe(&dev);
}
/**
* @brief Mount a filesystem
*
*
*
* @param Parent Parent Node
* @param inode Inode from the filesystem as root of the mount point
* @param Name Name of the mount point
* @param fsi FileSystemInfo structure
* @return eNode{Node, errno}
*/
eNode Mount(Node &Parent, Inode *inode, std::string Name, FileSystemInfo *fsi);
/**
* @brief Mount a filesystem
*
*
*
* @param Parent Parent Node
* @param Name Name of the mount point
* @param fsi FileSystemInfo structure
* @param Device Device to mount
* @return eNode{Node, errno}
*/
eNode Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device);
/**
* Wrapper for Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device)
*/
eNode Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, Node Device)
{
FileSystemDevice dev;
dev.inode.node = Device->inode;
dev.inode.ops = &Device->fsi->Ops;
dev.Block = nullptr;
return this->Mount(Parent, Name, fsi, &dev);
}
/**
* Wrapper for Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device)
*/
eNode Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, BlockDevice *Device)
{
FileSystemDevice dev;
dev.inode.node = nullptr;
dev.inode.ops = nullptr;
dev.Block = Device;
return this->Mount(Parent, Name, fsi, &dev);
}
int Umount(Node &node);
int Umount(Node &Parent, std::string Name);
#pragma endregion Mounting
void Initialize();
Virtual();
~Virtual();
};
}

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

@ -322,11 +322,29 @@ struct InodeOperations
int (*Stat)(struct Inode *Node, struct kstat *Stat);
} __attribute__((packed));
#define I_FLAG_ROOT 0x1
#define I_FLAG_MOUNTPOINT 0x2
#define I_FLAG_CACHE_KEEP 0x4
struct FileSystemInfo;
struct FileSystemDevice
{
struct
{
/**
* @brief Inode
*
* If the device is a block device, this will be NULL.
*/
struct Inode *node;
struct InodeOperations *ops;
} inode;
/**
* @brief Block Device
*
* If the device is a block device, this will be non-NULL.
*/
struct BlockDevice *Block;
};
struct SuperBlockOperations
{
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
@ -337,8 +355,8 @@ struct SuperBlockOperations
*
* Write all pending changes to the disk.
*
* @param Info Inode to synchronize. If NULL, synchronize all inodes.
* @param Node Inode to synchronize.
* @param Info Inode to synchronize.
* @param Node Inode to synchronize. If NULL, synchronize all inodes.
*
* @return Zero on success, otherwise an error code.
*/
@ -354,13 +372,50 @@ struct SuperBlockOperations
* @return Zero on success, otherwise an error code.
*/
int (*Destroy)(struct FileSystemInfo *Info);
/**
* Probe the filesystem.
*
* Check if the filesystem is supported by the driver.
*
* @param Device Device to probe.
*
* @return Zero on success, otherwise an error code.
*/
int (*Probe)(struct FileSystemDevice *Device);
/**
* Mount the filesystem.
*
* Mount the filesystem on the given device.
*
* @param FS Filesystem to mount.
* @param Root Pointer to the root inode.
* @param Device Device to mount. This pointer will be undefined after the function returns!
*
* @return Zero on success, otherwise an error code.
*/
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, struct FileSystemDevice *Device);
/**
* Unmount the filesystem.
*
* Unmount the filesystem from the given device.
*
* @param FS Filesystem to unmount.
*
* @return Zero on success, otherwise an error code.
*/
int (*Unmount)(struct FileSystemInfo *FS);
} __attribute__((packed));
struct FileSystemInfo
{
const char *Name;
const char *RootName;
int Flags;
int Capabilities;
struct SuperBlockOperations SuperOps;
struct InodeOperations Ops;
@ -368,6 +423,9 @@ struct FileSystemInfo
} __attribute__((packed));
#ifndef __kernel__
dev_t RegisterMountPoint(FileSystemInfo *fsi, Inode *Root);
int UnregisterMountPoint(dev_t Device);
dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
int UnregisterFileSystem(dev_t Device);
#endif // !__kernel__

View File

@ -155,8 +155,6 @@ namespace KernelConsole
*/
extern ConsoleTerminal *Terminals[16];
extern std::atomic<ConsoleTerminal *> CurrentTerminal;
extern int TermColors[];
extern int TermBrightColors[];
bool SetTheme(std::string Theme);

View File

@ -19,7 +19,7 @@
#define __FENNIX_KERNEL_INTERNAL_MEMORY_H__
#ifdef __cplusplus
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <boot/binfo.h>
#include <bitmap.hpp>
#include <lock.hpp>

View File

@ -19,7 +19,7 @@
#define __FENNIX_KERNEL_MEMORY_VMA_H__
#include <types.h>
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <bitmap.hpp>
#include <lock.hpp>
#include <list>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
#include <types.h>
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <memory/va.hpp>
#include <symbols.hpp>
#include <memory.hpp>
@ -219,7 +219,7 @@ namespace Tasking
TaskArchitecture Architecture = TaskArchitecture::UnknownArchitecture;
TaskCompatibility Compatibility = TaskCompatibility::UnknownPlatform;
cwk_path_style PathStyle = CWK_STYLE_UNIX;
FileNode *RootNode = nullptr;
Node RootNode = nullptr;
};
struct ThreadLocalStorage
@ -445,7 +445,7 @@ namespace Tasking
PID ID = -1;
const char *Name = nullptr;
PCB *Parent = nullptr;
FileNode *ProcDirectory = nullptr;
Node ProcDirectory = nullptr;
/* Statuses */
std::atomic_int ExitCode;
@ -489,14 +489,14 @@ namespace Tasking
} Linux{};
/* Filesystem */
FileNode *CWD;
FileNode *Executable;
Node CWD;
Node Executable;
FileDescriptorTable *FileDescriptors;
/* stdio */
FileNode *stdin;
FileNode *stdout;
FileNode *stderr;
Node stdin;
Node stdout;
Node stderr;
/*TTY::TeletypeDriver*/ void *tty;
/* Memory */
@ -521,7 +521,7 @@ namespace Tasking
void SetState(TaskState state);
void SetExitCode(int code);
void Rename(const char *name);
void SetWorkingDirectory(FileNode *node);
void SetWorkingDirectory(Node node);
void SetExe(const char *path);
size_t GetSize();
TCB *GetThread(TID ID);

View File

@ -458,6 +458,10 @@ typedef uint48_t uint_fast48_t;
#define hot __attribute__((hot))
#define cold __attribute__((cold))
#define OPTIONAL
#define IN
#define OUT
#define NoSecurityAnalysis __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_sanitize_thread
#define nsa NoSecurityAnalysis
@ -476,12 +480,11 @@ typedef uint48_t uint_fast48_t;
*((type *)stack++)
#define ReturnLogError(ret, format, ...) \
do \
{ \
trace(format, ##__VA_ARGS__); \
return ret; \
} \
while (0) \
__builtin_unreachable()
} while (0)
#define AssertReturnError(condition, ret) \
do \

View File

@ -17,9 +17,16 @@
#pragma once
#include <utility>
#include <cstddef>
namespace std
{
template <typename T>
typename std::remove_reference<T>::type &&__algo_move(T &&arg)
{
return static_cast<typename std::remove_reference<T>::type &&>(arg);
}
template <typename InputIt, typename OutputIt>
OutputIt copy(InputIt first, InputIt last, OutputIt result)
{
@ -57,9 +64,9 @@ namespace std
template <class T>
void swap(T &a, T &b) noexcept(std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value)
{
T temp = std::move(a);
a = std::move(b);
b = std::move(temp);
T temp = __algo_move(a);
a = __algo_move(b);
b = __algo_move(temp);
}
template <class T2, std::size_t N>
@ -180,7 +187,7 @@ namespace std
if (first != last)
for (ForwardIt i = first; ++i != last;)
if (!(*i == value))
*first++ = std::move(*i);
*first++ = __algo_move(*i);
return first;
}
@ -191,7 +198,7 @@ namespace std
if (first != last)
for (ForwardIt i = first; ++i != last;)
if (!p(*i))
*first++ = std::move(*i);
*first++ = __algo_move(*i);
return first;
}
@ -362,4 +369,44 @@ namespace std
template <class ExecutionPolicy, class RandomIt, class Compare>
void sort(ExecutionPolicy &&policy, RandomIt first, RandomIt last, Compare comp);
template <class InputIt1, class InputIt2>
constexpr bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
{
for (; (first1 != last1) && (first2 != last2); ++first1, (void)++first2)
{
if (*first1 < *first2)
return true;
if (*first2 < *first1)
return false;
}
return (first1 == last1) && (first2 != last2);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2>
bool lexicographical_compare(ExecutionPolicy &&policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2);
template <class InputIt1, class InputIt2, class Compare>
constexpr bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp)
{
for (; (first1 != last1) && (first2 != last2); ++first1, (void)++first2)
{
if (comp(*first1, *first2))
return true;
if (comp(*first2, *first1))
return false;
}
return (first1 == last1) && (first2 != last2);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class Compare>
bool lexicographical_compare(ExecutionPolicy &&policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2, Compare comp);
template <class InputIt1, class InputIt2, class Cmp>
constexpr auto lexicographical_compare_three_way(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Cmp comp) -> decltype(comp(*first1, *first2));
template <class InputIt1, class InputIt2>
constexpr auto lexicographical_compare_three_way(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2);
}

295
Kernel/include_std/compare Normal file
View File

@ -0,0 +1,295 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <type_traits>
#include <utility>
#include <cmath>
namespace std
{
namespace __cmp_dtl
{
using type = signed char;
enum order : type
{
less = -1,
equivalent = 0,
greater = 1,
unordered = 2
};
struct __unspecified
{
consteval __unspecified(__unspecified *) noexcept {}
};
};
class partial_ordering
{
private:
__cmp_dtl::type value;
constexpr explicit partial_ordering(__cmp_dtl::order v) noexcept : value(__cmp_dtl::type(v)) {}
friend class weak_ordering;
friend class strong_ordering;
public:
static const partial_ordering less;
static const partial_ordering equivalent;
static const partial_ordering greater;
static const partial_ordering unordered;
friend constexpr bool operator==(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 0; }
friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default;
friend constexpr bool operator<(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == -1; }
friend constexpr bool operator<(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return v.value == 1; }
friend constexpr bool operator<=(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value <= 0; }
friend constexpr bool operator<=(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return __cmp_dtl::type(v.value & 1) == v.value; }
friend constexpr bool operator>(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 1; }
friend constexpr bool operator>(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return v.value == -1; }
friend constexpr bool operator>=(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return __cmp_dtl::type(v.value & 1) == v.value; }
friend constexpr bool operator>=(__cmp_dtl::__unspecified u, partial_ordering v) noexcept { return 0 >= v.value; }
friend constexpr partial_ordering operator<=>(partial_ordering v, __cmp_dtl::__unspecified u) noexcept { return v; }
friend constexpr partial_ordering operator<=>(__cmp_dtl::__unspecified u, partial_ordering v) noexcept
{
if (v.value & 1)
return partial_ordering(__cmp_dtl::order(-v.value));
else
return v;
}
};
inline constexpr partial_ordering partial_ordering::less(__cmp_dtl::order::less);
inline constexpr partial_ordering partial_ordering::equivalent(__cmp_dtl::order::equivalent);
inline constexpr partial_ordering partial_ordering::greater(__cmp_dtl::order::greater);
inline constexpr partial_ordering partial_ordering::unordered(__cmp_dtl::order::unordered);
class weak_ordering
{
private:
__cmp_dtl::type value;
constexpr explicit weak_ordering(__cmp_dtl::order v) noexcept : value(__cmp_dtl::type(v)) {}
friend class strong_ordering;
public:
static const weak_ordering less;
static const weak_ordering equivalent;
static const weak_ordering greater;
constexpr operator partial_ordering() const noexcept
{
return partial_ordering(__cmp_dtl::order(value));
}
friend constexpr bool operator==(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 0; }
friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default;
friend constexpr bool operator<(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value < 0; }
friend constexpr bool operator<(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 < v.value; }
friend constexpr bool operator<=(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value <= 0; }
friend constexpr bool operator<=(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 <= v.value; }
friend constexpr bool operator>(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value > 0; }
friend constexpr bool operator>(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 > v.value; }
friend constexpr bool operator>=(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value >= 0; }
friend constexpr bool operator>=(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return 0 >= v.value; }
friend constexpr weak_ordering operator<=>(weak_ordering v, __cmp_dtl::__unspecified u) noexcept { return v; }
friend constexpr weak_ordering operator<=>(__cmp_dtl::__unspecified u, weak_ordering v) noexcept { return weak_ordering(__cmp_dtl::order(-v.value)); }
};
inline constexpr weak_ordering weak_ordering::less(__cmp_dtl::order::less);
inline constexpr weak_ordering weak_ordering::equivalent(__cmp_dtl::order::equivalent);
inline constexpr weak_ordering weak_ordering::greater(__cmp_dtl::order::greater);
class strong_ordering
{
private:
__cmp_dtl::type value;
constexpr explicit strong_ordering(__cmp_dtl::order v) noexcept : value(__cmp_dtl::type(v)) {}
public:
static const strong_ordering less;
static const strong_ordering equivalent;
static const strong_ordering equal;
static const strong_ordering greater;
constexpr operator partial_ordering() const noexcept
{
return partial_ordering(__cmp_dtl::order(value));
}
constexpr operator weak_ordering() const noexcept
{
return weak_ordering(__cmp_dtl::order(value));
}
friend constexpr bool operator==(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value == 0; }
friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default;
friend constexpr bool operator<(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value < 0; }
friend constexpr bool operator<(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 < v.value; }
friend constexpr bool operator<=(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value <= 0; }
friend constexpr bool operator<=(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 <= v.value; }
friend constexpr bool operator>(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value > 0; }
friend constexpr bool operator>(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 > v.value; }
friend constexpr bool operator>=(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v.value >= 0; }
friend constexpr bool operator>=(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return 0 >= v.value; }
friend constexpr strong_ordering operator<=>(strong_ordering v, __cmp_dtl::__unspecified u) noexcept { return v; }
friend constexpr strong_ordering operator<=>(__cmp_dtl::__unspecified u, strong_ordering v) noexcept { return strong_ordering(__cmp_dtl::order(-v.value)); }
};
inline constexpr strong_ordering strong_ordering::less(__cmp_dtl::order::less);
inline constexpr strong_ordering strong_ordering::equivalent(__cmp_dtl::order::equivalent);
inline constexpr strong_ordering strong_ordering::equal(__cmp_dtl::order::equivalent);
inline constexpr strong_ordering strong_ordering::greater(__cmp_dtl::order::greater);
constexpr bool is_eq(partial_ordering cmp) noexcept { return cmp == 0; }
constexpr bool is_neq(partial_ordering cmp) noexcept { return cmp != 0; }
constexpr bool is_lt(partial_ordering cmp) noexcept { return cmp < 0; }
constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
constexpr bool is_gt(partial_ordering cmp) noexcept { return cmp > 0; }
constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }
namespace detail
{
template <unsigned int>
struct common_cmpcat_base
{
using type = void;
};
template <>
struct common_cmpcat_base<0u>
{
using type = std::strong_ordering;
};
template <>
struct common_cmpcat_base<2u>
{
using type = std::partial_ordering;
};
template <>
struct common_cmpcat_base<4u>
{
using type = std::weak_ordering;
};
template <>
struct common_cmpcat_base<6u>
{
using type = std::partial_ordering;
};
}
template <class... Ts>
struct common_comparison_category
: detail::common_cmpcat_base<(0u | ... |
(std::is_same_v<Ts, std::strong_ordering> ? 0u
: std::is_same_v<Ts, std::weak_ordering> ? 4u
: std::is_same_v<Ts, std::partial_ordering> ? 2u
: 1u))>
{
};
template <class... Ts>
using common_comparison_category_t = common_comparison_category<Ts...>::type;
template <class T, class U = T>
using compare_three_way_result_t = decltype(std::declval<const std::remove_reference_t<T> &>() <=> std::declval<const std::remove_reference_t<U> &>());
template <class T, class U = T>
struct compare_three_way_result
{
};
template <class T, class U>
requires requires { typename compare_three_way_result_t<T, U>; }
struct compare_three_way_result<T, U>
{
using type = compare_three_way_result_t<T, U>;
};
struct compare_three_way
{
template <class T, class U>
constexpr auto operator()(T &&t, U &&u) const
{
return std::forward<T>(t) <=> std::forward<U>(u);
}
using is_transparent = void;
};
inline constexpr struct strong_order_fn
{
} strong_order;
inline constexpr struct weak_order_fn
{
} weak_order;
inline constexpr struct partial_order_fn
{
} partial_order;
inline constexpr struct compare_strong_order_fallback_fn
{
} compare_strong_order_fallback;
inline constexpr struct compare_weak_order_fallback_fn
{
} compare_weak_order_fallback;
inline constexpr struct compare_partial_order_fallback_fn
{
} compare_partial_order_fallback;
inline constexpr struct __SynthThreeWayCompare
{
template <typename T, typename U>
constexpr auto operator()(const T &lhs, const U &rhs) const
{
if (lhs < rhs)
return weak_ordering::less;
else if (rhs < lhs)
return weak_ordering::greater;
else
return weak_ordering::equivalent;
}
} __synth_three_way = {};
}

View File

@ -260,6 +260,28 @@ namespace std
}
};
template <typename T>
struct less<T *>
{
constexpr bool operator()(const T *lhs, const T *rhs) const
{
if (__builtin_is_constant_evaluated())
return lhs < rhs;
return (uintptr_t)lhs < (uintptr_t)rhs;
}
};
template <>
class less<void>
{
public:
template <class T, class U>
constexpr auto operator()(T &&lhs, U &&rhs) const -> decltype(std::forward<T>(lhs) < std::forward<U>(rhs))
{
return std::forward<T>(lhs) < std::forward<U>(rhs);
}
};
template <class F, class... Args>
constexpr typename std::result_of<F()>::type bind(F &&f, Args &&...args);

View File

@ -94,7 +94,7 @@ namespace std
#pragma endregion Member types and constants
#pragma region Member Functions
#pragma region Constructors
protected:
ios_base();
@ -104,7 +104,7 @@ namespace std
virtual ~ios_base() = default;
ios_base &operator=(const ios_base &) = delete;
#pragma endregion Member Functions
#pragma endregion Constructors
#pragma region Formatting

View File

@ -18,6 +18,7 @@
#pragma once
#include <type_traits>
#include <cstddef>
namespace std
{
@ -56,6 +57,18 @@ namespace std
using iterator_category = typename Iter::iterator_category;
};
template <class T>
struct iterator_traits<T *>
{
public:
using difference_type = std::ptrdiff_t;
using value_type = std::remove_cv_t<T>;
using pointer = T *;
using reference = T &;
using iterator_category = std::random_access_iterator_tag;
using iterator_concept = std::contiguous_iterator_tag;
};
namespace detail
{
template <class It>

View File

@ -163,7 +163,7 @@ namespace std
bool operator!=(const const_iterator &rhs) const { return _node != rhs._node; }
};
#pragma region Member Functions
#pragma region Constructors
list()
{
@ -282,7 +282,7 @@ namespace std
return alloc;
}
#pragma endregion Member Functions
#pragma endregion Constructors
#pragma region Element Access

View File

@ -69,7 +69,7 @@ namespace std
#pragma endregion Member Objects
#pragma region Member Functions
#pragma region Constructors
locale() noexcept
{
@ -154,6 +154,6 @@ namespace std
assert(!"Function not implemented");
}
#pragma endregion Member Functions
#pragma endregion Constructors
};
}

View File

@ -19,9 +19,11 @@
#include <type_traits>
#include <functional>
#include <iterator>
#include <cstddef>
#include <utility>
#include <limits>
#include <atomic>
#include <new>
#include <debug.h>
@ -302,7 +304,7 @@ namespace std
pointer _ptr;
public:
#pragma region Member Functions
#pragma region Constructors
constexpr unique_ptr() noexcept : _ptr(nullptr) {}
@ -350,7 +352,7 @@ namespace std
unique_ptr &operator=(const unique_ptr &) = delete;
#pragma endregion Member Functions
#pragma endregion Constructors
#pragma region Modifiers
@ -406,7 +408,7 @@ namespace std
pointer _ptr;
public:
#pragma region Member Functions
#pragma region Constructors
constexpr unique_ptr() noexcept : _ptr(nullptr) {}
@ -457,7 +459,7 @@ namespace std
unique_ptr &operator=(const unique_ptr &) = delete;
#pragma endregion Member Functions
#pragma endregion Constructors
#pragma region Modifiers
@ -619,146 +621,514 @@ namespace std
constexpr std::allocator_arg_t allocator_arg{};
template <class T>
class auto_ptr;
template <>
class auto_ptr<void>;
template <class T>
class weak_ptr;
template <class T>
class shared_ptr
{
private:
struct control_block_base
{
long ref_count;
virtual void destroy() = 0;
virtual void *get_ptr() const = 0;
control_block_base() : ref_count(1) {}
virtual ~control_block_base() = default;
};
template <class Y, class Deleter>
struct control_block_impl : control_block_base
{
Y *ptr;
Deleter deleter;
void destroy() override { deleter(ptr); }
void *get_ptr() const override { return ptr; }
control_block_impl(Y *p, Deleter d) : ptr(p), deleter(d) {}
~control_block_impl() override {}
};
struct control_block_default : control_block_base
{
T *ptr;
void destroy() override { delete ptr; }
void *get_ptr() const override { return ptr; }
control_block_default(T *p) : ptr(p) {}
~control_block_default() override {}
};
template <class Y, class Deleter, class Alloc>
struct control_block_alloc : control_block_base
{
Y *ptr;
Deleter deleter;
Alloc alloc;
void destroy() override { deleter(ptr); }
void *get_ptr() const override { return ptr; }
control_block_alloc(Y *p, Deleter d, Alloc a) : ptr(p), deleter(d), alloc(a) {}
~control_block_alloc() override {}
void *operator new(std::size_t sz, Alloc &a)
{
using AllocTraits = std::allocator_traits<Alloc>;
return AllocTraits::allocate(a, sz);
}
void operator delete(void *p, std::size_t sz)
{
::operator delete(p);
}
};
control_block_base *cb;
public:
using weak_type = std::weak_ptr<T>;
using element_type = std::remove_extent_t<T>;
constexpr shared_ptr() noexcept;
constexpr shared_ptr(std::nullptr_t) noexcept;
constexpr shared_ptr() noexcept : cb(nullptr) {}
constexpr shared_ptr(std::nullptr_t) noexcept : cb(nullptr) {}
template <class Y>
explicit shared_ptr(Y *ptr);
explicit shared_ptr(Y *ptr) : cb(ptr ? new control_block_default(ptr) : nullptr) {}
template <class Y, class Deleter>
shared_ptr(Y *ptr, Deleter d);
shared_ptr(Y *ptr, Deleter d) : cb(ptr ? new control_block_impl<Y, Deleter>(ptr, d) : nullptr) {}
template <class Deleter>
shared_ptr(std::nullptr_t ptr, Deleter d);
shared_ptr(std::nullptr_t ptr, Deleter d) : cb(nullptr) {}
template <class Y, class Deleter, class Alloc>
shared_ptr(Y *ptr, Deleter d, Alloc alloc);
shared_ptr(Y *ptr, Deleter d, Alloc alloc)
: cb(ptr ? new(alloc) control_block_alloc<Y, Deleter, Alloc>(ptr, d, alloc) : nullptr) {}
template <class Deleter, class Alloc>
shared_ptr(std::nullptr_t ptr, Deleter d, Alloc alloc);
shared_ptr(std::nullptr_t ptr, Deleter d, Alloc alloc) : cb(nullptr) {}
template <class Y>
shared_ptr(const shared_ptr<Y> &r, element_type *ptr) noexcept;
shared_ptr(const shared_ptr<Y> &r, element_type *ptr) noexcept : cb(r.cb)
{
if (cb)
++cb->ref_count;
}
template <class Y>
shared_ptr(shared_ptr<Y> &&r, element_type *ptr) noexcept;
shared_ptr(shared_ptr<Y> &&r, element_type *ptr) noexcept : cb(r.cb) { r.cb = nullptr; }
shared_ptr(const shared_ptr &r) noexcept;
shared_ptr(const shared_ptr &r) noexcept : cb(r.cb)
{
if (cb)
++cb->ref_count;
}
template <class Y>
shared_ptr(const shared_ptr<Y> &r) noexcept;
shared_ptr(const shared_ptr<Y> &r) noexcept : cb(r.cb)
{
if (cb)
++cb->ref_count;
}
shared_ptr(shared_ptr &&r) noexcept;
shared_ptr(shared_ptr &&r) noexcept : cb(r.cb) { r.cb = nullptr; }
template <class Y>
shared_ptr(shared_ptr<Y> &&r) noexcept;
shared_ptr(shared_ptr<Y> &&r) noexcept : cb(r.cb) { r.cb = nullptr; }
template <class Y>
explicit shared_ptr(const std::weak_ptr<Y> &r);
template <class Y>
shared_ptr(std::auto_ptr<Y> &&r);
explicit shared_ptr(const std::weak_ptr<Y> &r) : cb(nullptr) { /* Not implemented */ }
template <class Y, class Deleter>
shared_ptr(std::unique_ptr<Y, Deleter> &&r);
shared_ptr(std::unique_ptr<Y, Deleter> &&r) : cb(r.get() ? new control_block_impl<Y, Deleter>(r.release(), Deleter()) : nullptr) {}
~shared_ptr();
~shared_ptr()
{
if (cb)
{
if (--cb->ref_count == 0)
{
cb->destroy();
delete cb;
}
}
}
shared_ptr &operator=(const shared_ptr &r) noexcept;
shared_ptr &operator=(const shared_ptr &r) noexcept
{
if (this != &r)
{
if (cb && --cb->ref_count == 0)
{
cb->destroy();
delete cb;
}
cb = r.cb;
if (cb)
++cb->ref_count;
}
return *this;
}
template <class Y>
shared_ptr &operator=(const shared_ptr<Y> &r) noexcept;
shared_ptr &operator=(const shared_ptr<Y> &r) noexcept
{
if (cb && --cb->ref_count == 0)
{
cb->destroy();
delete cb;
}
cb = r.cb;
if (cb)
++cb->ref_count;
return *this;
}
shared_ptr &operator=(shared_ptr &&r) noexcept;
shared_ptr &operator=(shared_ptr &&r) noexcept
{
if (this != &r)
{
if (cb && --cb->ref_count == 0)
{
cb->destroy();
delete cb;
}
cb = r.cb;
r.cb = nullptr;
}
return *this;
}
template <class Y>
shared_ptr &operator=(shared_ptr<Y> &&r) noexcept;
template <class Y>
shared_ptr &operator=(std::auto_ptr<Y> &&r);
shared_ptr &operator=(shared_ptr<Y> &&r) noexcept
{
if (cb && --cb->ref_count == 0)
{
cb->destroy();
delete cb;
}
cb = r.cb;
r.cb = nullptr;
return *this;
}
template <class Y, class Deleter>
shared_ptr &operator=(std::unique_ptr<Y, Deleter> &&r);
shared_ptr &operator=(std::unique_ptr<Y, Deleter> &&r)
{
reset(r.get(), Deleter());
r.release();
return *this;
}
void reset() noexcept;
void reset() noexcept
{
if (cb && --cb->ref_count == 0)
{
cb->destroy();
delete cb;
}
cb = nullptr;
}
template <class Y>
void reset(Y *ptr);
void reset(Y *ptr)
{
reset();
if (ptr)
cb = new control_block_default(ptr);
}
template <class Y, class Deleter>
void reset(Y *ptr, Deleter d);
void reset(Y *ptr, Deleter d)
{
reset();
if (ptr)
cb = new control_block_impl<Y, Deleter>(ptr, d);
}
template <class Y, class Deleter, class Alloc>
void reset(Y *ptr, Deleter d, Alloc alloc);
void reset(Y *ptr, Deleter d, Alloc alloc)
{
reset();
if (ptr)
cb = new (alloc) control_block_alloc<Y, Deleter, Alloc>(ptr, d, alloc);
}
void swap(shared_ptr &r) noexcept;
void swap(shared_ptr &r) noexcept
{
control_block_base *tmp = cb;
cb = r.cb;
r.cb = tmp;
}
T *get() const noexcept;
// element_type *get() const noexcept;
T &operator*() const noexcept;
T *operator->() const noexcept;
element_type &operator[](std::ptrdiff_t idx) const;
long use_count() const noexcept;
bool unique() const noexcept;
explicit operator bool() const noexcept { return get() != nullptr; }
element_type *get() const noexcept { return cb ? static_cast<element_type *>(cb->get_ptr()) : nullptr; }
T &operator*() const noexcept { return *get(); }
T *operator->() const noexcept { return get(); }
element_type &operator[](std::ptrdiff_t idx) const { return get()[idx]; }
long use_count() const noexcept { return cb ? cb->ref_count : 0; }
explicit operator bool() const noexcept { return cb != nullptr; }
template <class Y>
bool owner_before(const shared_ptr<Y> &other) const noexcept;
bool owner_before(const shared_ptr<Y> &other) const noexcept { return cb < other.cb; }
template <class Y>
bool owner_before(const std::weak_ptr<Y> &other) const noexcept;
std::size_t owner_hash() const noexcept;
template <class Y>
bool owner_equal(const std::shared_ptr<Y> &other) const noexcept;
template <class Y>
bool owner_equal(const std::weak_ptr<Y> &other) const noexcept;
bool owner_before(const std::weak_ptr<Y> &other) const noexcept { return cb < other.cb; }
};
template <class T, class... Args>
shared_ptr<T> make_shared(Args &&...args);
shared_ptr<T> make_shared(Args &&...args) { return shared_ptr<T>(new T(std::forward<Args>(args)...)); }
template <class T>
shared_ptr<T> make_shared(std::size_t N);
shared_ptr<T> make_shared(std::size_t N) { return shared_ptr<T>(new T[N]); }
template <class T>
shared_ptr<T> make_shared();
shared_ptr<T> make_shared() { return shared_ptr<T>(new T); }
template <class T>
shared_ptr<T> make_shared(std::size_t N, const std::remove_extent_t<T> &u);
shared_ptr<T> make_shared(std::size_t N, const std::remove_extent_t<T> &u) { return shared_ptr<T>(new T[N](u)); }
template <class T>
shared_ptr<T> make_shared(const std::remove_extent_t<T> &u);
shared_ptr<T> make_shared(const std::remove_extent_t<T> &u) { return shared_ptr<T>(new T(u)); }
template <class T>
shared_ptr<T> make_shared_for_overwrite();
shared_ptr<T> make_shared_for_overwrite() { return shared_ptr<T>(new T); }
template <class T>
shared_ptr<T> make_shared_for_overwrite(std::size_t N);
shared_ptr<T> make_shared_for_overwrite(std::size_t N) { return shared_ptr<T>(new T[N]); }
template <class T, class Alloc, class... Args>
shared_ptr<T> allocate_shared(const Alloc &alloc, Args &&...args)
{
using AllocTraits = std::allocator_traits<Alloc>;
using U = typename std::remove_extent<T>::type;
Alloc a = alloc;
U *ptr = AllocTraits::allocate(a, 1);
try
{
AllocTraits::construct(a, ptr, std::forward<Args>(args)...);
return shared_ptr<T>(ptr, [a](U *p) mutable
{
AllocTraits::destroy(a, p);
AllocTraits::deallocate(a, p, 1); }, a);
}
catch (...)
{
AllocTraits::deallocate(a, ptr, 1);
throw;
}
}
template <class T, class Alloc>
shared_ptr<T> allocate_shared(const Alloc &alloc, std::size_t N)
{
using AllocTraits = std::allocator_traits<Alloc>;
using U = typename std::remove_extent<T>::type;
Alloc a = alloc;
U *ptr = AllocTraits::allocate(a, N);
try
{
for (std::size_t i = 0; i < N; ++i)
AllocTraits::construct(a, ptr + i);
return shared_ptr<T>(ptr, [a, N](U *p) mutable
{
for (std::size_t i = 0; i < N; ++i)
AllocTraits::destroy(a, p + i);
AllocTraits::deallocate(a, p, N); }, a);
}
catch (...)
{
AllocTraits::deallocate(a, ptr, N);
throw;
}
}
template <class T, class Alloc>
shared_ptr<T> allocate_shared(const Alloc &alloc)
{
return allocate_shared<T>(alloc);
}
template <class T, class Alloc>
shared_ptr<T> allocate_shared(const Alloc &alloc, std::size_t N, const std::remove_extent_t<T> &u)
{
using AllocTraits = std::allocator_traits<Alloc>;
using U = typename std::remove_extent<T>::type;
Alloc a = alloc;
U *ptr = AllocTraits::allocate(a, N);
try
{
for (std::size_t i = 0; i < N; ++i)
AllocTraits::construct(a, ptr + i, u);
return shared_ptr<T>(ptr, [a, N](U *p) mutable
{
for (std::size_t i = 0; i < N; ++i)
AllocTraits::destroy(a, p + i);
AllocTraits::deallocate(a, p, N); }, a);
}
catch (...)
{
AllocTraits::deallocate(a, ptr, N);
throw;
}
}
template <class T, class Alloc>
shared_ptr<T> allocate_shared(const Alloc &alloc, const std::remove_extent_t<T> &u)
{
return allocate_shared<T>(alloc, 1, u);
}
template <class T, class Alloc>
shared_ptr<T> allocate_shared_for_overwrite(const Alloc &alloc)
{
using AllocTraits = std::allocator_traits<Alloc>;
using U = typename std::remove_extent<T>::type;
Alloc a = alloc;
U *ptr = AllocTraits::allocate(a, 1);
return shared_ptr<T>(ptr, [a](U *p) mutable
{ AllocTraits::deallocate(a, p, 1); }, a);
}
template <class T, class Alloc>
shared_ptr<T> allocate_shared_for_overwrite(const Alloc &alloc, std::size_t N)
{
using AllocTraits = std::allocator_traits<Alloc>;
using U = typename std::remove_extent<T>::type;
Alloc a = alloc;
U *ptr = AllocTraits::allocate(a, N);
return shared_ptr<T>(ptr, [a, N](U *p) mutable
{ AllocTraits::deallocate(a, p, N); }, a);
}
template <class T, class U>
std::shared_ptr<T> static_pointer_cast(const std::shared_ptr<U> &r) noexcept
{
auto p = static_cast<typename std::shared_ptr<T>::element_type *>(r.get());
return std::shared_ptr<T>{r, p};
}
template <class T, class U>
std::shared_ptr<T> static_pointer_cast(std::shared_ptr<U> &&r) noexcept
{
auto p = static_cast<typename std::shared_ptr<T>::element_type *>(r.get());
return std::shared_ptr<T>{r, p};
}
template <class T, class U>
std::shared_ptr<T> dynamic_pointer_cast(const std::shared_ptr<U> &r) noexcept
{
if (auto p = dynamic_cast<typename std::shared_ptr<T>::element_type *>(r.get()))
return std::shared_ptr<T>{r, p};
else
return std::shared_ptr<T>{};
}
template <class T, class U>
std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U> &&r) noexcept
{
if (auto p = dynamic_cast<typename std::shared_ptr<T>::element_type *>(r.get()))
return std::shared_ptr<T>{r, p};
else
return std::shared_ptr<T>{};
}
template <class T, class U>
std::shared_ptr<T> const_pointer_cast(const std::shared_ptr<U> &r) noexcept
{
auto p = const_cast<typename std::shared_ptr<T>::element_type *>(r.get());
return std::shared_ptr<T>{r, p};
}
template <class T, class U>
std::shared_ptr<T> const_pointer_cast(std::shared_ptr<U> &&r) noexcept
{
auto p = const_cast<typename std::shared_ptr<T>::element_type *>(r.get());
return std::shared_ptr<T>{r, p};
}
template <class T, class U>
std::shared_ptr<T> reinterpret_pointer_cast(const std::shared_ptr<U> &r) noexcept
{
auto p = reinterpret_cast<typename std::shared_ptr<T>::element_type *>(r.get());
return std::shared_ptr<T>{r, p};
}
template <class T, class U>
std::shared_ptr<T> reinterpret_pointer_cast(std::shared_ptr<U> &&r) noexcept
{
auto p = reinterpret_cast<typename std::shared_ptr<T>::element_type *>(r.get());
return std::shared_ptr<T>{r, p};
}
template <class Deleter, class T>
Deleter *get_deleter(const std::shared_ptr<T> &p) noexcept { return p.cb ? &p.cb->deleter : nullptr; }
template <class T, class U>
bool operator==(const std::shared_ptr<T> &lhs, const std::shared_ptr<U> &rhs) noexcept { return lhs.get() == rhs.get(); }
template <class T, class U>
bool operator!=(const std::shared_ptr<T> &lhs, const std::shared_ptr<U> &rhs) noexcept { return !(lhs == rhs); }
// template <class T, class U>
// bool operator<(const std::shared_ptr<T> &lhs, const std::shared_ptr<U> &rhs) noexcept { return std::less<V>()(lhs.get(), rhs.get()); }
template <class T, class U>
bool operator>(const std::shared_ptr<T> &lhs, const std::shared_ptr<U> &rhs) noexcept { return rhs < lhs; }
template <class T, class U>
bool operator<=(const std::shared_ptr<T> &lhs, const std::shared_ptr<U> &rhs) noexcept { return !(rhs < lhs); }
template <class T, class U>
bool operator>=(const std::shared_ptr<T> &lhs, const std::shared_ptr<U> &rhs) noexcept { return !(lhs < rhs); }
// template <class T, class U>
// std::strong_ordering operator<=>(const std::shared_ptr<T> &lhs, const std::shared_ptr<U> &rhs) noexcept { return std::compare_three_way{}(x.get(), y.get()); }
template <class T>
bool operator==(const std::shared_ptr<T> &lhs, std::nullptr_t) noexcept { return !lhs; }
template <class T>
bool operator==(std::nullptr_t, const std::shared_ptr<T> &rhs) noexcept { return !rhs; }
template <class T>
bool operator!=(const std::shared_ptr<T> &lhs, std::nullptr_t) noexcept { return (bool)lhs; }
template <class T>
bool operator!=(std::nullptr_t, const std::shared_ptr<T> &rhs) noexcept { return (bool)rhs; }
// template <class T>
// bool operator<(const std::shared_ptr<T> &lhs, std::nullptr_t) noexcept { return std::less<std::shared_ptr<T>::element_type *>()(lhs.get(), nullptr); }
// template <class T>
// bool operator<(std::nullptr_t, const std::shared_ptr<T> &rhs) noexcept { return std::less<std::shared_ptr<T>::element_type *>()(nullptr, rhs.get()); }
template <class T>
bool operator>(const std::shared_ptr<T> &lhs, std::nullptr_t) noexcept { return nullptr < lhs; }
template <class T>
bool operator>(std::nullptr_t, const std::shared_ptr<T> &rhs) noexcept { return rhs < nullptr; }
template <class T>
bool operator<=(const std::shared_ptr<T> &lhs, std::nullptr_t) noexcept { return !(nullptr < lhs); }
template <class T>
bool operator<=(std::nullptr_t, const std::shared_ptr<T> &rhs) noexcept { return !(rhs < nullptr); }
template <class T>
bool operator>=(const std::shared_ptr<T> &lhs, std::nullptr_t) noexcept { return !(lhs < nullptr); }
template <class T>
bool operator>=(std::nullptr_t, const std::shared_ptr<T> &rhs) noexcept { return !(nullptr < rhs); }
// template <class T>
// std::strong_ordering operator<=>(const std::shared_ptr<T> &lhs, std::nullptr_t) noexcept { return std::compare_three_way{}(x.get(), static_cast<std::shared_ptr<T>::element_type*>(nullptr)); }
// template <class T, class U, class V>
// std::basic_ostream<U, V> &operator<<(std::basic_ostream<U, V> &os, const std::shared_ptr<T> &ptr) { return os << ptr.get(); }
template <class T>
void swap(std::shared_ptr<T> &lhs, std::shared_ptr<T> &rhs) noexcept { lhs.swap(rhs); }
// template <class T>
// struct std::atomic<std::shared_ptr<T>>;
template <class T>
struct hash<std::shared_ptr<T>>;
}

311
Kernel/include_std/set Normal file
View File

@ -0,0 +1,311 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <initializer_list>
#include <functional>
#include <algorithm>
#include <compare>
#include <memory>
#warning "std::set not implemented; Do not use"
namespace std
{
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>>
class multiset;
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>>
class set
{
public:
template <class Iter, class NodeType>
struct __set_return_type
{
Iter position;
bool inserted;
NodeType node;
};
using key_type = Key;
using value_type = Key;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using key_compare = Compare;
using value_compare = Compare;
using allocator_type = Allocator;
using reference = value_type &;
using const_reference = const value_type &;
using pointer = std::allocator_traits<Allocator>::pointer;
using const_pointer = std::allocator_traits<Allocator>::const_pointer;
using iterator = value_type;
using const_iterator = const value_type;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using node_type = std::unique_ptr<value_type>;
using insert_return_type = __set_return_type<iterator, node_type>;
private:
public:
#pragma region Constructors
set() : set(Compare()) {}
explicit set(const Compare &comp, const Allocator &alloc = Allocator());
explicit set(const Allocator &alloc);
template <class InputIt>
set(InputIt first, InputIt last, const Compare &comp = Compare(), const Allocator &alloc = Allocator());
template <class InputIt>
set(InputIt first, InputIt last, const Allocator &alloc) : set(first, last, Compare(), alloc) {}
set(const set &other);
set(const set &other, const Allocator &alloc);
set(set &&other);
set(set &&other, const Allocator &alloc);
set(std::initializer_list<value_type> init, const Compare &comp = Compare(), const Allocator &alloc = Allocator());
set(std::initializer_list<value_type> init, const Allocator &alloc) : set(init, Compare(), alloc) {}
~set();
#pragma endregion Constructors
#pragma region Assignment
set &operator=(const set &other);
set &operator=(set &&other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value && std::is_nothrow_move_assignable<Compare>::value);
set &operator=(std::initializer_list<value_type> ilist);
allocator_type get_allocator() const noexcept;
#pragma endregion Assignment
#pragma region Iterators
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
#pragma endregion Iterators
#pragma region Capacity
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
#pragma endregion Capacity
#pragma region Modifiers
void clear() noexcept;
std::pair<iterator, bool> insert(const value_type &value);
std::pair<iterator, bool> insert(value_type &&value);
iterator insert(const_iterator pos, const value_type &value);
iterator insert(const_iterator pos, value_type &&value);
template <class InputIt>
void insert(InputIt first, InputIt last);
void insert(std::initializer_list<value_type> ilist);
insert_return_type insert(node_type &&nh);
iterator insert(const_iterator pos, node_type &&nh);
template <class... Args>
std::pair<iterator, bool> emplace(Args &&...args);
template <class... Args>
iterator emplace_hint(const_iterator hint, Args &&...args);
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
size_type erase(const Key &key);
void swap(set &other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value && std::is_nothrow_swappable<Compare>::value);
node_type extract(const_iterator position);
node_type extract(const Key &k);
template <class C2>
void merge(std::set<Key, C2, Allocator> &source);
template <class C2>
void merge(std::set<Key, C2, Allocator> &&source);
template <class C2>
void merge(std::multiset<Key, C2, Allocator> &source);
template <class C2>
void merge(std::multiset<Key, C2, Allocator> &&source);
#pragma endregion Modifiers
#pragma region Lookup
size_type count(const Key &key) const;
template <class K>
size_type count(const K &x) const;
iterator find(const Key &key);
const_iterator find(const Key &key) const;
template <class K>
iterator find(const K &x);
template <class K>
const_iterator find(const K &x) const;
bool contains(const Key &key) const;
template <class K>
bool contains(const K &x) const;
std::pair<iterator, iterator> equal_range(const Key &key);
std::pair<const_iterator, const_iterator> equal_range(const Key &key) const;
template <class K>
std::pair<iterator, iterator> equal_range(const K &x);
template <class K>
std::pair<const_iterator, const_iterator> equal_range(const K &x) const;
iterator lower_bound(const Key &key);
const_iterator lower_bound(const Key &key) const;
template <class K>
iterator lower_bound(const K &x);
template <class K>
const_iterator lower_bound(const K &x) const;
iterator upper_bound(const Key &key);
const_iterator upper_bound(const Key &key) const;
template <class K>
iterator upper_bound(const K &x);
template <class K>
const_iterator upper_bound(const K &x) const;
#pragma endregion Lookup
#pragma region Observers
key_compare key_comp() const;
set::value_compare value_comp() const;
#pragma endregion Observers
};
template <class Key, class Compare, class Alloc>
bool operator==(const std::set<Key, Compare, Alloc> &lhs, const std::set<Key, Compare, Alloc> &rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <class Key, class Compare, class Alloc>
std::strong_ordering operator<=>(const std::set<Key, Compare, Alloc> &lhs, const std::set<Key, Compare, Alloc> &rhs)
{
// return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), __synth_three_way);
auto it1 = lhs.begin();
auto it2 = rhs.begin();
auto end1 = lhs.end();
auto end2 = rhs.end();
while (it1 != end1 && it2 != end2)
{
if (*it1 < *it2)
return std::strong_ordering::less;
if (*it2 < *it1)
return std::strong_ordering::greater;
++it1;
++it2;
}
if (it1 == end1 && it2 == end2)
return std::strong_ordering::equal;
return (it1 == end1) ? std::strong_ordering::less : std::strong_ordering::greater;
}
template <class Key, class Compare, class Alloc>
void swap(std::set<Key, Compare, Alloc> &lhs, std::set<Key, Compare, Alloc> &rhs) noexcept(noexcept(lhs.swap(rhs)))
{
lhs.swap(rhs);
}
template <class Key, class Compare, class Alloc, class Pred>
std::set<Key, Compare, Alloc>::size_type erase_if(std::set<Key, Compare, Alloc> &c, Pred pred)
{
auto old_size = c.size();
for (auto first = c.begin(), last = c.end(); first != last;)
{
if (pred(*first))
first = c.erase(first);
else
++first;
}
return old_size - c.size();
}
}

View File

@ -17,12 +17,16 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#include <initializer_list>
#include <algorithm>
#include <stdexcept>
#include <convert.h>
#include <iterator>
#include <cstddef>
#include <compare>
#include <memory>
#include <ranges>
@ -830,7 +834,7 @@ namespace std
size_t _capacity;
public:
#pragma region Member Functions
#pragma region Constructors
basic_string()
: _alloc(Allocator()),
@ -1221,7 +1225,7 @@ namespace std
return _alloc;
}
#pragma endregion Member Functions
#pragma endregion Constructors
#pragma region Element Access
@ -1415,6 +1419,9 @@ namespace std
{
if (_size < _capacity)
{
if (_size == 0)
_size = Traits::length(_data);
CharT *new_data = _alloc.allocate(_size);
memcpy(new_data, _data, _size);
@ -1654,17 +1661,17 @@ namespace std
template <class InputIt>
constexpr basic_string &append(InputIt first, InputIt last)
{
// size_type count = distance(first, last);
size_type count = last - first;
if (count > 0)
{
size_type new_size = _size + count;
if (new_size > _capacity)
reserve(new_size);
std::copy(first, last, _data + _size);
_data[new_size] = '\0';
_size = new_size;
}
size_type old_size = _size;
size_type new_size = old_size + count;
if (new_size + 1 > _capacity)
reserve(new_size + 1);
std::copy(first, last, _data + old_size);
_size = new_size;
_data[_size] = '\0';
return *this;
}
@ -1825,6 +1832,9 @@ namespace std
constexpr void resize(size_type count)
{
if (_size == 0 && _data != nullptr)
_size = Traits::length(_data);
if (count < _size)
erase(count);
else if (count > _size)
@ -2255,12 +2265,24 @@ namespace std
return lhs.compare(rhs) == 0;
}
template <class CharT, class Traits, class Alloc>
constexpr auto operator<=>(const std::basic_string<CharT, Traits, Alloc> &lhs, const std::basic_string<CharT, Traits, Alloc> &rhs) noexcept -> decltype(static_cast<weak_ordering>(0 <=> 0))
{
return static_cast<weak_ordering>(lhs.compare(rhs) <=> 0);
}
template <class CharT, class Traits, class Alloc>
constexpr bool operator==(const std::basic_string<CharT, Traits, Alloc> &lhs, const CharT *rhs)
{
return lhs.compare(rhs) == 0;
}
template <class CharT, class Traits, class Alloc>
constexpr auto operator<=>(const std::basic_string<CharT, Traits, Alloc> &lhs, const CharT *rhs) -> decltype(static_cast<weak_ordering>(0 <=> 0))
{
return static_cast<weak_ordering>(lhs.compare(rhs) <=> 0);
}
template <class CharT, class Traits, class Alloc>
std::basic_string<CharT, Traits, Alloc> constexpr operator+(const std::basic_string<CharT, Traits, Alloc> &lhs, const std::basic_string<CharT, Traits, Alloc> &rhs)
{
@ -2476,3 +2498,5 @@ namespace std
}
}
}
#pragma GCC diagnostic pop

View File

@ -721,4 +721,12 @@ namespace std
template <class T>
constexpr bool is_pointer_v = is_pointer<T>::value;
template <class T>
struct is_floating_point : std::integral_constant<bool, std::is_same<float, typename std::remove_cv<T>::type>::value || std::is_same<double, typename std::remove_cv<T>::type>::value || std::is_same<long double, typename std::remove_cv<T>::type>::value>
{
};
template <class T>
constexpr bool is_floating_point_v = is_floating_point<T>::value;
}

View File

@ -367,7 +367,7 @@ namespace std
size_type elementsCount = 0;
public:
#pragma region Member Functions
#pragma region Constructors
unordered_map() = default;
@ -412,7 +412,7 @@ namespace std
return allocator_type();
}
#pragma endregion Member Functions
#pragma endregion Constructors
#pragma region Iterators
@ -908,6 +908,7 @@ namespace std
index = hashFunction(key) % buckets.size();
}
bucket = buckets[index];
return bucket.back().second;
}
@ -934,6 +935,7 @@ namespace std
index = hashFunction(key) % buckets.size();
}
bucket = buckets[index];
return bucket.back().second;
}

View File

@ -21,6 +21,7 @@
#include <stdexcept>
#include <algorithm>
#include <iterator>
#include <compare>
#include <memory>
namespace std
@ -357,7 +358,7 @@ namespace std
pointer _data;
public:
#pragma region Member Functions
#pragma region Constructors
constexpr vector() noexcept(noexcept(Allocator()))
: _size(0),
@ -583,7 +584,7 @@ namespace std
return _alloc;
}
#pragma endregion Member Functions
#pragma endregion Constructors
#pragma region Element Access
@ -984,17 +985,32 @@ namespace std
constexpr bool operator==(const std::vector<T, Alloc> &lhs, const std::vector<T, Alloc> &rhs)
{
if (lhs.size() != rhs.size())
{
return false;
}
for (size_t i = 0; i < lhs.size(); i++)
return std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <class T, class Alloc>
constexpr auto operator<=>(const std::vector<T, Alloc> &lhs, const std::vector<T, Alloc> &rhs)
{
// return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), __synth_three_way);
auto it1 = lhs.begin();
auto it2 = rhs.begin();
while (it1 != lhs.end() && it2 != rhs.end())
{
if (lhs[i] != rhs[i])
{
return false;
}
if (*it1 < *it2)
return std::strong_ordering::less;
if (*it1 > *it2)
return std::strong_ordering::greater;
++it1;
++it2;
}
return true;
if (it1 == lhs.end() && it2 == rhs.end())
return std::strong_ordering::equal;
return (it1 == lhs.end()) ? std::strong_ordering::less : std::strong_ordering::greater;
}
template <class T, class Alloc>

View File

@ -17,7 +17,7 @@
#include "kernel.h"
#include <filesystem/ustar.hpp>
#include <fs/ustar.hpp>
#include <memory.hpp>
#include <convert.h>
#include <ints.hpp>
@ -27,11 +27,14 @@
#include <debug.h>
#include <smp.hpp>
#include <cargs.h>
#include <efi.h>
#include <io.h>
#include "core/smbios.hpp"
#include "tests/t.h"
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
bool DebuggerIsAttached = false;
NewLock(KernelLock);
@ -73,23 +76,15 @@ EXTERNC void _KPrint(const char *Format, va_list Args)
{
SmartLock(KernelLock);
if (TimeManager)
{
uint64_t Nanoseconds = TimeManager->GetNanosecondsSinceClassCreation();
if (Nanoseconds != 0)
{
uint64_t nano = TimeManager ? TimeManager->GetNanosecondsSinceClassCreation() : 0;
#if defined(__amd64__)
printf("\x1b[1;30m[\x1b[1;34m%lu.%07lu\x1b[1;30m]\x1b[0m ",
Nanoseconds / 10000000, Nanoseconds % 10000000);
printf("\x1b[1;30m[\x1b[1;34m%lu.%07lu\x1b[1;30m]\x1b[0m ", nano / 10000000, nano % 10000000);
#elif defined(__i386__)
printf("\x1b[1;30m[\x1b[1;34m%llu.%07llu\x1b[1;30m]\x1b[0m ",
Nanoseconds / 10000000, Nanoseconds % 10000000);
printf("\x1b[1;30m[\x1b[1;34m%llu.%07llu\x1b[1;30m]\x1b[0m ", nano / 10000000, nano % 10000000);
#elif defined(__aarch64__)
printf("\x1b[1;30m[\x1b[1;34m%lu.%07lu\x1b[1;30m]\x1b[0m ",
Nanoseconds / 10000000, Nanoseconds % 10000000);
printf("\x1b[1;30m[\x1b[1;34m%lu.%07lu\x1b[1;30m]\x1b[0m ", nano / 10000000, nano % 10000000);
#endif
}
}
vprintf(Format, Args);
printf("\x1b[0m\n");
@ -112,6 +107,10 @@ EXTERNC void KPrint(const char *Format, ...)
va_start(args, Format);
vfctprintf(uart_wrapper, nullptr, Format, args);
va_end(args);
uart_wrapper('\x1b', nullptr);
uart_wrapper('[', nullptr);
uart_wrapper('0', nullptr);
uart_wrapper('m', nullptr);
uart_wrapper('\n', nullptr);
#endif
}
@ -248,6 +247,10 @@ EXTERNC nif cold void Main()
KPrint("Initializing Filesystem");
KernelVFS();
#ifdef DEBUG
__early_playground();
#endif
KPrint("\x1b[1;32m################################");
TaskManager = new Tasking::Task(Tasking::IP(KernelMainThread));
TaskManager->StartScheduler();
@ -269,6 +272,9 @@ EXTERNC __no_stack_protector nif cold void Entry(BootInfo *Info)
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
DebuggerIsAttached = true;
if (bInfo.EFI.Info.IH || bInfo.EFI.Info.ST)
efi_main((EFI_HANDLE)bInfo.EFI.ImageHandle, (EFI_SYSTEM_TABLE *)bInfo.EFI.SystemTable);
#if defined(__amd64__) || defined(__i386__)
if (!bInfo.SMBIOSPtr)
{

View File

@ -22,7 +22,7 @@
#include <boot/binfo.h>
#ifdef __cplusplus
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <display.hpp>
#include <symbols.hpp>
#include <kconfig.hpp>

View File

@ -20,7 +20,7 @@
#include "tests/t.h"
#endif
#include <filesystem/ustar.hpp>
#include <fs/ustar.hpp>
#include <subsystems.hpp>
#include <kshell.hpp>
#include <power.hpp>
@ -70,11 +70,11 @@ int SpawnLinuxInit()
"/startup/init"};
const char *foundPath = nullptr;
FileNode *root = fs->GetRoot(1);
Node root = fs->GetRoot(1);
for (const std::string &path : fallbackPaths)
{
const char *str = path.c_str();
if (!fs->PathExists(str, root))
if (fs->Lookup(root, str) == false)
continue;
foundPath = str;
break;
@ -123,8 +123,6 @@ void KernelMainThread()
KPrint("Initializing Driver Manager");
DriverManager = new Driver::Manager;
TaskManager->CreateThread(thisProcess, Tasking::IP(Driver::ManagerDaemonWrapper))
->Rename("Device Service");
KPrint("Loading Drivers");
DriverManager->PreloadDrivers();
@ -141,6 +139,10 @@ void KernelMainThread()
Subsystem::Linux::InitializeSubSystem();
Subsystem::Windows::InitializeSubSystem();
#ifdef DEBUG
__late_playground();
#endif
KPrint("Executing %s", Config.InitPath);
int ExitCode = -1;
Tasking::PCB *initProc;

View File

@ -17,7 +17,7 @@
#include "kernel.h"
#include <filesystem/ustar.hpp>
#include <fs/ustar.hpp>
#include <memory.hpp>
vfs::Virtual *fs = nullptr;

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include "../../kernel.h"
@ -28,7 +28,7 @@ void cmd_cat(const char *args)
if (args[0] == '\0')
return;
FileNode *node = fs->GetByPath(args, nullptr);
Node node = fs->Lookup(thisProcess->CWD, args);
if (node == nullptr)
{
@ -48,11 +48,11 @@ void cmd_cat(const char *args)
return;
}
kstat stat = {};
node->Stat(&stat);
kstat stat;
fs->Stat(node, &stat);
uint8_t *buffer = new uint8_t[stat.Size + 1];
ssize_t rBytes = node->Read(buffer, stat.Size, 0);
ssize_t rBytes = fs->Read(node, buffer, stat.Size, 0);
if (rBytes > 0)
printf("%s\n", buffer);
else

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include "../../kernel.h"
@ -28,8 +28,7 @@ void cmd_cd(const char *args)
if (args[0] == '\0')
return;
FileNode *node = fs->GetByPath(args, nullptr);
Node node = fs->Lookup(thisProcess->CWD, args);
if (node == nullptr)
{
printf("cd: %s: No such file or directory\n", args);
@ -43,4 +42,5 @@ void cmd_cd(const char *args)
}
thisProcess->CWD = node;
debug("changed cwd to %s", node->Path.c_str());
}

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <acpi.hpp>
#include "../../kernel.h"
@ -38,9 +38,41 @@ void cmd_dump(const char *args)
*strLen = '\0';
strLen++;
void *Address = (void *)strtoul(strAddr, nullptr, 16);
void *Address;
unsigned long Length = strtoul(strLen, nullptr, 10);
Node root = fs->GetRoot(0);
Node fileNode = fs->Lookup(root, strAddr);
if (fileNode && !fileNode->IsDirectory() && !fileNode->IsFIFO() && !fileNode->IsSocket())
{
kstat stat;
int status = fs->Stat(fileNode, &stat);
if (status != 0)
{
printf("cannot get stat: %s\n", strerror(status));
return;
}
size_t size = stat.Size > (off_t)Length ? Length : stat.Size;
Address = new char[size]; /* FIXME: memory leak */
size_t read = fs->Read(fileNode, Address, size, 0);
if (read < Length)
{
debug("clamp %lu to %lu", Length, read);
Length = read;
}
}
else
{
if (fileNode)
{
printf("file %s cannot be dumped\n", strAddr);
return;
}
Address = (void *)strtoul(strAddr, nullptr, 16);
debug("address %s", strAddr);
}
{
unsigned char *AddressChar = (unsigned char *)Address;
unsigned char Buffer[17];
@ -74,4 +106,4 @@ void cmd_dump(const char *args)
}
putchar('\n');
}
}
}

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,98 +17,60 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include "../../kernel.h"
using namespace vfs;
const char *ColorNodeType(FileNode *node)
const char *ColorNodeType(Node node)
{
if (node->IsRegularFile())
return "\x1b[32m";
return "\x1b[0m";
else if (node->IsDirectory())
return "\x1b[34m";
return "\x1b[1;34m";
else if (node->IsBlockDevice())
return "\x1b[33m";
return "\x1b[1;33m";
else if (node->IsCharacterDevice())
return "\x1b[33m";
return "\x1b[1;33m";
else if (node->IsFIFO())
return "\x1b[33m";
return "\x1b[0;33m";
else if (node->IsSymbolicLink())
return "\x1b[35m";
return "\x1b[1;36m";
else
return "\x1b[0m";
}
__no_sanitize("alignment") size_t MaxNameLength(FileNode *nodes)
__no_sanitize("alignment") void PrintLS(Node node)
{
size_t maxLength = 0;
kdirent *dirBuffer = new kdirent[16];
ssize_t read = 0;
off_t offset = 0;
while ((read = nodes->ReadDir(dirBuffer, sizeof(kdirent) * 16, offset, LONG_MAX)) > 0)
{
if (read / sizeof(kdirent) == 0)
break;
off_t bufOffset = 0;
debug("There are %ld entries in this directory", read / sizeof(kdirent));
for (size_t i = 0; i < read / sizeof(kdirent); i++)
{
kdirent *dirent = (kdirent *)((uintptr_t)dirBuffer + bufOffset);
if (dirent->d_reclen == 0)
break;
bufOffset += dirent->d_reclen;
maxLength = std::max(maxLength, strlen(dirent->d_name));
debug("dirent->d_name: %s (max length: %ld)", dirent->d_name, maxLength);
}
offset += read / sizeof(kdirent);
}
delete[] dirBuffer;
return maxLength;
}
__no_sanitize("alignment") void PrintLS(FileNode *node)
{
size_t maxNameLength = MaxNameLength(node);
size_t maxNameLength = 0;
int count = 0;
bool first = true;
kdirent *dirBuffer = new kdirent[16];
ssize_t read = 0;
off_t offset = 0;
while ((read = node->ReadDir(dirBuffer, sizeof(kdirent) * 16, offset, LONG_MAX)) > 0)
{
if (read / sizeof(kdirent) == 0)
break;
std::list<Node> children = fs->ReadDirectory(node);
off_t bufOffset = 0;
for (size_t i = 0; i < read / sizeof(kdirent); i++)
{
if (count % 5 == 0 && !first)
printf("\n");
kdirent *dirent = (kdirent *)((uintptr_t)dirBuffer + bufOffset);
if (dirent->d_reclen == 0)
break;
bufOffset += dirent->d_reclen;
printf(" %s%-*s ", ColorNodeType(node), (int)maxNameLength, dirent->d_name);
count++;
first = false;
}
offset += read / sizeof(kdirent);
for (auto &&i : children)
std::max(maxNameLength, i->Name.length());
for (auto &&i : children)
{
if (count % 5 == 0 && !first)
printf("\n");
printf(" %s%-*s ", ColorNodeType(i), (int)maxNameLength, i->Name.c_str());
count++;
first = false;
}
printf("\x1b[0m\n");
delete[] dirBuffer;
}
void cmd_ls(const char *args)
{
if (args[0] == '\0')
{
FileNode *rootNode = thisProcess->CWD;
Node rootNode = thisProcess->CWD;
if (rootNode == nullptr)
rootNode = fs->GetRoot(0);
@ -117,7 +79,7 @@ void cmd_ls(const char *args)
return;
}
FileNode *thisNode = fs->GetByPath(args, nullptr);
Node thisNode = fs->Lookup(thisProcess->CWD, args);
if (thisNode == nullptr)
{

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <acpi.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include <task.hpp>
#include "../../kernel.h"

View File

@ -17,70 +17,38 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include "../../kernel.h"
void tree_loop(FileNode *rootNode, int depth = 0)
// Enhancing the tree_loop function to display a fancier tree structure
__no_sanitize("alignment") void tree_loop(Node rootNode, int depth = 0, std::string prefix = "")
{
// for (auto Child : rootNode->GetChildren(true))
// {
// Display->UpdateBuffer();
// if (Child->Stat.IsType(DIRECTORY) || Child->Stat.IsType(MOUNTPOINT))
// {
// printf("%*s%*s%*s|- %s\n",
// depth, "",
// depth, "",
// depth, "",
// Child->FileName);
// tree_loop(Child, depth + 1);
// }
// else
// printf("%*s%*s%*s|- %s\n",
// depth, "",
// depth, "",
// depth, "",
// Child->FileName);
// }
std::list<Node> children = fs->ReadDirectory(rootNode);
size_t count = children.size();
size_t index = 0;
kdirent *dirBuffer = new kdirent[16];
ssize_t read = 0;
off_t offset = 0;
while ((read = rootNode->ReadDir(dirBuffer, sizeof(kdirent) * 16, offset, LONG_MAX)) > 0)
{
if (read / sizeof(kdirent) == 0)
break;
for (auto &&child : children)
{
if (child->Name == "." || child->Name == "..")
continue;
off_t bufOffset = 0;
for (size_t i = 0; i < read / sizeof(kdirent); i++)
{
kdirent *dirent = (kdirent *)((uintptr_t)dirBuffer + bufOffset);
if (dirent->d_reclen == 0)
break;
bufOffset += dirent->d_reclen;
bool isLast = (++index == count);
if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0)
continue;
printf("%s%s- %s\n", prefix.c_str(), isLast ? "\\" : "|-", child->Name.c_str());
FileNode *node = fs->GetByPath(dirent->d_name, rootNode);
if (node == nullptr)
continue;
for (int i = 0; i < depth; i++)
printf(" ");
printf("|- %s\n", dirent->d_name);
if (node->IsDirectory())
tree_loop(node, depth + 1);
}
offset += read;
}
delete[] dirBuffer;
if (child->IsDirectory())
{
std::string newPrefix = prefix + (isLast ? " " : "| ");
tree_loop(child, depth + 1, newPrefix);
}
}
}
void cmd_tree(const char *args)
{
FileNode *rootNode = thisProcess->CWD;
Node rootNode = thisProcess->CWD;
if (args[0] == '\0')
{
if (rootNode == nullptr)
@ -88,7 +56,7 @@ void cmd_tree(const char *args)
}
else
{
rootNode = fs->GetByPath(args, nullptr);
rootNode = fs->Lookup(thisProcess->CWD, args);
if (rootNode == nullptr)
{
printf("ls: %s: No such file or directory\n", args);

View File

@ -17,7 +17,7 @@
#include "../cmds.hpp"
#include <filesystem.hpp>
#include <fs/vfs.hpp>
#include "../../kernel.h"

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