Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd73cf833f | ||
|
|
71fe3d733b | ||
|
|
991b13424e |
21
.clang-format
Normal file
21
.clang-format
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
|
||||
ColumnLimit: 100
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
UseTab: Always
|
||||
|
||||
AccessModifierOffset: -4
|
||||
|
||||
AlignEscapedNewlinesLeft: true
|
||||
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
|
||||
AlwaysBreakAfterReturnType: AllDefinitions
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
|
||||
BreakBeforeBraces: Linux
|
||||
@@ -1,11 +0,0 @@
|
||||
[section] Imperative-voiced title in less than 50
|
||||
|
||||
# Body describes what was done, and why. New obviously-needed features
|
||||
# don't necessarily require a why.
|
||||
|
||||
# Links to relevant bugs or web pages
|
||||
See: Github bug #242
|
||||
See: [frobozz blog post](https://jsix.dev/posts/frobozz/)
|
||||
|
||||
# Tags and keywords useful for searching
|
||||
Tags:
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,15 +1,10 @@
|
||||
.cache
|
||||
.lock*
|
||||
/build*
|
||||
*.bak
|
||||
tags
|
||||
jsix.log
|
||||
*.out
|
||||
*.o
|
||||
*.a
|
||||
sysroot
|
||||
.gdb_history
|
||||
.peru
|
||||
__pycache__
|
||||
/venv
|
||||
compile_commands.json
|
||||
|
||||
38
NOTES.md
Normal file
38
NOTES.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Design / WIP notes
|
||||
|
||||
## TODO
|
||||
|
||||
- Paging manager
|
||||
- Copy-on-write pages
|
||||
- Better page-allocation model?
|
||||
- Allow for more than one IOAPIC in ACPI module
|
||||
- The objects get created, but GSI lookup only uses the one at index 0
|
||||
- mark kernel memory pages global
|
||||
- Serial out based on circular/bip biffer and interrupts, not spinning on
|
||||
`write_ready()`
|
||||
- Split out more code into kutil for testing
|
||||
- AHCI / MSI interrupts on Vbox break?
|
||||
- FXSAVE to save XMM registers.
|
||||
- optimization using #NM (0x7) to detect SSE usage
|
||||
- Clean up of process memory maps
|
||||
- Better stack tracer
|
||||
- Bootloader rewrite
|
||||
- C++ and sharing library code for ELF, initrd, etc
|
||||
- Parse initrd and pre-load certain ELF images, eg the process loader process?
|
||||
- Do initial memory bootstrap?
|
||||
- Calling global ctors
|
||||
- Device Tree
|
||||
- Actual serial driver
|
||||
- Disk driver
|
||||
- File system
|
||||
- Multiprocessing
|
||||
- Fast syscalls using syscall/sysret
|
||||
|
||||
### Build
|
||||
|
||||
- Clean up build generator and its templates
|
||||
- More robust objects to represent modules & targets to pass to templates
|
||||
- Read project setup from a simple JSON/TOML/etc
|
||||
- Better compartmentalizing when doing template inheritance
|
||||
- Move to LLD as sysroot linker
|
||||
|
||||
185
README.md
185
README.md
@@ -1,19 +1,15 @@
|
||||

|
||||
# jsix: A toy OS kernel
|
||||
|
||||
# The jsix operating system
|
||||
|
||||
**jsix** is a custom multi-core x64 operating system that I am building from
|
||||
scratch. It's far from finished, or even being usable (see the *Status and
|
||||
Roadmap* section, below) but all currently-planned major kernel features are
|
||||
now implemented to at least a passable level.
|
||||
**jsix** is the kernel for the hobby OS that I am currently building. It's
|
||||
far from finished, or even being usable. Instead, it's a sandbox for me to play
|
||||
with kernel-level code and explore architectures.
|
||||
|
||||
The design goals of the project are:
|
||||
|
||||
* Modernity - I'm not interested in designing for legacy systems, or running on
|
||||
all hardware out there. My target is only 64 bit architectures, and modern
|
||||
all hardware out there. My target is only 64 bit architecutres, and modern
|
||||
commodity hardware. Currently that means x64 systems with Nehalem or newer
|
||||
CPUs and UEFI firmware. (See [this list][cpu_features] for the currently
|
||||
required CPU features.) Eventually I'd like to work on an AArch64 port,
|
||||
CPUs and UEFI firmware. Eventually I'd like to work on an AArch64 port,
|
||||
partly to force myself to factor out the architecture-dependent pieces of the
|
||||
code base.
|
||||
|
||||
@@ -21,11 +17,13 @@ The design goals of the project are:
|
||||
processes as possible, in the microkernel fashion. A sub-goal of this is to
|
||||
explore where the bottlenecks of such a microkernel are now, and whether
|
||||
eschewing legacy hardware will let me design a system that's less bogged down
|
||||
by the traditional microkernel problems.
|
||||
by the traditional microkernel problems. Given that there are no processes
|
||||
yet, the kernel is monolithic by default.
|
||||
|
||||
* Exploration - I'm really mostly doing this to have fun learning and exploring
|
||||
modern OS development. Initial feature implementations may temporarily throw
|
||||
away modular design to allow for exploration of the related hardware.
|
||||
modern OS development. Modular design may be tossed out (hopefully
|
||||
temporarily) in some places to allow me to play around with the related
|
||||
hardware.
|
||||
|
||||
A note on the name: This kernel was originally named Popcorn, but I have since
|
||||
discovered that the Popcorn Linux project is also developing a kernel with that
|
||||
@@ -33,149 +31,48 @@ name, started around the same time as this project. So I've renamed this kernel
|
||||
jsix (Always styled _jsix_ or `j6`, never capitalized) as an homage to L4, xv6,
|
||||
and my wonderful wife.
|
||||
|
||||
[cpu_features]: https://github.com/justinian/jsix/blob/master/src/libraries/cpu/include/cpu/features.inc
|
||||
|
||||
## Status and Roadmap
|
||||
|
||||
The following major feature areas are targets for jsix development:
|
||||
|
||||
#### UEFI boot loader
|
||||
|
||||
_Done._ The bootloader loads the kernel and initial userspace programs, and
|
||||
sets up necessary kernel arguments about the memory map and EFI GOP
|
||||
framebuffer. Possible future ideas:
|
||||
|
||||
- take over more init-time functions from the kernel
|
||||
- rewrite it in Zig
|
||||
|
||||
#### Memory
|
||||
|
||||
_Virtual memory: Sufficient._ The kernel manages virtual memory with a number
|
||||
of kinds of `vm_area` objects representing mapped areas, which can belong to
|
||||
one or more `vm_space` objects which represent a whole virtual memory space.
|
||||
(Each process has a `vm_space`, and so does the kernel itself.)
|
||||
|
||||
Remaining to do:
|
||||
|
||||
- TLB shootdowns
|
||||
- Page swapping
|
||||
- Large / huge page support
|
||||
|
||||
_Physical page allocation: Sufficient._ The current physical page allocator
|
||||
implementation uses a group of blocks representing up-to-1GiB areas of usable
|
||||
memory as defined by the bootloader. Each block has a three-level bitmap
|
||||
denoting free/used pages.
|
||||
|
||||
Future work:
|
||||
|
||||
- Align blocks so that their first page is 1GiB-aligned, making finding free
|
||||
large/huge pages easier.
|
||||
|
||||
#### Multitasking
|
||||
|
||||
_Sufficient._ The global scheduler object keeps separate ready/blocked lists
|
||||
per core. Cores periodically attempt to balance load via work stealing.
|
||||
|
||||
User-space tasks are able to create threads as well as other processes.
|
||||
|
||||
#### API
|
||||
|
||||
_Syscalls: Sufficient._ User-space tasks are able to make syscalls to the
|
||||
kernel via fast SYSCALL/SYSRET instructions. Syscalls made via `libj6` look to
|
||||
both the callee and the caller like standard SysV ABI function calls. The
|
||||
implementations are wrapped in generated wrapper functions which validate the
|
||||
request, check capabilities, and find the appropriate kernel objects or handles
|
||||
before calling the implementation functions.
|
||||
|
||||
_IPC: Working, needs optimization._ The current IPC primitives are:
|
||||
|
||||
- _Mailboxes_: endpoints for asynchronously-delivered small messages. Currently
|
||||
these messages are double-copied - once from the caller into a kernel buffer,
|
||||
and once from the kernel to the receiver. This works and is not a major cause
|
||||
of slowdown, but will need to be optimized in the future.
|
||||
- _Channels_: endpoints for asynchronous uni-directional streams of bytes.
|
||||
Currently these also suffer from a double-copy problem, and should probably
|
||||
be replaced eventually by userspace shared memory communication.
|
||||
- _Events_: objects that can be signalled to send asynchronous notifications to
|
||||
waiting threads.
|
||||
|
||||
#### Hardware Support
|
||||
|
||||
- Framebuffer driver: _In progress._ Currently on machines with a video
|
||||
device accessible by UEFI, jsix starts a user-space framebuffer driver that
|
||||
only prints out kernel logs.
|
||||
- Serial driver: _In progress._ The current UART currently only exposes COM1
|
||||
as an output channel, but no input or other serial ports are exposed.
|
||||
- USB driver: _To do_
|
||||
- AHCI (SATA) driver: _To do_
|
||||
|
||||
## Building
|
||||
|
||||
jsix uses the [Ninja][] build tool, and generates the build files for it with
|
||||
the `configure` script. The build also relies on a custom toolchain sysroot, which can be
|
||||
downloaded or built using the scripts in [jsix-os/toolchain][].
|
||||
jsix uses the [Ninja][] build tool, and generates the build files for it with a
|
||||
custom tool called [Bonnibel][]. Bonnibel can be installed with [Cargo][], or
|
||||
downloaded as a prebuilt binary from its Github repository.
|
||||
|
||||
[Ninja]: https://ninja-build.org
|
||||
[jsix-os/toolchain]: https://github.com/jsix-os/toolchain
|
||||
[Ninja]: https://ninja-build.org
|
||||
[Bonnibel]: https://github.com/justinian/bonnibel
|
||||
[Cargo]: https://crates.io/crates/bonnibel
|
||||
|
||||
Other build dependencies:
|
||||
Requrirements:
|
||||
|
||||
* [clang][]: the C/C++ compiler
|
||||
* [nasm][]: the assembler
|
||||
* [lld][]: the linker
|
||||
* [mtools][]: for creating the FAT image
|
||||
* bonnibel
|
||||
* ninja
|
||||
* clang
|
||||
* nasm
|
||||
* mtools
|
||||
* curl for downloading the toolchain
|
||||
|
||||
[clang]: https://clang.llvm.org
|
||||
[nasm]: https://www.nasm.us
|
||||
[lld]: https://lld.llvm.org
|
||||
[mtools]: https://www.gnu.org/software/mtools/
|
||||
### Setting up the cross toolchain
|
||||
|
||||
The `configure` script has some Python dependencies - these can be installed via
|
||||
`pip`, though doing so in a python virtual environment is recommended.
|
||||
Installing via `pip` will also install `ninja`.
|
||||
Running `pb sync` will download and unpack the toolchain into `sysroot`.
|
||||
|
||||
A Debian 11 (Bullseye) system can be configured with the necessary build
|
||||
dependencies by running the following commands from the jsix repository root:
|
||||
#### Compiling the toolchain yourself
|
||||
|
||||
```bash
|
||||
sudo apt install clang lld nasm mtools python3-pip python3-venv
|
||||
python3 -m venv ./venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
peru sync
|
||||
```
|
||||
|
||||
### Setting up the sysroot
|
||||
|
||||
Build or download the toolchain sysroot as mentioned above with
|
||||
[jsix-os/toolchain][], and symlink the built toolchain directory as `sysroot`
|
||||
at the root of this project.
|
||||
|
||||
```bash
|
||||
# Example if both the toolchain and this project are cloned under ~/src
|
||||
ln -s ~/src/toolchain/toolchains/llvm-13 ~/src/jsix/sysroot
|
||||
```
|
||||
If you have `clang` and `curl` installed, runing the `scripts/build_sysroot.sh`
|
||||
script will download and build a LLVM toolchain configured for building jsix
|
||||
host binaries.
|
||||
|
||||
### Building and running jsix
|
||||
|
||||
Once the toolchain has been set up, running the `./configure` script (see
|
||||
`./configure --help` for available options) will set up the build configuration,
|
||||
and `ninja -C build` (or wherever you put the build directory) will actually run
|
||||
the build. If you have `qemu-system-x86_64` installed, the `qemu.sh` script will
|
||||
to run jsix in QEMU `-nographic` mode.
|
||||
Once the toolchain has been set up, running Bonnibel's `pb init` command will
|
||||
set up the build configuration, and `pb build` will actually run the build. If
|
||||
you have `qemu-system-x86_64` installed, the `qemu.sh` script will to run jsix
|
||||
in QEMU `-nographic` mode.
|
||||
|
||||
I personally run this either from a real debian amd64 bullseye machine or
|
||||
a windows WSL debian bullseye installation. Your mileage may vary with other
|
||||
setups and distros.
|
||||
I personally run this either from a real debian amd64 testing/buster machine or
|
||||
a windows WSL debian testing/buster installation. The following should be
|
||||
enough to set up such a system to build the kernel:
|
||||
|
||||
### Running the test suite
|
||||
sudo apt install qemu-system-x86 nasm clang-6.0 mtools curl
|
||||
sudo update-alternatives /usr/bin/clang clang /usr/bin/clang-6.0 1000
|
||||
sudo update-alternatives /usr/bin/clang++ clang++ /usr/bin/clang++-6.0 1000
|
||||
curl -L -o pb https://github.com/justinian/bonnibel/releases/download/2.0.0/pb_linux_amd64 && chmod a+x pb
|
||||
|
||||
jsix now has the `test_runner` userspace program that runs various automated
|
||||
tests. It is not included in the default build, but if you use the `test.yml`
|
||||
manifest it will be built, and can be run with the `test.sh` script or the
|
||||
`qemu.sh` script.
|
||||
|
||||
```bash
|
||||
./configure --manifest=assets/manifests/test.yml
|
||||
if ./test.sh; then echo "All tests passed!"; else echo "Failed."; fi
|
||||
```
|
||||
|
||||
@@ -2,7 +2,7 @@ import gdb
|
||||
|
||||
class PrintStackCommand(gdb.Command):
|
||||
def __init__(self):
|
||||
super().__init__("j6stack", gdb.COMMAND_DATA)
|
||||
super().__init__("popc_stack", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
args = gdb.string_to_argv(arg)
|
||||
@@ -10,260 +10,22 @@ class PrintStackCommand(gdb.Command):
|
||||
base = "$rsp"
|
||||
if len(args) > 0:
|
||||
base = args[0]
|
||||
base = int(gdb.parse_and_eval(base))
|
||||
|
||||
depth = 22
|
||||
if len(args) > 1:
|
||||
depth = int(args[1])
|
||||
|
||||
for i in range(depth-1, -1, -1):
|
||||
try:
|
||||
offset = i * 8
|
||||
value = gdb.parse_and_eval(f"*(uint64_t*)({base:#x} + {offset:#x})")
|
||||
print("{:016x} (+{:04x}): {:016x}".format(base + offset, offset, int(value)))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
continue
|
||||
offset = i * 8
|
||||
base_addr = gdb.parse_and_eval(base)
|
||||
value = gdb.parse_and_eval(f"*(uint64_t*)({base} + {offset})")
|
||||
print("{:016x} (+{:04x}): {:016x}".format(int(base_addr) + offset, offset, int(value)))
|
||||
|
||||
|
||||
def stack_walk(frame, depth):
|
||||
for i in range(depth-1, -1, -1):
|
||||
ret = gdb.parse_and_eval(f"*(uint64_t*)({frame:#x} + 0x8)")
|
||||
|
||||
name = ""
|
||||
try:
|
||||
block = gdb.block_for_pc(int(ret))
|
||||
if block:
|
||||
name = block.function or ""
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
print("{:016x}: {:016x} {}".format(int(frame), int(ret), name))
|
||||
frame = int(gdb.parse_and_eval(f"*(uint64_t*)({frame:#x})"))
|
||||
except gdb.MemoryError:
|
||||
return
|
||||
|
||||
if frame == 0 or ret == 0:
|
||||
return
|
||||
|
||||
|
||||
class PrintBacktraceCommand(gdb.Command):
|
||||
def __init__(self):
|
||||
super().__init__("j6bt", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
args = gdb.string_to_argv(arg)
|
||||
|
||||
frame = "$rbp"
|
||||
if len(args) > 0:
|
||||
frame = args[0]
|
||||
|
||||
frame = int(gdb.parse_and_eval(f"{frame}"))
|
||||
|
||||
depth = 30
|
||||
if len(args) > 1:
|
||||
depth = int(gdb.parse_and_eval(args[1]))
|
||||
|
||||
stack_walk(frame, depth)
|
||||
|
||||
|
||||
class TableWalkCommand(gdb.Command):
|
||||
def __init__(self):
|
||||
super().__init__("j6tw", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
args = gdb.string_to_argv(arg)
|
||||
if len(args) < 2:
|
||||
raise Exception("Must be: j6tw <pml4> <addr>")
|
||||
|
||||
pml4 = int(gdb.parse_and_eval(args[0]))
|
||||
addr = int(gdb.parse_and_eval(args[1]))
|
||||
|
||||
indices = [
|
||||
(addr >> 39) & 0x1ff,
|
||||
(addr >> 30) & 0x1ff,
|
||||
(addr >> 21) & 0x1ff,
|
||||
(addr >> 12) & 0x1ff,
|
||||
]
|
||||
|
||||
names = ["PML4", "PDP", "PD", "PT"]
|
||||
|
||||
table_flags = [
|
||||
(0x0001, "present"),
|
||||
(0x0002, "write"),
|
||||
(0x0004, "user"),
|
||||
(0x0008, "pwt"),
|
||||
(0x0010, "pcd"),
|
||||
(0x0020, "accessed"),
|
||||
(0x0040, "dirty"),
|
||||
(0x0080, "largepage"),
|
||||
(0x0100, "global"),
|
||||
(0x1080, "pat"),
|
||||
((1<<63), "xd"),
|
||||
]
|
||||
|
||||
page_flags = [
|
||||
(0x0001, "present"),
|
||||
(0x0002, "write"),
|
||||
(0x0004, "user"),
|
||||
(0x0008, "pwt"),
|
||||
(0x0010, "pcd"),
|
||||
(0x0020, "accessed"),
|
||||
(0x0040, "dirty"),
|
||||
(0x0080, "pat"),
|
||||
(0x0100, "global"),
|
||||
((1<<63), "xd"),
|
||||
]
|
||||
|
||||
flagsets = [table_flags, table_flags, table_flags, page_flags]
|
||||
|
||||
table = pml4
|
||||
entry = 0
|
||||
for i in range(len(indices)):
|
||||
entry = int(gdb.parse_and_eval(f'((uint64_t*)0x{table:x})[0x{indices[i]:x}]'))
|
||||
flagset = flagsets[i]
|
||||
flag_names = " | ".join([f[1] for f in flagset if (entry & f[0]) == f[0]])
|
||||
|
||||
print(f"{names[i]:>4}: {table:016x}")
|
||||
print(f" index: {indices[i]:3} {entry:016x}")
|
||||
print(f" flags: {flag_names}")
|
||||
|
||||
if (entry & 1) == 0 or (i < 3 and (entry & 0x80)):
|
||||
break
|
||||
|
||||
table = (entry & 0x7ffffffffffffe00) | 0xffffc00000000000
|
||||
|
||||
|
||||
class GetThreadsCommand(gdb.Command):
|
||||
FLAGS = {
|
||||
"ready": 0x01,
|
||||
"loading": 0x02,
|
||||
"exited": 0x04,
|
||||
"constant": 0x80,
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("j6threads", gdb.COMMAND_DATA)
|
||||
|
||||
def get_flags(self, bitset):
|
||||
flags = []
|
||||
for k, v in GetThreadsCommand.FLAGS.items():
|
||||
if bitset & v:
|
||||
flags.append(k)
|
||||
return " ".join(flags)
|
||||
|
||||
def print_thread(self, addr):
|
||||
if addr == 0:
|
||||
print(" <no thread>\n")
|
||||
return
|
||||
|
||||
tcb = f"((TCB*){addr:#x})"
|
||||
thread = f"({tcb}->thread)"
|
||||
stack = int(gdb.parse_and_eval(f"{tcb}->kernel_stack"))
|
||||
rsp = int(gdb.parse_and_eval(f"{tcb}->rsp"))
|
||||
pri = int(gdb.parse_and_eval(f"{tcb}->priority"))
|
||||
flags = int(gdb.parse_and_eval(f"{thread}->m_state"))
|
||||
koid = int(gdb.parse_and_eval(f"{thread}->m_koid"))
|
||||
proc = int(gdb.parse_and_eval(f"{thread}->m_parent.m_koid"))
|
||||
|
||||
creator = int(gdb.parse_and_eval(f"{thread}->m_creator"))
|
||||
if creator != 0:
|
||||
creator_koid = int(gdb.parse_and_eval(f"{thread}->m_creator->m_koid"))
|
||||
creator = f"{creator_koid:x}"
|
||||
else:
|
||||
creator = "<no thread>"
|
||||
|
||||
print(f" Thread {proc:x}:{koid:x}")
|
||||
print(f" creator: {creator}")
|
||||
print(f" priority: {pri}")
|
||||
print(f" flags: {self.get_flags(flags)}")
|
||||
print(f" kstack: {stack:#x}")
|
||||
print(f" rsp: {rsp:#x}")
|
||||
print("------------------------------------")
|
||||
|
||||
if stack != 0:
|
||||
rsp = int(gdb.parse_and_eval(f"{tcb}->rsp"))
|
||||
stack_walk(rsp + 5*8, 5)
|
||||
|
||||
print("")
|
||||
|
||||
def print_thread_list(self, addr, name):
|
||||
if addr == 0:
|
||||
return
|
||||
|
||||
print(f"=== {name} ===")
|
||||
|
||||
while addr != 0:
|
||||
self.print_thread(addr)
|
||||
addr = int(gdb.parse_and_eval(f"((tcb_node*){addr:#x})->m_next"))
|
||||
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
args = gdb.string_to_argv(arg)
|
||||
if len(args) > 1:
|
||||
raise RuntimeError("Usage: j6threads [cpu]")
|
||||
|
||||
ncpus = int(gdb.parse_and_eval("g_num_cpus"))
|
||||
cpus = list(range(ncpus))
|
||||
if len(args) == 1:
|
||||
cpus = [int(args[0])]
|
||||
|
||||
for cpu in cpus:
|
||||
runlist = f"scheduler::s_instance->m_run_queues.m_elements[{cpu:#x}]"
|
||||
|
||||
print(f"=== CPU {cpu:2}: CURRENT ===")
|
||||
current = int(gdb.parse_and_eval(f"{runlist}.current"))
|
||||
self.print_thread(current)
|
||||
|
||||
for pri in range(8):
|
||||
ready = int(gdb.parse_and_eval(f"{runlist}.ready[{pri:#x}].m_head"))
|
||||
self.print_thread_list(ready, f"CPU {cpu:2}: PRIORITY {pri}")
|
||||
|
||||
blocked = int(gdb.parse_and_eval(f"{runlist}.blocked.m_head"))
|
||||
self.print_thread_list(blocked, f"CPU {cpu:2}: BLOCKED")
|
||||
|
||||
|
||||
class PrintProfilesCommand(gdb.Command):
|
||||
def __init__(self):
|
||||
super().__init__("j6prof", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
args = gdb.string_to_argv(arg)
|
||||
if len(args) != 1:
|
||||
raise RuntimeError("Usage: j6prof <profiler class>")
|
||||
|
||||
profclass = args[0]
|
||||
root_type = f"profile_class<{profclass}>"
|
||||
|
||||
try:
|
||||
baseclass = gdb.lookup_type(root_type)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return
|
||||
|
||||
results = {}
|
||||
max_len = 0
|
||||
count = gdb.parse_and_eval(f"{profclass}::count")
|
||||
for i in range(count):
|
||||
name = gdb.parse_and_eval(f"{root_type}::function_names[{i:#x}]")
|
||||
if name == 0: continue
|
||||
|
||||
call_counts = gdb.parse_and_eval(f"{root_type}::call_counts[{i:#x}]")
|
||||
call_durations = gdb.parse_and_eval(f"{root_type}::call_durations[{i:#x}]")
|
||||
results[name.string()] = float(call_durations) / float(call_counts)
|
||||
max_len = max(max_len, len(name.string()))
|
||||
|
||||
for name, avg in results.items():
|
||||
print(f"{name:>{max_len}}: {avg:15.3f}")
|
||||
|
||||
PrintStackCommand()
|
||||
PrintBacktraceCommand()
|
||||
TableWalkCommand()
|
||||
GetThreadsCommand()
|
||||
PrintProfilesCommand()
|
||||
|
||||
import time
|
||||
time.sleep(3.5)
|
||||
gdb.execute("target remote :1234")
|
||||
gdb.execute("set waiting = false")
|
||||
gdb.execute("display/i $rip")
|
||||
if not gdb.selected_inferior().was_attached:
|
||||
gdb.execute("add-symbol-file build/panic.serial.elf")
|
||||
gdb.execute("target remote :1234")
|
||||
|
||||
Binary file not shown.
@@ -1,47 +0,0 @@
|
||||
start: import_statement* (object|interface)+
|
||||
|
||||
import_statement: "import" PATH
|
||||
|
||||
object: description? "object" name options? super? "{" uid cname? capabilities? method* "}"
|
||||
|
||||
interface: description? "interface" name options? "{" uid interface_param* "}"
|
||||
|
||||
?interface_param: expose | function
|
||||
|
||||
expose: "expose" type
|
||||
|
||||
uid: "uid" UID
|
||||
|
||||
cname: "cname" IDENTIFIER
|
||||
|
||||
capabilities: "capabilities" "[" IDENTIFIER+ "]"
|
||||
|
||||
super: ":" name
|
||||
|
||||
function: description? "function" name options? ("{" param* "}")?
|
||||
|
||||
method: description? "method" name options? ("{" param* "}")?
|
||||
|
||||
param: "param" name type options? description?
|
||||
|
||||
?type: PRIMITIVE | object_name
|
||||
|
||||
object_name: "ref" name
|
||||
|
||||
id: NUMBER
|
||||
name: IDENTIFIER
|
||||
options: "[" ( OPTION | IDENTIFIER )+ "]"
|
||||
description: COMMENT+
|
||||
|
||||
PRIMITIVE: INT_TYPE | "size" | "string" | "buffer" | "address"
|
||||
INT_TYPE: /u?int(8|16|32|64)?/
|
||||
NUMBER: /(0x)?[0-9a-fA-F]+/
|
||||
UID: /[0-9a-fA-F]{16}/
|
||||
OPTION.2: IDENTIFIER ":" IDENTIFIER
|
||||
COMMENT: /#.*/
|
||||
PATH: /"[^"]*"/
|
||||
|
||||
%import common.LETTER
|
||||
%import common.CNAME -> IDENTIFIER
|
||||
%import common.WS
|
||||
%ignore WS
|
||||
28
assets/initrd.toml
Normal file
28
assets/initrd.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
# This is the manifest for the initial ramdisk, read by the `makerd` tool.
|
||||
# The contents should be a table array of files to add to the ramdistk:
|
||||
#
|
||||
# [[files]]
|
||||
# dest = "foo.bar" # Name of the file in the ramdisk
|
||||
# source = "build/foo/foo.bar" # Location of the file from the project root
|
||||
# executable = true # Optional, default false. Whether this is an
|
||||
# # initial application for the kernel to execute
|
||||
# # on startup
|
||||
|
||||
[[files]]
|
||||
dest = "vdso.so"
|
||||
source = "host/libvdso.so"
|
||||
type = "vdso"
|
||||
|
||||
[[files]]
|
||||
dest = "screenfont.psf"
|
||||
source = "../assets/fonts/tamsyn8x16r.psf"
|
||||
|
||||
[[files]]
|
||||
dest = "nulldrv1"
|
||||
source = "user/nulldrv"
|
||||
type = "executable"
|
||||
|
||||
[[files]]
|
||||
dest = "nulldrv2"
|
||||
source = "user/nulldrv"
|
||||
type = "executable"
|
||||
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="176.562 356.069 211.11 113" width="211.11pt" height="113pt"><g><g><rect x="176.562" y="356.069" width="211.11" height="113" transform="matrix(1,0,0,1,0,0)" fill="rgb(255,255,255)"/><g><path d=" M 212.981 372.36 L 219.564 376.16 L 226.147 379.961 L 226.147 387.563 L 226.147 395.164 L 219.564 398.965 L 212.981 402.766 L 206.398 398.965 L 199.815 395.164 L 199.815 387.563 L 199.815 379.961 L 206.398 376.16 L 212.981 372.36 L 212.981 372.36 L 212.981 372.36 Z M 256.292 397.366 L 262.875 401.166 L 269.458 404.967 L 269.458 412.569 L 269.458 420.17 L 262.875 423.971 L 256.292 427.772 L 249.709 423.971 L 243.126 420.17 L 243.126 412.569 L 243.126 404.967 L 249.709 401.166 L 256.292 397.366 L 256.292 397.366 Z M 183.622 387.283 L 205.52 374.64 L 227.418 361.997 L 249.316 374.64 L 271.214 387.283 L 271.214 412.569 L 271.214 437.854 L 249.316 450.497 L 227.418 463.14 L 205.52 450.497 L 183.622 437.854 L 183.622 412.569 L 183.622 387.283 L 183.622 387.283 L 183.622 387.283 Z M 241.855 372.36 L 248.438 376.16 L 255.021 379.961 L 255.021 387.563 L 255.021 395.164 L 248.438 398.965 L 241.855 402.766 L 235.272 398.965 L 228.689 395.164 L 228.689 387.563 L 228.689 379.961 L 235.272 376.16 L 241.855 372.36 Z " fill-rule="evenodd" fill="rgb(49,79,128)"/><path d=" M 298.642 379.579 L 291.621 379.579 L 291.621 372.558 L 298.642 372.558 L 298.642 379.579 Z M 285.214 446.718 L 285.214 441.452 L 287.32 441.452 L 287.32 441.452 Q 289.339 441.452 290.524 440.092 L 290.524 440.092 L 290.524 440.092 Q 291.708 438.731 291.708 436.625 L 291.708 436.625 L 291.708 387.039 L 298.729 387.039 L 298.729 436.011 L 298.729 436.011 Q 298.729 440.925 295.921 443.822 L 295.921 443.822 L 295.921 443.822 Q 293.113 446.718 288.286 446.718 L 288.286 446.718 L 285.214 446.718 Z M 306.628 432.676 L 306.628 427.41 L 314.088 427.41 L 314.088 427.41 Q 317.862 427.41 319.573 425.347 L 319.573 425.347 L 319.573 425.347 Q 321.285 423.285 321.285 419.95 L 321.285 419.95 L 321.285 419.95 Q 321.285 417.317 319.705 415.474 L 319.705 415.474 L 319.705 415.474 Q 318.125 413.631 314.966 411.174 L 314.966 411.174 L 314.966 411.174 Q 312.245 408.98 310.621 407.356 L 310.621 407.356 L 310.621 407.356 Q 308.998 405.732 307.813 403.319 L 307.813 403.319 L 307.813 403.319 Q 306.628 400.905 306.628 397.746 L 306.628 397.746 L 306.628 397.746 Q 306.628 393.095 309.744 390.067 L 309.744 390.067 L 309.744 390.067 Q 312.859 387.039 318.125 387.039 L 318.125 387.039 L 325.76 387.039 L 325.76 392.305 L 319.441 392.305 L 319.441 392.305 Q 313.21 392.305 313.21 398.185 L 313.21 398.185 L 313.21 398.185 Q 313.21 400.467 314.615 402.134 L 314.615 402.134 L 314.615 402.134 Q 316.019 403.802 319.003 406.083 L 319.003 406.083 L 319.003 406.083 Q 321.723 408.19 323.479 409.901 L 323.479 409.901 L 323.479 409.901 Q 325.234 411.613 326.463 414.202 L 326.463 414.202 L 326.463 414.202 Q 327.691 416.791 327.691 420.301 L 327.691 420.301 L 327.691 420.301 Q 327.691 426.532 324.4 429.604 L 324.4 429.604 L 324.4 429.604 Q 321.109 432.676 315.141 432.676 L 315.141 432.676 L 306.628 432.676 Z M 342.611 379.579 L 335.59 379.579 L 335.59 372.558 L 342.611 372.558 L 342.611 379.579 Z M 342.611 432.676 L 335.59 432.676 L 335.59 387.039 L 342.611 387.039 L 342.611 432.676 Z M 356.126 432.676 L 348.754 432.676 L 361.392 409.77 L 349.632 387.039 L 356.39 387.039 L 364.639 403.187 L 372.977 387.039 L 379.735 387.039 L 367.974 409.77 L 380.612 432.676 L 373.24 432.676 L 364.639 416.001 L 356.126 432.676 Z " fill="rgb(49,79,128)"/></g></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 3.6 KiB |
@@ -1,8 +0,0 @@
|
||||
---
|
||||
init: srv.init
|
||||
programs:
|
||||
- name: panic.serial
|
||||
target: kernel
|
||||
flags: panic
|
||||
- name: srv.logger
|
||||
- name: drv.uart
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
init: srv.init
|
||||
flags: ["test"]
|
||||
programs:
|
||||
- name: panic.serial
|
||||
target: kernel
|
||||
flags: panic
|
||||
- name: drv.uart
|
||||
- name: test_runner
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
variables:
|
||||
cc: "${source_root}/sysroot/bin/clang"
|
||||
cxx: "${source_root}/sysroot/bin/clang++"
|
||||
ld: "${source_root}/sysroot/bin/ld.lld"
|
||||
ar: ar
|
||||
nasm: nasm
|
||||
objcopy: objcopy
|
||||
|
||||
ccflags: [
|
||||
"-I${source_root}/src/include",
|
||||
"-I${source_root}/src/include/x86_64",
|
||||
"-fcolor-diagnostics",
|
||||
"-U__STDCPP_THREADS__",
|
||||
"-D_LIBCPP_HAS_NO_THREADS",
|
||||
"-DVERSION_MAJOR=${version_major}",
|
||||
"-DVERSION_MINOR=${version_minor}",
|
||||
"-DVERSION_PATCH=${version_patch}",
|
||||
"-DVERSION_GITSHA=0x${version_sha}",
|
||||
'-DGIT_VERSION=\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"',
|
||||
'-DGIT_VERSION_WIDE=L\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"',
|
||||
|
||||
"-Wformat=2", "-Winit-self", "-Wfloat-equal", "-Winline", "-Wmissing-format-attribute",
|
||||
"-Wmissing-include-dirs", "-Wswitch", "-Wundef", "-Wdisabled-optimization",
|
||||
"-Wpointer-arith", "-Wno-attributes", "-Wno-sign-compare", "-Wno-multichar",
|
||||
"-Wno-div-by-zero", "-Wno-endif-labels", "-Wno-pragmas", "-Wno-format-extra-args",
|
||||
"-Wno-unused-result", "-Wno-deprecated-declarations", "-Wno-unused-function",
|
||||
"-Wno-address-of-packed-member", "-Wno-invalid-offsetof", "-Wno-format-nonliteral",
|
||||
"-Werror" ]
|
||||
|
||||
asflags: [
|
||||
"-DVERSION_MAJOR=${version_major}",
|
||||
"-DVERSION_MINOR=${version_minor}",
|
||||
"-DVERSION_PATCH=${version_patch}",
|
||||
"-DVERSION_GITSHA=0x${version_sha}",
|
||||
"-I${source_root}/src/include" ]
|
||||
|
||||
cflags: [ "-std=c11" ]
|
||||
cxxflags: [ "-std=c++17" ]
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
extends: base
|
||||
|
||||
variables:
|
||||
ld: clang++
|
||||
|
||||
ccflags: [
|
||||
"-nostdlib",
|
||||
"-nodefaultlibs",
|
||||
"-fno-builtin",
|
||||
|
||||
"-I${source_root}/external",
|
||||
"--target=x86_64-unknown-windows",
|
||||
"-ffreestanding",
|
||||
"-mno-red-zone",
|
||||
"-fshort-wchar",
|
||||
"-fno-omit-frame-pointer",
|
||||
"-ggdb",
|
||||
"-g3" ]
|
||||
|
||||
cxxflags: [ "-fno-exceptions", "-fno-rtti" ]
|
||||
|
||||
ldflags: [
|
||||
"--target=x86_64-unknown-windows",
|
||||
"-nostdlib",
|
||||
"-Wl,-entry:efi_main",
|
||||
"-Wl,-subsystem:efi_application",
|
||||
"-fuse-ld=lld-link",
|
||||
"-g" ]
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
extends: base
|
||||
|
||||
variables:
|
||||
asflags: [ "-I${source_root}/src/kernel/" ]
|
||||
|
||||
ccflags: [
|
||||
"--target=x86_64-jsix-elf",
|
||||
"-fno-stack-protector",
|
||||
|
||||
"-I${source_root}/external",
|
||||
|
||||
"-nostdinc",
|
||||
"-nostdlib",
|
||||
"-ffreestanding",
|
||||
"-nodefaultlibs",
|
||||
"-fno-builtin",
|
||||
|
||||
"-mno-sse",
|
||||
"-fno-omit-frame-pointer",
|
||||
"-mno-red-zone",
|
||||
"-mcmodel=kernel",
|
||||
|
||||
"-g3",
|
||||
"-ggdb",
|
||||
|
||||
"-D__ELF__",
|
||||
"-D__jsix__",
|
||||
"-D__j6kernel",
|
||||
"-U__linux",
|
||||
"-U__linux__",
|
||||
"-DPRINTF_ALIAS_STANDARD_FUNCTION_NAMES=1",
|
||||
"-DPRINTF_INCLUDE_CONFIG_H=1",
|
||||
|
||||
"-isystem${build_root}/include/libc",
|
||||
"-isystem${source_root}/sysroot/include",
|
||||
"--sysroot='${source_root}/sysroot'" ]
|
||||
|
||||
|
||||
cflags: [ '-nostdinc' ]
|
||||
|
||||
cxxflags: [
|
||||
"-fno-exceptions",
|
||||
"-fno-rtti",
|
||||
"-nostdinc",
|
||||
"-isystem${source_root}/sysroot/include/c++/v1" ]
|
||||
|
||||
ldflags: [
|
||||
"-g",
|
||||
"-nostdlib",
|
||||
"-Bstatic",
|
||||
"--no-eh-frame-hdr",
|
||||
"-z", "norelro",
|
||||
"-z", "separate-code" ]
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
# This file is automatically generated by bonnibel
|
||||
|
||||
rule compile.c
|
||||
command = $cc -MMD -MF $out.d $cflags $ccflags -o $out -c $in
|
||||
description = Compiling $name
|
||||
depfile = $out.d
|
||||
deps = gcc
|
||||
|
||||
rule dump_c_defs
|
||||
command = echo | $cc $ccflags $cflags -dM -E - > $out
|
||||
description = Dumping C defines for $target
|
||||
|
||||
rule dump_c_run
|
||||
command = echo '#!/bin/bash' > $out; echo '$cc $ccflags $cflags $$*' >> $
|
||||
$out; chmod a+x $out
|
||||
description = Dumping C arguments for $target
|
||||
|
||||
rule compile.cpp
|
||||
command = $cxx -MMD -MF $out.d $cxxflags $ccflags -o $out -c $in
|
||||
description = Compiling $name
|
||||
depfile = $out.d
|
||||
deps = gcc
|
||||
|
||||
rule dump_cpp_defs
|
||||
command = echo | $cxx -x c++ $ccflags $cxxflags -dM -E - > $out
|
||||
description = Dumping C++ defines for $target
|
||||
|
||||
rule dump_cpp_run
|
||||
command = echo '#!/bin/bash' > $out; echo '$cxx $ccflags $cxxflags $$*' $
|
||||
>> $out; chmod a+x $out
|
||||
description = Dumping C++ arguments for $target
|
||||
|
||||
rule compile.s
|
||||
command = $nasm -o $out -felf64 -MD $out.d $asflags $in
|
||||
description = Assembling $name
|
||||
depfile = $out.d
|
||||
deps = gcc
|
||||
|
||||
rule parse.cog
|
||||
command = cog -o $out -d -D target=$target $cogflags $in
|
||||
description = Parsing $name
|
||||
|
||||
rule exe
|
||||
command = $ld $ldflags -o $out $in $libs
|
||||
description = Linking $name
|
||||
|
||||
rule lib
|
||||
command = $ar qcs $out $in
|
||||
description = Archiving $name
|
||||
|
||||
rule cp
|
||||
command = cp $in $out
|
||||
description = Copying $name
|
||||
|
||||
rule dump
|
||||
command = objdump -DSC -M intel $in > $out
|
||||
description = Dumping decompiled $name
|
||||
|
||||
rule makest
|
||||
description = Making symbol table
|
||||
command = nm -n -S --demangle $in | ${source_root}/scripts/build_symbol_table.py $out
|
||||
|
||||
rule makefat
|
||||
description = Creating $name
|
||||
command = $
|
||||
cp $in $out; $
|
||||
mcopy -s -D o -i $out@@1M ${build_root}/fatroot/* ::/
|
||||
|
||||
rule strip
|
||||
description = Stripping $name
|
||||
command = $
|
||||
cp $in $out; $
|
||||
objcopy --only-keep-debug $out $debug; $
|
||||
strip -g $out; $
|
||||
objcopy --add-gnu-debuglink=$debug $out
|
||||
|
||||
rule touch
|
||||
command = touch $out
|
||||
|
||||
rule compdb
|
||||
command = ninja -t compdb > $out
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
extends: base
|
||||
|
||||
variables:
|
||||
asflags: [ "-I${source_root}/src/kernel/" ]
|
||||
|
||||
ccflags: [
|
||||
"--target=x86_64-jsix-elf",
|
||||
"-mno-sse",
|
||||
"-fno-omit-frame-pointer",
|
||||
"-fno-stack-protector",
|
||||
|
||||
"-g",
|
||||
|
||||
"-D__ELF__",
|
||||
"-D__jsix__",
|
||||
"-U__linux",
|
||||
"-U__linux__",
|
||||
|
||||
"-isystem${source_root}/sysroot/include",
|
||||
"-isystem${build_root}/include/libc",
|
||||
"--sysroot='${source_root}/sysroot'" ]
|
||||
|
||||
|
||||
cxxflags: [
|
||||
"-fno-exceptions",
|
||||
"-fno-rtti",
|
||||
"-isystem${source_root}/sysroot/include/c++/v1" ]
|
||||
|
||||
ldflags: [
|
||||
"-g",
|
||||
"-Bstatic",
|
||||
"--sysroot='${source_root}/sysroot'",
|
||||
"-L", "${source_root}/sysroot/lib",
|
||||
"-z", "separate-code",
|
||||
"-lc++", "-lc++abi", "-lunwind",
|
||||
"--no-dependent-libraries",
|
||||
]
|
||||
|
||||
70
configure
vendored
70
configure
vendored
@@ -1,70 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
def generate(output, config, manifest):
|
||||
from os import makedirs, walk
|
||||
from pathlib import Path
|
||||
from bonnibel.module import Module
|
||||
from bonnibel.project import Project
|
||||
|
||||
root = Path(__file__).parent.resolve()
|
||||
project = Project(root)
|
||||
|
||||
output = root / output
|
||||
sources = root / "src"
|
||||
manifest = root / manifest
|
||||
|
||||
modules = {}
|
||||
for base, dirs, files in walk(sources):
|
||||
path = Path(base)
|
||||
for f in files:
|
||||
if f.endswith(".module"):
|
||||
fullpath = path / f
|
||||
|
||||
def module_init(name, **kwargs):
|
||||
m = Module(name, fullpath, path, **kwargs)
|
||||
modules[m.name] = m
|
||||
return m
|
||||
|
||||
glo = {
|
||||
"module": module_init,
|
||||
"source_root": root,
|
||||
"built_root": output,
|
||||
"module_root": path,
|
||||
}
|
||||
code = compile(open(fullpath, 'r').read(), fullpath, "exec")
|
||||
|
||||
loc = {}
|
||||
exec(code, glo, loc)
|
||||
|
||||
Module.update(modules)
|
||||
|
||||
makedirs(output.resolve(), exist_ok=True)
|
||||
project.generate(root, output, modules, config, manifest)
|
||||
for mod in modules.values():
|
||||
mod.generate(output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).parent / "scripts"))
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from bonnibel import BonnibelError
|
||||
|
||||
p = ArgumentParser(description="Generate jsix build files")
|
||||
p.add_argument("--manifest", "-m", metavar="FILE", default="assets/manifests/default.yaml",
|
||||
help="File to use as the system manifest")
|
||||
p.add_argument("--config", "-c", metavar="NAME", default="debug",
|
||||
help="Configuration to build (eg, 'debug' or 'release')")
|
||||
p.add_argument("output", metavar="DIR", default="build", nargs='?',
|
||||
help="Where to create the build root")
|
||||
|
||||
args = p.parse_args()
|
||||
|
||||
try:
|
||||
generate(args.output, args.config, args.manifest)
|
||||
|
||||
except BonnibelError as be:
|
||||
import sys
|
||||
print(f"Error: {be}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
- name: linear
|
||||
size: 64T
|
||||
shared: true
|
||||
|
||||
- name: bitmap
|
||||
size: 1T
|
||||
shared: true
|
||||
|
||||
- name: heap
|
||||
size: 64G
|
||||
|
||||
- name: stacks
|
||||
size: 64G
|
||||
|
||||
- name: buffers
|
||||
size: 64G
|
||||
|
||||
- name: slabs
|
||||
size: 64G
|
||||
@@ -1,21 +0,0 @@
|
||||
object channel : object {
|
||||
uid 3ea38b96aa0e54c8
|
||||
|
||||
capabilities [
|
||||
send
|
||||
receive
|
||||
close
|
||||
]
|
||||
|
||||
method create [constructor]
|
||||
method close [destructor cap:close]
|
||||
|
||||
method send [cap:send] {
|
||||
param data buffer [inout]
|
||||
}
|
||||
|
||||
method receive [cap:receive] {
|
||||
param data buffer [out]
|
||||
param flags uint64
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
object event : object {
|
||||
uid f441e03da5516b1a
|
||||
|
||||
capabilities [
|
||||
signal
|
||||
wait
|
||||
]
|
||||
|
||||
method create [constructor]
|
||||
|
||||
# Signal events on this object
|
||||
method signal [cap:signal] {
|
||||
param signals uint64 # A bitset of which events to signal
|
||||
}
|
||||
|
||||
# Wait for signaled events on this object
|
||||
method wait [cap:wait] {
|
||||
param signals uint64 [out] # A bitset of which events were signaled
|
||||
param timeout uint64 # Wait timeout in nanoseconds
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Mailboxes are objects that enable synchronous or asynchronous
|
||||
# IPC via short message-passing of bytes and handles.
|
||||
|
||||
object mailbox : object {
|
||||
uid 99934ad04ece1e07
|
||||
|
||||
capabilities [
|
||||
send
|
||||
receive
|
||||
close
|
||||
]
|
||||
|
||||
method create [constructor]
|
||||
method close [destructor cap:close]
|
||||
|
||||
# Asynchronously send a message to the reciever
|
||||
method send [cap:send handle] {
|
||||
param tag uint64
|
||||
param data buffer [zero_ok]
|
||||
param handles ref object [list]
|
||||
}
|
||||
|
||||
# Receive a pending message, or block waiting for a message to
|
||||
# arrive if block is true.
|
||||
method receive [cap:receive] {
|
||||
param tag uint64 [out]
|
||||
param data buffer [out zero_ok]
|
||||
param handles ref object [out list zero_ok]
|
||||
param reply_tag uint16 [out optional]
|
||||
param badge uint64 [out optional]
|
||||
param flags uint64
|
||||
}
|
||||
|
||||
# Send a message to the reciever, and block until a
|
||||
# response is sent. Note that getting this response
|
||||
# does not require the receive capability.
|
||||
method call [cap:send handle] {
|
||||
param tag uint64 [inout]
|
||||
param data buffer [inout zero_ok]
|
||||
param handles ref object [inout list zero_ok]
|
||||
}
|
||||
|
||||
# Respond to a message sent using call. Note that this
|
||||
# requires the receive capability and not the send capability.
|
||||
method respond [cap:receive] {
|
||||
param tag uint64
|
||||
param data buffer [zero_ok]
|
||||
param handles ref object [list zero_ok]
|
||||
param reply_tag uint16
|
||||
}
|
||||
|
||||
# Respond to a message sent using call, and wait for another
|
||||
# message to arrive. Note that this does not require the send
|
||||
# capability.
|
||||
method respond_receive [cap:receive] {
|
||||
param tag uint64 [inout]
|
||||
param data buffer [inout zero_ok]
|
||||
param data_in size
|
||||
param handles ref object [inout list zero_ok]
|
||||
param handles_in size
|
||||
param reply_tag uint16 [inout]
|
||||
param badge uint64 [out optional]
|
||||
param flags uint64
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
# The base type of all kernel-exposed objects
|
||||
object object [virtual] {
|
||||
uid 667f61fb2cd57bb4
|
||||
cname kobject
|
||||
|
||||
capabilities [
|
||||
clone
|
||||
]
|
||||
|
||||
# Get the internal kernel object id of an object
|
||||
method koid {
|
||||
param koid uint64 [out]
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import "objects/object.def"
|
||||
|
||||
# Processes are a collection of handles and a virtual memory
|
||||
# space inside which threads are run.
|
||||
|
||||
object process : object {
|
||||
uid 0c69ee0b7502ba31
|
||||
|
||||
capabilities [
|
||||
kill
|
||||
create_thread
|
||||
]
|
||||
|
||||
# Create a new empty process
|
||||
method create [constructor]
|
||||
|
||||
# Stop all threads and exit the given process
|
||||
method kill [destructor cap:kill]
|
||||
|
||||
# Stop all threads and exit the current process
|
||||
method exit [static noreturn] {
|
||||
param result int32 # The result to retrun to the parent process
|
||||
}
|
||||
|
||||
# Give the given process a handle that points to the same
|
||||
# object as the specified handle.
|
||||
method give_handle {
|
||||
param target ref object [handle] # A handle in the caller process to send
|
||||
param received ref object [out optional] # The handle as the recipient will see it
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
# The system object represents a handle to kernel functionality
|
||||
# needed by drivers and other priviledged services
|
||||
object system : object {
|
||||
uid fa72506a2cf71a30
|
||||
|
||||
capabilities [
|
||||
get_log
|
||||
bind_irq
|
||||
map_phys
|
||||
change_iopl
|
||||
]
|
||||
|
||||
# Get a log line from the kernel log
|
||||
method get_log [cap:get_log] {
|
||||
param buffer buffer [out zero_ok] # Buffer for the log message data structure
|
||||
}
|
||||
|
||||
# Ask the kernel to send this process messages whenever
|
||||
# the given IRQ fires
|
||||
method bind_irq [cap:bind_irq] {
|
||||
param dest ref event # Event object that will receive messages
|
||||
param irq uint # IRQ number to bind
|
||||
param signal uint # Signal number on the event to bind to
|
||||
}
|
||||
|
||||
# Create a VMA and map an area of physical memory into it,
|
||||
# also mapping that VMA into the current process
|
||||
method map_phys [cap:map_phys] {
|
||||
param area ref vma [out] # Receives a handle to the VMA created
|
||||
param phys address # The physical address of the area
|
||||
param size size # Size of the area, in pages
|
||||
param flags uint32 # Flags to apply to the created VMA
|
||||
}
|
||||
|
||||
# Request the kernel change the IOPL for this process. The only values
|
||||
# that make sense are 0 and 3.
|
||||
method request_iopl [cap:change_iopl] {
|
||||
param iopl uint # The IOPL to set for this process
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
object thread : object {
|
||||
uid 11f23e593d5761bd
|
||||
|
||||
capabilities [
|
||||
kill
|
||||
]
|
||||
|
||||
method create [constructor] {
|
||||
param process ref process [cap:create_thread]
|
||||
param stack_top address
|
||||
param entrypoint address
|
||||
}
|
||||
|
||||
method kill [destructor cap:kill]
|
||||
|
||||
method exit [static] {
|
||||
param status int32
|
||||
}
|
||||
|
||||
method sleep [static] {
|
||||
param duration uint64
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import "objects/process.def"
|
||||
|
||||
object vma : object {
|
||||
uid d6a12b63b3ed3937
|
||||
cname vm_area
|
||||
|
||||
capabilities [
|
||||
map
|
||||
unmap
|
||||
resize
|
||||
]
|
||||
|
||||
method create [constructor] {
|
||||
param size size
|
||||
param flags uint32
|
||||
}
|
||||
|
||||
method create_map [constructor cap:map] {
|
||||
param size size
|
||||
param address address
|
||||
param flags uint32
|
||||
}
|
||||
|
||||
method map [cap:map] {
|
||||
param process ref process
|
||||
param address address
|
||||
}
|
||||
|
||||
method unmap [cap:unmap] {
|
||||
param process ref process
|
||||
}
|
||||
|
||||
method resize [cap:resize] {
|
||||
param size size [inout]
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import "objects/object.def"
|
||||
|
||||
import "objects/channel.def"
|
||||
import "objects/event.def"
|
||||
import "objects/mailbox.def"
|
||||
import "objects/process.def"
|
||||
import "objects/system.def"
|
||||
import "objects/thread.def"
|
||||
import "objects/vma.def"
|
||||
|
||||
interface syscalls [syscall] {
|
||||
uid 01d9b6a948961097
|
||||
|
||||
expose ref object
|
||||
expose ref system
|
||||
expose ref event
|
||||
expose ref process
|
||||
expose ref thread
|
||||
expose ref mailbox
|
||||
expose ref channel
|
||||
expose ref vma
|
||||
|
||||
# Simple no-op syscall for testing
|
||||
function noop
|
||||
|
||||
# Write a message to the kernel log
|
||||
function log {
|
||||
param message string
|
||||
}
|
||||
|
||||
# Get a list of handles owned by this process. If the
|
||||
# supplied list is not big enough, will set the size
|
||||
# needed in `size` and return j6_err_insufficient
|
||||
function handle_list {
|
||||
param handles ref object [list inout zero_ok] # A list of handles to be filled
|
||||
}
|
||||
|
||||
# Create a clone of an existing handle, possibly with
|
||||
# some capabilities masked out.
|
||||
function handle_clone {
|
||||
param orig ref object [handle cap:clone] # The handle to clone
|
||||
param clone ref object [out] # The new handle
|
||||
param mask uint32 # The capability bitmask
|
||||
}
|
||||
|
||||
# Testing mode only: Have the kernel finish and exit QEMU with the given exit code
|
||||
function test_finish [test] {
|
||||
param exit_code uint32
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
address: 0x6a360000
|
||||
vars:
|
||||
- name: version_major
|
||||
section: kernel
|
||||
type: uint8_t
|
||||
|
||||
- name: version_minor
|
||||
section: kernel
|
||||
type: uint8_t
|
||||
|
||||
- name: version_patch
|
||||
section: kernel
|
||||
type: uint16_t
|
||||
|
||||
- name: version_gitsha
|
||||
section: kernel
|
||||
type: uint32_t
|
||||
|
||||
- name: page_size
|
||||
section: sys
|
||||
type: size_t
|
||||
|
||||
- name: large_page_size
|
||||
section: sys
|
||||
type: size_t
|
||||
|
||||
- name: huge_page_size
|
||||
section: sys
|
||||
type: size_t
|
||||
|
||||
- name: num_cpus
|
||||
section: sys
|
||||
type: uint32_t
|
||||
2389
external/catch/catch.hpp
vendored
2389
external/catch/catch.hpp
vendored
File diff suppressed because it is too large
Load Diff
3669
external/cpptoml/cpptoml.h
vendored
Normal file
3669
external/cpptoml/cpptoml.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
external/uefi/boot_services.h
vendored
103
external/uefi/boot_services.h
vendored
@@ -1,103 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_boot_services_h_
|
||||
#define _uefi_boot_services_h_
|
||||
|
||||
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||
// not distributed with this file, You can obtain one at
|
||||
// http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <uefi/tables.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace bs_impl {
|
||||
using allocate_pages = status (*)(allocate_type, memory_type, size_t, void**);
|
||||
using free_pages = status (*)(void*, size_t);
|
||||
using get_memory_map = status (*)(size_t*, memory_descriptor*, size_t*, size_t*, uint32_t*);
|
||||
using allocate_pool = status (*)(memory_type, uint64_t, void**);
|
||||
using free_pool = status (*)(void*);
|
||||
using handle_protocol = status (*)(handle, const guid*, void**);
|
||||
using create_event = status (*)(evt, tpl, event_notify, void*, event*);
|
||||
using exit_boot_services = status (*)(handle, size_t);
|
||||
using locate_protocol = status (*)(const guid*, void*, void**);
|
||||
using copy_mem = void (*)(void*, void*, size_t);
|
||||
using set_mem = void (*)(void*, uint64_t, uint8_t);
|
||||
}
|
||||
|
||||
struct boot_services {
|
||||
static constexpr uint64_t signature = 0x56524553544f4f42ull;
|
||||
|
||||
table_header header;
|
||||
|
||||
// Task Priority Level management
|
||||
void *raise_tpl;
|
||||
void *restore_tpl;
|
||||
|
||||
// Memory Services
|
||||
bs_impl::allocate_pages allocate_pages;
|
||||
bs_impl::free_pages free_pages;
|
||||
bs_impl::get_memory_map get_memory_map;
|
||||
bs_impl::allocate_pool allocate_pool;
|
||||
bs_impl::free_pool free_pool;
|
||||
|
||||
// Event & Timer Services
|
||||
bs_impl::create_event create_event;
|
||||
void *set_timer;
|
||||
void *wait_for_event;
|
||||
void *signal_event;
|
||||
void *close_event;
|
||||
void *check_event;
|
||||
|
||||
// Protocol Handler Services
|
||||
void *install_protocol_interface;
|
||||
void *reinstall_protocol_interface;
|
||||
void *uninstall_protocol_interface;
|
||||
bs_impl::handle_protocol handle_protocol;
|
||||
void *_reserved;
|
||||
void *register_protocol_notify;
|
||||
void *locate_handle;
|
||||
void *locate_device_path;
|
||||
void *install_configuration_table;
|
||||
|
||||
// Image Services
|
||||
void *load_image;
|
||||
void *start_image;
|
||||
void *exit;
|
||||
void *unload_image;
|
||||
bs_impl::exit_boot_services exit_boot_services;
|
||||
|
||||
// Miscellaneous Services
|
||||
void *get_next_monotonic_count;
|
||||
void *stall;
|
||||
void *set_watchdog_timer;
|
||||
|
||||
// DriverSupport Services
|
||||
void *connect_controller;
|
||||
void *disconnect_controller;
|
||||
|
||||
// Open and Close Protocol Services
|
||||
void *open_protocol;
|
||||
void *close_protocol;
|
||||
void *open_protocol_information;
|
||||
|
||||
// Library Services
|
||||
void *protocols_per_handle;
|
||||
void *locate_handle_buffer;
|
||||
bs_impl::locate_protocol locate_protocol;
|
||||
void *install_multiple_protocol_interfaces;
|
||||
void *uninstall_multiple_protocol_interfaces;
|
||||
|
||||
// 32-bit CRC Services
|
||||
void *calculate_crc32;
|
||||
|
||||
// Miscellaneous Services
|
||||
bs_impl::copy_mem copy_mem;
|
||||
bs_impl::set_mem set_mem;
|
||||
void *create_event_ex;
|
||||
};
|
||||
|
||||
} // namespace uefi
|
||||
|
||||
#endif
|
||||
39
external/uefi/errors.inc
vendored
39
external/uefi/errors.inc
vendored
@@ -1,39 +0,0 @@
|
||||
STATUS_WARNING( warn_unknown_glyph, 1)
|
||||
STATUS_WARNING( warn_delete_failure, 2)
|
||||
STATUS_WARNING( warn_write_failure, 3)
|
||||
STATUS_WARNING( warn_buffer_too_small,4)
|
||||
STATUS_WARNING( warn_stale_data, 5)
|
||||
STATUS_WARNING( warn_file_system, 6)
|
||||
|
||||
STATUS_ERROR( load_error, 1)
|
||||
STATUS_ERROR( invalid_parameter, 2)
|
||||
STATUS_ERROR( unsupported, 3)
|
||||
STATUS_ERROR( bad_buffer_size, 4)
|
||||
STATUS_ERROR( buffer_too_small, 5)
|
||||
STATUS_ERROR( not_ready, 6)
|
||||
STATUS_ERROR( device_error, 7)
|
||||
STATUS_ERROR( write_protected, 8)
|
||||
STATUS_ERROR( out_of_resources, 9)
|
||||
STATUS_ERROR( volume_corrupted, 10)
|
||||
STATUS_ERROR( volume_full, 11)
|
||||
STATUS_ERROR( no_media, 12)
|
||||
STATUS_ERROR( media_changed, 13)
|
||||
STATUS_ERROR( not_found, 14)
|
||||
STATUS_ERROR( access_denied, 15)
|
||||
STATUS_ERROR( no_response, 16)
|
||||
STATUS_ERROR( no_mapping, 17)
|
||||
STATUS_ERROR( timeout, 18)
|
||||
STATUS_ERROR( not_started, 19)
|
||||
STATUS_ERROR( already_started, 20)
|
||||
STATUS_ERROR( aborted, 21)
|
||||
STATUS_ERROR( icmp_error, 22)
|
||||
STATUS_ERROR( tftp_error, 23)
|
||||
STATUS_ERROR( protocol_error, 24)
|
||||
STATUS_ERROR( incompatible_version, 25)
|
||||
STATUS_ERROR( security_violation, 26)
|
||||
STATUS_ERROR( crc_error, 27)
|
||||
STATUS_ERROR( end_of_media, 28)
|
||||
STATUS_ERROR( end_of_file, 31)
|
||||
STATUS_ERROR( invalid_language, 32)
|
||||
STATUS_ERROR( compromised_data, 33)
|
||||
STATUS_ERROR( http_error, 35)
|
||||
92
external/uefi/graphics.h
vendored
92
external/uefi/graphics.h
vendored
@@ -1,92 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_graphics_h_
|
||||
#define _uefi_graphics_h_
|
||||
|
||||
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||
// not distributed with this file, You can obtain one at
|
||||
// http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
|
||||
struct text_output_mode
|
||||
{
|
||||
int32_t max_mode;
|
||||
int32_t mode;
|
||||
int32_t attribute;
|
||||
int32_t cursor_column;
|
||||
int32_t cursor_row;
|
||||
bool cursor_visible;
|
||||
};
|
||||
|
||||
struct pixel_bitmask
|
||||
{
|
||||
uint32_t red_mask;
|
||||
uint32_t green_mask;
|
||||
uint32_t blue_mask;
|
||||
uint32_t reserved_mask;
|
||||
};
|
||||
|
||||
enum class pixel_format
|
||||
{
|
||||
rgb8,
|
||||
bgr8,
|
||||
bitmask,
|
||||
blt_only
|
||||
};
|
||||
|
||||
struct graphics_output_mode_info
|
||||
{
|
||||
uint32_t version;
|
||||
uint32_t horizontal_resolution;
|
||||
uint32_t vertical_resolution;
|
||||
pixel_format pixel_format;
|
||||
pixel_bitmask pixel_information;
|
||||
uint32_t pixels_per_scanline;
|
||||
};
|
||||
|
||||
struct graphics_output_mode
|
||||
{
|
||||
uint32_t max_mode;
|
||||
uint32_t mode;
|
||||
graphics_output_mode_info *info;
|
||||
uint64_t size_of_info;
|
||||
uintptr_t frame_buffer_base;
|
||||
uint64_t frame_buffer_size;
|
||||
};
|
||||
|
||||
enum class attribute : uint64_t
|
||||
{
|
||||
black,
|
||||
blue,
|
||||
green,
|
||||
cyan,
|
||||
red,
|
||||
magenta,
|
||||
brown,
|
||||
light_gray,
|
||||
dark_gray,
|
||||
light_blue,
|
||||
light_green,
|
||||
light_cyan,
|
||||
light_red,
|
||||
light_magenta,
|
||||
yellow,
|
||||
white,
|
||||
|
||||
background_black = 0x00,
|
||||
background_blue = 0x10,
|
||||
background_green = 0x20,
|
||||
background_cyan = 0x30,
|
||||
background_red = 0x40,
|
||||
background_magenta = 0x50,
|
||||
background_brown = 0x60,
|
||||
background_light_gray = 0x70,
|
||||
};
|
||||
|
||||
} // namespace uefi
|
||||
|
||||
#endif
|
||||
29
external/uefi/guid.h
vendored
29
external/uefi/guid.h
vendored
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_guid_h_
|
||||
#define _uefi_guid_h_
|
||||
|
||||
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||
// not distributed with this file, You can obtain one at
|
||||
// http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace uefi {
|
||||
|
||||
struct guid
|
||||
{
|
||||
uint32_t data1;
|
||||
uint16_t data2;
|
||||
uint16_t data3;
|
||||
uint8_t data4[8];
|
||||
|
||||
inline bool operator==(const guid &other) const {
|
||||
return reinterpret_cast<const uint64_t*>(this)[0] == reinterpret_cast<const uint64_t*>(&other)[0]
|
||||
&& reinterpret_cast<const uint64_t*>(this)[1] == reinterpret_cast<const uint64_t*>(&other)[1];
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace uefi
|
||||
|
||||
#endif
|
||||
390
external/uefi/networking.h
vendored
390
external/uefi/networking.h
vendored
@@ -1,390 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_networking_h_
|
||||
#define _uefi_networking_h_
|
||||
|
||||
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||
// not distributed with this file, You can obtain one at
|
||||
// http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
|
||||
//
|
||||
// IPv4 definitions
|
||||
//
|
||||
struct ipv4_address
|
||||
{
|
||||
uint8_t addr[4];
|
||||
};
|
||||
|
||||
//
|
||||
// IPv6 definitions
|
||||
//
|
||||
struct ipv6_address
|
||||
{
|
||||
uint8_t addr[16];
|
||||
};
|
||||
|
||||
struct ip6_address_info
|
||||
{
|
||||
ipv6_address address;
|
||||
uint8_t prefix_length;
|
||||
};
|
||||
|
||||
struct ip6_route_table
|
||||
{
|
||||
ipv6_address gateway;
|
||||
ipv6_address destination;
|
||||
uint8_t prefix_length;
|
||||
};
|
||||
|
||||
enum class ip6_neighbor_state : int {
|
||||
incomplete,
|
||||
reachable,
|
||||
stale,
|
||||
delay,
|
||||
probe,
|
||||
}
|
||||
|
||||
struct ip6_neighbor_cache
|
||||
{
|
||||
ipv6_address neighbor;
|
||||
mac_address link_address;
|
||||
ip6_neighbor_state state;
|
||||
};
|
||||
|
||||
enum class icmpv6_type : uint8_t
|
||||
{
|
||||
dest_unreachable = 0x1,
|
||||
packet_too_big = 0x2,
|
||||
time_exceeded = 0x3,
|
||||
parameter_problem = 0x4,
|
||||
echo_request = 0x80,
|
||||
echo_reply = 0x81,
|
||||
listener_query = 0x82,
|
||||
listener_report = 0x83,
|
||||
listener_done = 0x84,
|
||||
router_solicit = 0x85,
|
||||
router_advertise = 0x86,
|
||||
neighbor_solicit = 0x87,
|
||||
neighbor_advertise = 0x88,
|
||||
redirect = 0x89,
|
||||
listener_report_2 = 0x8f,
|
||||
};
|
||||
|
||||
enum class icmpv6_code : uint8_t
|
||||
{
|
||||
// codes for icmpv6_type::dest_unreachable
|
||||
no_route_to_dest = 0x0,
|
||||
comm_prohibited = 0x1,
|
||||
beyond_scope = 0x2,
|
||||
addr_unreachable = 0x3,
|
||||
port_unreachable = 0x4,
|
||||
source_addr_failed = 0x5,
|
||||
route_rejected = 0x6,
|
||||
|
||||
// codes for icmpv6_type::time_exceeded
|
||||
timeout_hop_limit = 0x0,
|
||||
timeout_reassemble = 0x1,
|
||||
|
||||
// codes for icmpv6_type::parameter_problem
|
||||
erroneous_header = 0x0,
|
||||
unrecognize_next_hdr = 0x1,
|
||||
unrecognize_option = 0x2,
|
||||
};
|
||||
|
||||
struct ip6_icmp_type
|
||||
{
|
||||
icmpv6_type type;
|
||||
icmpv6_code code;
|
||||
};
|
||||
|
||||
struct ip6_config_data
|
||||
{
|
||||
uint8_t default_protocol;
|
||||
bool accept_any_protocol;
|
||||
bool accept_icmp_errors;
|
||||
bool accept_promiscuous;
|
||||
ipv6_address destination_address;
|
||||
ipv6_address station_address;
|
||||
uint8_t traffic_class;
|
||||
uint8_t hop_limit;
|
||||
uint32_t flow_label;
|
||||
uint32_t receive_timeout;
|
||||
uint32_t transmit_timeout;
|
||||
};
|
||||
|
||||
struct ip6_mode_data
|
||||
{
|
||||
bool is_started;
|
||||
uint32_t max_packet_size;
|
||||
ip6_config_data config_data;
|
||||
bool is_configured;
|
||||
uint32_t address_count;
|
||||
ip6_address_info * address_list;
|
||||
uint32_t group_count;
|
||||
ipv6_address * group_table;
|
||||
uint32_t route_count;
|
||||
ip6_route_table * route_table;
|
||||
uint32_t neighbor_count;
|
||||
ip6_neighbor_cache * neighbor_cache;
|
||||
uint32_t prefix_count;
|
||||
ip6_address_info * prefix_table;
|
||||
uint32_t icmp_type_count;
|
||||
* icmp_type_list;
|
||||
};
|
||||
|
||||
struct ip6_header
|
||||
{
|
||||
uint8_t traffic_class_h : 4;
|
||||
uint8_t version : 4;
|
||||
uint8_t flow_label_h : 4;
|
||||
uint8_t traffic_class_l : 4;
|
||||
uint16_t flow_label_l;
|
||||
uint16_t payload_length;
|
||||
uint8_t next_header;
|
||||
uint8_t hop_limit;
|
||||
ipv6_address source_address;
|
||||
ipv6_address destination_address;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ip6_fragment_data
|
||||
{
|
||||
uint32_t fragment_length;
|
||||
void *fragment_buffer;
|
||||
};
|
||||
|
||||
struct ip6_override_data
|
||||
{
|
||||
uint8_t protocol;
|
||||
uint8_t hop_limit;
|
||||
uint32_t flow_label;
|
||||
};
|
||||
|
||||
struct ip6_receive_data
|
||||
{
|
||||
time time_stamp;
|
||||
event recycle_signal;
|
||||
uint32_t header_length;
|
||||
ip6_header *header;
|
||||
uint32_t data_length;
|
||||
uint32_t fragment_count;
|
||||
ip6_fragment_data fragment_table[1];
|
||||
};
|
||||
|
||||
struct ip6_transmit_data
|
||||
{
|
||||
ipv6_address destination_address;
|
||||
ip6_override_data *override_data;
|
||||
|
||||
uint32_t ext_hdrs_length;
|
||||
void *ext_hdrs;
|
||||
uint8_t next_header;
|
||||
uint32_t data_length;
|
||||
uint32_t fragment_count;
|
||||
ip6_fragment_data fragment_table[1];
|
||||
};
|
||||
|
||||
struct ip6_completion_token
|
||||
{
|
||||
event event;
|
||||
status status;
|
||||
union {
|
||||
ip6_receive_data *rx_data;
|
||||
ip6_transmit_data *tx_data;
|
||||
} packet;
|
||||
};
|
||||
|
||||
enum class ip6_config_data_type : int
|
||||
{
|
||||
interface_info,
|
||||
alt_interface_id,
|
||||
policy,
|
||||
dup_addr_detect_transmits,
|
||||
manual_address,
|
||||
gateway,
|
||||
dns_server,
|
||||
maximum
|
||||
};
|
||||
|
||||
struct ip6_config_interface_info
|
||||
{
|
||||
wchar_t name[32];
|
||||
uint8_t if_type;
|
||||
uint32_t hw_address_size;
|
||||
mac_address hw_address;
|
||||
uint32_t address_info_count;
|
||||
ip6_address_info *address_info;
|
||||
uint32_t route_count;
|
||||
ip6_route_table *route_table;
|
||||
};
|
||||
|
||||
struct ip6_config_interface_id
|
||||
{
|
||||
uint8_t id[8];
|
||||
};
|
||||
|
||||
enum class ip6_config_policy : int
|
||||
{
|
||||
manual,
|
||||
automatic
|
||||
};
|
||||
|
||||
struct ip6_config_dup_addr_detect_transmits
|
||||
{
|
||||
uint32_t dup_addr_detect_transmits;
|
||||
};
|
||||
|
||||
struct ip6_config_manual_address
|
||||
{
|
||||
ipv6_address address;
|
||||
bool is_anycast;
|
||||
uint8_t prefix_length;
|
||||
};
|
||||
|
||||
//
|
||||
// IP definitions
|
||||
//
|
||||
union ip_address
|
||||
{
|
||||
uint8_t addr[4];
|
||||
ipv4_address v4;
|
||||
ipv6_address v6;
|
||||
};
|
||||
|
||||
//
|
||||
// HTTP definitions
|
||||
//
|
||||
struct httpv4_access_point
|
||||
{
|
||||
bool use_default_address;
|
||||
ipv4_address local_address;
|
||||
ipv4_address local_subnet;
|
||||
uint16_t local_port;
|
||||
};
|
||||
|
||||
struct httpv6_access_point
|
||||
{
|
||||
ipv6_address local_address;
|
||||
uint16_t local_port;
|
||||
};
|
||||
|
||||
enum class http_version : int {
|
||||
v10,
|
||||
v11,
|
||||
unsupported,
|
||||
};
|
||||
|
||||
struct http_config_data
|
||||
{
|
||||
http_version http_version;
|
||||
uint32_t time_out_millisec;
|
||||
bool local_address_is_ipv6;
|
||||
union {
|
||||
httpv4_access_point *ipv4_node;
|
||||
httpv6_access_point *ipv6_node;
|
||||
} access_point;
|
||||
};
|
||||
|
||||
enum class http_method : int {
|
||||
get,
|
||||
post,
|
||||
patch,
|
||||
options,
|
||||
connect,
|
||||
head,
|
||||
put,
|
||||
delete_,
|
||||
trace,
|
||||
};
|
||||
|
||||
struct http_request_data
|
||||
{
|
||||
http_method method;
|
||||
wchar_t *url;
|
||||
};
|
||||
|
||||
enum class http_status_code : int {
|
||||
unsupported,
|
||||
continue_,
|
||||
switching_protocols,
|
||||
ok,
|
||||
created,
|
||||
accepted,
|
||||
non_authoritative_information,
|
||||
no_content,
|
||||
reset_content,
|
||||
partial_content,
|
||||
multiple_choices,
|
||||
moved_permanently,
|
||||
found,
|
||||
see_other,
|
||||
not_modified,
|
||||
use_proxy,
|
||||
temporary_redirect,
|
||||
bad_request,
|
||||
unauthorized,
|
||||
payment_required,
|
||||
forbidden,
|
||||
not_found,
|
||||
method_not_allowed,
|
||||
not_acceptable,
|
||||
proxy_authentication_required,
|
||||
request_time_out,
|
||||
conflict,
|
||||
gone,
|
||||
length_required,
|
||||
precondition_failed,
|
||||
request_entity_too_large,
|
||||
request_uri_too_large,
|
||||
unsupported_media_type,
|
||||
requested_range_not_satisfied,
|
||||
expectation_failed,
|
||||
internal_server_error,
|
||||
not_implemented,
|
||||
bad_gateway,
|
||||
service_unavailable,
|
||||
gateway_timeout,
|
||||
http_version_not_supported,
|
||||
permanent_redirect, // I hate your decisions, uefi.
|
||||
};
|
||||
|
||||
struct http_response_data
|
||||
{
|
||||
http_status_code status_code;
|
||||
};
|
||||
|
||||
struct http_header
|
||||
{
|
||||
char *field_name;
|
||||
char *field_value;
|
||||
};
|
||||
|
||||
struct http_message
|
||||
{
|
||||
union {
|
||||
http_request_data *request;
|
||||
http_response_data *response;
|
||||
} data;
|
||||
|
||||
size_t header_count;
|
||||
http_header *headers;
|
||||
|
||||
size_t body_length;
|
||||
void *body;
|
||||
};
|
||||
|
||||
struct http_token
|
||||
{
|
||||
event event;
|
||||
status status;
|
||||
http_message *message;
|
||||
};
|
||||
|
||||
|
||||
} // namespace uefi
|
||||
|
||||
#endif
|
||||
31
external/uefi/protos/device_path.h
vendored
31
external/uefi/protos/device_path.h
vendored
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_device_path_h_
|
||||
#define _uefi_protos_device_path_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct device_path;
|
||||
|
||||
struct device_path
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x09576e91,0x6d3f,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||
|
||||
|
||||
uint8_t type;
|
||||
uint8_t sub_type;
|
||||
uint16_t length;
|
||||
|
||||
protected:
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_device_path_h_
|
||||
126
external/uefi/protos/file.h
vendored
126
external/uefi/protos/file.h
vendored
@@ -1,126 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_file_h_
|
||||
#define _uefi_protos_file_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct file;
|
||||
|
||||
struct file
|
||||
{
|
||||
|
||||
|
||||
inline uefi::status open(file ** new_handle, const wchar_t * file_name, file_mode open_mode, file_attr attributes) {
|
||||
return _open(this, new_handle, file_name, open_mode, attributes);
|
||||
}
|
||||
|
||||
inline uefi::status close() {
|
||||
return _close(this);
|
||||
}
|
||||
|
||||
inline uefi::status delete_file() {
|
||||
return _delete_file(this);
|
||||
}
|
||||
|
||||
inline uefi::status read(uint64_t * buffer_size, void * buffer) {
|
||||
return _read(this, buffer_size, buffer);
|
||||
}
|
||||
|
||||
inline uefi::status write(uint64_t * buffer_size, void * buffer) {
|
||||
return _write(this, buffer_size, buffer);
|
||||
}
|
||||
|
||||
inline uefi::status get_position(uint64_t * position) {
|
||||
return _get_position(this, position);
|
||||
}
|
||||
|
||||
inline uefi::status set_position(uint64_t position) {
|
||||
return _set_position(this, position);
|
||||
}
|
||||
|
||||
inline uefi::status get_info(const guid * info_type, uint64_t * buffer_size, void * buffer) {
|
||||
return _get_info(this, info_type, buffer_size, buffer);
|
||||
}
|
||||
|
||||
inline uefi::status set_info(const guid * info_type, uint64_t buffer_size, void * buffer) {
|
||||
return _set_info(this, info_type, buffer_size, buffer);
|
||||
}
|
||||
|
||||
inline uefi::status flush() {
|
||||
return _flush(this);
|
||||
}
|
||||
|
||||
inline uefi::status open_ex(file ** new_handle, const wchar_t * file_name, uint64_t open_mode, uint64_t attributes, file_io_token * token) {
|
||||
return _open_ex(this, new_handle, file_name, open_mode, attributes, token);
|
||||
}
|
||||
|
||||
inline uefi::status read_ex(file_io_token * token) {
|
||||
return _read_ex(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status write_ex(file_io_token * token) {
|
||||
return _write_ex(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status flush_ex(file_io_token * token) {
|
||||
return _flush_ex(this, token);
|
||||
}
|
||||
|
||||
uint64_t revision;
|
||||
|
||||
protected:
|
||||
using _open_def = uefi::status (*)(uefi::protos::file *, file **, const wchar_t *, file_mode, file_attr);
|
||||
_open_def _open;
|
||||
|
||||
using _close_def = uefi::status (*)(uefi::protos::file *);
|
||||
_close_def _close;
|
||||
|
||||
using _delete_file_def = uefi::status (*)(uefi::protos::file *);
|
||||
_delete_file_def _delete_file;
|
||||
|
||||
using _read_def = uefi::status (*)(uefi::protos::file *, uint64_t *, void *);
|
||||
_read_def _read;
|
||||
|
||||
using _write_def = uefi::status (*)(uefi::protos::file *, uint64_t *, void *);
|
||||
_write_def _write;
|
||||
|
||||
using _get_position_def = uefi::status (*)(uefi::protos::file *, uint64_t *);
|
||||
_get_position_def _get_position;
|
||||
|
||||
using _set_position_def = uefi::status (*)(uefi::protos::file *, uint64_t);
|
||||
_set_position_def _set_position;
|
||||
|
||||
using _get_info_def = uefi::status (*)(uefi::protos::file *, const guid *, uint64_t *, void *);
|
||||
_get_info_def _get_info;
|
||||
|
||||
using _set_info_def = uefi::status (*)(uefi::protos::file *, const guid *, uint64_t, void *);
|
||||
_set_info_def _set_info;
|
||||
|
||||
using _flush_def = uefi::status (*)(uefi::protos::file *);
|
||||
_flush_def _flush;
|
||||
|
||||
using _open_ex_def = uefi::status (*)(uefi::protos::file *, file **, const wchar_t *, uint64_t, uint64_t, file_io_token *);
|
||||
_open_ex_def _open_ex;
|
||||
|
||||
using _read_ex_def = uefi::status (*)(uefi::protos::file *, file_io_token *);
|
||||
_read_ex_def _read_ex;
|
||||
|
||||
using _write_ex_def = uefi::status (*)(uefi::protos::file *, file_io_token *);
|
||||
_write_ex_def _write_ex;
|
||||
|
||||
using _flush_ex_def = uefi::status (*)(uefi::protos::file *, file_io_token *);
|
||||
_flush_ex_def _flush_ex;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_file_h_
|
||||
36
external/uefi/protos/file_info.h
vendored
36
external/uefi/protos/file_info.h
vendored
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_file_info_h_
|
||||
#define _uefi_protos_file_info_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct file_info;
|
||||
|
||||
struct file_info
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x09576e92,0x6d3f,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||
|
||||
|
||||
uint64_t size;
|
||||
uint64_t file_size;
|
||||
uint64_t physical_size;
|
||||
time create_time;
|
||||
time last_access_time;
|
||||
time modification_time;
|
||||
uint64_t attribute;
|
||||
wchar_t file_name[];
|
||||
|
||||
protected:
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_file_info_h_
|
||||
51
external/uefi/protos/graphics_output.h
vendored
51
external/uefi/protos/graphics_output.h
vendored
@@ -1,51 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_graphics_output_h_
|
||||
#define _uefi_protos_graphics_output_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/graphics.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct graphics_output;
|
||||
|
||||
struct graphics_output
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x9042a9de,0x23dc,0x4a38,{0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a} };
|
||||
|
||||
|
||||
inline uefi::status query_mode(uint32_t mode_number, uint64_t * size_of_info, uefi::graphics_output_mode_info ** info) {
|
||||
return _query_mode(this, mode_number, size_of_info, info);
|
||||
}
|
||||
|
||||
inline uefi::status set_mode(uint32_t mode_number) {
|
||||
return _set_mode(this, mode_number);
|
||||
}
|
||||
|
||||
inline uefi::status blt() {
|
||||
return _blt(this);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using _query_mode_def = uefi::status (*)(uefi::protos::graphics_output *, uint32_t, uint64_t *, uefi::graphics_output_mode_info **);
|
||||
_query_mode_def _query_mode;
|
||||
|
||||
using _set_mode_def = uefi::status (*)(uefi::protos::graphics_output *, uint32_t);
|
||||
_set_mode_def _set_mode;
|
||||
|
||||
using _blt_def = uefi::status (*)(uefi::protos::graphics_output *);
|
||||
_blt_def _blt;
|
||||
|
||||
public:
|
||||
uefi::graphics_output_mode * mode;
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_graphics_output_h_
|
||||
72
external/uefi/protos/http.h
vendored
72
external/uefi/protos/http.h
vendored
@@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_http_h_
|
||||
#define _uefi_protos_http_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/networking.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct http;
|
||||
|
||||
struct http
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x7a59b29b,0x910b,0x4171,{0x82,0x42,0xa8,0x5a,0x0d,0xf2,0x5b,0x5b} };
|
||||
static constexpr uefi::guid service_binding{ 0xbdc8e6af,0xd9bc,0x4379,{0xa7,0x2a,0xe0,0xc4,0xe7,0x5d,0xae,0x1c} };
|
||||
|
||||
|
||||
inline uefi::status get_mode_data(uefi::http_config_data * http_config_data) {
|
||||
return _get_mode_data(this, http_config_data);
|
||||
}
|
||||
|
||||
inline uefi::status configure(uefi::http_config_data * http_config_data) {
|
||||
return _configure(this, http_config_data);
|
||||
}
|
||||
|
||||
inline uefi::status request(uefi::http_token * token) {
|
||||
return _request(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status cancel(uefi::http_token * token) {
|
||||
return _cancel(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status response(uefi::http_token * token) {
|
||||
return _response(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status poll() {
|
||||
return _poll(this);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using _get_mode_data_def = uefi::status (*)(uefi::protos::http *, uefi::http_config_data *);
|
||||
_get_mode_data_def _get_mode_data;
|
||||
|
||||
using _configure_def = uefi::status (*)(uefi::protos::http *, uefi::http_config_data *);
|
||||
_configure_def _configure;
|
||||
|
||||
using _request_def = uefi::status (*)(uefi::protos::http *, uefi::http_token *);
|
||||
_request_def _request;
|
||||
|
||||
using _cancel_def = uefi::status (*)(uefi::protos::http *, uefi::http_token *);
|
||||
_cancel_def _cancel;
|
||||
|
||||
using _response_def = uefi::status (*)(uefi::protos::http *, uefi::http_token *);
|
||||
_response_def _response;
|
||||
|
||||
using _poll_def = uefi::status (*)(uefi::protos::http *);
|
||||
_poll_def _poll;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_http_h_
|
||||
93
external/uefi/protos/ip6.h
vendored
93
external/uefi/protos/ip6.h
vendored
@@ -1,93 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_ip6_h_
|
||||
#define _uefi_protos_ip6_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/networking.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct ip6;
|
||||
|
||||
struct ip6
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x2c8759d5,0x5c2d,0x66ef,{0x92,0x5f,0xb6,0x6c,0x10,0x19,0x57,0xe2} };
|
||||
static constexpr uefi::guid service_binding{ 0xec835dd3,0xfe0f,0x617b,{0xa6,0x21,0xb3,0x50,0xc3,0xe1,0x33,0x88} };
|
||||
|
||||
|
||||
inline uefi::status get_mode_data(uefi::ip6_mode_data * ip6_mode_data, uefi::managed_network_config_data * mnp_config_data, uefi::simple_network_mode * snp_config_data) {
|
||||
return _get_mode_data(this, ip6_mode_data, mnp_config_data, snp_config_data);
|
||||
}
|
||||
|
||||
inline uefi::status configure(uefi::ip6_config_data * ip6_config_data) {
|
||||
return _configure(this, ip6_config_data);
|
||||
}
|
||||
|
||||
inline uefi::status groups(bool join_flag, uefi::ipv6_address * group_address) {
|
||||
return _groups(this, join_flag, group_address);
|
||||
}
|
||||
|
||||
inline uefi::status routes(bool delete_route, uefi::ipv6_address * destination, uint8_t prefix_length, uefi::ipv6_address * gateway_address) {
|
||||
return _routes(this, delete_route, destination, prefix_length, gateway_address);
|
||||
}
|
||||
|
||||
inline uefi::status neighbors(bool delete_flag, uefi::ipv6_address * target_ip6_address, uefi::mac_address * target_link_address, uint32_t timeout, bool override) {
|
||||
return _neighbors(this, delete_flag, target_ip6_address, target_link_address, timeout, override);
|
||||
}
|
||||
|
||||
inline uefi::status transmit(uefi::ip6_completion_token * token) {
|
||||
return _transmit(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status receive(uefi::ip6_completion_token * token) {
|
||||
return _receive(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status cancel(uefi::ip6_completion_token * token) {
|
||||
return _cancel(this, token);
|
||||
}
|
||||
|
||||
inline uefi::status poll() {
|
||||
return _poll(this);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using _get_mode_data_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_mode_data *, uefi::managed_network_config_data *, uefi::simple_network_mode *);
|
||||
_get_mode_data_def _get_mode_data;
|
||||
|
||||
using _configure_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_config_data *);
|
||||
_configure_def _configure;
|
||||
|
||||
using _groups_def = uefi::status (*)(uefi::protos::ip6 *, bool, uefi::ipv6_address *);
|
||||
_groups_def _groups;
|
||||
|
||||
using _routes_def = uefi::status (*)(uefi::protos::ip6 *, bool, uefi::ipv6_address *, uint8_t, uefi::ipv6_address *);
|
||||
_routes_def _routes;
|
||||
|
||||
using _neighbors_def = uefi::status (*)(uefi::protos::ip6 *, bool, uefi::ipv6_address *, uefi::mac_address *, uint32_t, bool);
|
||||
_neighbors_def _neighbors;
|
||||
|
||||
using _transmit_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_completion_token *);
|
||||
_transmit_def _transmit;
|
||||
|
||||
using _receive_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_completion_token *);
|
||||
_receive_def _receive;
|
||||
|
||||
using _cancel_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_completion_token *);
|
||||
_cancel_def _cancel;
|
||||
|
||||
using _poll_def = uefi::status (*)(uefi::protos::ip6 *);
|
||||
_poll_def _poll;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_ip6_h_
|
||||
57
external/uefi/protos/ip6_config.h
vendored
57
external/uefi/protos/ip6_config.h
vendored
@@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_ip6_config_h_
|
||||
#define _uefi_protos_ip6_config_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/networking.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct ip6_config;
|
||||
|
||||
struct ip6_config
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x937fe521,0x95ae,0x4d1a,{0x89,0x29,0x48,0xbc,0xd9,0x0a,0xd3,0x1a} };
|
||||
|
||||
|
||||
inline uefi::status set_data(uefi::ip6_config_data_type data_type, size_t data_size, void * data) {
|
||||
return _set_data(this, data_type, data_size, data);
|
||||
}
|
||||
|
||||
inline uefi::status get_data(uefi::ip6_config_data_type data_type, size_t data_size, void * data) {
|
||||
return _get_data(this, data_type, data_size, data);
|
||||
}
|
||||
|
||||
inline uefi::status register_data_notify(uefi::ip6_config_data_type data_type, uefi::event event) {
|
||||
return _register_data_notify(this, data_type, event);
|
||||
}
|
||||
|
||||
inline uefi::status unregister_data_notify(uefi::ip6_config_data_type data_type, uefi::event event) {
|
||||
return _unregister_data_notify(this, data_type, event);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using _set_data_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, size_t, void *);
|
||||
_set_data_def _set_data;
|
||||
|
||||
using _get_data_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, size_t, void *);
|
||||
_get_data_def _get_data;
|
||||
|
||||
using _register_data_notify_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, uefi::event);
|
||||
_register_data_notify_def _register_data_notify;
|
||||
|
||||
using _unregister_data_notify_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, uefi::event);
|
||||
_unregister_data_notify_def _unregister_data_notify;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_ip6_config_h_
|
||||
36
external/uefi/protos/load_file.h
vendored
36
external/uefi/protos/load_file.h
vendored
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_load_file_h_
|
||||
#define _uefi_protos_load_file_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/protos/device_path.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct load_file;
|
||||
|
||||
struct load_file
|
||||
{
|
||||
static constexpr uefi::guid guid{ {0x56ec3091,0x954c,0x11d2,{0x8e,0x3f,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||
|
||||
|
||||
inline uefi::status load_file(uefi::protos::device_path * file_path, bool boot_policy, size_t * buffer_size, void * buffer) {
|
||||
return _load_file(this, file_path, boot_policy, buffer_size, buffer);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using _load_file_def = uefi::status (*)(uefi::protos::load_file *, uefi::protos::device_path *, bool, size_t *, void *);
|
||||
_load_file_def _load_file;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_load_file_h_
|
||||
49
external/uefi/protos/loaded_image.h
vendored
49
external/uefi/protos/loaded_image.h
vendored
@@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_loaded_image_h_
|
||||
#define _uefi_protos_loaded_image_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/tables.h>
|
||||
#include <uefi/protos/device_path.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct loaded_image;
|
||||
|
||||
struct loaded_image
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x5b1b31a1,0x9562,0x11d2,{0x8e,0x3f,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||
|
||||
|
||||
inline uefi::status unload(uefi::handle image_handle) {
|
||||
return _unload(image_handle);
|
||||
}
|
||||
|
||||
uint32_t revision;
|
||||
uefi::handle parent_handle;
|
||||
uefi::system_table * system_table;
|
||||
uefi::handle device_handle;
|
||||
uefi::protos::device_path * file_path;
|
||||
void * reserved;
|
||||
uint32_t load_options_size;
|
||||
void * load_options;
|
||||
void * image_base;
|
||||
uint64_t image_size;
|
||||
uefi::memory_type image_code_type;
|
||||
uefi::memory_type image_data_type;
|
||||
|
||||
protected:
|
||||
using _unload_def = uefi::status (*)(uefi::handle);
|
||||
_unload_def _unload;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_loaded_image_h_
|
||||
41
external/uefi/protos/service_binding.h
vendored
41
external/uefi/protos/service_binding.h
vendored
@@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_service_binding_h_
|
||||
#define _uefi_protos_service_binding_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct service_binding;
|
||||
|
||||
struct service_binding
|
||||
{
|
||||
|
||||
|
||||
inline uefi::status create_child(uefi::handle * child_handle) {
|
||||
return _create_child(this, child_handle);
|
||||
}
|
||||
|
||||
inline uefi::status destroy_child(uefi::handle child_handle) {
|
||||
return _destroy_child(this, child_handle);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using _create_child_def = uefi::status (*)(uefi::protos::service_binding *, uefi::handle *);
|
||||
_create_child_def _create_child;
|
||||
|
||||
using _destroy_child_def = uefi::status (*)(uefi::protos::service_binding *, uefi::handle);
|
||||
_destroy_child_def _destroy_child;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_service_binding_h_
|
||||
37
external/uefi/protos/simple_file_system.h
vendored
37
external/uefi/protos/simple_file_system.h
vendored
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_simple_file_system_h_
|
||||
#define _uefi_protos_simple_file_system_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/protos/file.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct simple_file_system;
|
||||
|
||||
struct simple_file_system
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x0964e5b22,0x6459,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||
|
||||
|
||||
inline uefi::status open_volume(uefi::protos::file ** root) {
|
||||
return _open_volume(this, root);
|
||||
}
|
||||
|
||||
uint64_t revision;
|
||||
|
||||
protected:
|
||||
using _open_volume_def = uefi::status (*)(uefi::protos::simple_file_system *, uefi::protos::file **);
|
||||
_open_volume_def _open_volume;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_simple_file_system_h_
|
||||
93
external/uefi/protos/simple_text_output.h
vendored
93
external/uefi/protos/simple_text_output.h
vendored
@@ -1,93 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_protos_simple_text_output_h_
|
||||
#define _uefi_protos_simple_text_output_h_
|
||||
|
||||
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
#include <uefi/graphics.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace protos {
|
||||
struct simple_text_output;
|
||||
|
||||
struct simple_text_output
|
||||
{
|
||||
static constexpr uefi::guid guid{ 0x387477c2,0x69c7,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||
|
||||
|
||||
inline uefi::status reset(bool extended_verification) {
|
||||
return _reset(this, extended_verification);
|
||||
}
|
||||
|
||||
inline uefi::status output_string(const wchar_t * string) {
|
||||
return _output_string(this, string);
|
||||
}
|
||||
|
||||
inline uefi::status test_string(const wchar_t * string) {
|
||||
return _test_string(this, string);
|
||||
}
|
||||
|
||||
inline uefi::status query_mode(uint64_t mode_number, uint64_t * columns, uint64_t * rows) {
|
||||
return _query_mode(this, mode_number, columns, rows);
|
||||
}
|
||||
|
||||
inline uefi::status set_mode(uint64_t mode_number) {
|
||||
return _set_mode(this, mode_number);
|
||||
}
|
||||
|
||||
inline uefi::status set_attribute(uefi::attribute attribute) {
|
||||
return _set_attribute(this, attribute);
|
||||
}
|
||||
|
||||
inline uefi::status clear_screen() {
|
||||
return _clear_screen(this);
|
||||
}
|
||||
|
||||
inline uefi::status set_cursor_position(uint64_t column, uint64_t row) {
|
||||
return _set_cursor_position(this, column, row);
|
||||
}
|
||||
|
||||
inline uefi::status enable_cursor(bool visible) {
|
||||
return _enable_cursor(this, visible);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
using _reset_def = uefi::status (*)(uefi::protos::simple_text_output *, bool);
|
||||
_reset_def _reset;
|
||||
|
||||
using _output_string_def = uefi::status (*)(uefi::protos::simple_text_output *, const wchar_t *);
|
||||
_output_string_def _output_string;
|
||||
|
||||
using _test_string_def = uefi::status (*)(uefi::protos::simple_text_output *, const wchar_t *);
|
||||
_test_string_def _test_string;
|
||||
|
||||
using _query_mode_def = uefi::status (*)(uefi::protos::simple_text_output *, uint64_t, uint64_t *, uint64_t *);
|
||||
_query_mode_def _query_mode;
|
||||
|
||||
using _set_mode_def = uefi::status (*)(uefi::protos::simple_text_output *, uint64_t);
|
||||
_set_mode_def _set_mode;
|
||||
|
||||
using _set_attribute_def = uefi::status (*)(uefi::protos::simple_text_output *, uefi::attribute);
|
||||
_set_attribute_def _set_attribute;
|
||||
|
||||
using _clear_screen_def = uefi::status (*)(uefi::protos::simple_text_output *);
|
||||
_clear_screen_def _clear_screen;
|
||||
|
||||
using _set_cursor_position_def = uefi::status (*)(uefi::protos::simple_text_output *, uint64_t, uint64_t);
|
||||
_set_cursor_position_def _set_cursor_position;
|
||||
|
||||
using _enable_cursor_def = uefi::status (*)(uefi::protos::simple_text_output *, bool);
|
||||
_enable_cursor_def _enable_cursor;
|
||||
|
||||
public:
|
||||
uefi::text_output_mode * mode;
|
||||
};
|
||||
|
||||
} // namespace protos
|
||||
} // namespace uefi
|
||||
|
||||
#endif // _uefi_protos_simple_text_output_h_
|
||||
52
external/uefi/runtime_services.h
vendored
52
external/uefi/runtime_services.h
vendored
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_runtime_services_h_
|
||||
#define _uefi_runtime_services_h_
|
||||
|
||||
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||
// not distributed with this file, You can obtain one at
|
||||
// http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <uefi/tables.h>
|
||||
|
||||
namespace uefi {
|
||||
namespace rs_impl {
|
||||
using convert_pointer = uefi::status (*)(uint64_t, void **);
|
||||
using set_virtual_address_map = uefi::status (*)(size_t, size_t, uint32_t, memory_descriptor *);
|
||||
}
|
||||
|
||||
struct runtime_services {
|
||||
static constexpr uint64_t signature = 0x56524553544e5552ull;
|
||||
|
||||
table_header header;
|
||||
|
||||
// Time Services
|
||||
void *get_time;
|
||||
void *set_time;
|
||||
void *get_wakeup_time;
|
||||
void *set_wakeup_time;
|
||||
|
||||
// Virtual Memory Services
|
||||
rs_impl::set_virtual_address_map set_virtual_address_map;
|
||||
rs_impl::convert_pointer convert_pointer;
|
||||
|
||||
// Variable Services
|
||||
void *get_variable;
|
||||
void *get_next_variable_name;
|
||||
void *set_variable;
|
||||
|
||||
// Miscellaneous Services
|
||||
void *get_next_high_monotonic_count;
|
||||
void *reset_system;
|
||||
|
||||
// UEFI 2.0 Capsule Services
|
||||
void *update_capsule;
|
||||
void *query_capsule_capabilities;
|
||||
|
||||
// Miscellaneous UEFI 2.0 Service
|
||||
void *query_variable_info;
|
||||
};
|
||||
|
||||
} // namespace uefi
|
||||
#endif
|
||||
73
external/uefi/tables.h
vendored
73
external/uefi/tables.h
vendored
@@ -1,73 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_tables_h_
|
||||
#define _uefi_tables_h_
|
||||
|
||||
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||
// not distributed with this file, You can obtain one at
|
||||
// http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <uefi/guid.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
namespace uefi {
|
||||
|
||||
struct runtime_services;
|
||||
struct boot_services;
|
||||
namespace protos {
|
||||
struct simple_text_input;
|
||||
struct simple_text_output;
|
||||
}
|
||||
|
||||
struct table_header
|
||||
{
|
||||
uint64_t signature;
|
||||
uint32_t revision;
|
||||
uint32_t header_size;
|
||||
uint32_t crc32;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct configuration_table
|
||||
{
|
||||
guid vendor_guid;
|
||||
void *vendor_table;
|
||||
};
|
||||
|
||||
struct system_table
|
||||
{
|
||||
table_header header;
|
||||
|
||||
char16_t *firmware_vendor;
|
||||
uint32_t firmware_revision;
|
||||
|
||||
handle console_in_handle;
|
||||
protos::simple_text_input *con_in;
|
||||
handle console_out_handle;
|
||||
protos::simple_text_output *con_out;
|
||||
handle standard_error_handle;
|
||||
protos::simple_text_output *std_err;
|
||||
|
||||
runtime_services *runtime_services;
|
||||
boot_services *boot_services;
|
||||
|
||||
unsigned int number_of_table_entries;
|
||||
configuration_table *configuration_table;
|
||||
};
|
||||
|
||||
constexpr uint32_t make_system_table_revision(int major, int minor) {
|
||||
return (major << 16) | minor;
|
||||
}
|
||||
|
||||
constexpr uint64_t system_table_signature = 0x5453595320494249ull;
|
||||
constexpr uint32_t system_table_revision = make_system_table_revision(2, 70);
|
||||
constexpr uint32_t specification_revision = system_table_revision;
|
||||
|
||||
namespace vendor_guids {
|
||||
constexpr guid acpi1{ 0xeb9d2d30,0x2d88,0x11d3,{0x9a,0x16,0x00,0x90,0x27,0x3f,0xc1,0x4d} };
|
||||
constexpr guid acpi2{ 0x8868e871,0xe4f1,0x11d3,{0xbc,0x22,0x00,0x80,0xc7,0x3c,0x88,0x81} };
|
||||
} // namespace vendor_guids
|
||||
} // namespace uefi
|
||||
|
||||
#endif
|
||||
157
external/uefi/types.h
vendored
157
external/uefi/types.h
vendored
@@ -1,157 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef _uefi_types_h_
|
||||
#define _uefi_types_h_
|
||||
|
||||
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||
// not distributed with this file, You can obtain one at
|
||||
// http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace uefi {
|
||||
|
||||
using handle = void *;
|
||||
|
||||
|
||||
//
|
||||
// Error and status code definitions
|
||||
//
|
||||
constexpr uint64_t error_bit = 0x8000000000000000ull;
|
||||
constexpr uint64_t make_error(uint64_t e) { return e|error_bit; }
|
||||
|
||||
enum class status : uint64_t
|
||||
{
|
||||
success = 0,
|
||||
|
||||
#define STATUS_WARNING(name, num) name = num,
|
||||
#define STATUS_ERROR(name, num) name = make_error(num),
|
||||
#include "uefi/errors.inc"
|
||||
#undef STATUS_WARNING
|
||||
#undef STATUS_ERROR
|
||||
};
|
||||
|
||||
inline bool is_error(status s) { return static_cast<uint64_t>(s) & error_bit; }
|
||||
inline bool is_warning(status s) { return !is_error(s) && s != status::success; }
|
||||
|
||||
|
||||
//
|
||||
// Time defitions
|
||||
//
|
||||
struct time
|
||||
{
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t second;
|
||||
uint8_t _pad0;
|
||||
uint32_t nanosecond;
|
||||
int16_t time_zone;
|
||||
uint8_t daylight;
|
||||
uint8_t _pad1;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Memory and allocation defitions
|
||||
//
|
||||
enum class memory_type : uint32_t
|
||||
{
|
||||
reserved,
|
||||
loader_code,
|
||||
loader_data,
|
||||
boot_services_code,
|
||||
boot_services_data,
|
||||
runtime_services_code,
|
||||
runtime_services_data,
|
||||
conventional_memory,
|
||||
unusable_memory,
|
||||
acpi_reclaim_memory,
|
||||
acpi_memory_nvs,
|
||||
memory_mapped_io,
|
||||
memory_mapped_io_port_space,
|
||||
pal_code,
|
||||
persistent_memory,
|
||||
max_memory_type
|
||||
};
|
||||
|
||||
enum class allocate_type : uint32_t
|
||||
{
|
||||
any_pages,
|
||||
max_address,
|
||||
address
|
||||
};
|
||||
|
||||
struct memory_descriptor
|
||||
{
|
||||
memory_type type;
|
||||
uintptr_t physical_start;
|
||||
uintptr_t virtual_start;
|
||||
uint64_t number_of_pages;
|
||||
uint64_t attribute;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Event handling defitions
|
||||
//
|
||||
using event = void *;
|
||||
|
||||
enum class evt : uint32_t
|
||||
{
|
||||
notify_wait = 0x00000100,
|
||||
notify_signal = 0x00000200,
|
||||
|
||||
signal_exit_boot_services = 0x00000201,
|
||||
signal_virtual_address_change = 0x60000202,
|
||||
|
||||
runtime = 0x40000000,
|
||||
timer = 0x80000000
|
||||
};
|
||||
|
||||
enum class tpl : uint64_t
|
||||
{
|
||||
application = 4,
|
||||
callback = 8,
|
||||
notify = 16,
|
||||
high_level = 31
|
||||
};
|
||||
|
||||
using event_notify = void (*)(event, void*);
|
||||
|
||||
|
||||
//
|
||||
// File IO defitions
|
||||
//
|
||||
struct file_io_token
|
||||
{
|
||||
event event;
|
||||
status status;
|
||||
uint64_t buffer_size;
|
||||
void *buffer;
|
||||
};
|
||||
|
||||
enum class file_mode : uint64_t
|
||||
{
|
||||
read = 0x0000000000000001ull,
|
||||
write = 0x0000000000000002ull,
|
||||
|
||||
create = 0x8000000000000000ull
|
||||
};
|
||||
|
||||
enum class file_attr : uint64_t
|
||||
{
|
||||
none = 0,
|
||||
read_only = 0x0000000000000001ull,
|
||||
hidden = 0x0000000000000002ull,
|
||||
system = 0x0000000000000004ull,
|
||||
reserved = 0x0000000000000008ull,
|
||||
directory = 0x0000000000000010ull,
|
||||
archive = 0x0000000000000020ull
|
||||
};
|
||||
|
||||
} // namespace uefi
|
||||
|
||||
#endif
|
||||
147
modules.yaml
Normal file
147
modules.yaml
Normal file
@@ -0,0 +1,147 @@
|
||||
name: jsix
|
||||
templates: scripts/templates
|
||||
modules:
|
||||
kernel:
|
||||
kind: exe
|
||||
output: jsix.elf
|
||||
target: host
|
||||
deps:
|
||||
- elf
|
||||
- initrd
|
||||
- kutil
|
||||
- vdso
|
||||
includes:
|
||||
- src/kernel
|
||||
source:
|
||||
- src/kernel/crti.s
|
||||
- src/kernel/apic.cpp
|
||||
- src/kernel/assert.cpp
|
||||
- src/kernel/boot.s
|
||||
- src/kernel/console.cpp
|
||||
- src/kernel/cpprt.cpp
|
||||
- src/kernel/cpu.cpp
|
||||
- src/kernel/debug.cpp
|
||||
- src/kernel/debug.s
|
||||
- src/kernel/device_manager.cpp
|
||||
- src/kernel/font.cpp
|
||||
- src/kernel/frame_allocator.cpp
|
||||
- src/kernel/fs/gpt.cpp
|
||||
- src/kernel/gdt.cpp
|
||||
- src/kernel/gdt.s
|
||||
- src/kernel/interrupts.cpp
|
||||
- src/kernel/interrupts.s
|
||||
- src/kernel/io.cpp
|
||||
- src/kernel/loader.s
|
||||
- src/kernel/log.cpp
|
||||
- src/kernel/main.cpp
|
||||
- src/kernel/memory_bootstrap.cpp
|
||||
- src/kernel/msr.cpp
|
||||
- src/kernel/objects/handle.cpp
|
||||
- src/kernel/objects/kobject.cpp
|
||||
- src/kernel/page_manager.cpp
|
||||
- src/kernel/pci.cpp
|
||||
- src/kernel/process.cpp
|
||||
- src/kernel/scheduler.cpp
|
||||
- src/kernel/screen.cpp
|
||||
- src/kernel/serial.cpp
|
||||
- src/kernel/syscall.cpp
|
||||
- src/kernel/syscall.s
|
||||
- src/kernel/syscalls/object.cpp
|
||||
- src/kernel/syscalls/process.cpp
|
||||
- src/kernel/task.s
|
||||
- src/kernel/crtn.s
|
||||
|
||||
boot:
|
||||
kind: exe
|
||||
target: boot
|
||||
output: boot.elf
|
||||
source:
|
||||
- src/boot/crt0.s
|
||||
- src/boot/console.cpp
|
||||
- src/boot/guids.cpp
|
||||
- src/boot/loader.cpp
|
||||
- src/boot/main.cpp
|
||||
- src/boot/memory.cpp
|
||||
- src/boot/reloc.cpp
|
||||
- src/boot/utility.cpp
|
||||
|
||||
vdso:
|
||||
kind: exe
|
||||
target: host
|
||||
output: libvdso.so
|
||||
extra:
|
||||
- src/arch/x86_64/vdso.ld
|
||||
source:
|
||||
- src/vdso/syscalls.cpp
|
||||
- src/vdso/overrides.cpp
|
||||
|
||||
nulldrv:
|
||||
kind: exe
|
||||
target: user
|
||||
output: nulldrv
|
||||
source:
|
||||
- src/drivers/nulldrv/main.cpp
|
||||
- src/drivers/nulldrv/main.s
|
||||
|
||||
elf:
|
||||
kind: lib
|
||||
output: libelf.a
|
||||
deps:
|
||||
- kutil
|
||||
includes:
|
||||
- src/libraries/elf/include
|
||||
source:
|
||||
- src/libraries/elf/elf.cpp
|
||||
|
||||
initrd:
|
||||
kind: lib
|
||||
output: libinitrd.a
|
||||
deps:
|
||||
- kutil
|
||||
includes:
|
||||
- src/libraries/initrd/include
|
||||
source:
|
||||
- src/libraries/initrd/initrd.cpp
|
||||
|
||||
kutil:
|
||||
kind: lib
|
||||
output: libkutil.a
|
||||
includes:
|
||||
- src/libraries/kutil/include
|
||||
source:
|
||||
- src/libraries/kutil/assert.cpp
|
||||
- src/libraries/kutil/bip_buffer.cpp
|
||||
- src/libraries/kutil/heap_allocator.cpp
|
||||
- src/libraries/kutil/logger.cpp
|
||||
- src/libraries/kutil/memory.cpp
|
||||
- src/libraries/kutil/printf.c
|
||||
- src/libraries/kutil/vm_space.cpp
|
||||
|
||||
makerd:
|
||||
kind: exe
|
||||
target: native
|
||||
output: makerd
|
||||
deps:
|
||||
- initrd
|
||||
source:
|
||||
- src/tools/makerd/entry.cpp
|
||||
- src/tools/makerd/main.cpp
|
||||
|
||||
tests:
|
||||
kind: exe
|
||||
target: native
|
||||
output: tests
|
||||
deps:
|
||||
- kutil
|
||||
source:
|
||||
- src/tests/address_manager.cpp
|
||||
- src/tests/constexpr_hash.cpp
|
||||
- src/tests/linked_list.cpp
|
||||
- src/tests/logger.cpp
|
||||
- src/tests/heap_allocator.cpp
|
||||
- src/tests/main.cpp
|
||||
overlays:
|
||||
- url: https://f000.backblazeb2.com/file/jsix-os/sysroot-llvm8-20190706.tar.bz2
|
||||
path: sysroot
|
||||
- url: https://f000.backblazeb2.com/file/jsix-os/sysroot-j6libc-8cb8ce7.tar.bz2
|
||||
path: sysroot
|
||||
@@ -33,18 +33,42 @@ Boost Software license:
|
||||
> ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
> DEALINGS IN THE SOFTWARE.
|
||||
|
||||
## cpptoml
|
||||
|
||||
jsix uses the [cpptoml][] library for parsing TOML configuration files. cpptoml
|
||||
is released under the terms of the MIT license:
|
||||
|
||||
[cpptoml]: https://github.com/skystrife/cpptoml
|
||||
|
||||
> Copyright (c) 2014 Chase Geigle
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
> this software and associated documentation files (the "Software"), to deal in
|
||||
> the Software without restriction, including without limitation the rights to
|
||||
> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
> the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
> subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in all
|
||||
> copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
## printf
|
||||
|
||||
The implementation of jsix's `*printf()` family of functions is derived from
|
||||
Marco Paland and Eyal Rozenberg's tiny [printf][] library, which is also
|
||||
released under the terms of the MIT license:
|
||||
jsix uses Marco Paland's tiny [printf][] library for its `*printf()` functions,
|
||||
which is also released under the terms of the MIT license:
|
||||
|
||||
[printf]: https://github.com/eyalroz/printf
|
||||
[printf]: https://github.com/mpaland/printf
|
||||
|
||||
> The MIT License (MIT)
|
||||
>
|
||||
> Copyright (c) 2014 Marco Paland
|
||||
> Copyright (c) 2021 Eyal Rozenberg
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -63,3 +87,46 @@ released under the terms of the MIT license:
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
> SOFTWARE.
|
||||
|
||||
## GNU-EFI
|
||||
|
||||
jsix's UEFI bootloader initially used [GNU-EFI][], and still uses one file (the
|
||||
linker script for the bootloader) from that project. GNU-EFI claims to be
|
||||
released under the BSD license. Again, I could not find its specific license
|
||||
file, so I am reproducing a generic 3-clause BSD license (the most restrictive,
|
||||
so as not to assume any extra rights that may not actually be granted) for it
|
||||
here:
|
||||
|
||||
[GNU-EFI]: https://gnu-efi.sourceforge.net
|
||||
|
||||
> Copyright (c) Nigel Croxon
|
||||
>
|
||||
> Redistribution and use in source and binary forms, with or without
|
||||
> modification, are permitted provided that the following conditions are met:
|
||||
>
|
||||
> 1. Redistributions of source code must retain the above copyright notice, this
|
||||
> list of conditions and the following disclaimer.
|
||||
>
|
||||
> 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
> this list of conditions and the following disclaimer in the documentation
|
||||
> and/or other materials provided with the distribution.
|
||||
>
|
||||
> 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
> may be used to endorse or promote products derived from this software
|
||||
> without specific prior written permission.
|
||||
>
|
||||
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
## Intel EFI Application Toolkit
|
||||
|
||||
jsix's UEFI loader uses code from Intel's EFI Application toolkit. Relevant
|
||||
code includes license statements at the top of each file.
|
||||
|
||||
71
qemu.sh
71
qemu.sh
@@ -3,55 +3,26 @@
|
||||
build="$(dirname $0)/build"
|
||||
assets="$(dirname $0)/assets"
|
||||
debug=""
|
||||
isaexit='-device isa-debug-exit,iobase=0xf4,iosize=0x04'
|
||||
debugtarget="${build}/jsix.elf"
|
||||
flash_name="ovmf_vars"
|
||||
gfx="-nographic"
|
||||
vga="-vga none"
|
||||
log=""
|
||||
kvm=""
|
||||
cpu="Broadwell,+pdpe1gb"
|
||||
smp=4
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-b | --debugboot)
|
||||
debug="-s -S"
|
||||
debugtarget="${build}/boot/boot.efi"
|
||||
shift
|
||||
for arg in $@; do
|
||||
case "${arg}" in
|
||||
--debug)
|
||||
debug="-s"
|
||||
flash_name="ovmf_vars_d"
|
||||
;;
|
||||
-d | --debug)
|
||||
debug="-s -S"
|
||||
isaexit=""
|
||||
shift
|
||||
;;
|
||||
-g | --gfx)
|
||||
--gfx)
|
||||
gfx=""
|
||||
vga=""
|
||||
shift
|
||||
;;
|
||||
-v | --vga)
|
||||
vga=""
|
||||
shift
|
||||
;;
|
||||
-k | --kvm)
|
||||
--kvm)
|
||||
kvm="-enable-kvm"
|
||||
cpu="host"
|
||||
shift
|
||||
;;
|
||||
-c | --cpus)
|
||||
smp=$2
|
||||
shift 2
|
||||
;;
|
||||
-l | --log)
|
||||
log="-d mmu,int,guest_errors -D jsix.log"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if [ -d "$1" ]; then
|
||||
build="$1"
|
||||
shift
|
||||
fi
|
||||
break
|
||||
build="${arg}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -66,33 +37,29 @@ fi
|
||||
|
||||
if [[ -n $TMUX ]]; then
|
||||
if [[ -n $debug ]]; then
|
||||
tmux split-window -h "gdb ${debugtarget}" &
|
||||
tmux split-window "gdb ${build}/jsix.elf" &
|
||||
else
|
||||
tmux split-window -h -l 80 "sleep 1; telnet localhost 45455" &
|
||||
tmux last-pane
|
||||
tmux split-window -l 10 "sleep 1; telnet localhost 45454" &
|
||||
fi
|
||||
elif [[ $DESKTOP_SESSION = "i3" ]]; then
|
||||
if [[ -n $debug ]]; then
|
||||
i3-msg exec i3-sensible-terminal -- -e "gdb ${debugtarget}" &
|
||||
i3-msg exec i3-sensible-terminal -- -e "gdb ${PWD}/${build}/jsix.elf" &
|
||||
else
|
||||
i3-msg exec i3-sensible-terminal -- -e 'telnet localhost 45454' &
|
||||
fi
|
||||
fi
|
||||
|
||||
qemu-system-x86_64 \
|
||||
exec qemu-system-x86_64 \
|
||||
-drive "if=pflash,format=raw,readonly,file=${assets}/ovmf/x64/ovmf_code.fd" \
|
||||
-drive "if=pflash,format=raw,file=${build}/ovmf_vars.fd" \
|
||||
-drive "if=pflash,format=raw,file=${build}/${flash_name}.fd" \
|
||||
-drive "format=raw,file=${build}/jsix.img" \
|
||||
-device "isa-debug-exit,iobase=0xf4,iosize=0x04" \
|
||||
-monitor telnet:localhost:45454,server,nowait \
|
||||
-serial stdio \
|
||||
-serial telnet:localhost:45455,server,nowait \
|
||||
-smp "${smp}" \
|
||||
-m 4096 \
|
||||
-smp 4 \
|
||||
-m 512 \
|
||||
-d mmu,int,guest_errors \
|
||||
-D jsix.log \
|
||||
-cpu "${cpu}" \
|
||||
-M q35 \
|
||||
-no-reboot \
|
||||
$isaexit $log $gfx $vga $kvm $debug
|
||||
|
||||
((result = ($? >> 1) - 1))
|
||||
exit $result
|
||||
$gfx $kvm $debug
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
cogapp >= 3
|
||||
ninja >= 1.10.2
|
||||
peru >= 1.2.1
|
||||
pyyaml >= 5.4
|
||||
lark == 0.12.0
|
||||
@@ -1,25 +0,0 @@
|
||||
from os.path import join
|
||||
|
||||
class BonnibelError(Exception):
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
|
||||
def load_config(filename):
|
||||
from yaml import safe_load
|
||||
with open(filename, 'r') as infile:
|
||||
return safe_load(infile.read())
|
||||
|
||||
def mod_rel(path):
|
||||
return join("${module_dir}", path)
|
||||
|
||||
def target_rel(path, module=None):
|
||||
if module:
|
||||
return join("${target_dir}", module + ".dir", path)
|
||||
else:
|
||||
return join("${target_dir}", path)
|
||||
|
||||
def include_rel(path, module=None):
|
||||
if module:
|
||||
return join("${build_root}", "include", module, path)
|
||||
else:
|
||||
return join("${build_root}", "include", path)
|
||||
@@ -1,103 +0,0 @@
|
||||
from . import BonnibelError
|
||||
|
||||
class Manifest:
|
||||
from collections import namedtuple
|
||||
Entry = namedtuple("Entry", ("module", "target", "output", "location", "description", "flags"))
|
||||
|
||||
flags = {
|
||||
"graphical": 0x01,
|
||||
"panic": 0x02,
|
||||
"symbols": 0x04,
|
||||
}
|
||||
|
||||
boot_flags = {
|
||||
"debug": 0x01,
|
||||
"test": 0x02,
|
||||
}
|
||||
|
||||
def __init__(self, path, modules):
|
||||
from . import load_config
|
||||
|
||||
config = load_config(path)
|
||||
|
||||
self.kernel = self.__build_entry(modules,
|
||||
config.get("kernel", dict()),
|
||||
name="kernel", target="kernel")
|
||||
|
||||
self.init = self.__build_entry(modules,
|
||||
config.get("init", None))
|
||||
|
||||
self.programs = [self.__build_entry(modules, i)
|
||||
for i in config.get("programs", tuple())]
|
||||
|
||||
self.flags = config.get("flags", tuple())
|
||||
|
||||
self.data = []
|
||||
for d in config.get("data", tuple()):
|
||||
self.add_data(**d)
|
||||
|
||||
def __build_entry(self, modules, config, target="user", name=None):
|
||||
flags = tuple()
|
||||
|
||||
if isinstance(config, str):
|
||||
name = config
|
||||
elif isinstance(config, dict):
|
||||
name = config.get("name", name)
|
||||
target = config.get("target", target)
|
||||
flags = config.get("flags", tuple())
|
||||
if isinstance(flags, str):
|
||||
flags = flags.split()
|
||||
|
||||
mod = modules.get(name)
|
||||
if not mod:
|
||||
raise BonnibelError(f"Manifest specifies unknown module '{name}'")
|
||||
|
||||
for f in flags:
|
||||
if not f in Manifest.flags:
|
||||
raise BonnibelError(f"Manifest specifies unknown flag '{f}'")
|
||||
|
||||
return Manifest.Entry(name, target, mod.output, mod.location, mod.description, flags)
|
||||
|
||||
def add_data(self, output, location, desc, flags=tuple()):
|
||||
e = Manifest.Entry(None, None, output, location, desc, flags)
|
||||
self.data.append(e)
|
||||
return e
|
||||
|
||||
def write_boot_config(self, path):
|
||||
from os.path import join
|
||||
import struct
|
||||
|
||||
with open(path, 'wb') as outfile:
|
||||
magic = "jsixboot".encode("utf-8") # magic string
|
||||
version = 0
|
||||
reserved = 0
|
||||
|
||||
bootflags = sum([Manifest.boot_flags.get(s, 0) for s in self.flags])
|
||||
|
||||
outfile.write(struct.pack("<8sBBHHH",
|
||||
magic, version, reserved,
|
||||
len(self.programs), len(self.data),
|
||||
bootflags))
|
||||
|
||||
def write_str(s):
|
||||
outfile.write(struct.pack("<H", (len(s)+1)*2))
|
||||
outfile.write(s.encode("utf-16le"))
|
||||
outfile.write(b"\0\0")
|
||||
|
||||
def write_ent(ent):
|
||||
flags = 0
|
||||
for f in ent.flags:
|
||||
flags |= Manifest.flags[f]
|
||||
|
||||
outfile.write(struct.pack("<H", flags))
|
||||
write_str(join(ent.location, ent.output).replace('/','\\'))
|
||||
write_str(ent.description)
|
||||
|
||||
write_ent(self.kernel)
|
||||
write_ent(self.init)
|
||||
|
||||
for p in self.programs:
|
||||
write_ent(p)
|
||||
|
||||
for d in self.data:
|
||||
write_ent(d)
|
||||
@@ -1,276 +0,0 @@
|
||||
from . import include_rel, mod_rel, target_rel
|
||||
|
||||
def resolve(path):
|
||||
if path.startswith('/') or path.startswith('$'):
|
||||
return path
|
||||
from pathlib import Path
|
||||
return str(Path(path).resolve())
|
||||
|
||||
class BuildOptions:
|
||||
def __init__(self, includes=tuple(), libs=tuple(), order_only=tuple()):
|
||||
self.includes = list(includes)
|
||||
self.libs = list(libs)
|
||||
self.order_only = list(order_only)
|
||||
|
||||
|
||||
class Module:
|
||||
__fields = {
|
||||
# name: (type, default)
|
||||
"kind": (str, "exe"),
|
||||
"output": (str, None),
|
||||
"targets": (set, ()),
|
||||
"deps": (set, ()),
|
||||
"public_headers": (set, ()),
|
||||
"includes": (tuple, ()),
|
||||
"sources": (tuple, ()),
|
||||
"variables": (dict, ()),
|
||||
"default": (bool, False),
|
||||
"location": (str, "jsix"),
|
||||
"description": (str, None),
|
||||
"no_libc": (bool, False),
|
||||
}
|
||||
|
||||
def __init__(self, name, modfile, root, **kwargs):
|
||||
from .source import make_source
|
||||
|
||||
# Required fields
|
||||
self.root = root
|
||||
self.name = name
|
||||
self.modfile = modfile
|
||||
|
||||
for name, data in self.__fields.items():
|
||||
ctor, default = data
|
||||
value = kwargs.get(name, default)
|
||||
if value is not None:
|
||||
value = ctor(value)
|
||||
|
||||
setattr(self, name, value)
|
||||
|
||||
for name in kwargs:
|
||||
if not name in self.__fields:
|
||||
raise AttributeError(f"No attribute named {name} on Module")
|
||||
|
||||
# Turn strings into real Source objects
|
||||
self.sources = [make_source(root, f) for f in self.sources]
|
||||
self.public_headers = [make_source(root, f) for f in self.public_headers]
|
||||
|
||||
# Filled by Module.update
|
||||
self.depmods = set()
|
||||
|
||||
def __str__(self):
|
||||
return "Module {} {}\n\t{}".format(self.kind, self.name, "\n\t".join(map(str, self.sources)))
|
||||
|
||||
@property
|
||||
def output(self):
|
||||
if self.__output is not None:
|
||||
return self.__output
|
||||
|
||||
if self.kind == "lib":
|
||||
return f"lib{self.name}.a"
|
||||
else:
|
||||
return f"{self.name}.elf"
|
||||
|
||||
@output.setter
|
||||
def output(self, value):
|
||||
self.__output = value
|
||||
|
||||
@classmethod
|
||||
def update(cls, mods):
|
||||
from . import BonnibelError
|
||||
|
||||
def resolve(source, modlist):
|
||||
resolved = set()
|
||||
for dep in modlist:
|
||||
if not dep in mods:
|
||||
raise BonnibelError(f"module '{source.name}' references unknown module '{dep}'")
|
||||
mod = mods[dep]
|
||||
resolved.add(mod)
|
||||
return resolved
|
||||
|
||||
for mod in mods.values():
|
||||
mod.depmods = resolve(mod, mod.deps)
|
||||
|
||||
target_mods = [mod for mod in mods.values() if mod.targets]
|
||||
for mod in target_mods:
|
||||
closed = set()
|
||||
children = set(mod.depmods)
|
||||
while children:
|
||||
child = children.pop()
|
||||
closed.add(child)
|
||||
child.targets |= mod.targets
|
||||
children |= {m for m in child.depmods if not m in closed}
|
||||
|
||||
def generate(self, output):
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
from ninja.ninja_syntax import Writer
|
||||
|
||||
def walk_deps(deps):
|
||||
open_set = set(deps)
|
||||
closed_set = set()
|
||||
while open_set:
|
||||
dep = open_set.pop()
|
||||
closed_set.add(dep)
|
||||
open_set |= {m for m in dep.depmods if not m in closed_set}
|
||||
return closed_set
|
||||
|
||||
all_deps = walk_deps(self.depmods)
|
||||
|
||||
def gather_phony(build, deps, child_rel, add_headers=False):
|
||||
phony = ".headers.phony"
|
||||
child_phony = [child_rel(phony, module=c.name)
|
||||
for c in all_deps]
|
||||
|
||||
header_targets = []
|
||||
if add_headers:
|
||||
if not self.no_libc:
|
||||
header_targets.append(f"${{build_root}}/include/libc/{phony}")
|
||||
if self.public_headers:
|
||||
header_targets.append(f"${{build_root}}/include/{self.name}/{phony}")
|
||||
|
||||
build.build(
|
||||
rule = "touch",
|
||||
outputs = [mod_rel(phony)],
|
||||
implicit = child_phony + header_targets,
|
||||
order_only = list(map(mod_rel, deps)),
|
||||
)
|
||||
|
||||
filename = str(output / f"headers.{self.name}.ninja")
|
||||
with open(filename, "w") as buildfile:
|
||||
build = Writer(buildfile)
|
||||
|
||||
build.comment("This file is automatically generated by bonnibel")
|
||||
build.newline()
|
||||
|
||||
build.variable("module_dir", f"${{build_root}}/include/{self.name}")
|
||||
|
||||
header_deps = []
|
||||
|
||||
inputs = []
|
||||
headers = set(self.public_headers)
|
||||
while headers:
|
||||
source = headers.pop()
|
||||
headers.update(source.next)
|
||||
|
||||
if source.action:
|
||||
build.newline()
|
||||
build.build(rule=source.action, **source.args)
|
||||
|
||||
if source.gather:
|
||||
header_deps += list(source.outputs)
|
||||
|
||||
if source.input:
|
||||
inputs.extend(map(mod_rel, source.outputs))
|
||||
|
||||
build.newline()
|
||||
gather_phony(build, header_deps, include_rel)
|
||||
|
||||
filename = str(output / f"module.{self.name}.ninja")
|
||||
with open(filename, "w") as buildfile:
|
||||
build = Writer(buildfile)
|
||||
|
||||
build.comment("This file is automatically generated by bonnibel")
|
||||
build.newline()
|
||||
|
||||
build.variable("module_dir", target_rel(self.name + ".dir"))
|
||||
|
||||
modopts = BuildOptions(
|
||||
includes = [self.root, "${module_dir}"],
|
||||
)
|
||||
if self.public_headers:
|
||||
modopts.includes += [f"${{build_root}}/include/{self.name}"]
|
||||
|
||||
for key, value in self.variables.items():
|
||||
build.variable(key, value)
|
||||
build.newline()
|
||||
|
||||
for include in self.includes:
|
||||
p = Path(include)
|
||||
if p.is_absolute():
|
||||
if not p in modopts.includes:
|
||||
modopts.includes.append(str(p.resolve()))
|
||||
elif include != ".":
|
||||
incpath = self.root / p
|
||||
destpath = mod_rel(p)
|
||||
for header in incpath.rglob("*.h"):
|
||||
dest_header = f"{destpath}/" + str(header.relative_to(incpath))
|
||||
modopts.includes.append(str(incpath))
|
||||
modopts.includes.append(destpath)
|
||||
|
||||
all_deps = walk_deps(self.depmods)
|
||||
for dep in all_deps:
|
||||
if dep.public_headers:
|
||||
modopts.includes += [f"${{build_root}}/include/{dep.name}"]
|
||||
|
||||
if dep.kind == "lib":
|
||||
modopts.libs.append(target_rel(dep.output))
|
||||
else:
|
||||
modopts.order_only.append(target_rel(dep.output))
|
||||
|
||||
if modopts.includes:
|
||||
build.variable("ccflags", ["${ccflags}"] + [f"-I{i}" for i in modopts.includes])
|
||||
build.variable("asflags", ["${asflags}"] + [f"-I{i}" for i in modopts.includes])
|
||||
|
||||
if modopts.libs:
|
||||
build.variable("libs", ["${libs}"] + modopts.libs)
|
||||
|
||||
header_deps = []
|
||||
|
||||
inputs = []
|
||||
sources = set(self.sources)
|
||||
while sources:
|
||||
source = sources.pop()
|
||||
sources.update(source.next)
|
||||
|
||||
if source.action:
|
||||
build.newline()
|
||||
build.build(rule=source.action, **source.args)
|
||||
|
||||
if source.gather:
|
||||
header_deps += list(source.outputs)
|
||||
|
||||
if source.input:
|
||||
inputs.extend(map(mod_rel, source.outputs))
|
||||
|
||||
build.newline()
|
||||
|
||||
gather_phony(build, header_deps, target_rel, add_headers=True)
|
||||
|
||||
output = target_rel(self.output)
|
||||
dump = output + ".dump"
|
||||
build.newline()
|
||||
build.build(
|
||||
rule = self.kind,
|
||||
outputs = output,
|
||||
inputs = inputs,
|
||||
implicit = modopts.libs,
|
||||
order_only = modopts.order_only,
|
||||
)
|
||||
|
||||
build.newline()
|
||||
build.build(
|
||||
rule = "dump",
|
||||
outputs = dump,
|
||||
inputs = output,
|
||||
variables = {"name": self.name},
|
||||
)
|
||||
|
||||
if self.default:
|
||||
build.newline()
|
||||
build.default(output)
|
||||
build.default(dump)
|
||||
|
||||
def add_input(self, path, **kwargs):
|
||||
from .source import Source
|
||||
s = Source(self.root, path, **kwargs)
|
||||
self.sources.append(s)
|
||||
return s.outputs
|
||||
|
||||
def add_depends(self, paths, deps):
|
||||
for source in self.sources:
|
||||
if source.path in paths:
|
||||
source.add_deps(deps)
|
||||
|
||||
for source in self.public_headers:
|
||||
if source.path in paths:
|
||||
source.add_deps(deps)
|
||||
@@ -1,234 +0,0 @@
|
||||
from . import BonnibelError
|
||||
|
||||
class Project:
|
||||
def __init__(self, root):
|
||||
from .version import git_version
|
||||
|
||||
self.root = root
|
||||
self.version = git_version(root)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} {self.version.major}.{self.version.minor}.{self.version.patch}-{self.version.sha}"
|
||||
|
||||
def generate(self, root, output, modules, config, manifest_file):
|
||||
import sys
|
||||
import bonnibel
|
||||
from os.path import join
|
||||
from ninja.ninja_syntax import Writer
|
||||
from .target import Target
|
||||
|
||||
targets = set()
|
||||
for mod in modules.values():
|
||||
targets.update({Target.load(root, t, config) for t in mod.targets})
|
||||
|
||||
with open(output / "build.ninja", "w") as buildfile:
|
||||
build = Writer(buildfile)
|
||||
|
||||
build.comment("This file is automatically generated by bonnibel")
|
||||
build.variable("ninja_required_version", "1.3")
|
||||
build.variable("build_root", output)
|
||||
build.variable("source_root", root)
|
||||
build.newline()
|
||||
|
||||
build.include(root / "configs" / "rules.ninja")
|
||||
build.newline()
|
||||
|
||||
build.variable("version_major", self.version.major)
|
||||
build.variable("version_minor", self.version.minor)
|
||||
build.variable("version_patch", self.version.patch)
|
||||
build.variable("version_sha", self.version.sha)
|
||||
build.newline()
|
||||
|
||||
build.variable("cogflags", [
|
||||
"-I", "${source_root}/scripts",
|
||||
"-D", "definitions_path=${source_root}/definitions",
|
||||
])
|
||||
build.newline()
|
||||
|
||||
for target in targets:
|
||||
build.subninja(output / target.name / "target.ninja")
|
||||
build.newline()
|
||||
|
||||
for mod in modules.values():
|
||||
build.subninja(output / f"headers.{mod.name}.ninja")
|
||||
build.newline()
|
||||
|
||||
build.build(
|
||||
rule = "touch",
|
||||
outputs = "${build_root}/.all_headers",
|
||||
implicit = [f"${{build_root}}/include/{m.name}/.headers.phony"
|
||||
for m in modules.values() if m.public_headers],
|
||||
)
|
||||
build.build(
|
||||
rule = "phony",
|
||||
outputs = ["all-headers"],
|
||||
inputs = ["${build_root}/.all_headers"])
|
||||
|
||||
debugroot = output / ".debug"
|
||||
debugroot.mkdir(exist_ok=True)
|
||||
|
||||
fatroot = output / "fatroot"
|
||||
fatroot.mkdir(exist_ok=True)
|
||||
|
||||
fatroot_content = []
|
||||
|
||||
def add_fatroot(source, entry):
|
||||
output = join(entry.location, entry.output)
|
||||
fatroot_output = f"${{build_root}}/fatroot/{output}"
|
||||
|
||||
build.build(
|
||||
rule = "cp",
|
||||
outputs = [fatroot_output],
|
||||
inputs = [source],
|
||||
variables = {
|
||||
"name": f"Installing {output}",
|
||||
})
|
||||
|
||||
fatroot_content.append(fatroot_output)
|
||||
build.newline()
|
||||
|
||||
def add_fatroot_exe(entry):
|
||||
input_path = f"${{build_root}}/{entry.target}/{entry.output}"
|
||||
intermediary = f"${{build_root}}/{entry.output}"
|
||||
|
||||
build.build(
|
||||
rule = "strip",
|
||||
outputs = [intermediary],
|
||||
inputs = [input_path],
|
||||
implicit = [f"{input_path}.dump"],
|
||||
variables = {
|
||||
"name": f"Stripping {entry.module}",
|
||||
"debug": f"${{build_root}}/.debug/{entry.output}.debug",
|
||||
})
|
||||
|
||||
add_fatroot(intermediary, entry)
|
||||
|
||||
from .manifest import Manifest
|
||||
manifest = Manifest(manifest_file, modules)
|
||||
|
||||
add_fatroot_exe(manifest.kernel)
|
||||
add_fatroot_exe(manifest.init)
|
||||
for program in manifest.programs:
|
||||
add_fatroot_exe(program)
|
||||
|
||||
syms = manifest.add_data("symbol_table.dat",
|
||||
manifest.kernel.location, "Symbol table", ("symbols",))
|
||||
|
||||
sym_out = f"${{build_root}}/symbol_table.dat"
|
||||
build.build(
|
||||
rule = "makest",
|
||||
outputs = [sym_out],
|
||||
inputs = [f"${{build_root}}/{modules['kernel'].output}"],
|
||||
)
|
||||
add_fatroot(sym_out, syms)
|
||||
|
||||
bootloader = "${build_root}/fatroot/efi/boot/bootx64.efi"
|
||||
build.build(
|
||||
rule = "cp",
|
||||
outputs = [bootloader],
|
||||
inputs = ["${build_root}/boot/boot.efi"],
|
||||
variables = {
|
||||
"name": "Installing bootloader",
|
||||
})
|
||||
build.newline()
|
||||
|
||||
boot_config = join(fatroot, "jsix_boot.dat")
|
||||
manifest.write_boot_config(boot_config)
|
||||
|
||||
build.build(
|
||||
rule = "makefat",
|
||||
outputs = ["${build_root}/jsix.img"],
|
||||
inputs = ["${source_root}/assets/diskbase.img"],
|
||||
implicit = fatroot_content + [bootloader],
|
||||
variables = {"name": "jsix.img"},
|
||||
)
|
||||
build.newline()
|
||||
|
||||
default_assets = {
|
||||
"UEFI Variables": ("ovmf/x64/ovmf_vars.fd", "ovmf_vars.fd"),
|
||||
"GDB Debug Helpers": ("debugging/jsix.elf-gdb.py", "jsix.elf-gdb.py"),
|
||||
}
|
||||
|
||||
for name, assets in default_assets.items():
|
||||
p = root / "assets" / assets[0]
|
||||
out = f"${{build_root}}/{assets[1]}"
|
||||
build.build(
|
||||
rule = "cp",
|
||||
outputs = [out],
|
||||
inputs = [str(p)],
|
||||
variables = {"name": name},
|
||||
)
|
||||
build.default([out])
|
||||
build.newline()
|
||||
|
||||
compdb = "${source_root}/compile_commands.json"
|
||||
|
||||
build.rule("regen",
|
||||
command = " ".join([str(root / 'configure')] + sys.argv[1:]),
|
||||
description = "Regenerate build files",
|
||||
generator = True,
|
||||
)
|
||||
build.newline()
|
||||
|
||||
regen_implicits = \
|
||||
[f"{self.root}/configure", str(manifest_file)] + \
|
||||
[str(mod.modfile) for mod in modules.values()]
|
||||
|
||||
for target in targets:
|
||||
regen_implicits += target.depfiles
|
||||
|
||||
build.build(
|
||||
rule = "compdb",
|
||||
outputs = [compdb],
|
||||
implicit = regen_implicits,
|
||||
)
|
||||
build.default([compdb])
|
||||
build.newline()
|
||||
|
||||
build.build(
|
||||
rule = "regen",
|
||||
outputs = ['build.ninja'],
|
||||
implicit = regen_implicits,
|
||||
implicit_outputs =
|
||||
[f"module.{mod.name}.ninja" for mod in modules.values()] +
|
||||
[f"{target.name}/target.ninja" for target in targets] +
|
||||
[boot_config],
|
||||
)
|
||||
|
||||
build.newline()
|
||||
build.default(["${build_root}/jsix.img"])
|
||||
|
||||
for target in targets:
|
||||
mods = [m.name for m in modules.values() if target.name in m.targets]
|
||||
|
||||
targetdir = output / target.name
|
||||
targetdir.mkdir(exist_ok=True)
|
||||
|
||||
buildfilename = str(targetdir / "target.ninja")
|
||||
with open(buildfilename, "w") as buildfile:
|
||||
build = Writer(buildfile)
|
||||
build.comment("This file is automatically generated by bonnibel")
|
||||
build.newline()
|
||||
|
||||
build.variable("target", target.name)
|
||||
build.variable("target_dir", output / target.name)
|
||||
build.newline()
|
||||
|
||||
for name, value in target.items():
|
||||
build.variable(name, value)
|
||||
|
||||
build.newline()
|
||||
for kind in ('defs', 'run'):
|
||||
for lang in ('c', 'cpp'):
|
||||
deffile = str(output / target.name / f"{lang}.{kind}")
|
||||
|
||||
build.build(
|
||||
rule = f"dump_{lang}_{kind}",
|
||||
outputs = [deffile],
|
||||
implicit = [buildfilename],
|
||||
)
|
||||
build.default(deffile)
|
||||
build.newline()
|
||||
|
||||
for mod in mods:
|
||||
build.subninja(f"module.{mod}.ninja")
|
||||
@@ -1,119 +0,0 @@
|
||||
from os.path import join, splitext
|
||||
from . import mod_rel
|
||||
|
||||
def _resolve(path):
|
||||
if path.startswith('/') or path.startswith('$'):
|
||||
return path
|
||||
from pathlib import Path
|
||||
return str(Path(path).resolve())
|
||||
|
||||
def _dynamic_action(name):
|
||||
def prop(self):
|
||||
root, suffix = splitext(self.path)
|
||||
return f"{name}{suffix}"
|
||||
return prop
|
||||
|
||||
|
||||
class Source:
|
||||
next = tuple()
|
||||
action = None
|
||||
args = dict()
|
||||
gather = False
|
||||
outputs = tuple()
|
||||
input = False
|
||||
|
||||
def __init__(self, path, root = "${module_dir}", deps=tuple()):
|
||||
self.path = path
|
||||
self.root = root
|
||||
self.deps = deps
|
||||
|
||||
def add_deps(self, deps):
|
||||
self.deps += tuple(deps)
|
||||
|
||||
@property
|
||||
def fullpath(self):
|
||||
return join(self.root, self.path)
|
||||
|
||||
class ParseSource(Source):
|
||||
action = property(_dynamic_action("parse"))
|
||||
|
||||
@property
|
||||
def output(self):
|
||||
root, _ = splitext(self.path)
|
||||
return root
|
||||
|
||||
@property
|
||||
def outputs(self):
|
||||
return (self.output,)
|
||||
|
||||
@property
|
||||
def gather(self):
|
||||
_, suffix = splitext(self.output)
|
||||
return suffix in (".h", ".inc")
|
||||
|
||||
@property
|
||||
def next(self):
|
||||
_, suffix = splitext(self.output)
|
||||
nextType = {
|
||||
".s": CompileSource,
|
||||
".cpp": CompileSource,
|
||||
}.get(suffix)
|
||||
|
||||
if nextType:
|
||||
return (nextType(self.output),)
|
||||
return tuple()
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
return dict(
|
||||
outputs = list(map(mod_rel, self.outputs)),
|
||||
inputs = [self.fullpath],
|
||||
implicit = list(map(_resolve, self.deps)),
|
||||
variables = dict(name=self.path),
|
||||
)
|
||||
|
||||
class HeaderSource(Source):
|
||||
action = "cp"
|
||||
gather = True
|
||||
|
||||
@property
|
||||
def outputs(self):
|
||||
return (self.path,)
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
return dict(
|
||||
outputs = [mod_rel(self.path)],
|
||||
inputs = [join(self.root, self.path)],
|
||||
implicit = list(map(_resolve, self.deps)),
|
||||
variables = dict(name=self.path),
|
||||
)
|
||||
|
||||
class CompileSource(Source):
|
||||
action = property(_dynamic_action("compile"))
|
||||
input = True
|
||||
|
||||
@property
|
||||
def outputs(self):
|
||||
return (self.path + ".o",)
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
return dict(
|
||||
outputs = list(map(mod_rel, self.outputs)),
|
||||
inputs = [join(self.root, self.path)],
|
||||
implicit = list(map(_resolve, self.deps)) + [mod_rel(".headers.phony")],
|
||||
variables = dict(name=self.path),
|
||||
)
|
||||
|
||||
def make_source(root, path):
|
||||
_, suffix = splitext(path)
|
||||
|
||||
if suffix in (".s", ".c", ".cpp"):
|
||||
return CompileSource(path, root)
|
||||
elif suffix in (".cog",):
|
||||
return ParseSource(path, root)
|
||||
elif suffix in (".h", ".inc"):
|
||||
return HeaderSource(path, root)
|
||||
else:
|
||||
raise RuntimeError(f"{path} has no Source type")
|
||||
@@ -1,50 +0,0 @@
|
||||
class Target(dict):
|
||||
__targets = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, root, name, config=None):
|
||||
from . import load_config
|
||||
|
||||
if (name, config) in cls.__targets:
|
||||
return cls.__targets[(name, config)]
|
||||
|
||||
configs = root / "configs"
|
||||
|
||||
dicts = []
|
||||
depfiles = []
|
||||
basename = name
|
||||
if config:
|
||||
basename += f"-{config}"
|
||||
|
||||
while basename is not None:
|
||||
filename = str(configs / (basename + ".yaml"))
|
||||
depfiles.append(filename)
|
||||
desc = load_config(filename)
|
||||
basename = desc.get("extends")
|
||||
dicts.append(desc.get("variables", dict()))
|
||||
|
||||
t = Target(name, config, depfiles)
|
||||
for d in reversed(dicts):
|
||||
for k, v in d.items():
|
||||
if isinstance(v, (list, tuple)):
|
||||
t[k] = t.get(k, list()) + list(v)
|
||||
elif isinstance(v, dict):
|
||||
t[k] = t.get(k, dict())
|
||||
t[k].update(v)
|
||||
else:
|
||||
t[k] = v
|
||||
|
||||
cls.__targets[(name, config)] = t
|
||||
return t
|
||||
|
||||
def __init__(self, name, config, depfiles):
|
||||
self.__name = name
|
||||
self.__config = config
|
||||
self.__depfiles = tuple(depfiles)
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.__name, self.__config))
|
||||
|
||||
name = property(lambda self: self.__name)
|
||||
config = property(lambda self: self.__config)
|
||||
depfiles = property(lambda self: self.__depfiles)
|
||||
@@ -1,41 +0,0 @@
|
||||
from collections import namedtuple as _namedtuple
|
||||
|
||||
version = _namedtuple('version', [
|
||||
'major',
|
||||
'minor',
|
||||
'patch',
|
||||
'sha',
|
||||
'dirty',
|
||||
])
|
||||
|
||||
|
||||
def _run_git(root, *args):
|
||||
from subprocess import run
|
||||
|
||||
git = run(['git', '-C', root] + list(args),
|
||||
check=True, capture_output=True)
|
||||
return git.stdout.decode('utf-8').strip()
|
||||
|
||||
|
||||
def git_version(root):
|
||||
full_version = _run_git(root, 'describe', '--dirty')
|
||||
full_sha = _run_git(root, 'rev-parse', 'HEAD')
|
||||
|
||||
dirty = False
|
||||
parts1 = full_version.split('-')
|
||||
if parts1[-1] == "dirty":
|
||||
dirty = True
|
||||
parts1 = parts1[:-1]
|
||||
|
||||
if parts1[0][0] == 'v':
|
||||
parts1[0] = parts1[0][1:]
|
||||
|
||||
parts2 = parts1[0].split('.')
|
||||
|
||||
return version(
|
||||
parts2[0],
|
||||
parts2[1],
|
||||
parts2[2],
|
||||
full_sha[:7],
|
||||
dirty)
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Generate the jsix style symbol table. The format in memory of this table
|
||||
# is as follows:
|
||||
#
|
||||
# <num_entires> : 8 bytes
|
||||
# <index> : 24 * N bytes
|
||||
# <name data> : variable
|
||||
#
|
||||
# Each index entry has the format
|
||||
# <symbol address> : 8 bytes
|
||||
# <symbol size> : 8 bytes
|
||||
# <offset of name> : 8 bytes
|
||||
#
|
||||
# Name offsets are from the start of the symbol table as a whole. (ie,
|
||||
# where <num_entries> is located.)
|
||||
|
||||
import re
|
||||
|
||||
sym_re = re.compile(r'([0-9a-fA-F]{16}) ([0-9a-fA-F]{16}) [tTvVwW] (.*)')
|
||||
|
||||
def parse_syms(infile):
|
||||
"""Take the output of the `nm` command, and parse it into a tuple
|
||||
representing the symbols in the text segment of the binary. Returns
|
||||
a list of (address, symbol_name)."""
|
||||
|
||||
syms = []
|
||||
for line in sys.stdin:
|
||||
match = sym_re.match(line)
|
||||
if not match: continue
|
||||
|
||||
addr = int(match.group(1), base=16)
|
||||
size = int(match.group(2), base=16)
|
||||
name = match.group(3)
|
||||
syms.append([addr, size, name, 0])
|
||||
|
||||
return syms
|
||||
|
||||
|
||||
def write_table(syms, outfile):
|
||||
"""Write the given symbol table as generated by parse_syms()
|
||||
to the outfile, index first, and then name character data."""
|
||||
|
||||
import struct
|
||||
|
||||
outfile.write(struct.pack("@Q", len(syms)))
|
||||
index_pos = outfile.tell()
|
||||
|
||||
outfile.seek(struct.calcsize("@QQQ") * len(syms), 1)
|
||||
nul = b'\0'
|
||||
|
||||
for s in syms:
|
||||
s[3] = outfile.tell()
|
||||
outfile.write(s[2].encode('utf-8'))
|
||||
outfile.write(nul)
|
||||
|
||||
outfile.seek(index_pos)
|
||||
for s in syms:
|
||||
addr = s[0]
|
||||
size = s[1]
|
||||
pos = s[3]
|
||||
outfile.write(struct.pack("@QQQ", addr, size, pos))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Usage: nm -n -S --demangle | {sys.argv[0]} <output>")
|
||||
sys.exit(1)
|
||||
|
||||
outfile = open(sys.argv[1], "wb")
|
||||
write_table(parse_syms(sys.stdin), outfile)
|
||||
131
scripts/build_sysroot.sh
Executable file
131
scripts/build_sysroot.sh
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TARGET="x86_64-elf"
|
||||
LLVM_BRANCH="release_80"
|
||||
|
||||
TOOLS="clang lld" # lld libunwind libcxxabi libcxx"
|
||||
PROJECTS="compiler-rt libcxxabi libcxx libunwind"
|
||||
#RUNTIMES="compiler-rt libcxxabi libcxx libunwind"
|
||||
|
||||
set -e
|
||||
|
||||
README=$(realpath "$(dirname $0)/readme_for_prebuilt_sysroots.md")
|
||||
SYSROOT=$(realpath "$(dirname $0)/../sysroot")
|
||||
WORK=$(realpath "$(dirname $0)/sysroot")
|
||||
mkdir -p "${SYSROOT}"
|
||||
mkdir -p "${WORK}"
|
||||
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
|
||||
if [[ ! -d "${WORK}/llvm" ]]; then
|
||||
echo "Downloading LLVM..."
|
||||
git clone -q \
|
||||
--branch "${LLVM_BRANCH}" \
|
||||
--depth 1 \
|
||||
"https://git.llvm.org/git/llvm.git" "${WORK}/llvm"
|
||||
fi
|
||||
|
||||
for tool in ${TOOLS}; do
|
||||
if [[ ! -d "${WORK}/llvm/tools/${tool}" ]]; then
|
||||
echo "Downloading ${tool}..."
|
||||
git clone -q \
|
||||
--branch "${LLVM_BRANCH}" \
|
||||
--depth 1 \
|
||||
"https://git.llvm.org/git/${tool}.git" "${WORK}/llvm/tools/${tool}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ! -d "${WORK}/llvm/tools/clang/tools/extra" ]]; then
|
||||
echo "Downloading clang-tools-extra..."
|
||||
git clone -q \
|
||||
--branch "${LLVM_BRANCH}" \
|
||||
--depth 1 \
|
||||
"https://git.llvm.org/git/clang-tools-extra.git" "${WORK}/llvm/tools/clang/tools/extra"
|
||||
fi
|
||||
|
||||
for proj in ${PROJECTS}; do
|
||||
if [[ ! -d "${WORK}/llvm/projects/${proj}" ]]; then
|
||||
echo "Downloading ${proj}..."
|
||||
git clone -q \
|
||||
--branch "${LLVM_BRANCH}" \
|
||||
--depth 1 \
|
||||
"https://git.llvm.org/git/${proj}.git" "${WORK}/llvm/projects/${proj}"
|
||||
fi
|
||||
done
|
||||
|
||||
for proj in ${RUNTIMES}; do
|
||||
if [[ ! -d "${WORK}/llvm/runtimes/${proj}" ]]; then
|
||||
echo "Downloading ${proj}..."
|
||||
git clone -q \
|
||||
--branch "${LLVM_BRANCH}" \
|
||||
--depth 1 \
|
||||
"https://git.llvm.org/git/${proj}.git" "${WORK}/llvm/runtime/${proj}"
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir -p "${WORK}/build/llvm"
|
||||
pushd "${WORK}/build/llvm"
|
||||
|
||||
echo "Configuring LLVM..."
|
||||
|
||||
cmake -G Ninja \
|
||||
-DCLANG_DEFAULT_RTLIB=compiler-rt \
|
||||
-DCLANG_DEFAULT_STD_C=c11 \
|
||||
-DCLANG_DEFAULT_STD_CXX=cxx14 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER="clang" \
|
||||
-DCMAKE_CXX_COMPILER="clang++" \
|
||||
-DCMAKE_CXX_FLAGS="-Wno-unused-parameter -D_LIBCPP_HAS_NO_ALIGNED_ALLOCATION -D_LIBUNWIND_IS_BAREMETAL=1 -U_LIBUNWIND_SUPPORT_DWARF_UNWIND" \
|
||||
-DCMAKE_INSTALL_PREFIX="${SYSROOT}" \
|
||||
-DCMAKE_MAKE_PROGRAM=`which ninja` \
|
||||
-DDEFAULT_SYSROOT="${SYSROOT}" \
|
||||
-DLIBCXX_CXX_ABI=libcxxabi \
|
||||
-DLIBCXX_CXX_ABI_INCLUDE_PATHS="${WORK}/llvm/projects/libcxxabi/include" \
|
||||
-DLIBCXX_CXX_ABI_LIBRARY_PATH=lib \
|
||||
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \
|
||||
-DLIBCXX_ENABLE_NEW_DELETE_DEFINITIONS=ON \
|
||||
-DLIBCXX_ENABLE_SHARED=OFF \
|
||||
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
|
||||
-DLIBCXX_ENABLE_THREADS=OFF \
|
||||
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
|
||||
-DLIBCXX_USE_COMPILER_RT=ON \
|
||||
-DLIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS=OFF \
|
||||
-DLIBCXXABI_ENABLE_SHARED=OFF \
|
||||
-DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
|
||||
-DLIBCXXABI_ENABLE_THREADS=OFF \
|
||||
-DLIBCXXABI_LIBCXX_PATH="${WORK}/llvm/projects/libcxx" \
|
||||
-DLIBCXXABI_USE_COMPILER_RT=ON \
|
||||
-DLIBCXXABI_USE_LLVM_UNWINDER=ON \
|
||||
-DLIBUNWIND_ENABLE_SHARED=OFF \
|
||||
-DLIBUNWIND_ENABLE_THREADS=OFF \
|
||||
-DLIBUNWIND_USE_COMPILER_RT=ON \
|
||||
-DLLVM_CONFIG_PATH="${SYSROOT}/bin/llvm-config" \
|
||||
-DLLVM_DEFAULT_TARGET_TRIPLE="x86_64-unknown-elf" \
|
||||
-DLLVM_ENABLE_LIBCXX=ON \
|
||||
-DLLVM_ENABLE_LLD=ON \
|
||||
-DLLVM_ENABLE_PIC=OFF \
|
||||
-DLLVM_ENABLE_THREADS=OFF \
|
||||
-DLLVM_INSTALL_BINUTILS_SYMLINKS=ON \
|
||||
-DLLVM_TARGETS_TO_BUILD="X86" \
|
||||
${WORK}/llvm > cmake_configure.log
|
||||
|
||||
# -DCMAKE_ASM_COMPILER=nasm \
|
||||
# -DCMAKE_LINKER="${SYSROOT}/bin/ld.lld" \
|
||||
# -DCOMPILER_RT_ENABLE_LLD=ON \
|
||||
# -DLIBCXX_ENABLE_LLD=ON \
|
||||
# -DLIBCXX_ENABLE_STATIC_UNWINDER=ON \
|
||||
# -DLIBCXXABI_ENABLE_LLD=ON \
|
||||
# -DLIBUNWIND_ENABLE_LLD=ON \
|
||||
# -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind;compiler-rt" \
|
||||
# -DCOMPILER_RT_BAREMETAL_BUILD=ON \
|
||||
# -DLIBCXXABI_BAREMETAL=ON \
|
||||
|
||||
echo "Building LLVM..."
|
||||
ninja && ninja install
|
||||
ninja cxx cxxabi compiler-rt
|
||||
ninja install-compiler-rt install-cxx install-cxxabi
|
||||
popd
|
||||
|
||||
|
||||
cp "${README}" "${SYSROOT}/README.md"
|
||||
@@ -1,83 +0,0 @@
|
||||
class NotFound(Exception): pass
|
||||
|
||||
class Context:
|
||||
def __init__(self, path, verbose=False):
|
||||
if isinstance(path, str):
|
||||
self.__paths = [path]
|
||||
else:
|
||||
self.__paths = path
|
||||
|
||||
self.__closed = set()
|
||||
self.__verbose = verbose
|
||||
|
||||
self.__deps = {}
|
||||
|
||||
self.objects = dict()
|
||||
self.interfaces = dict()
|
||||
|
||||
verbose = property(lambda self: self.__verbose)
|
||||
|
||||
def find(self, filename):
|
||||
from os.path import exists, isabs, join
|
||||
|
||||
if exists(filename) or isabs(filename):
|
||||
return filename
|
||||
|
||||
for path in self.__paths:
|
||||
full = join(path, filename)
|
||||
if exists(full):
|
||||
return full
|
||||
|
||||
raise NotFound(filename)
|
||||
|
||||
def parse(self, filename):
|
||||
pending = set()
|
||||
pending.add(filename)
|
||||
|
||||
from .parser import LarkError
|
||||
from .parser import Lark_StandAlone as Parser
|
||||
from .transformer import DefTransformer
|
||||
|
||||
objects = {}
|
||||
interfaces = {}
|
||||
|
||||
while pending:
|
||||
name = pending.pop()
|
||||
self.__closed.add(name)
|
||||
|
||||
path = self.find(name)
|
||||
|
||||
parser = Parser(transformer=DefTransformer(name))
|
||||
|
||||
try:
|
||||
imps, objs, ints = parser.parse(open(path, "r").read())
|
||||
except LarkError as e:
|
||||
import sys
|
||||
import textwrap
|
||||
print(f"\nError parsing {name}:", file=sys.stderr)
|
||||
print(textwrap.indent(str(e), " "), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
objects.update(objs)
|
||||
interfaces.update(ints)
|
||||
|
||||
self.__deps[name] = imps
|
||||
|
||||
pending.update(imps.difference(self.__closed))
|
||||
|
||||
from .types import ObjectRef
|
||||
ObjectRef.connect(objects)
|
||||
|
||||
for obj in objects.values():
|
||||
for method in obj.methods:
|
||||
caps = method.options.get("cap", list())
|
||||
for cap in caps:
|
||||
if not cap in obj.caps:
|
||||
from .errors import UnknownCapError
|
||||
raise UnknownCapError(f"Unknown capability {cap} on {obj.name}::{method.name}")
|
||||
|
||||
self.objects.update(objects)
|
||||
self.interfaces.update(interfaces)
|
||||
|
||||
def deps(self):
|
||||
return {self.find(k): tuple(map(self.find, v)) for k, v in self.__deps.items()}
|
||||
@@ -1,3 +0,0 @@
|
||||
class InvalidType(Exception): pass
|
||||
class UnknownTypeError(Exception): pass
|
||||
class UnknownCapError(Exception): pass
|
||||
File diff suppressed because one or more lines are too long
@@ -1,23 +0,0 @@
|
||||
%macro SYSCALL 2
|
||||
global __syscall_%1
|
||||
__syscall_%1:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
; args should already be in rdi, etc, but rcx will
|
||||
; get stomped, so stash it in r10, which isn't a
|
||||
; callee-saved register, but also isn't used in the
|
||||
; function call ABI.
|
||||
mov r10, rcx
|
||||
|
||||
mov rax, %2
|
||||
syscall
|
||||
; result is now already in rax, so just return
|
||||
|
||||
pop rbp
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
{% for id, scope, method in interface.methods %}
|
||||
SYSCALL {% if scope %}{{ scope.name }}_{% endif %}{{ method.name }} {{ id }}
|
||||
{% endfor %}
|
||||
@@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
/// \file {{filename}}
|
||||
{% if object.super %}
|
||||
|
||||
#include <j6/{{ object.super.name }}.hh>
|
||||
{% endif %}
|
||||
|
||||
namespace j6 {
|
||||
|
||||
{% if object.desc %}
|
||||
{{ object.desc|indent('/// ', first=True) }}
|
||||
{% endif %}
|
||||
class {{ object.name }}
|
||||
{% if object.super %} : public {{ object.super.name }}
|
||||
{% endif %}
|
||||
{
|
||||
public:
|
||||
{% macro argument(type, name, first, options=False) -%}
|
||||
{%- for ctype, suffix in type.c_names(options) -%}
|
||||
{%- if not first or not loop.first %}, {% endif %}{{ ctype }} {{ name }}{{ suffix }}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{% for method in object.methods %}
|
||||
{% if method.desc %} /// {{ method.desc|indent(' /// ') }}{% endif %}
|
||||
{% for param in method.params %}
|
||||
{% if param.desc %} /// \arg {{ "%-10s"|format(param.name) }} {{ param.desc }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{%+ if method.static %}static {% endif %}j6_status_t {{ method.name }} (
|
||||
{%- for param in method.params %}{{ argument(param.type, param.name, loop.first, options=param.options) }}{% endfor -%});
|
||||
|
||||
{% endfor %}
|
||||
~{{ object.name }}();
|
||||
|
||||
private:
|
||||
{{ object.name }}(j6_handle_t handle) : m_handle {handle} {}
|
||||
j6_handle_t m_handle;
|
||||
}
|
||||
|
||||
} // namespace j6
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <j6/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
{% macro argument(type, name, first, options=False) -%}
|
||||
{%- for ctype, suffix in type.c_names(options) -%}
|
||||
{%- if not first or not loop.first %}, {% endif %}{{ ctype }} {{ name }}{{ suffix }}
|
||||
{%- endfor -%}
|
||||
{%- endmacro %}
|
||||
|
||||
{% for id, scope, method in interface.methods %}
|
||||
j6_status_t __syscall_{% if scope %}{{ scope.name }}_{% endif %}{{ method.name }} (
|
||||
{%- if not method.static -%}{{ argument(scope.reftype, "self", True) }}{% endif -%}
|
||||
{%- set first = method.static -%}
|
||||
{%- for param in method.params %}{{ argument(param.type, param.name, first, options=param.options) }}{% set first = False %}{% endfor -%}
|
||||
);
|
||||
{% endfor %}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
from .parser import Transformer, v_args
|
||||
|
||||
def get_opts(args):
|
||||
from .types import Caps, CName, Description, Options, Type, UID
|
||||
|
||||
kinds = {
|
||||
Description: "desc",
|
||||
Options: "opts",
|
||||
CName: "cname",
|
||||
Caps: "caps",
|
||||
UID: "uid",
|
||||
Type: "typename",
|
||||
}
|
||||
|
||||
result = dict()
|
||||
outargs = []
|
||||
for a in args:
|
||||
for kind, name in kinds.items():
|
||||
if isinstance(a, kind):
|
||||
result[name] = a
|
||||
break
|
||||
else:
|
||||
outargs.append(a)
|
||||
|
||||
return result, outargs
|
||||
|
||||
class DefTransformer(Transformer):
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
|
||||
def start(self, args):
|
||||
from .types import Import, Interface, Object
|
||||
|
||||
imports = set()
|
||||
objects = dict()
|
||||
interfaces = dict()
|
||||
|
||||
for o in args:
|
||||
if isinstance(o, Object):
|
||||
objects[o.name] = o
|
||||
|
||||
elif isinstance(o, Interface):
|
||||
interfaces[o.name] = o
|
||||
|
||||
elif isinstance(o, Import):
|
||||
imports.add(o)
|
||||
|
||||
return imports, objects, interfaces
|
||||
|
||||
@v_args(inline=True)
|
||||
def import_statement(self, path):
|
||||
from .types import Import
|
||||
return Import(path)
|
||||
|
||||
def object(self, args):
|
||||
from .types import Object
|
||||
specials, args = get_opts(args)
|
||||
name, args = args[0], args[1:]
|
||||
return Object(name, children=args, **specials)
|
||||
|
||||
def interface(self, args):
|
||||
from .types import Interface
|
||||
specials, args = get_opts(args)
|
||||
name, args = args[0], args[1:]
|
||||
return Interface(name, children=args, **specials)
|
||||
|
||||
def method(self, args):
|
||||
from .types import Method
|
||||
specials, args = get_opts(args)
|
||||
name, args = args[0], args[1:]
|
||||
return Method(name, children=args, **specials)
|
||||
|
||||
def function(self, args):
|
||||
from .types import Function
|
||||
specials, args = get_opts(args)
|
||||
name, args = args[0], args[1:]
|
||||
return Function(name, children=args, **specials)
|
||||
|
||||
def param(self, args):
|
||||
from .types import Param
|
||||
specials, args = get_opts(args)
|
||||
name = args[0]
|
||||
return Param(name, **specials)
|
||||
|
||||
@v_args(inline=True)
|
||||
def expose(self, s):
|
||||
from .types import Expose
|
||||
return Expose(s)
|
||||
|
||||
@v_args(inline=True)
|
||||
def uid(self, s):
|
||||
return s
|
||||
|
||||
@v_args(inline=True)
|
||||
def cname(self, s):
|
||||
from .types import CName
|
||||
return CName(s)
|
||||
|
||||
@v_args(inline=True)
|
||||
def name(self, s):
|
||||
return s
|
||||
|
||||
@v_args(inline=True)
|
||||
def type(self, s):
|
||||
return s
|
||||
|
||||
@v_args(inline=True)
|
||||
def super(self, s):
|
||||
from .types import ObjectRef
|
||||
return ObjectRef(s, self.filename)
|
||||
|
||||
def options(self, args):
|
||||
from .types import Options
|
||||
return Options([str(s) for s in args])
|
||||
|
||||
def capabilities(self, args):
|
||||
from .types import Caps
|
||||
return Caps([str(s) for s in args])
|
||||
|
||||
def description(self, s):
|
||||
from .types import Description
|
||||
return Description("\n".join(s))
|
||||
|
||||
@v_args(inline=True)
|
||||
def object_name(self, n):
|
||||
from .types import ObjectRef
|
||||
return ObjectRef(n, self.filename)
|
||||
|
||||
def PRIMITIVE(self, s):
|
||||
from .types import get_primitive
|
||||
return get_primitive(s)
|
||||
|
||||
def UID(self, s):
|
||||
from .types import UID
|
||||
return UID(int(s, base=16))
|
||||
|
||||
def INT_TYPE(self, s):
|
||||
return s
|
||||
|
||||
def NUMBER(self, s):
|
||||
if s.startswith("0x"):
|
||||
return int(s,16)
|
||||
return int(s)
|
||||
|
||||
def COMMENT(self, s):
|
||||
return s[2:].strip()
|
||||
|
||||
def OPTION(self, s):
|
||||
return str(s)
|
||||
|
||||
def IDENTIFIER(self, s):
|
||||
return str(s)
|
||||
|
||||
def PATH(self, s):
|
||||
return str(s[1:-1])
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
def _indent(x):
|
||||
from textwrap import indent
|
||||
return indent(str(x), ' ')
|
||||
|
||||
class CName(str): pass
|
||||
class Description(str): pass
|
||||
class Import(str): pass
|
||||
class Caps(list): pass
|
||||
|
||||
class Options(dict):
|
||||
def __init__(self, opts = tuple()):
|
||||
for opt in opts:
|
||||
parts = opt.split(":", 1)
|
||||
self[parts[0]] = self.get(parts[0], []) + ["".join(parts[1:])]
|
||||
|
||||
class UID(int):
|
||||
def __str__(self):
|
||||
return f"{self:016x}"
|
||||
|
||||
from .object import Object
|
||||
from .interface import Interface, Expose
|
||||
from .function import Function, Method, Param
|
||||
|
||||
from .type import Type
|
||||
from .primitive import get_primitive
|
||||
from .objref import ObjectRef
|
||||
@@ -1,68 +0,0 @@
|
||||
from . import _indent
|
||||
from . import Options
|
||||
|
||||
def _hasopt(opt):
|
||||
def test(self):
|
||||
return opt in self.options
|
||||
return test
|
||||
|
||||
class Function:
|
||||
typename = "function"
|
||||
|
||||
def __init__(self, name, opts=Options(), desc="", children=tuple()):
|
||||
self.name = name
|
||||
self.options = opts
|
||||
self.desc = desc
|
||||
self.params = [c for c in children if isinstance(c, Param)]
|
||||
self.id = -1
|
||||
|
||||
def __str__(self):
|
||||
parts = ["{} {}".format(self.typename, self.name)]
|
||||
if self.desc:
|
||||
parts.append(_indent(self.desc))
|
||||
if self.options:
|
||||
parts.append(f" Options: {self.options}")
|
||||
parts.extend(map(_indent, self.params))
|
||||
return "\n".join(parts)
|
||||
|
||||
static = property(lambda x: True)
|
||||
constructor = property(lambda x: False)
|
||||
|
||||
|
||||
class Method(Function):
|
||||
typename = "method"
|
||||
|
||||
static = property(_hasopt("static"))
|
||||
constructor = property(_hasopt("constructor"))
|
||||
|
||||
|
||||
class Param:
|
||||
def __init__(self, name, typename, opts=Options(), desc=""):
|
||||
self.name = name
|
||||
self.type = typename
|
||||
self.options = opts
|
||||
self.desc = desc
|
||||
|
||||
self.caps = set()
|
||||
for key, values in opts.items():
|
||||
if key == "cap":
|
||||
self.caps.update(values)
|
||||
|
||||
def __str__(self):
|
||||
return "param {} {} {} {}".format(
|
||||
self.name, repr(self.type), self.options, self.desc or "")
|
||||
|
||||
@property
|
||||
def outparam(self):
|
||||
return "out" in self.options or "inout" in self.options
|
||||
|
||||
@property
|
||||
def refparam(self):
|
||||
return self.type.reference or self.outparam
|
||||
|
||||
@property
|
||||
def optional(self):
|
||||
if "optional" in self.options: return "optional"
|
||||
elif "zero_ok" in self.options: return "zero_ok"
|
||||
else: return "required"
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
from . import _indent
|
||||
from . import Options
|
||||
|
||||
class Expose(object):
|
||||
def __init__(self, type):
|
||||
self.type = type
|
||||
|
||||
def __repr__(self):
|
||||
return f'expose {repr(self.type)}'
|
||||
|
||||
class Interface:
|
||||
def __init__(self, name, uid, opts=Options(), desc="", children=tuple()):
|
||||
from .function import Function
|
||||
|
||||
self.name = name
|
||||
self.uid = uid
|
||||
self.options = opts
|
||||
self.desc = desc
|
||||
|
||||
self.functions = [c for c in children if isinstance(c, Function)]
|
||||
self.__exposes = [e.type for e in children if isinstance(e, Expose)]
|
||||
|
||||
def __str__(self):
|
||||
parts = [f"interface {self.name}: {self.uid}"]
|
||||
if self.desc:
|
||||
parts.append(_indent(self.desc))
|
||||
if self.options:
|
||||
parts.append(f" Options: {self.options}")
|
||||
parts.extend(map(_indent, self.exposes))
|
||||
parts.extend(map(_indent, self.functions))
|
||||
return "\n".join(parts)
|
||||
|
||||
@property
|
||||
def methods(self):
|
||||
mm = [(i, None, self.functions[i]) for i in range(len(self.functions))]
|
||||
|
||||
base = len(mm)
|
||||
for o in self.exposes:
|
||||
mm.extend([(base + i, o, o.methods[i]) for i in range(len(o.methods))])
|
||||
base += len(o.methods)
|
||||
|
||||
return mm
|
||||
|
||||
@property
|
||||
def exposes(self):
|
||||
return [ref.object for ref in self.__exposes]
|
||||
@@ -1,33 +0,0 @@
|
||||
from . import _indent
|
||||
from . import Caps, Options
|
||||
|
||||
class Object:
|
||||
def __init__(self, name, uid, typename=None, opts=Options(), caps=Caps(), desc="", children=tuple(), cname=None):
|
||||
self.name = name
|
||||
self.uid = uid
|
||||
self.options = opts
|
||||
self.desc = desc
|
||||
self.methods = children
|
||||
self.cname = cname or name
|
||||
self.caps = caps
|
||||
|
||||
self.__super = typename
|
||||
|
||||
from . import ObjectRef
|
||||
self.__ref = ObjectRef(name)
|
||||
|
||||
def __str__(self):
|
||||
parts = [f"object {self.name}: {self.uid}"]
|
||||
if self.desc:
|
||||
parts.append(_indent(self.desc))
|
||||
if self.options:
|
||||
parts.append(f" Options: {self.options}")
|
||||
parts.extend(map(_indent, self.methods))
|
||||
return "\n".join(parts)
|
||||
|
||||
reftype = property(lambda self: self.__ref)
|
||||
|
||||
@property
|
||||
def super(self):
|
||||
if self.__super is not None:
|
||||
return self.__super.object
|
||||
@@ -1,49 +0,0 @@
|
||||
from .type import Type
|
||||
|
||||
class ObjectRef(Type):
|
||||
all_refs = {}
|
||||
|
||||
def __init__(self, name, filename=None):
|
||||
super().__init__(name)
|
||||
self.__c_type = "j6_handle_t"
|
||||
self.__object = None
|
||||
ObjectRef.all_refs[self] = filename
|
||||
|
||||
def __repr__(self):
|
||||
return f'ObjectRef({self.name})'
|
||||
|
||||
object = property(lambda self: self.__object)
|
||||
|
||||
def c_names(self, options):
|
||||
one = self.__c_type
|
||||
out = bool({"out", "inout"}.intersection(options))
|
||||
|
||||
if "list" in options:
|
||||
two = "size_t"
|
||||
one = f"{one} *"
|
||||
|
||||
if out:
|
||||
two += " *"
|
||||
return ((one, ""), (two, "_count"))
|
||||
|
||||
else:
|
||||
if out:
|
||||
one += " *"
|
||||
return ((one, ""),)
|
||||
|
||||
def cxx_names(self, options):
|
||||
if not self.needs_object(options):
|
||||
return self.c_names(options)
|
||||
return ((f"obj::{self.name} *", ""),)
|
||||
|
||||
def needs_object(self, options):
|
||||
return not bool({"out", "inout", "list", "handle"}.intersection(options))
|
||||
|
||||
|
||||
@classmethod
|
||||
def connect(cls, objects):
|
||||
for ref, filename in cls.all_refs.items():
|
||||
ref.__object = objects.get(ref.name)
|
||||
if ref.__object is None:
|
||||
from ..errors import UnknownTypeError
|
||||
raise UnknownTypeError(ref.name, filename)
|
||||
@@ -1,72 +0,0 @@
|
||||
from .type import Type
|
||||
|
||||
class Primitive(Type):
|
||||
def __init__(self, name, c_type):
|
||||
super().__init__(name)
|
||||
self.c_type = c_type
|
||||
|
||||
def __repr__(self):
|
||||
return f'Primitive({self.name})'
|
||||
|
||||
def c_names(self, options=dict()):
|
||||
one = self.c_type
|
||||
if "out" in options or "inout" in options:
|
||||
one += " *"
|
||||
|
||||
return ((one, ""),)
|
||||
|
||||
def cxx_names(self, options):
|
||||
return self.c_names(options)
|
||||
|
||||
class PrimitiveRef(Primitive):
|
||||
def __init__(self, name, c_type, counted=False):
|
||||
super().__init__(name, c_type)
|
||||
self.__counted = counted
|
||||
|
||||
reference = property(lambda self: True)
|
||||
|
||||
def c_names(self, options=dict()):
|
||||
one = f"{self.c_type} *"
|
||||
two = "size_t"
|
||||
|
||||
if "out" in options or "inout" in options:
|
||||
two += " *"
|
||||
else:
|
||||
one = "const " + one
|
||||
|
||||
if self.__counted:
|
||||
return ((one, ""), (two, "_len"))
|
||||
else:
|
||||
return ((one, ""),)
|
||||
|
||||
def cxx_names(self, options):
|
||||
return self.c_names(options)
|
||||
|
||||
_primitives = {
|
||||
"string": PrimitiveRef("string", "char"),
|
||||
"buffer": PrimitiveRef("buffer", "void", counted=True),
|
||||
|
||||
"int": Primitive("int", "int"),
|
||||
"uint": Primitive("uint", "unsigned"),
|
||||
"size": Primitive("size", "size_t"),
|
||||
"address": Primitive("address", "uintptr_t"),
|
||||
|
||||
"int8": Primitive("int8", "int8_t"),
|
||||
"uint8": Primitive("uint8", "uint8_t"),
|
||||
|
||||
"int16": Primitive("int16", "int16_t"),
|
||||
"uint16": Primitive("uint16", "uint16_t"),
|
||||
|
||||
"int32": Primitive("int32", "int32_t"),
|
||||
"uint32": Primitive("uint32", "uint32_t"),
|
||||
|
||||
"int64": Primitive("int64", "int64_t"),
|
||||
"uint64": Primitive("uint64", "uint64_t"),
|
||||
}
|
||||
|
||||
def get_primitive(name):
|
||||
p = _primitives.get(name)
|
||||
if not p:
|
||||
from ..errors import InvalidType
|
||||
raise InvalidType(name)
|
||||
return p
|
||||
@@ -1,15 +0,0 @@
|
||||
class Type:
|
||||
def __init__(self, name):
|
||||
self.__name = name
|
||||
|
||||
name = property(lambda self: self.__name)
|
||||
reference = property(lambda self: False)
|
||||
|
||||
def c_names(self, options):
|
||||
raise NotImplemented("Call to base Type.c_names")
|
||||
|
||||
def cxx_names(self, options):
|
||||
raise NotImplemented("Call to base Type.c_names")
|
||||
|
||||
def needs_object(self, options):
|
||||
return False
|
||||
@@ -1,75 +0,0 @@
|
||||
_MAGIC = (0x72, 0xb5, 0x4a, 0x86)
|
||||
_VERSION = 0
|
||||
|
||||
class PSF2:
|
||||
from collections import namedtuple
|
||||
Header = namedtuple("PSF2Header",
|
||||
["version", "offset", "flags", "count", "charsize", "height", "width"])
|
||||
|
||||
def __init__(self, filename, header, data):
|
||||
self.__filename = filename
|
||||
self.__header = header
|
||||
self.__data = data
|
||||
|
||||
data = property(lambda self: self.__data)
|
||||
header = property(lambda self: self.__header)
|
||||
count = property(lambda self: self.__header.count)
|
||||
charsize = property(lambda self: self.__header.charsize)
|
||||
dimension = property(lambda self: (self.__header.width, self.__header.height))
|
||||
filename = property(lambda self: self.__filename)
|
||||
|
||||
@classmethod
|
||||
def load(cls, filename):
|
||||
from os.path import basename
|
||||
from struct import unpack_from
|
||||
|
||||
data = open(filename, 'rb').read()
|
||||
|
||||
fmt = "BBBBIIIIIII"
|
||||
values = unpack_from(fmt, data)
|
||||
|
||||
if values[:len(_MAGIC)] != _MAGIC:
|
||||
raise Exception("Bad magic number in header")
|
||||
|
||||
header = PSF2.Header(*values[len(_MAGIC):])
|
||||
if header.version != _VERSION:
|
||||
raise Exception(f"Bad version {header.version} in header")
|
||||
|
||||
return cls(basename(filename), header, data)
|
||||
|
||||
class Glyph:
|
||||
__slots__ = ['index', 'data']
|
||||
def __init__(self, i, data):
|
||||
self.index = i
|
||||
self.data = data
|
||||
def __index__(self):
|
||||
return self.index
|
||||
def empty(self):
|
||||
return not bool([b for b in self.data if b != 0])
|
||||
def description(self):
|
||||
c = chr(self.index)
|
||||
if c.isprintable():
|
||||
return "Glyph {:02x}: '{}'".format(self.index, c)
|
||||
else:
|
||||
return "Glyph {:02x}".format(self.index)
|
||||
|
||||
def __getitem__(self, i):
|
||||
c = self.__header.charsize
|
||||
n = i * c + self.__header.offset
|
||||
return PSF2.Glyph(i, self.__data[n:n+c])
|
||||
|
||||
class __iter:
|
||||
__slots__ = ['font', 'n']
|
||||
def __init__(self, font):
|
||||
self.font = font
|
||||
self.n = 0
|
||||
def __next__(self):
|
||||
if self.n < self.font.count:
|
||||
glyph = self.font[self.n]
|
||||
self.n += 1
|
||||
return glyph
|
||||
else:
|
||||
raise StopIteration
|
||||
|
||||
def __iter__(self):
|
||||
return PSF2.__iter(self)
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
def hashid(s):
|
||||
from hashlib import shake_128 as sh
|
||||
return sh(s.encode('utf-8')).hexdigest(8)
|
||||
|
||||
import sys
|
||||
|
||||
for arg in sys.argv[1:]:
|
||||
id = hashid(arg)
|
||||
print(f"{arg}: {id}")
|
||||
@@ -1,56 +0,0 @@
|
||||
import cog
|
||||
|
||||
supported_architectures = {
|
||||
"amd64": "__amd64__",
|
||||
}
|
||||
|
||||
def arch_includes(header):
|
||||
prefix = "if"
|
||||
for arch, define in supported_architectures.items():
|
||||
cog.outl(f"#{prefix} defined({define})")
|
||||
cog.outl(f"#include <__j6libc/arch/{arch}/{header}>")
|
||||
prefix = "elif"
|
||||
cog.outl("#endif")
|
||||
|
||||
|
||||
int_widths = (8, 16, 32, 64)
|
||||
int_mods = ("fast", "least")
|
||||
|
||||
int_types = {
|
||||
# type: abbrev
|
||||
"char": "char",
|
||||
"short": "short",
|
||||
"int": "int",
|
||||
"long": "long",
|
||||
"long long": "llong",
|
||||
}
|
||||
|
||||
def definition(kind, name, val, width=24):
|
||||
cog.outl(f"{kind} {name:{width}} {val}")
|
||||
|
||||
|
||||
atomic_types = {
|
||||
"_Bool": "bool",
|
||||
"signed char": "schar",
|
||||
"char16_t": "char16_t",
|
||||
"char32_t": "char32_t",
|
||||
"wchar_t": "wchar_t",
|
||||
"wchar_t": "wchar_t",
|
||||
"size_t": "size_t",
|
||||
"ptrdiff_t": "ptrdiff_t",
|
||||
"intptr_t": "intptr_t",
|
||||
"uintptr_t": "uintptr_t",
|
||||
"intmax_t": "intmax_t",
|
||||
"uintmax_t": "uintmax_t",
|
||||
}
|
||||
|
||||
for name, abbrev in int_types.items():
|
||||
atomic_types.update({name: abbrev, f"unsigned {name}": f"u{abbrev}"})
|
||||
|
||||
for width in int_widths:
|
||||
atomic_types.update({t: t for t in (
|
||||
f"int_least{width}_t",
|
||||
f"uint_least{width}_t",
|
||||
f"int_fast{width}_t",
|
||||
f"uint_fast{width}_t")})
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
class Layout:
|
||||
from collections import namedtuple
|
||||
Region = namedtuple("Region", ("name", "start", "size", "shared"))
|
||||
|
||||
sizes = {'G': 1024 ** 3, 'T': 1024 ** 4}
|
||||
|
||||
@staticmethod
|
||||
def get_size(desc):
|
||||
size, mag = int(desc[:-1]), desc[-1]
|
||||
|
||||
try:
|
||||
mult = Layout.sizes[mag]
|
||||
except KeyError:
|
||||
raise RuntimeError(f"No magnitude named '{mag}'.")
|
||||
|
||||
return size * mult
|
||||
|
||||
def __init__(self, path):
|
||||
from yaml import safe_load
|
||||
|
||||
regions = []
|
||||
addr = 1 << 64
|
||||
|
||||
with open(path, 'r') as infile:
|
||||
data = safe_load(infile.read())
|
||||
for r in data:
|
||||
size = Layout.get_size(r["size"])
|
||||
addr -= size
|
||||
regions.append(Layout.Region(r["name"], addr, size,
|
||||
r.get("shared", False)))
|
||||
|
||||
self.regions = tuple(regions)
|
||||
34
scripts/parse_font.py
Executable file → Normal file
34
scripts/parse_font.py
Executable file → Normal file
@@ -1,6 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from fontpsf import PSF2
|
||||
MAGIC = (0x72, 0xb5, 0x4a, 0x86)
|
||||
|
||||
from collections import namedtuple
|
||||
PSF2 = namedtuple("PSF2", ["version", "offset", "flags", "count", "charsize", "height", "width"])
|
||||
|
||||
def read_header(data):
|
||||
from struct import unpack_from, calcsize
|
||||
|
||||
fmt = "BBBBIIIIIII"
|
||||
|
||||
values = unpack_from(fmt, data)
|
||||
if values[:len(MAGIC)] != MAGIC:
|
||||
raise Exception("Bad magic number in header")
|
||||
|
||||
return PSF2(*values[len(MAGIC):])
|
||||
|
||||
|
||||
def print_glyph(header, data):
|
||||
bw = (header.width + 7) // 8
|
||||
@@ -13,15 +28,16 @@ def print_glyph(header, data):
|
||||
|
||||
|
||||
def display_font(filename):
|
||||
font = PSF2.load(filename)
|
||||
print(font.header)
|
||||
data = open(filename, 'rb').read()
|
||||
|
||||
for glyph in font:
|
||||
if glyph.empty():
|
||||
print("{}: BLANK".format(glyph.description()))
|
||||
else:
|
||||
print("{}:".format(glyph.description()))
|
||||
print_glyph(font.header, glyph.data)
|
||||
header = read_header(data)
|
||||
print(header)
|
||||
|
||||
c = header.charsize
|
||||
for i in range(0, header.count):
|
||||
n = i * c + header.offset
|
||||
print("Glyph {}:".format(i))
|
||||
print_glyph(header, data[n:n+c])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
10
scripts/parse_syms.py
Executable file
10
scripts/parse_syms.py
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
def parse_elf(filename):
|
||||
import struct
|
||||
with open(filename, 'rb') as elf:
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
for arg in sys.argv[1:]:
|
||||
parse_elf(arg)
|
||||
14
scripts/readme_for_prebuilt_sysroots.md
Normal file
14
scripts/readme_for_prebuilt_sysroots.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# jsix OS sysroot
|
||||
|
||||
This is a pre-built sysroot for building the jsix operating system kernel,
|
||||
bootloader, and utilities. This package is provided as a convenience, and
|
||||
contains software from the following repositories.
|
||||
|
||||
## The LLVM toolchain
|
||||
|
||||
The LLVM sources as downloaded via git from [llvm.org][llvm] under the terms of
|
||||
the [Apache License v2.0][apache2], modified [as described here][llvmlic].
|
||||
|
||||
[llvm]: https://llvm.org
|
||||
[apache2]: https://www.apache.org/licenses/LICENSE-2.0
|
||||
[llvmlic]: https://llvm.org/docs/DeveloperPolicy.html#new-llvm-project-license-framework
|
||||
@@ -1,17 +0,0 @@
|
||||
class Sysconf:
|
||||
from collections import namedtuple
|
||||
Var = namedtuple("Var", ("name", "section", "type"))
|
||||
|
||||
def __init__(self, path):
|
||||
from yaml import safe_load
|
||||
|
||||
sys_vars = []
|
||||
|
||||
with open(path, 'r') as infile:
|
||||
data = safe_load(infile.read())
|
||||
self.address = data["address"]
|
||||
|
||||
for v in data["vars"]:
|
||||
sys_vars.append(Sysconf.Var(v["name"], v["section"], v["type"]))
|
||||
|
||||
self.vars = tuple(sys_vars)
|
||||
208
scripts/templates/build.ninja.j2
Normal file
208
scripts/templates/build.ninja.j2
Normal file
@@ -0,0 +1,208 @@
|
||||
ninja_required_version = 1.3
|
||||
builddir = {{ buildroot }}
|
||||
srcroot = {{ srcroot }}
|
||||
modulefile = {{ modulefile }}
|
||||
|
||||
{%- for var, value in vars %}
|
||||
{{ var }} = {{ value }}
|
||||
{%- endfor %}
|
||||
|
||||
warnflags = $
|
||||
-Wformat=2 $
|
||||
-Winit-self $
|
||||
-Wfloat-equal $
|
||||
-Winline $
|
||||
-Wmissing-format-attribute $
|
||||
-Wmissing-include-dirs $
|
||||
-Wswitch $
|
||||
-Wundef $
|
||||
-Wdisabled-optimization $
|
||||
-Wpointer-arith $
|
||||
-Wno-attributes $
|
||||
-Wno-sign-compare $
|
||||
-Wno-multichar $
|
||||
-Wno-div-by-zero $
|
||||
-Wno-endif-labels $
|
||||
-Wno-pragmas $
|
||||
-Wno-format-extra-args $
|
||||
-Wno-unused-result $
|
||||
-Wno-deprecated-declarations $
|
||||
-Wno-unused-function $
|
||||
-Werror
|
||||
|
||||
ccflags = $
|
||||
-I${srcroot}/src/include $
|
||||
-I${srcroot}/src/include/x86_64 $
|
||||
-fcolor-diagnostics $
|
||||
-DVERSION_MAJOR={{ version_major }} $
|
||||
-DVERSION_MINOR={{ version_minor }} $
|
||||
-DVERSION_PATCH={{ version_patch }} $
|
||||
-DVERSION_GITSHA=0x0{{ version_sha }} $
|
||||
-DGIT_VERSION=\"{{ version }}\" $
|
||||
-DGIT_VERSION_WIDE=L\"{{ version }}\" $
|
||||
$warnflags
|
||||
|
||||
asflags = $
|
||||
-I${srcroot}/src/include $
|
||||
-DVERSION_MAJOR={{ version_major }} $
|
||||
-DVERSION_MINOR={{ version_minor }} $
|
||||
-DVERSION_PATCH={{ version_patch }} $
|
||||
-DVERSION_GITSHA=0x{{ version_sha }}
|
||||
|
||||
cflags = -std=c11
|
||||
cxxflags = -std=c++14
|
||||
libs =
|
||||
|
||||
rule c
|
||||
deps = gcc
|
||||
depfile = $out.d
|
||||
description = Compiling $name
|
||||
command = $cc -MMD -MF $out.d $ccflags $cflags -o $out -c $in
|
||||
|
||||
rule dump_c_defs
|
||||
description = Dumping C defines for $target
|
||||
command = echo "" | $cc $ccflags $cflags -dM -E - > $out
|
||||
|
||||
rule dump_c_run
|
||||
description = Dumping C arguments for $target
|
||||
command = $
|
||||
echo "#!/bin/bash" > $out; $
|
||||
echo '$cc $ccflags $cflags $$*' > $out; $
|
||||
chmod a+x $out
|
||||
|
||||
rule cpp
|
||||
deps = gcc
|
||||
depfile = $out.d
|
||||
description = Compiling $name
|
||||
command = $cxx -MMD -MF $out.d $cxxflags $ccflags -o $out -c $in
|
||||
|
||||
rule dump_cpp_defs
|
||||
description = Dumping C++ defines for $target
|
||||
command = echo "" | $cxx -x c++ $cxxflags $ccflags -dM -E - > $out
|
||||
|
||||
rule dump_cpp_run
|
||||
description = Dumping C++ arguments for $target
|
||||
command = $
|
||||
echo "#!/bin/bash" > $out; $
|
||||
echo '$cc $cxxflags $ccflags $$*' > $out; $
|
||||
chmod a+x $out
|
||||
|
||||
rule s
|
||||
deps = gcc
|
||||
depfile = $out.d
|
||||
description = Assembling $name
|
||||
command = $nasm -o $out -felf64 -MD $out.d $asflags $in
|
||||
|
||||
rule exe
|
||||
description = Linking $name
|
||||
command = $ld $ldflags -o $out $in $libs
|
||||
|
||||
rule lib
|
||||
description = Archiving $name
|
||||
command = $ar qcs $out $in
|
||||
|
||||
rule regen
|
||||
generator = true
|
||||
description = Regenrating build files
|
||||
command = $
|
||||
{{ generator }} $
|
||||
--file $modulefile $
|
||||
--dir $builddir $
|
||||
generate
|
||||
|
||||
rule cp
|
||||
description = Copying $name
|
||||
command = cp $in $out
|
||||
|
||||
rule dump
|
||||
description = Dumping decompiled $name
|
||||
command = objdump -DSC -M intel $in > $out
|
||||
|
||||
rule makerd
|
||||
description = Making init ramdisk
|
||||
command = $builddir/native/makerd $in $out
|
||||
|
||||
rule makeefi
|
||||
description = Converting $name
|
||||
command = objcopy $
|
||||
-j .text $
|
||||
-j .sdata $
|
||||
-j .data $
|
||||
-j .dynamic $
|
||||
-j .dynsym $
|
||||
-j .rel $
|
||||
-j .rela $
|
||||
-j .reloc $
|
||||
--target=efi-app-x86_64 $
|
||||
$in $out
|
||||
|
||||
rule makefat
|
||||
description = Creating $name
|
||||
command = $
|
||||
cp $srcroot/assets/diskbase.img $out; $
|
||||
mcopy -s -D o -i $out@@1M $builddir/fatroot/* ::/
|
||||
|
||||
rule strip
|
||||
description = Stripping $name
|
||||
command = $
|
||||
cp $in $out; $
|
||||
objcopy --only-keep-debug $out $out.debug; $
|
||||
strip -g $out; $
|
||||
objcopy --add-gnu-debuglink=$out.debug $out
|
||||
|
||||
{% for target in targets %}
|
||||
subninja {{ target }}/target.ninja
|
||||
{% endfor %}
|
||||
|
||||
build $
|
||||
{%- for buildfile in buildfiles %}
|
||||
{{ buildfile }} $
|
||||
{%- endfor %}
|
||||
: regen | $
|
||||
{%- for template in templates %}
|
||||
{{ template }} $
|
||||
{%- endfor %}
|
||||
$modulefile $
|
||||
{{ generator }}
|
||||
|
||||
build $builddir/ovmf_vars.fd : cp $srcroot/assets/ovmf/x64/ovmf_vars.fd
|
||||
name = ovmf_vars.fd
|
||||
|
||||
build $builddir/ovmf_vars_d.fd : cp $srcroot/assets/ovmf/x64/ovmf_vars_d.fd
|
||||
name = ovmf_vars_d.fd
|
||||
|
||||
build $builddir/jsix.elf | $builddir/jsix.elf.debug : strip $builddir/host/jsix.elf
|
||||
name = kernel
|
||||
|
||||
build $builddir/jsix.dump : dump $builddir/host/jsix.elf
|
||||
name = kernel
|
||||
|
||||
build $builddir/jsix.elf-gdb.py : cp ${srcroot}/assets/debugging/jsix.elf-gdb.py
|
||||
name = kernel debug python scripts
|
||||
|
||||
build $builddir/fatroot/jsix.elf : cp $builddir/jsix.elf
|
||||
name = kernel to FAT image
|
||||
|
||||
build $builddir/fatroot/efi/boot/bootx64.efi : cp $builddir/boot/boot.efi
|
||||
name = bootloader to FAT image
|
||||
|
||||
build $builddir/fatroot/initrd.img : makerd ${srcroot}/assets/initrd.toml | $
|
||||
${builddir}/host/libvdso.so $
|
||||
${builddir}/native/makerd $
|
||||
${builddir}/user/nulldrv
|
||||
|
||||
build $builddir/jsix.img : makefat | $
|
||||
$builddir/fatroot/initrd.img $
|
||||
$builddir/fatroot/jsix.elf $
|
||||
$builddir/fatroot/efi/boot/bootx64.efi
|
||||
name = jsix.img
|
||||
|
||||
default $
|
||||
$builddir/ovmf_vars.fd $
|
||||
$builddir/ovmf_vars_d.fd $
|
||||
$builddir/jsix.dump $
|
||||
$builddir/jsix.elf-gdb.py $
|
||||
$builddir/jsix.img
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
27
scripts/templates/exe.boot.j2
Normal file
27
scripts/templates/exe.boot.j2
Normal file
@@ -0,0 +1,27 @@
|
||||
{% extends "exe.default.j2" %}
|
||||
{% block variables %}
|
||||
{{ super() }}
|
||||
|
||||
ccflags = $ccflags $
|
||||
-DKERNEL_FILENAME=L\"jsix.elf\" $
|
||||
-DGNU_EFI_USE_MS_ABI $
|
||||
-DHAVE_USE_MS_ABI $
|
||||
-DEFI_DEBUG=0 $
|
||||
-DEFI_DEBUG_CLEAR_MEMORY=0 $
|
||||
-DBOOTLOADER_DEBUG
|
||||
|
||||
ldflags = $ldflags $
|
||||
-T ${srcroot}/src/arch/x86_64/boot.ld $
|
||||
-shared
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block extra %}
|
||||
|
||||
build $builddir/boot.efi : makeefi ${builddir}/{{ module.output }}
|
||||
name = boot.efi
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
8
scripts/templates/exe.default.j2
Normal file
8
scripts/templates/exe.default.j2
Normal file
@@ -0,0 +1,8 @@
|
||||
{% extends "module.base.j2" %}
|
||||
{% block variables %}
|
||||
{{ super() }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
12
scripts/templates/exe.kernel.j2
Normal file
12
scripts/templates/exe.kernel.j2
Normal file
@@ -0,0 +1,12 @@
|
||||
{% extends "exe.default.j2" %}
|
||||
{% block variables %}
|
||||
{{ super() }}
|
||||
|
||||
asflags = $asflags -I${srcroot}/src/kernel/
|
||||
libs = $libs
|
||||
ldflags = $ldflags -T ${srcroot}/src/arch/x86_64/kernel.ld
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
10
scripts/templates/exe.makerd.j2
Normal file
10
scripts/templates/exe.makerd.j2
Normal file
@@ -0,0 +1,10 @@
|
||||
{% extends "exe.default.j2" %}
|
||||
{% block variables %}
|
||||
{{ super() }}
|
||||
|
||||
ccflags = $ccflags -I${srcroot}/external/cpptoml
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
10
scripts/templates/exe.tests.j2
Normal file
10
scripts/templates/exe.tests.j2
Normal file
@@ -0,0 +1,10 @@
|
||||
{% extends "exe.default.j2" %}
|
||||
{% block variables %}
|
||||
{{ super() }}
|
||||
|
||||
ccflags = $ccflags -ggdb -I${srcroot}/external/catch
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
9
scripts/templates/exe.vdso.j2
Normal file
9
scripts/templates/exe.vdso.j2
Normal file
@@ -0,0 +1,9 @@
|
||||
{% extends "exe.default.j2" %}
|
||||
{% block variables %}
|
||||
{{ super() }}
|
||||
ccflags = $ccflags -fPIC -mcmodel=large
|
||||
ldflags = $ldflags -shared -znotext -T ${srcroot}/src/arch/x86_64/vdso.ld
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
4
scripts/templates/lib.default.j2
Normal file
4
scripts/templates/lib.default.j2
Normal file
@@ -0,0 +1,4 @@
|
||||
{% extends "module.base.j2" %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
45
scripts/templates/module.base.j2
Normal file
45
scripts/templates/module.base.j2
Normal file
@@ -0,0 +1,45 @@
|
||||
moddir = ${builddir}/{{ name }}.dir
|
||||
|
||||
{% block variables %}
|
||||
ccflags = $ccflags $
|
||||
{%- for dep in depmods %}
|
||||
{%- for inc in dep.includes %}
|
||||
-I${srcroot}/{{ inc }} $
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
{%- for inc in module.includes %}
|
||||
-I${srcroot}/{{ inc }} $
|
||||
{%- endfor %}
|
||||
{%- for define in module.defines %}
|
||||
-D{{ define }} $
|
||||
{%- endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% for source in module.source %}
|
||||
build ${moddir}/{{ source.output }} : {{ source.action }} ${srcroot}/{{ source.input }} || {{ buildfile }}
|
||||
name = {{ source.name }}
|
||||
{% endfor %}
|
||||
|
||||
build ${builddir}/{{ module.output }} : {{ module.kind }} $
|
||||
{%- for source in module.source %}
|
||||
${moddir}/{{ source.output }} $
|
||||
{%- endfor -%}
|
||||
{%- for dep in deplibs %}
|
||||
${builddir}/{{ dep.output }} $
|
||||
{%- endfor %}
|
||||
| $
|
||||
{%- for dep in depexes %}
|
||||
${builddir}/{{ dep.output }} $
|
||||
{%- endfor %}
|
||||
{{ buildfile }}
|
||||
name = {{ name }}
|
||||
|
||||
{% if module.default %}
|
||||
default ${builddir}/{{ module.output }}
|
||||
{% endif %}
|
||||
|
||||
{% block extra %}
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
40
scripts/templates/target.boot.j2
Normal file
40
scripts/templates/target.boot.j2
Normal file
@@ -0,0 +1,40 @@
|
||||
{% extends "target.default.j2" %}
|
||||
|
||||
{% block binaries %}
|
||||
cc = clang
|
||||
cxx = clang++
|
||||
ld = ld
|
||||
ar = ar
|
||||
nasm = nasm
|
||||
objcopy = objcopy
|
||||
{% endblock %}
|
||||
|
||||
{% block variables %}
|
||||
|
||||
ccflags = $ccflags $
|
||||
-ggdb $
|
||||
-nostdlib $
|
||||
-ffreestanding $
|
||||
-nodefaultlibs $
|
||||
-fno-builtin $
|
||||
-mno-sse $
|
||||
-fno-omit-frame-pointer $
|
||||
-mno-red-zone $
|
||||
-fshort-wchar $
|
||||
-D__ELF__ $
|
||||
-fPIC
|
||||
|
||||
cxxflags = $cxxflags $
|
||||
-fno-exceptions $
|
||||
-fno-rtti $
|
||||
|
||||
ldflags = $ldflags $
|
||||
-g $
|
||||
-nostdlib $
|
||||
-Bsymbolic $
|
||||
-nostartfiles
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
26
scripts/templates/target.default.j2
Normal file
26
scripts/templates/target.default.j2
Normal file
@@ -0,0 +1,26 @@
|
||||
builddir = $builddir/{{ target }}
|
||||
target = {{ target }}
|
||||
|
||||
{% block variables %}
|
||||
{% endblock %}
|
||||
|
||||
{% block binaries %}
|
||||
cc = clang
|
||||
cxx = clang++
|
||||
ld = ld
|
||||
ar = ar
|
||||
nasm = nasm
|
||||
objcopy = objcopy
|
||||
{% endblock %}
|
||||
|
||||
{% for module in modules %}
|
||||
subninja {{ module }}.ninja
|
||||
{% endfor %}
|
||||
|
||||
build ${builddir}/c.defs : dump_c_defs | {{ buildfile }}
|
||||
build ${builddir}/cpp.defs : dump_cpp_defs | {{ buildfile }}
|
||||
build ${builddir}/c.run : dump_c_run | {{ buildfile }}
|
||||
build ${builddir}/cpp.run : dump_cpp_run | {{ buildfile }}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
43
scripts/templates/target.host.j2
Normal file
43
scripts/templates/target.host.j2
Normal file
@@ -0,0 +1,43 @@
|
||||
{% extends "target.default.j2" %}
|
||||
|
||||
{% block binaries %}
|
||||
cc = ${srcroot}/sysroot/bin/clang
|
||||
cxx = ${srcroot}/sysroot/bin/clang++
|
||||
ld = ${srcroot}/sysroot/bin/ld.lld
|
||||
ar = ${srcroot}/sysroot/bin/ar
|
||||
nasm = nasm
|
||||
objcopy = ${srcroot}/sysroot/bin/objcopy
|
||||
{% endblock %}
|
||||
|
||||
{% block variables %}
|
||||
|
||||
ccflags = $ccflags $
|
||||
-nostdlib $
|
||||
-ffreestanding $
|
||||
-nodefaultlibs $
|
||||
-fno-builtin $
|
||||
-mno-sse $
|
||||
-fno-omit-frame-pointer $
|
||||
-mno-red-zone $
|
||||
-g $
|
||||
-mcmodel=large $
|
||||
-D__ELF__ $
|
||||
-D__JSIX__ $
|
||||
-isystem${srcroot}/sysroot/include $
|
||||
--sysroot="${srcroot}/sysroot"
|
||||
|
||||
cxxflags = $cxxflags $
|
||||
-fno-exceptions $
|
||||
-fno-rtti $
|
||||
-isystem${srcroot}/sysroot/include/c++/v1
|
||||
|
||||
ldflags = $ldflags $
|
||||
-g $
|
||||
-nostdlib $
|
||||
-Bsymbolic $
|
||||
-Bstatic
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
15
scripts/templates/target.native.j2
Normal file
15
scripts/templates/target.native.j2
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends "target.default.j2" %}
|
||||
|
||||
{% block binaries %}
|
||||
{{ super() }}
|
||||
ld = clang++
|
||||
{% endblock %}
|
||||
|
||||
{% block variables %}
|
||||
|
||||
ccflags = $ccflags -g -ggdb
|
||||
|
||||
{% endblock %}
|
||||
|
||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user