13 Commits

Author SHA1 Message Date
EnderIce2
ce3cf8162a chore: Update codebase
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 53s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 17m52s
Build OS / Analyze with CodeQL (cpp) (push) Has been skipped
Build OS / Build amd64 (push) Has been skipped
Build OS / Build i386 (push) Has been skipped
Build OS / Build aarch64 (push) Has been skipped
2024-11-28 04:47:30 +02:00
EnderIce2
640b902045 chore: Update vscode workspace files
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Has been cancelled
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Analyze with CodeQL (cpp) (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
2024-11-27 01:56:37 +02:00
EnderIce2
0dbdacb8df chore: General cleanup 2024-11-27 01:19:24 +02:00
EnderIce2
220238eff8 chore: Revert last change
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 13s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 9s
Build OS / Build GNU-EFI (push) Failing after 5s
Build OS / Analyze with CodeQL (cpp) (push) Has been skipped
Build OS / Build amd64 (push) Has been skipped
Build OS / Build i386 (push) Has been skipped
Build OS / Build aarch64 (push) Has been skipped
2024-11-26 04:13:34 +02:00
EnderIce2
360afdbc9c chore: Remove sudo & change "apt-get" to "apt"
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 18s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 10s
Build OS / Build GNU-EFI (push) Failing after 11s
Build OS / Analyze with CodeQL (cpp) (push) Has been skipped
Build OS / Build amd64 (push) Has been skipped
Build OS / Build i386 (push) Has been skipped
Build OS / Build aarch64 (push) Has been skipped
2024-11-26 04:03:57 +02:00
EnderIce2
f34a222bf1 chore: TODO: Fix workflows
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Waiting to run
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 20s
Build OS / Build GNU-EFI (push) Failing after 3s
Build OS / Analyze with CodeQL (cpp) (push) Has been skipped
Build OS / Build amd64 (push) Has been skipped
Build OS / Build i386 (push) Has been skipped
Build OS / Build aarch64 (push) Has been skipped
Awesome...
2024-11-26 03:46:43 +02:00
EnderIce2
1b1d3e68fd chore: Fix workflow error 2024-11-26 03:42:12 +02:00
EnderIce2
f11c00a4e3 chore: (Again) Fix workflow error
Too bad that there's no way of testing a workflow.
2024-11-26 03:37:31 +02:00
EnderIce2
ae07b07964 chore: Fix workflow error "this file was generated for autoconf 2.69" 2024-11-26 03:32:40 +02:00
EnderIce2
23853cbb15 chore: Add experimental docker build 2024-11-26 03:27:25 +02:00
EnderIce2
00a37325f6 chore: Fix build process 2024-11-26 03:27:08 +02:00
EnderIce2
ce4ebaf6c5 Remove submodule
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 1m14s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 1m2s
Build OS / Build GNU-EFI (push) Failing after 7s
Build OS / Analyze with CodeQL (cpp) (push) Has been skipped
Build OS / Build amd64 (push) Has been skipped
Build OS / Build i386 (push) Has been skipped
Build OS / Build aarch64 (push) Has been skipped
2024-11-20 05:49:33 +02:00
EnderIce2
5806c4feaf Update .gitmodules 2024-11-20 05:47:19 +02:00
61 changed files with 534 additions and 8224 deletions

34
.dockerignore Normal file
View File

@@ -0,0 +1,34 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/
**/.DS_Store
**/__pycache__
**/.venv
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

View File

@@ -9,7 +9,7 @@ on:
jobs: jobs:
deploydoc: deploydoc:
name: Deploy Documentation to GitHub Pages name: Deploy Documentation to GitHub Pages
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
@@ -17,7 +17,7 @@ jobs:
submodules: recursive submodules: recursive
- name: Install Doxygen - name: Install Doxygen
run: sudo apt-get install doxygen make -y run: sudo apt -y install doxygen make
- name: Generate Documentation - name: Generate Documentation
run: make doxygen run: make doxygen
@@ -32,7 +32,7 @@ jobs:
buildcompiler: buildcompiler:
name: Build Cross-Compiler & Toolchain name: Build Cross-Compiler & Toolchain
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
@@ -47,7 +47,7 @@ jobs:
- name: Update System - name: Update System
if: steps.cache-cross.outputs.cache-hit != 'true' if: steps.cache-cross.outputs.cache-hit != 'true'
run: sudo apt-get update run: sudo apt update
- name: Install GCC Dependencies - name: Install GCC Dependencies
if: steps.cache-cross.outputs.cache-hit != 'true' if: steps.cache-cross.outputs.cache-hit != 'true'
@@ -57,59 +57,24 @@ jobs:
if: steps.cache-cross.outputs.cache-hit != 'true' if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools __clone_all_no_qemu run: make --quiet -C tools __clone_all_no_qemu
- name: Compile Binutils amd64 - name: Compile Binutils
if: steps.cache-cross.outputs.cache-hit != 'true' if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools do_binutils_64 run: make --quiet -C tools do_binutils
- name: Compile Binutils i386 - name: Compile GCC
if: steps.cache-cross.outputs.cache-hit != 'true' if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools do_binutils_32 run: make --quiet -C tools do_gcc
- name: Compile GCC amd64
if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools do_gcc_64
- name: Compile GCC i386
if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools do_gcc_32
- name: Clean Up - name: Clean Up
if: steps.cache-cross.outputs.cache-hit != 'true' if: steps.cache-cross.outputs.cache-hit != 'true'
run: | run: |
cd tools cd tools
rm -rf binutils-gdb gcc build-binutils64 build-gcc64 build-binutils32 build-gcc32 rm -rf binutils-gdb gcc
compilegnuefi:
name: Build GNU-EFI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Cache gnu-efi Folder
id: cache-gnuefi
uses: actions/cache@v3
with:
path: Lynx/gnu-efi
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
- name: Update System
if: steps.cache-gnuefi.outputs.cache-hit != 'true'
run: sudo apt-get update
- name: Install MinGW compiler
if: steps.cache-gnuefi.outputs.cache-hit != 'true'
run: sudo apt-get install make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
- name: Get GNU-EFI source code and compile it
if: steps.cache-gnuefi.outputs.cache-hit != 'true'
run: make --quiet -C Lynx prepare
analyze: analyze:
name: Analyze with CodeQL name: Analyze with CodeQL
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: [buildcompiler, compilegnuefi] needs: [buildcompiler]
permissions: permissions:
actions: read actions: read
contents: read contents: read
@@ -133,12 +98,11 @@ jobs:
- name: Install Packages - name: Install Packages
run: | run: |
sudo apt-get update sudo apt update
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo -y sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo -y
make --quiet -C tools do_limine make --quiet -C tools do_limine
make --quiet -C Drivers prepare make --quiet -C Drivers prepare
make --quiet -C Userspace prepare make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare make --quiet -C Kernel prepare
- name: Cache cross - name: Cache cross
@@ -148,16 +112,8 @@ jobs:
path: tools/cross path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }} key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Cache gnuefi
id: cache-gnuefi
uses: actions/cache@v3
with:
path: Lynx/gnu-efi
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
- name: Build OS - name: Build OS
run: | run: |
make build_lynx
make build_userspace make build_userspace
make build_drivers make build_drivers
make build_kernel make build_kernel
@@ -168,8 +124,8 @@ jobs:
compile64: compile64:
name: Build amd64 name: Build amd64
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: [buildcompiler, compilegnuefi] needs: [buildcompiler]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
@@ -177,12 +133,11 @@ jobs:
- name: Update & Install Required Packages - name: Update & Install Required Packages
run: | run: |
sudo apt-get update sudo apt update
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine make --quiet -C tools do_limine
make --quiet -C Drivers prepare make --quiet -C Drivers prepare
make --quiet -C Userspace prepare make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare make --quiet -C Kernel prepare
- name: Cache cross Folder - name: Cache cross Folder
@@ -192,13 +147,6 @@ jobs:
path: tools/cross path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }} key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Cache gnu-efi Folder
id: cache-gnuefi
uses: actions/cache@v3
with:
path: Lynx/gnu-efi
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
- name: Configure Makefile.conf - name: Configure Makefile.conf
run: sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH run: sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
@@ -225,8 +173,8 @@ jobs:
compile32: compile32:
name: Build i386 name: Build i386
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: [buildcompiler, compilegnuefi] needs: [buildcompiler]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
@@ -234,12 +182,11 @@ jobs:
- name: Update & Install Required Packages - name: Update & Install Required Packages
run: | run: |
sudo apt-get update sudo apt update
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine make --quiet -C tools do_limine
make --quiet -C Drivers prepare make --quiet -C Drivers prepare
make --quiet -C Userspace prepare make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare make --quiet -C Kernel prepare
- name: Cache cross Folder - name: Cache cross Folder
@@ -249,13 +196,6 @@ jobs:
path: tools/cross path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }} key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Cache gnu-efi Folder
id: cache-gnuefi
uses: actions/cache@v3
with:
path: Lynx/gnu-efi
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
- name: Configure Makefile.conf - name: Configure Makefile.conf
run: sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./Makefile.conf && cat Makefile.conf | grep OSARCH run: sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
@@ -283,8 +223,8 @@ jobs:
compilearm64: compilearm64:
if: ${{ false }} # Disabled until we can get it to work if: ${{ false }} # Disabled until we can get it to work
name: Build aarch64 name: Build aarch64
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: [buildcompiler, compilegnuefi] needs: [buildcompiler]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
@@ -292,12 +232,11 @@ jobs:
- name: Update & Install Required Packages - name: Update & Install Required Packages
run: | run: |
sudo apt-get update sudo apt update
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine make --quiet -C tools do_limine
make --quiet -C Drivers prepare make --quiet -C Drivers prepare
make --quiet -C Userspace prepare make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare make --quiet -C Kernel prepare
- name: Cache cross Folder - name: Cache cross Folder
@@ -307,13 +246,6 @@ jobs:
path: tools/cross path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }} key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Cache gnu-efi Folder
id: cache-gnuefi
uses: actions/cache@v3
with:
path: Lynx/gnu-efi
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
- name: Configure Makefile.conf - name: Configure Makefile.conf
run: sed -i 's/.*OSARCH = .*/OSARCH = aarch64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH run: sed -i 's/.*OSARCH = .*/OSARCH = aarch64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH

4
.gitignore vendored
View File

@@ -11,9 +11,10 @@ tools/*
!tools/website !tools/website
!tools/Makefile !tools/Makefile
!tools/*.c !tools/*.c
!tools/*.patch
!tools/*.cpp !tools/*.cpp
!tools/*.cfg !tools/*.cfg
!tools/SSDT1.dat !tools/acpi
doxygen-doc doxygen-doc
initrd.tar initrd.tar
.dccache .dccache
@@ -28,3 +29,4 @@ initrd.tar
*.so *.so
*.o *.o
*.dmp *.dmp
*.pcap

View File

@@ -1,5 +1,5 @@
{ {
"C_Cpp.errorSquiggles": "Enabled", "C_Cpp.errorSquiggles": "enabled",
"C_Cpp.autocompleteAddParentheses": true, "C_Cpp.autocompleteAddParentheses": true,
"C_Cpp.codeAnalysis.clangTidy.enabled": true, "C_Cpp.codeAnalysis.clangTidy.enabled": true,
"C_Cpp.clang_format_style": "Visual Studio", "C_Cpp.clang_format_style": "Visual Studio",

43
Dockerfile Normal file
View File

@@ -0,0 +1,43 @@
FROM ubuntu:22.04 AS base
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /fennix
ADD . /fennix
RUN apt -y update
RUN apt -y install \
build-essential \
bison \
flex \
libgmp3-dev \
libmpc-dev \
libmpfr-dev \
texinfo \
libzstd-dev \
libisl-dev \
autoconf \
m4 \
automake \
gettext \
gperf \
dejagnu \
guile-3.0 \
guile-3.0-dev \
expect \
tcl \
autogen \
tex-common \
sphinx-common \
git \
ssh \
diffutils \
patch
RUN apt clean && rm -rf /var/lib/apt/lists
RUN make -C tools __clone_all_no_qemu
RUN make --quiet -C tools do_binutils
RUN make --quiet -C tools do_gcc
RUN cd tools && rm -rf binutils-gdb gcc
RUN make build

View File

@@ -864,7 +864,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = Kernel Lynx Userspace Drivers tools/doxymds/main.md INPUT = Kernel Userspace Drivers tools/doxymds/main.md
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View File

@@ -1,6 +1,6 @@
BSD 3-Clause License BSD 3-Clause License
Copyright (c) 2022, EnderIce2 Copyright (c) 2024, EnderIce2
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,11 +1 @@
# Drivers # Drivers
Drivers for [Fennix](https://github.com/Fennix-Project/Fennix).
---
Use `Fennix` repo to build the operating system.
```bash
git clone --recurse-submodules https://github.com/Fennix-Project/Fennix.git
```

View File

@@ -5,108 +5,7 @@
} }
], ],
"settings": { "settings": {
"debug.allowBreakpointsEverywhere": true, "terminal.integrated.cwd": "../",
"cSpell.words": [ "debug.allowBreakpointsEverywhere": true
"ABAR",
"ABSPOINTER",
"AHCI",
"BIST",
"Cardbus",
"CFIEN",
"cmdret",
"cmpb",
"driverinfo",
"ECTRL",
"EEPROM",
"Fennix",
"GETVERSION",
"HBAPRDT",
"IFCS",
"inportb",
"inportl",
"inportw",
"INTX",
"KAPI",
"LEDS",
"LPBK",
"LSTA",
"mminb",
"mminl",
"mminq",
"mminw",
"mmioin",
"mmioout",
"mmoutb",
"mmoutl",
"mmoutw",
"NABM",
"NABMB",
"NABMBOFF",
"outportb",
"outportl",
"outportw",
"PCIBAR",
"PCMOUT",
"PCNET",
"PCTRL",
"PMCF",
"PORTHB",
"PRDT",
"Prefetchable",
"RCTL",
"RCTRL",
"RDMTS",
"RDTR",
"rpci",
"RSRPD",
"RTCL",
"RTLC",
"RTLIB",
"RTLIL",
"RTLIW",
"RTLOB",
"RTLOL",
"RTLOW",
"RXDCTL",
"RXDESCHEAD",
"RXDESCHI",
"RXDESCLEN",
"RXDESCLO",
"RXDESCTAIL",
"Sata",
"SATAPI",
"SECRC",
"SEMB",
"SWXOFF",
"tclo",
"TCTL",
"TCTRL",
"TFES",
"TIPG",
"TSAD",
"TSTA",
"TXDESCHEAD",
"TXDESCHI",
"TXDESCLEN",
"TXDESCLO",
"TXDESCTAIL",
"TYPEMATIC",
"ubit",
"Virtio",
"Wmissing"
],
"files.associations": {
"*.su": "tsv",
"driver.h": "c",
"base.h": "c",
"types.h": "c",
"syscall.h": "c",
"aip.h": "c",
"input.h": "c",
"errno.h": "c",
"io.h": "c",
"rtl8139.hpp": "c",
"net.h": "c"
}
} }
} }

View File

@@ -5,513 +5,8 @@
} }
], ],
"settings": { "settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true, "debug.allowBreakpointsEverywhere": true,
"files.associations": {
"*.su": "tsv",
"thread": "cpp",
"bitset": "cpp",
"initializer_list": "cpp",
"semaphore": "cpp",
"memory": "cpp",
"limits": "cpp",
"climits": "cpp",
"iterator": "cpp",
"ranges": "cpp",
"cassert": "cpp",
"concepts": "cpp",
"cctype": "cpp",
"tuple": "cpp",
"streambuf": "cpp",
"system_error": "cpp",
"coroutine": "cpp",
"static_vector": "cpp",
"string_view": "cpp",
"compare": "cpp",
"limine.h": "c",
"types.h": "c",
"binfo.h": "c",
"liballoc_1_1.h": "c",
"cstring": "cpp",
"cargs.h": "c",
"memory.hpp": "c",
"convert.h": "c",
"limits.h": "c",
"assert.h": "c",
"cwalk.h": "c",
"md5.h": "c",
"stdint.h": "c",
"debug.h": "c",
"ubsan.h": "c",
"kernel.h": "c",
"filesystem.hpp": "c",
"vector.hpp": "c",
"string.hpp": "c",
"nc.hpp": "c",
"vector": "c",
"task.hpp": "c",
"recovery.hpp": "c",
"symbols.hpp": "c",
"cstddef": "cpp",
"atomic.hpp": "c",
"atomic": "cpp",
"syscalls.h": "c",
"cmath": "cpp",
"typeinfo": "c",
"exception": "cpp",
"errno.h": "c",
"float.h": "c",
"mutex": "cpp",
"type_trails": "cpp",
"utility": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"stdio.h": "c",
"string": "cpp",
"list": "cpp",
"stdexcept": "cpp",
"unistd.h": "c",
"unordered_map": "cpp",
"sched.h": "c",
"mman.h": "c",
"string.h": "c",
"macro.hpp": "c",
"stddef.h": "c",
"cfloat": "c",
"type_traits": "cpp",
"stdlib.h": "c",
"new": "cpp",
"ostream": "cpp",
"iostream": "cpp",
"istream": "cpp",
"ios": "cpp",
"locale": "cpp",
"unwind.h": "c",
"memory.h": "c",
"physical.hpp": "c",
"swap_pt.hpp": "c",
"brk.hpp": "c",
"bitmap.hpp": "c",
"lock.hpp": "c",
"virtual.hpp": "c",
"table.hpp": "c",
"vma.hpp": "c",
"abi.h": "c",
"kstack.hpp": "c",
"stack.hpp": "c",
"optional": "cpp"
},
"cSpell.words": [
"AABBCC",
"AAFF",
"AAFFAA",
"ABAR",
"ABIVERSION",
"ABSPOINTER",
"ACPI",
"ACPINVS",
"addralign",
"AEFF",
"AFAFAF",
"AHBA",
"AHCI",
"ALTLBA",
"APERF",
"apic",
"APICID",
"archaux",
"AROS",
"ARRAYSZ",
"auxv",
"BABABA",
"BADRAM",
"BGRT",
"bimi",
"binfo",
"biosdev",
"BIST",
"BITALG",
"BLOCKDEV",
"BLOCKDEVICE",
"BNDCFGS",
"bochs",
"bootanim",
"bootdev",
"Bootloader",
"brontobyte",
"CACACA",
"calloc",
"Cardbus",
"CCCCCCCPU",
"CHARDEV",
"CHARDEVICE",
"charsize",
"clac",
"CLOUDABI",
"CMCI",
"CMOS",
"cntvct",
"COMNULL",
"copydoc",
"cpudata",
"CPUID",
"crashdata",
"CSTAR",
"CTLS",
"cutlim",
"DADADA",
"daif",
"daifclr",
"daifset",
"DAPI",
"DBGP",
"DEBUGCTL",
"defragment",
"dfdesc",
"dialup",
"Didx",
"DLAB",
"Drivermemcpy",
"Drivermemset",
"Driversprintf",
"drvdir",
"DRVER",
"DSDT",
"DUID",
"dynstr",
"dynsym",
"EBDA",
"edid",
"EEPROM",
"EFER",
"Ehdr",
"ehsize",
"EISA",
"ELFABI",
"ELFCLASS",
"ELFDATA",
"ELFMAG",
"ELFOSABI",
"EMMINTRIN",
"endregion",
"Ensoniq",
"EVTSEL",
"EXECFN",
"exobyte",
"EXTD",
"FADT",
"FAFAFA",
"FAFAFAI",
"Fargc",
"Fargv",
"fcreat",
"fctprintf",
"Femto",
"FENIXOS",
"FENNIX",
"FFAA",
"FFAAAA",
"FFSMBIOS",
"FFXSR",
"filestatus",
"FMAPS",
"fonthdr",
"Framebuffer",
"FSGSBASE",
"fsmi",
"fxrstor",
"fxsave",
"Gamepad",
"Gameport",
"geopbyte",
"GETVERSION",
"GFNI",
"haddpd",
"headersize",
"HIPROC",
"HPET",
"hwaddress",
"ICRHI",
"ICRLO",
"IDIV",
"idtd",
"IFHLNK",
"infloop",
"inportb",
"inportl",
"inportw",
"INTFASTX",
"INTLEASTX",
"INTX",
"invlpg",
"ioapic",
"ioapicirq",
"IOCTLFS",
"IPCID",
"IRET",
"iretq",
"isdelim",
"ishld",
"ishst",
"itimerspec",
"itrfb",
"JMPREL",
"KAPI",
"KAPIPCI",
"kcalloc",
"kcon",
"kdentry",
"kdirent",
"kernelctl",
"kfree",
"klog",
"kmalloc",
"kproc",
"krealloc",
"kthrd",
"lapic",
"lfanew",
"LFLR",
"lgdt",
"liballoc",
"LIBLIST",
"lidt",
"limine",
"LMSLE",
"LOPROC",
"lsacpi",
"LSTAR",
"MADT",
"MADTIO",
"malloc",
"MCFG",
"memdbg",
"memmap",
"memsz",
"MEMTEST",
"mfence",
"MIDR",
"mminb",
"mminl",
"mminq",
"mminw",
"mmioin",
"mmioout",
"mmoutb",
"mmoutl",
"mmoutq",
"mmoutw",
"modbg",
"Modulememcpy",
"Modulememset",
"Modulesprintf",
"movaps",
"movddup",
"movdqa",
"movdqu",
"movntdq",
"movntdqa",
"movw",
"MPERF",
"MSRID",
"MTRR",
"MTRRCAP",
"multiboot",
"MWAIT",
"newfstatat",
"NIDENT",
"NOBITS",
"nullfd",
"nullptr",
"objptr",
"OEMID",
"Ofast",
"okstat",
"oldfd",
"OPENVOS",
"OPTMZ",
"OSABI",
"OSFXSR",
"OSXMMEXCPT",
"OSXSAVE",
"Outof",
"outportb",
"outportl",
"outportw",
"PAGESZ",
"palignr",
"PCIDE",
"pcmpistri",
"PCNET",
"PDBR",
"PDPTE",
"PEBS",
"PERFEVTSEL",
"PEXIT",
"PFLA",
"Phdrs",
"pheader",
"PHENT",
"phentsize",
"phnum",
"phoff",
"PHYSBASE",
"PHYSMASK",
"Pico",
"PINBASED",
"Pipefd",
"PKRU",
"PLTGOT",
"PLTREL",
"PLTRELSZ",
"POPCNT",
"PORTHB",
"powerline",
"Prefetchable",
"PREINIT",
"PROCBASED",
"PROGBITS",
"PTMX",
"ptys",
"pushfl",
"pushfq",
"Raphson",
"RARP",
"RBSTART",
"rdmsr",
"RDRAND",
"rdseed",
"rdtsc",
"readcr",
"readxcr",
"realloc",
"Realtek",
"RELAENT",
"RELASZ",
"RELSZ",
"Rodata",
"RPCI",
"rpmalloc",
"RRGGBB",
"RSDP",
"RSDT",
"RTIT",
"SATA",
"schedbg",
"SERCOS",
"serialports",
"sfence",
"sgdt",
"SGXLEPUBKEYHASH",
"Shdr",
"Sheader",
"shentsize",
"shnum",
"shoff",
"showbuf",
"shstrndx",
"shstrtab",
"sidt",
"SIGCOMP",
"sigsetsize",
"SIVR",
"SMAP",
"SMBASE",
"SMBIOSBIOS",
"SMEP",
"SMRR",
"SMXE",
"SNTP",
"SRAT",
"SSDT",
"sspt",
"SSSE",
"stac",
"strdbg",
"STRSZ",
"SVME",
"swapgs",
"Symbios",
"SYMENT",
"SYSENTER",
"sysret",
"sysretq",
"Tamsyn",
"targp",
"TCCR",
"TCLO",
"TCPA",
"TDCR",
"TEXIT",
"TEXTREL",
"Thrd",
"TICR",
"tlbi",
"Touchpad",
"tracepagetable",
"tskdbg",
"ttbr",
"uarch",
"uartmemdmp",
"ubsan",
"UINTFASTX",
"UINTLEASTX",
"UINTX",
"ultoa",
"UMIP",
"UMWAIT",
"UNMAP",
"Unmaskable",
"Unreserving",
"unseek",
"Unswap",
"unsynchronized",
"UPDT",
"UPID",
"uroot",
"UTID",
"VAES",
"VBMI",
"vectorize",
"vfctprintf",
"vfsdbg",
"Vidx",
"Virtio",
"VMCS",
"VMFUNC",
"vmouse",
"VMXE",
"VNNI",
"VNNIW",
"VPCLMULQDQ",
"VPID",
"VPOKE",
"VPOPCNTDQ",
"WAET",
"weakrefalias",
"Wignored",
"Wmissing",
"writecr",
"writexcr",
"wrmsr",
"WWVB",
"WWVH",
"Xalloc",
"xallocv",
"Xclac",
"xgetbv",
"Xmemcpy",
"Xmemset",
"XSDT",
"Xsize",
"XSLC",
"XSLF",
"XSLM",
"XSLR",
"Xstac",
"Xuintptr",
"yottabyte",
"zettabyte"
],
"editor.tabCompletion": "on", "editor.tabCompletion": "on",
"diffEditor.codeLens": true, "diffEditor.codeLens": true,
"editor.quickSuggestionsDelay": 100, "editor.quickSuggestionsDelay": 100,
@@ -529,4 +24,4 @@
"editor.cursorStyle": "line", "editor.cursorStyle": "line",
"editor.cursorWidth": 2 "editor.cursorWidth": 2
} }
} }

View File

@@ -1,22 +0,0 @@
{
"folders": [
{
"path": "./Lynx"
}
],
"settings": {
"debug.allowBreakpointsEverywhere": true,
"files.associations": {
"*.su": "tsv",
"limine.h": "c"
},
"cSpell.words": [
"Bootloader",
"COMNULL",
"CPUID",
"FENNIX",
"JMPREL",
"UBSAN"
]
}
}

View File

@@ -5,67 +5,7 @@
} }
], ],
"settings": { "settings": {
"debug.allowBreakpointsEverywhere": true, "terminal.integrated.cwd": "../",
"files.associations": { "debug.allowBreakpointsEverywhere": true
"*.su": "tsv",
"thread": "cpp",
"bitset": "cpp",
"initializer_list": "cpp",
"fex.hpp": "c",
"types.h": "c",
"dlfcn.h": "c",
"aux.h": "c",
"stddef.h": "c",
"stdio.h": "c",
"syscalls.h": "c",
"syslib.h": "c",
"sysfile.h": "c",
"ipc.h": "c",
"sysbase.h": "c",
"inttypes.h": "c",
"doomkeys.h": "c",
"doomgeneric.h": "c",
"elf.h": "c",
"init.h": "c",
"unused_code": "cpp",
"liballoc_1_1.h": "c",
"errno.h": "c",
"stdlib.h": "c",
"stdarg.h": "c",
"printf.h": "c",
"ctype.h": "c",
"unistd.h": "c",
"stat.h": "c",
"wait.h": "c",
"base.h": "c",
"ld.h": "c",
"syscall.h": "c",
"stdint.h": "c",
"setjmp.h": "c",
"limits.h": "c",
"fcntl.h": "c",
"pty.h": "c",
"string.h": "c",
"time.h": "c",
"reboot.h": "c",
"*.in": "c",
"signal.h": "c",
"alltypes.h": "c",
"pr44328.C": "cpp"
},
"cSpell.words": [
"auxv",
"cmpq",
"FENNIX",
"JMPREL",
"Krnl",
"liballoc",
"libinit",
"oldpath",
"preinit",
"Shdr",
"vfctprintf",
"WAITSTATUS"
]
} }
} }

View File

@@ -5,31 +5,6 @@
} }
], ],
"settings": { "settings": {
"debug.allowBreakpointsEverywhere": true, "debug.allowBreakpointsEverywhere": true
"files.associations": {
"*.su": "tsv",
"thread": "cpp",
"bitset": "cpp",
"initializer_list": "cpp",
"semaphore": "cpp",
"memory": "cpp",
"limits": "cpp",
"climits": "cpp",
"iterator": "cpp",
"ranges": "cpp",
"cassert": "cpp",
"concepts": "cpp",
"cctype": "cpp",
"tuple": "cpp",
"streambuf": "cpp",
"system_error": "cpp",
"coroutine": "cpp",
"static_vector": "cpp",
"string_view": "cpp",
"compare": "cpp",
"ostream": "cpp",
"unordered_map": "cpp",
"vector": "cpp"
}
} }
} }

View File

@@ -1,11 +1,3 @@
# Kernel # Kernel
The core of the operating system. The core of the operating system.
---
Use `Fennix` repo to build the operating system.
```bash
git clone --recurse-submodules https://github.com/Fennix-Project/Fennix.git
```

View File

@@ -1,6 +1,6 @@
BSD 3-Clause License BSD 3-Clause License
Copyright (c) 2022, EnderIce2 Copyright (c) 2024, EnderIce2
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,13 +0,0 @@
{
"folders": [
{
"path": "./Lynx"
}
],
"settings": {
"debug.allowBreakpointsEverywhere": true,
"files.associations": {
"efi.h": "c"
}
}
}

7
Lynx/.gitignore vendored
View File

@@ -1,7 +0,0 @@
*.o
efi-loader.bin
loader.bin
UEFI/gnu-efi
UEFI/include
UEFI/BOOTX64.EFI
UEFI/BOOTIA32.EFI

View File

@@ -1,210 +0,0 @@
{
"configurations": [
{
"name": "Fennix x64 (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/UEFI/include"
],
"defines": [
"__debug_vscode__",
"KERNEL_NAME=\"Fennix\"",
"KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"",
"a64",
"a86",
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/amd64-elf-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// Compiler flags
"-fno-pic",
"-fno-pie",
"-mno-red-zone",
"-march=core2",
"-pipe",
"-mcmodel=kernel",
"-fno-builtin",
// Warnings
"-Wall",
"-Wextra",
"-Wfloat-equal",
"-Wpointer-arith",
"-Wcast-align",
"-Wredundant-decls",
"-Winit-self",
"-Wswitch-default",
"-Wstrict-overflow=5",
"-Wconversion",
// C++ flags
"-fno-rtti",
"-fexceptions",
// Linker flags
"-T${workspaceFolder}/Architecture/amd64/linker.ld",
"-Wl,-static,--no-dynamic-linker,-ztext",
"-nostdlib",
"-nodefaultlibs",
"-nolibc",
"-zmax-page-size=0x1000",
"-shared",
// Debug flags
"-ggdb3",
"-O0",
"-fdiagnostics-color=always",
"-fverbose-asm",
"-fstack-usage",
"-fstack-check",
"-fsanitize=undefined",
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
},
{
"name": "Fennix x32 (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/UEFI/include"
],
"defines": [
"__debug_vscode__",
"KERNEL_NAME=\"Fennix\"",
"KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"",
"a32",
"a86",
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "gcc-x86",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// Compiler flags
"-fno-pic",
"-fno-pie",
"-mno-80387",
"-mno-mmx",
"-mno-3dnow",
"-mno-red-zone",
"-march=pentium",
"-pipe",
"-msoft-float",
"-fno-builtin",
// Warnings
"-Wall",
"-Wextra",
"-Wfloat-equal",
"-Wpointer-arith",
"-Wcast-align",
"-Wredundant-decls",
"-Winit-self",
"-Wswitch-default",
"-Wstrict-overflow=5",
"-Wconversion",
// C++ flags
"-fno-rtti",
"-fexceptions",
// Linker flags
"-T${workspaceFolder}/Architecture/i386/linker.ld",
"-Wl,-static,--no-dynamic-linker,-ztext",
"-nostdlib",
"-nodefaultlibs",
"-nolibc",
"-zmax-page-size=0x1000",
"-shared",
// Debug flags
"-ggdb3",
"-O0",
"-fdiagnostics-color=always",
"-fverbose-asm",
"-fstack-usage",
"-fstack-check",
"-fsanitize=undefined",
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
},
{
"name": "Fennix Aarch64 (Linux, GCC, debug)",
"includePath": [
"${workspaceFolder}/UEFI/include"
],
"defines": [
"__debug_vscode__",
"KERNEL_NAME=\"Fennix\"",
"KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"",
"aa64",
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-elf-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "linux-gcc-arm64",
"configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [
// Compiler flags
"-pipe",
"-fno-builtin",
"-msoft-float",
"-fPIC",
"-Wstack-protector",
// Warnings
"-Wall",
"-Wextra",
"-Wfloat-equal",
"-Wpointer-arith",
"-Wcast-align",
"-Wredundant-decls",
"-Winit-self",
"-Wswitch-default",
"-Wstrict-overflow=5",
"-Wconversion",
// C++ flags
"-fno-rtti",
"-fexceptions",
// Linker flags
"-T${workspaceFolder}/Architecture/aarch64/linker.ld",
"-fPIC",
// Debug flags
"-ggdb3",
"-O0",
"-fdiagnostics-color=always",
"-fverbose-asm",
"-fstack-usage",
"-fstack-check",
"-fsanitize=undefined",
// VSCode flags
"-ffreestanding",
"-nostdinc",
"-nostdinc++"
]
}
],
"version": 4
}

View File

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

View File

@@ -1,22 +0,0 @@
include ../../Makefile.conf
NAME=loader.bin
NASM = /usr/bin/nasm
ASM_SOURCES = $(shell find ./ -type f -name '*.asm')
OBJ = $(ASM_SOURCES:.asm=.o)
prepare:
$(info Nothing to prepare)
$(NAME): $(OBJ)
cat boot.o second.o > $@
build: $(NAME)
%.o: %.asm
$(info Compiling $<)
$(NASM) $< -f bin -o $@
clean:
rm -f $(OBJ) $(NAME)

View File

@@ -1,65 +0,0 @@
[ORG 0x7C00]
[BITS 16]
start:
jmp 0x0000:Boot
nop
times 8-($-$$) db 0
PrimaryVolumeDescriptor dd 0
BootFileLocation dd 0
BootFileLength dd 0
Checksum dd 0
Reserved times 40 db 0
times 90-($-$$) db 0
%include "print.inc"
Boot:
cli
mov [BOOT_DISK], dl
xor ax, ax
mov ds, ax
mov ss, ax
mov sp, 0x9C00
mov si, ErrorText
call Print
hlt
jmp $
mov si, BootloaderText
call Print
call ReadDisk
jmp EX_ADDRESS
jmp $
ReadDisk:
sti
mov ah, 0x02
mov bx, EX_ADDRESS
mov al, 20 ; max 65
mov dl, [BOOT_DISK]
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
int 0x13
jc DiskError
cli
ret
DiskError:
cli
mov si, DiskReadingErrorMessage
call Print
jmp $
ErrorText db 'BIOS boot not implemented', 0
BootloaderText db 'Lynx Bootloader', 0
DiskReadingErrorMessage: db ' Disk Error', 0
EX_ADDRESS equ 0x8000
BOOT_DISK: db 0
times 510-($-$$) db 0
db 0x55
db 0xAA

View File

@@ -1,9 +0,0 @@
Print:
lodsb
or al, al
jz PrintDone
mov ah, 0eh
int 10h
jmp Print
PrintDone:
ret

View File

@@ -1,9 +0,0 @@
; TODO
init:
mov si, LoadingText
call Print
jmp $
%include "print.inc"
LoadingText db ' Loading...', 0

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2022, EnderIce2
All rights reserved.
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.

View File

@@ -1,14 +0,0 @@
prepare:
make -C BIOS prepare
make -C UEFI prepare
build:
make -C BIOS build
make -C UEFI build
cp BIOS/loader.bin .
cp UEFI/efi-loader.bin .
clean:
make -C BIOS clean
make -C UEFI clean
rm -f loader.bin efi-loader.bin

View File

@@ -1,13 +0,0 @@
# Lynx
Bootloader for [Fennix](https://github.com/Fennix-Project/Fennix).
---
Currently under development.
Use `Fennix` repo to build the operating system.
```bash
git clone --recurse-submodules https://github.com/Fennix-Project/Fennix.git
```

View File

@@ -1,48 +0,0 @@
include ../../Makefile.conf
NAME=efi-loader.bin
CC = gcc
LD = ld
OBJCOPY = objcopy
C_SOURCES = $(shell find ./src -type f -name '*.c')
CPP_SOURCES = $(shell find ./src -type f -name '*.cpp')
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o)
GNUEFI_RELEASE_VERSION=3.0.14
gnuefi:
wget https://archive.org/download/gnu-efi-$(GNUEFI_RELEASE_VERSION).tar/gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
tar -xf gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
rm gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
mv ./gnu-efi-$(GNUEFI_RELEASE_VERSION) ./gnu-efi
mkdir -p include
cp -a ./gnu-efi/inc/. ./include
make -C gnu-efi
prepare: gnuefi
build: $(NAME)
$(NAME): BOOTX64
dd if=/dev/zero of=$(NAME) bs=512 count=93750
mformat -i $(NAME) ::
mmd -i $(NAME) ::/EFI
mmd -i $(NAME) ::/EFI/BOOT
mcopy -i $(NAME) BOOTX64.EFI ::/EFI/BOOT
BOOTX64: $(OBJ)
$(LD) -shared -Bsymbolic -Lgnu-efi/x86_64/lib -Lgnu-efi/x86_64/gnuefi -Tgnu-efi/gnuefi/elf_x86_64_efi.lds gnu-efi/x86_64/gnuefi/crt0-efi-x86_64.o $(OBJ) -o tmp.so -lgnuefi -lefi
$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target efi-app-x86_64 --subsystem=10 tmp.so BOOTX64.EFI
rm tmp.so
%.o: %.c
$(info Compiling $<)
$(CC) -Ignu-efi/inc -Ignu-efi/inc/x86_64 -Ignu-efi/inc/protocol -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -c $< -o $@
%.o: %.cpp
$(info Compiling $<)
$(CC) -Ignu-efi/inc -Ignu-efi/inc/x86_64 -Ignu-efi/inc/protocol -fpermissive -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -c $< -o $@
clean:
rm -f $(NAME) $(OBJ) BOOTX64.EFI

View File

@@ -1,28 +0,0 @@
#include "bitmap.hpp"
bool Bitmap::operator[](uint64_t index) { return Get(index); }
bool Bitmap::Get(uint64_t index)
{
if (index > Size * 8)
return false;
uint64_t byteIndex = index / 8;
uint8_t bitIndex = index % 8;
uint8_t bitIndexer = 0b10000000 >> bitIndex;
if ((Buffer[byteIndex] & bitIndexer) > 0)
return true;
return false;
}
bool Bitmap::Set(uint64_t index, bool value)
{
if (index > Size * 8)
return false;
uint64_t byteIndex = index / 8;
uint8_t bitIndex = index % 8;
uint8_t bitIndexer = 0b10000000 >> bitIndex;
Buffer[byteIndex] &= ~bitIndexer;
if (value)
Buffer[byteIndex] |= bitIndexer;
return true;
}

View File

@@ -1,8 +0,0 @@
#include "FileLoader.h"
// https://wiki.osdev.org/Loading_files_under_UEFI
EFI_FILE *LoadFile(EFI_FILE *Directory, CHAR16 *Path, EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
return NULL;
}

View File

@@ -1,5 +0,0 @@
#pragma once
#include <efi.h>
#include <efilib.h>
EFI_FILE *LoadFile(EFI_FILE *Directory, CHAR16 *Path, EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);

View File

@@ -1,89 +0,0 @@
#include <efi.h>
#include <efilib.h>
#include "Memory/memory.hpp"
#include "FileLoader.h"
#include "printf.h"
void port_byte_out(short unsigned int port, unsigned char value)
{
__asm__ volatile("outb %0, %1"
:
: "a"(value), "Nd"(port));
}
unsigned char port_byte_in(short unsigned int port)
{
unsigned char ReturnValue;
__asm__ volatile("inb %1, %0"
: "=a"(ReturnValue)
: "Nd"(port));
return ReturnValue;
}
int strlen(const char s[])
{
int i = 0;
while (s[i] != '\0')
++i;
return i;
}
int init_serial()
{
// TODO: fix crash on virtualbox (or virtualbox is faulty???????????)
port_byte_out(0x3F8 + 1, 0x00);
port_byte_out(0x3F8 + 3, 0x80);
port_byte_out(0x3F8 + 0, 0x03);
port_byte_out(0x3F8 + 1, 0x00);
port_byte_out(0x3F8 + 3, 0x03);
port_byte_out(0x3F8 + 2, 0xC7);
port_byte_out(0x3F8 + 4, 0x0B);
port_byte_out(0x3F8 + 4, 0x1E);
port_byte_out(0x3F8 + 0, 0xAE);
if (port_byte_in(0x3F8 + 0) != 0xAE)
{
return -1; // serial port is faulty
}
port_byte_out(0x3F8 + 4, 0x0F);
return 0;
}
void printf(const char *format, ...)
{
va_list args;
va_start(args, format);
printf_(format, args);
va_end(args);
}
extern void putchar(char c)
{
while ((port_byte_in(0x3F8 + 5) & 0x20) == 0)
;
port_byte_out(0x3F8, c);
}
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
InitializeLib(ImageHandle, SystemTable);
SystemTable->BootServices->SetWatchdogTimer(0, 0, 0, NULL);
Print(L"Lynx Bootloader © EnderIce2 2022\n");
Print(L"UEFI not implemented\n");
while (1)
asm("hlt");
InitializeMemoryManagement(ImageHandle, SystemTable);
EFI_FILE *Kernel = LoadFile(NULL, L"fennix.elf", ImageHandle, SystemTable);
if (Kernel == NULL)
{
Print(L"Kernel not found\n");
while (1)
asm("hlt");
}
while (1)
asm("hlt");
return EFI_SUCCESS;
}

View File

@@ -1,146 +0,0 @@
#include "memory.hpp"
#include "liballoc_1_1.h"
extern "C" void printf(const char *format, ...);
extern uint64_t ImageBase, _text, _etext, _data, _edata, _data_size;
using namespace Memory;
Physical KernelAllocator;
PageTable *KernelPageTable = nullptr;
static void *memset(void *s, int c, size_t n)
{
unsigned int i;
for (i = 0; i < n; i++)
((char *)s)[i] = c;
return s;
}
extern "C" void InitializeMemoryManagement(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
printf("Initializing Physical Memory Manager\n");
KernelAllocator = Physical();
KernelAllocator.Init(ImageHandle, SystemTable);
printf("Memory Info: %dMB / %dMB (%dMB reserved)",
(KernelAllocator.GetUsedMemory() / 1024 / 1024),
(KernelAllocator.GetTotalMemory() / 1024 / 1024),
(KernelAllocator.GetReservedMemory() / 1024 / 1024));
KernelPageTable = (PageTable *)KernelAllocator.RequestPage();
memset(KernelPageTable, 0, PAGE_SIZE);
Virtual kva = Virtual(KernelPageTable);
printf("Mapping...\n");
uint64_t BootloaderStart = (uint64_t)&ImageBase;
uint64_t BootloaderTextEnd = (uint64_t)&_text;
uint64_t BootloaderDataEnd = (uint64_t)&_data;
uint64_t BootloaderEnd = (uint64_t)&ImageBase + (uint64_t)&_etext + (uint64_t)&_edata;
uint64_t VirtualOffsetNormalVMA = NORMAL_VMA_OFFSET;
uint64_t BaseKernelMapAddress = (uint64_t)0; // TODO: Info->Kernel.PhysicalBase;
EFI_MEMORY_DESCRIPTOR *memDesc = nullptr;
UINTN MapSize, MapKey;
UINTN DescriptorSize;
UINT32 DescriptorVersion;
{
SystemTable->BootServices->GetMemoryMap(&MapSize, memDesc, &MapKey, &DescriptorSize, &DescriptorVersion);
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, (void **)&memDesc);
SystemTable->BootServices->GetMemoryMap(&MapSize, memDesc, &MapKey, &DescriptorSize, &DescriptorVersion);
}
for (uint64_t t = 0; t < MapSize / DescriptorSize; t += PAGE_SIZE)
{
kva.Map((void *)t, (void *)t, PTFlag::RW);
kva.Map((void *)VirtualOffsetNormalVMA, (void *)t, PTFlag::RW);
VirtualOffsetNormalVMA += PAGE_SIZE;
}
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
UINTN SizeOfInfo, numModes = 0; //, MaximumSupportedMode = 0;
EFI_STATUS status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
EFI_GUID gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
status = uefi_call_wrapper(BS->LocateProtocol, 3, &gopGuid, NULL, (void **)&gop);
if (EFI_ERROR(status))
{
printf("Unable to locate the Graphics Output Protocol.\n");
}
status = uefi_call_wrapper(gop->QueryMode, 4, gop, gop->Mode == NULL ? 0 : gop->Mode->Mode, &SizeOfInfo, &info);
if (status == EFI_NOT_STARTED)
{
printf("The EFI not started!\n");
status = uefi_call_wrapper(gop->SetMode, 2, gop, 0);
}
/* Mapping Framebuffer address */
int itrfb = 0;
while (1)
{
for (uint64_t fb_base = (uint64_t)gop->Mode->FrameBufferBase;
fb_base < ((uint64_t)gop->Mode->FrameBufferBase + ((gop->Mode->Info->PixelsPerScanLine) + PAGE_SIZE));
fb_base += PAGE_SIZE)
kva.Map((void *)fb_base, (void *)fb_base, PTFlag::RW | PTFlag::US);
itrfb++;
}
/* Kernel mapping */
for (uint64_t k = BootloaderStart; k < BootloaderTextEnd; k += PAGE_SIZE)
{
kva.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
}
for (uint64_t k = BootloaderTextEnd; k < BootloaderDataEnd; k += PAGE_SIZE)
{
kva.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
}
for (uint64_t k = BootloaderDataEnd; k < BootloaderEnd; k += PAGE_SIZE)
{
kva.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
}
printf("\nStart: %#llx - Text End: %#llx - End: %#llx\nStart Physical: %#llx - End Physical: %#llx",
BootloaderStart, BootloaderTextEnd, BootloaderEnd, /* Info->Kernel.PhysicalBase */ 0, BaseKernelMapAddress - PAGE_SIZE);
/* BootloaderStart BootloaderTextEnd KernelRoDataEnd BootloaderEnd
Kernel Start & Text Start ------ Text End ------ Kernel Rodata End ------ Kernel Data End & Kernel End
*/
printf("Applying new page table from address %p", KernelPageTable);
__asm__ volatile("mov %0, %%cr3" ::"r"(KernelPageTable));
}
extern "C" void *HeapMalloc(uint64_t Size) { return PREFIX(malloc)(Size); }
extern "C" void *HeapCalloc(uint64_t n, uint64_t Size) { return PREFIX(calloc)(n, Size); }
extern "C" void *HeapRealloc(void *Address, uint64_t Size) { return PREFIX(realloc)(Address, Size); }
extern "C" void HeapFree(void *Address)
{
PREFIX(free)
(Address);
}
void *operator new(uint64_t Size) { return HeapMalloc(Size); }
void *operator new[](uint64_t Size) { return HeapMalloc(Size); }
void operator delete(void *Pointer) { HeapFree(Pointer); }
void operator delete[](void *Pointer) { HeapFree(Pointer); }
void operator delete(void *Pointer, long unsigned int Size) { HeapFree(Pointer); }
void operator delete[](void *Pointer, long unsigned int Size) { HeapFree(Pointer); }
EXTERNC int liballoc_lock() {}
EXTERNC int liballoc_unlock() {}
EXTERNC void *liballoc_alloc(size_t Pages) { return KernelAllocator.RequestPages(Pages); }
EXTERNC int liballoc_free(void *Address, size_t Pages)
{
KernelAllocator.FreePages(Address, Pages);
return 0;
}

View File

@@ -1,284 +0,0 @@
#include "memory.hpp"
extern "C" void printf(const char *format, ...);
namespace Memory
{
uint64_t Physical::GetTotalMemory()
{
return this->TotalMemory;
}
uint64_t Physical::GetFreeMemory()
{
return this->FreeMemory;
}
uint64_t Physical::GetReservedMemory()
{
return this->ReservedMemory;
}
uint64_t Physical::GetUsedMemory()
{
return this->UsedMemory;
}
bool Physical::SwapPage(void *Address)
{
printf("%p", Address);
return false;
}
bool Physical::SwapPages(void *Address, uint64_t PageCount)
{
for (uint64_t i = 0; i < PageCount; i++)
if (!this->SwapPage((void *)((uint64_t)Address + (i * PAGE_SIZE))))
return false;
return false;
}
bool Physical::UnswapPage(void *Address)
{
printf("%p", Address);
return false;
}
bool Physical::UnswapPages(void *Address, uint64_t PageCount)
{
for (uint64_t i = 0; i < PageCount; i++)
if (!this->UnswapPage((void *)((uint64_t)Address + (i * PAGE_SIZE))))
return false;
return false;
}
void *Physical::RequestPage()
{
for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++)
{
if (PageBitmap[PageBitmapIndex] == true)
continue;
this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE));
return (void *)(PageBitmapIndex * PAGE_SIZE);
}
if (this->SwapPage((void *)(PageBitmapIndex * PAGE_SIZE)))
{
this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE));
return (void *)(PageBitmapIndex * PAGE_SIZE);
}
printf("Out of memory! (Free: %ldMB; Used: %ldMB; Reserved: %ldMB)", (FreeMemory / 1024 / 1024), (UsedMemory / 1024 / 1024), (ReservedMemory / 1024 / 1024));
while (1)
__asm__("hlt");
return nullptr;
}
void *Physical::RequestPages(uint64_t Count)
{
for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++)
{
if (PageBitmap[PageBitmapIndex] == true)
continue;
for (uint64_t Index = PageBitmapIndex; Index < PageBitmap.Size * 8; Index++)
{
if (PageBitmap[Index] == true)
continue;
for (uint64_t i = 0; i < Count; i++)
if (PageBitmap[Index + i] == true)
goto NextPage;
this->LockPages((void *)(Index * PAGE_SIZE), Count);
return (void *)(Index * PAGE_SIZE);
NextPage:
Index += Count;
continue;
}
}
if (this->SwapPages((void *)(PageBitmapIndex * PAGE_SIZE), Count))
{
this->LockPages((void *)(PageBitmapIndex * PAGE_SIZE), Count);
return (void *)(PageBitmapIndex * PAGE_SIZE);
}
printf("Out of memory! (Free: %ldMB; Used: %ldMB; Reserved: %ldMB)", (FreeMemory / 1024 / 1024), (UsedMemory / 1024 / 1024), (ReservedMemory / 1024 / 1024));
while (1)
__asm__("hlt");
return nullptr;
}
void Physical::FreePage(void *Address)
{
if (Address == nullptr)
{
printf("Null pointer passed to FreePage.");
return;
}
uint64_t Index = (uint64_t)Address / PAGE_SIZE;
if (PageBitmap[Index] == false)
return;
if (PageBitmap.Set(Index, false))
{
FreeMemory += PAGE_SIZE;
UsedMemory -= PAGE_SIZE;
if (PageBitmapIndex > Index)
PageBitmapIndex = Index;
}
}
void Physical::FreePages(void *Address, uint64_t Count)
{
if (Address == nullptr || Count == 0)
{
printf("%s%s passed to FreePages.", Address == nullptr ? "Null pointer" : "", Count == 0 ? "Zero count" : "");
return;
}
for (uint64_t t = 0; t < Count; t++)
this->FreePage((void *)((uint64_t)Address + (t * PAGE_SIZE)));
}
void Physical::LockPage(void *Address)
{
if (Address == nullptr)
printf("Trying to lock null address.");
uint64_t Index = (uint64_t)Address / PAGE_SIZE;
if (PageBitmap[Index] == true)
return;
if (PageBitmap.Set(Index, true))
{
FreeMemory -= PAGE_SIZE;
UsedMemory += PAGE_SIZE;
}
}
void Physical::LockPages(void *Address, uint64_t PageCount)
{
if (Address == nullptr || PageCount == 0)
printf("Trying to lock %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : "");
for (uint64_t i = 0; i < PageCount; i++)
this->LockPage((void *)((uint64_t)Address + (i * PAGE_SIZE)));
}
void Physical::ReservePage(void *Address)
{
if (Address == nullptr)
printf("Trying to reserve null address.");
uint64_t Index = (uint64_t)Address / PAGE_SIZE;
if (PageBitmap[Index] == true)
return;
if (PageBitmap.Set(Index, true))
{
FreeMemory -= PAGE_SIZE;
ReservedMemory += PAGE_SIZE;
}
}
void Physical::ReservePages(void *Address, uint64_t PageCount)
{
if (Address == nullptr || PageCount == 0)
printf("Trying to reserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : "");
for (uint64_t t = 0; t < PageCount; t++)
this->ReservePage((void *)((uint64_t)Address + (t * PAGE_SIZE)));
}
void Physical::UnreservePage(void *Address)
{
if (Address == nullptr)
printf("Trying to unreserve null address.");
uint64_t Index = (uint64_t)Address / PAGE_SIZE;
if (PageBitmap[Index] == false)
return;
if (PageBitmap.Set(Index, false))
{
FreeMemory += PAGE_SIZE;
ReservedMemory -= PAGE_SIZE;
if (PageBitmapIndex > Index)
PageBitmapIndex = Index;
}
}
void Physical::UnreservePages(void *Address, uint64_t PageCount)
{
if (Address == nullptr || PageCount == 0)
printf("Trying to unreserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : "");
for (uint64_t t = 0; t < PageCount; t++)
this->UnreservePage((void *)((uint64_t)Address + (t * PAGE_SIZE)));
}
void Physical::Init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
printf("Initializing physical memory manager...\n");
EFI_MEMORY_DESCRIPTOR *memDesc = nullptr;
UINTN MapSize, MapKey;
UINTN DescriptorSize;
UINT32 DescriptorVersion;
{
SystemTable->BootServices->GetMemoryMap(&MapSize, memDesc, &MapKey, &DescriptorSize, &DescriptorVersion);
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, (void **)&memDesc);
SystemTable->BootServices->GetMemoryMap(&MapSize, memDesc, &MapKey, &DescriptorSize, &DescriptorVersion);
}
uint64_t MemoryMapSize = MapSize / DescriptorSize;
static uint64_t MemorySizeBytes = 0;
void *LargestFreeMemorySegment = nullptr;
uint64_t LargestFreeMemorySegmentSize = 0;
uint64_t MemorySize = MapSize;
TotalMemory = MemorySize;
FreeMemory = MemorySize;
for (int i = 0; i < MemoryMapSize; i++)
{
EFI_MEMORY_DESCRIPTOR *Descriptor = (EFI_MEMORY_DESCRIPTOR *)((uint64_t)memDesc + (i * DescriptorSize));
MemorySizeBytes += Descriptor->NumberOfPages * 4096;
switch (Descriptor->Type)
{
case EfiConventionalMemory:
if ((Descriptor->NumberOfPages * 4096) > LargestFreeMemorySegmentSize)
{
LargestFreeMemorySegment = (void *)Descriptor->PhysicalStart;
LargestFreeMemorySegmentSize = Descriptor->NumberOfPages * 4096;
printf("Largest free memory segment: %p (%dKB)",
(void *)Descriptor->PhysicalStart,
((Descriptor->NumberOfPages * 4096) / 1024));
}
break;
}
}
uint64_t BitmapSize = ALIGN_UP((MemorySize / 0x1000) / 8, 0x1000);
printf("Initializing Bitmap (%p %dKB)", LargestFreeMemorySegment, (BitmapSize / 1024));
PageBitmap.Size = BitmapSize;
PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegment;
for (uint64_t i = 0; i < BitmapSize; i++)
*(uint8_t *)(PageBitmap.Buffer + i) = 0;
this->ReservePages(0, MemorySize / PAGE_SIZE + 1);
for (uint64_t i = 0; i < MemoryMapSize; i++)
{
EFI_MEMORY_DESCRIPTOR *Descriptor = (EFI_MEMORY_DESCRIPTOR *)((uint64_t)memDesc + (i * DescriptorSize));
if (Descriptor->Type == EfiConventionalMemory)
this->UnreservePages((void *)Descriptor->PhysicalStart, (Descriptor->NumberOfPages * 4096) / PAGE_SIZE + 1);
}
this->ReservePages(0, 0x100); // Reserve between 0 and 0x100000
this->LockPages(PageBitmap.Buffer, PageBitmap.Size / PAGE_SIZE + 1);
}
Physical::Physical() {}
Physical::~Physical() {}
}

View File

@@ -1,119 +0,0 @@
#include "memory.hpp"
extern "C" void printf(const char* format, ...);
void *memset(void *dest, int c, size_t n)
{
unsigned int i;
for (i = 0; i < n; i++)
((char *)dest)[i] = c;
return dest;
}
namespace Memory
{
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
{
if (!this->Table)
{
printf("No page table");
return;
}
PageMapIndexer Index = PageMapIndexer((uint64_t)VirtualAddress);
PageDirectoryEntry PDE = this->Table->Entries[Index.PDP_i];
PageTable *PDP;
if (!PDE.GetFlag(PTFlag::P))
{
PDP = (PageTable *)KernelAllocator.RequestPage();
memset(PDP, 0, PAGE_SIZE);
PDE.SetAddress((uint64_t)PDP >> 12);
PDE.SetFlag(PTFlag::P, true);
PDE.AddFlag(Flags);
this->Table->Entries[Index.PDP_i] = PDE;
}
else
PDP = (PageTable *)((uint64_t)PDE.GetAddress() << 12);
PDE = PDP->Entries[Index.PD_i];
PageTable *PD;
if (!PDE.GetFlag(PTFlag::P))
{
PD = (PageTable *)KernelAllocator.RequestPage();
memset(PD, 0, PAGE_SIZE);
PDE.SetAddress((uint64_t)PD >> 12);
PDE.SetFlag(PTFlag::P, true);
PDE.AddFlag(Flags);
PDP->Entries[Index.PD_i] = PDE;
}
else
PD = (PageTable *)((uint64_t)PDE.GetAddress() << 12);
PDE = PD->Entries[Index.PT_i];
PageTable *PT;
if (!PDE.GetFlag(PTFlag::P))
{
PT = (PageTable *)KernelAllocator.RequestPage();
memset(PT, 0, PAGE_SIZE);
PDE.SetAddress((uint64_t)PT >> 12);
PDE.SetFlag(PTFlag::P, true);
PDE.AddFlag(Flags);
PD->Entries[Index.PT_i] = PDE;
}
else
PT = (PageTable *)((uint64_t)PDE.GetAddress() << 12);
PDE = PT->Entries[Index.P_i];
PDE.SetAddress((uint64_t)PhysicalAddress >> 12);
PDE.SetFlag(PTFlag::P, true);
PDE.AddFlag(Flags);
PT->Entries[Index.P_i] = PDE;
__asm__ volatile("invlpg (%0)"
:
: "r"(VirtualAddress)
: "memory");
}
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t PageCount, uint64_t Flags)
{
for (uint64_t i = 0; i < PageCount; i++)
this->Map((void *)((uint64_t)VirtualAddress + (i * PAGE_SIZE)), (void *)((uint64_t)PhysicalAddress + (i * PAGE_SIZE)), Flags);
}
void Virtual::Unmap(void *VirtualAddress)
{
if (!this->Table)
{
printf("No page table");
return;
}
PageMapIndexer Index = PageMapIndexer((uint64_t)VirtualAddress);
PageDirectoryEntry PDE = this->Table->Entries[Index.PDP_i];
PDE.ClearFlags();
__asm__ volatile("invlpg (%0)"
:
: "r"(VirtualAddress)
: "memory");
}
void Virtual::Unmap(void *VirtualAddress, uint64_t PageCount)
{
for (uint64_t i = 0; i < PageCount; i++)
this->Unmap((void *)((uint64_t)VirtualAddress + (i * PAGE_SIZE)));
}
Virtual::Virtual(PageTable *Table)
{
uint64_t cr3;
__asm__ volatile("mov %%cr3, %0"
: "=r"(cr3));
if (Table)
this->Table = Table;
else
this->Table = (PageTable *)cr3;
}
Virtual::~Virtual() {}
}

View File

@@ -1,787 +0,0 @@
#include "liballoc_1_1.h"
/** Durand's Amazing Super Duper Memory functions. */
#define VERSION "1.1"
#define ALIGNMENT 16ul // 4ul ///< This is the byte alignment that memory must be allocated on. IMPORTANT for GTK and other stuff.
#define ALIGN_TYPE char /// unsigned char[16] /// unsigned short
#define ALIGN_INFO sizeof(ALIGN_TYPE) * 16 ///< Alignment information is stored right before the pointer. This is the number of bytes of information stored there.
#define USE_CASE1
#define USE_CASE2
#define USE_CASE3
#define USE_CASE4
#define USE_CASE5
/** This macro will conveniently align our pointer upwards */
#define ALIGN(ptr) \
if (ALIGNMENT > 1) \
{ \
uintptr_t diff; \
ptr = (void *)((uintptr_t)ptr + ALIGN_INFO); \
diff = (uintptr_t)ptr & (ALIGNMENT - 1); \
if (diff != 0) \
{ \
diff = ALIGNMENT - diff; \
ptr = (void *)((uintptr_t)ptr + diff); \
} \
*((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)) = \
diff + ALIGN_INFO; \
}
#define UNALIGN(ptr) \
if (ALIGNMENT > 1) \
{ \
uintptr_t diff = *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)); \
if (diff < (ALIGNMENT + ALIGN_INFO)) \
{ \
ptr = (void *)((uintptr_t)ptr - diff); \
} \
}
#define LIBALLOC_MAGIC 0xc001c0de
#define LIBALLOC_DEAD 0xdeaddead
// #define LIBALLOCDEBUG 1
#define LIBALLOCINFO 1
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
// #define FLUSH() fflush(stdout)
#define FLUSH()
#define atexit(x)
#define printf(m, ...)
#endif
/** A structure found at the top of all system allocated
* memory blocks. It details the usage of the memory block.
*/
struct liballoc_major
{
struct liballoc_major *prev; ///< Linked list information.
struct liballoc_major *next; ///< Linked list information.
unsigned int pages; ///< The number of pages in the block.
unsigned int size; ///< The number of pages in the block.
unsigned int usage; ///< The number of bytes used in the block.
struct liballoc_minor *first; ///< A pointer to the first allocated memory in the block.
};
/** This is a structure found at the beginning of all
* sections in a major block which were allocated by a
* malloc, calloc, realloc call.
*/
struct liballoc_minor
{
struct liballoc_minor *prev; ///< Linked list information.
struct liballoc_minor *next; ///< Linked list information.
struct liballoc_major *block; ///< The owning block. A pointer to the major structure.
unsigned int magic; ///< A magic number to idenfity correctness.
unsigned int size; ///< The size of the memory allocated. Could be 1 byte or more.
unsigned int req_size; ///< The size of memory requested.
};
static struct liballoc_major *l_memRoot = NULL; ///< The root memory block acquired from the system.
static struct liballoc_major *l_bestBet = NULL; ///< The major with the most free memory.
static unsigned int l_pageSize = 4096; ///< The size of an individual page. Set up in liballoc_init.
static unsigned int l_pageCount = 16; ///< The number of pages to request per chunk. Set up in liballoc_init.
static unsigned long long l_allocated = 0; ///< Running total of allocated memory.
static unsigned long long l_inuse = 0; ///< Running total of used memory.
static long long l_warningCount = 0; ///< Number of warnings encountered
static long long l_errorCount = 0; ///< Number of actual errors
static long long l_possibleOverruns = 0; ///< Number of possible overruns
// *********** HELPER FUNCTIONS *******************************
static void *liballoc_memset(void *s, int c, size_t n)
{
unsigned int i;
for (i = 0; i < n; i++)
((char *)s)[i] = c;
return s;
}
static void *liballoc_memcpy(void *s1, const void *s2, size_t n)
{
char *cdest;
char *csrc;
unsigned int *ldest = (unsigned int *)s1;
unsigned int *lsrc = (unsigned int *)s2;
while (n >= sizeof(unsigned int))
{
*ldest++ = *lsrc++;
n -= sizeof(unsigned int);
}
cdest = (char *)ldest;
csrc = (char *)lsrc;
while (n > 0)
{
*cdest++ = *csrc++;
n -= 1;
}
return s1;
}
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
static void liballoc_dump()
{
#ifdef LIBALLOCDEBUG
struct liballoc_major *maj = l_memRoot;
struct liballoc_minor *min = NULL;
#endif
printf("liballoc: ------ Memory data ---------------\n");
printf("liballoc: System memory allocated: %i bytes\n", l_allocated);
printf("liballoc: Memory in used (malloc'ed): %i bytes\n", l_inuse);
printf("liballoc: Warning count: %i\n", l_warningCount);
printf("liballoc: Error count: %i\n", l_errorCount);
printf("liballoc: Possible overruns: %i\n", l_possibleOverruns);
#ifdef LIBALLOCDEBUG
while (maj != NULL)
{
printf("liballoc: %x: total = %i, used = %i\n",
maj,
maj->size,
maj->usage);
min = maj->first;
while (min != NULL)
{
printf("liballoc: %x: %i bytes\n",
min,
min->size);
min = min->next;
}
maj = maj->next;
}
#endif
FLUSH();
}
#endif
// ***************************************************************
static struct liballoc_major *allocate_new_page(unsigned int size)
{
unsigned int st;
struct liballoc_major *maj;
// This is how much space is required.
st = size + sizeof(struct liballoc_major);
st += sizeof(struct liballoc_minor);
// Perfect amount of space?
if ((st % l_pageSize) == 0)
st = st / (l_pageSize);
else
st = st / (l_pageSize) + 1;
// No, add the buffer.
// Make sure it's >= the minimum size.
if (st < l_pageCount)
st = l_pageCount;
maj = (struct liballoc_major *)liballoc_alloc(st);
if (maj == NULL)
{
l_warningCount += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: WARNING: liballoc_alloc( %i ) return NULL\n", st);
FLUSH();
#endif
return NULL; // uh oh, we ran out of memory.
}
maj->prev = NULL;
maj->next = NULL;
maj->pages = st;
maj->size = st * l_pageSize;
maj->usage = sizeof(struct liballoc_major);
maj->first = NULL;
l_allocated += maj->size;
#ifdef LIBALLOCDEBUG
printf("liballoc: Resource allocated %x of %i pages (%i bytes) for %i size.\n", maj, st, maj->size, size);
printf("liballoc: Total memory usage = %i KB\n", (int)((l_allocated / (1024))));
FLUSH();
#endif
return maj;
}
void *PREFIX(malloc)(size_t req_size)
{
int startedBet = 0;
unsigned long long bestSize = 0;
void *p = NULL;
uintptr_t diff;
struct liballoc_major *maj;
struct liballoc_minor *min;
struct liballoc_minor *new_min;
unsigned long size = req_size;
// For alignment, we adjust size so there's enough space to align.
if (ALIGNMENT > 1)
{
size += ALIGNMENT + ALIGN_INFO;
}
// So, ideally, we really want an alignment of 0 or 1 in order
// to save space.
liballoc_lock();
if (size == 0)
{
l_warningCount += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: WARNING: alloc( 0 ) called from %x\n",
__builtin_return_address(0));
FLUSH();
#endif
liballoc_unlock();
return PREFIX(malloc)(1);
}
if (l_memRoot == NULL)
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#ifdef LIBALLOCDEBUG
printf("liballoc: initialization of liballoc " VERSION "\n");
#endif
atexit(liballoc_dump);
FLUSH();
#endif
// This is the first time we are being used.
l_memRoot = allocate_new_page(size);
if (l_memRoot == NULL)
{
liballoc_unlock();
#ifdef LIBALLOCDEBUG
printf("liballoc: initial l_memRoot initialization failed\n", p);
FLUSH();
#endif
return NULL;
}
#ifdef LIBALLOCDEBUG
printf("liballoc: set up first memory major %x\n", l_memRoot);
FLUSH();
#endif
}
#ifdef LIBALLOCDEBUG
printf("liballoc: %x PREFIX(malloc)( %i ): ",
__builtin_return_address(0),
size);
FLUSH();
#endif
// Now we need to bounce through every major and find enough space....
maj = l_memRoot;
startedBet = 0;
// Start at the best bet....
if (l_bestBet != NULL)
{
bestSize = l_bestBet->size - l_bestBet->usage;
if (bestSize > (size + sizeof(struct liballoc_minor)))
{
maj = l_bestBet;
startedBet = 1;
}
}
while (maj != NULL)
{
diff = maj->size - maj->usage;
// free memory in the block
if (bestSize < diff)
{
// Hmm.. this one has more memory then our bestBet. Remember!
l_bestBet = maj;
bestSize = diff;
}
#ifdef USE_CASE1
// CASE 1: There is not enough space in this major block.
if (diff < (size + sizeof(struct liballoc_minor)))
{
#ifdef LIBALLOCDEBUG
printf("CASE 1: Insufficient space in block %x\n", maj);
FLUSH();
#endif
// Another major block next to this one?
if (maj->next != NULL)
{
maj = maj->next; // Hop to that one.
continue;
}
if (startedBet == 1) // If we started at the best bet,
{ // let's start all over again.
maj = l_memRoot;
startedBet = 0;
continue;
}
// Create a new major block next to this one and...
maj->next = allocate_new_page(size); // next one will be okay.
if (maj->next == NULL)
break; // no more memory.
maj->next->prev = maj;
maj = maj->next;
// .. fall through to CASE 2 ..
}
#endif
#ifdef USE_CASE2
// CASE 2: It's a brand new block.
if (maj->first == NULL)
{
maj->first = (struct liballoc_minor *)((uintptr_t)maj + sizeof(struct liballoc_major));
maj->first->magic = LIBALLOC_MAGIC;
maj->first->prev = NULL;
maj->first->next = NULL;
maj->first->block = maj;
maj->first->size = size;
maj->first->req_size = req_size;
maj->usage += size + sizeof(struct liballoc_minor);
l_inuse += size;
p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor));
ALIGN(p);
#ifdef LIBALLOCDEBUG
printf("CASE 2: returning %x\n", p);
FLUSH();
#endif
liballoc_unlock(); // release the lock
return p;
}
#endif
#ifdef USE_CASE3
// CASE 3: Block in use and enough space at the start of the block.
diff = (uintptr_t)(maj->first);
diff -= (uintptr_t)maj;
diff -= sizeof(struct liballoc_major);
if (diff >= (size + sizeof(struct liballoc_minor)))
{
// Yes, space in front. Squeeze in.
maj->first->prev = (struct liballoc_minor *)((uintptr_t)maj + sizeof(struct liballoc_major));
maj->first->prev->next = maj->first;
maj->first = maj->first->prev;
maj->first->magic = LIBALLOC_MAGIC;
maj->first->prev = NULL;
maj->first->block = maj;
maj->first->size = size;
maj->first->req_size = req_size;
maj->usage += size + sizeof(struct liballoc_minor);
l_inuse += size;
p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor));
ALIGN(p);
#ifdef LIBALLOCDEBUG
printf("CASE 3: returning %x\n", p);
FLUSH();
#endif
liballoc_unlock(); // release the lock
return p;
}
#endif
#ifdef USE_CASE4
// CASE 4: There is enough space in this block. But is it contiguous?
min = maj->first;
// Looping within the block now...
while (min != NULL)
{
// CASE 4.1: End of minors in a block. Space from last and end?
if (min->next == NULL)
{
// the rest of this block is free... is it big enough?
diff = (uintptr_t)(maj) + maj->size;
diff -= (uintptr_t)min;
diff -= sizeof(struct liballoc_minor);
diff -= min->size;
// minus already existing usage..
if (diff >= (size + sizeof(struct liballoc_minor)))
{
// yay....
min->next = (struct liballoc_minor *)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size);
min->next->prev = min;
min = min->next;
min->next = NULL;
min->magic = LIBALLOC_MAGIC;
min->block = maj;
min->size = size;
min->req_size = req_size;
maj->usage += size + sizeof(struct liballoc_minor);
l_inuse += size;
p = (void *)((uintptr_t)min + sizeof(struct liballoc_minor));
ALIGN(p);
#ifdef LIBALLOCDEBUG
printf("CASE 4.1: returning %x\n", p);
FLUSH();
#endif
liballoc_unlock(); // release the lock
return p;
}
}
// CASE 4.2: Is there space between two minors?
if (min->next != NULL)
{
// is the difference between here and next big enough?
diff = (uintptr_t)(min->next);
diff -= (uintptr_t)min;
diff -= sizeof(struct liballoc_minor);
diff -= min->size;
// minus our existing usage.
if (diff >= (size + sizeof(struct liballoc_minor)))
{
// yay......
new_min = (struct liballoc_minor *)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size);
new_min->magic = LIBALLOC_MAGIC;
new_min->next = min->next;
new_min->prev = min;
new_min->size = size;
new_min->req_size = req_size;
new_min->block = maj;
min->next->prev = new_min;
min->next = new_min;
maj->usage += size + sizeof(struct liballoc_minor);
l_inuse += size;
p = (void *)((uintptr_t)new_min + sizeof(struct liballoc_minor));
ALIGN(p);
#ifdef LIBALLOCDEBUG
printf("CASE 4.2: returning %x\n", p);
FLUSH();
#endif
liballoc_unlock(); // release the lock
return p;
}
} // min->next != NULL
min = min->next;
} // while min != NULL ...
#endif
#ifdef USE_CASE5
// CASE 5: Block full! Ensure next block and loop.
if (maj->next == NULL)
{
#ifdef LIBALLOCDEBUG
printf("CASE 5: block full\n");
FLUSH();
#endif
if (startedBet == 1)
{
maj = l_memRoot;
startedBet = 0;
continue;
}
// we've run out. we need more...
maj->next = allocate_new_page(size); // next one guaranteed to be okay
if (maj->next == NULL)
break; // uh oh, no more memory.....
maj->next->prev = maj;
}
#endif
maj = maj->next;
} // while (maj != NULL)
liballoc_unlock(); // release the lock
#ifdef LIBALLOCDEBUG
printf("All cases exhausted. No memory available.\n");
FLUSH();
#endif
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: WARNING: PREFIX(malloc)( %i ) returning NULL.\n", size);
liballoc_dump();
FLUSH();
#endif
return NULL;
}
void PREFIX(free)(void *ptr)
{
struct liballoc_minor *min;
struct liballoc_major *maj;
if (ptr == NULL)
{
l_warningCount += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: WARNING: PREFIX(free)( NULL ) called from %x\n",
__builtin_return_address(0));
FLUSH();
#endif
return;
}
UNALIGN(ptr);
liballoc_lock(); // lockit
min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor));
if (min->magic != LIBALLOC_MAGIC)
{
l_errorCount += 1;
// Check for overrun errors. For all bytes of LIBALLOC_MAGIC
if (
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF)))
{
l_possibleOverruns += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: ERROR: Possible 1-3 byte overrun for magic %x != %x\n",
min->magic,
LIBALLOC_MAGIC);
FLUSH();
#endif
}
if (min->magic == LIBALLOC_DEAD)
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: ERROR: multiple PREFIX(free)() attempt on %x from %x.\n",
ptr,
__builtin_return_address(0));
FLUSH();
#endif
}
else
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: ERROR: Bad PREFIX(free)( %x ) called from %x\n",
ptr,
__builtin_return_address(0));
FLUSH();
#endif
}
// being lied to...
liballoc_unlock(); // release the lock
return;
}
#ifdef LIBALLOCDEBUG
printf("liballoc: %x PREFIX(free)( %x ): ",
__builtin_return_address(0),
ptr);
FLUSH();
#endif
maj = min->block;
l_inuse -= min->size;
maj->usage -= (min->size + sizeof(struct liballoc_minor));
min->magic = LIBALLOC_DEAD; // No mojo.
if (min->next != NULL)
min->next->prev = min->prev;
if (min->prev != NULL)
min->prev->next = min->next;
if (min->prev == NULL)
maj->first = min->next;
// Might empty the block. This was the first
// minor.
// We need to clean up after the majors now....
if (maj->first == NULL) // Block completely unused.
{
if (l_memRoot == maj)
l_memRoot = maj->next;
if (l_bestBet == maj)
l_bestBet = NULL;
if (maj->prev != NULL)
maj->prev->next = maj->next;
if (maj->next != NULL)
maj->next->prev = maj->prev;
l_allocated -= maj->size;
liballoc_free(maj, maj->pages);
}
else
{
if (l_bestBet != NULL)
{
int bestSize = l_bestBet->size - l_bestBet->usage;
int majSize = maj->size - maj->usage;
if (majSize > bestSize)
l_bestBet = maj;
}
}
#ifdef LIBALLOCDEBUG
printf("OK\n");
FLUSH();
#endif
liballoc_unlock(); // release the lock
}
void *PREFIX(calloc)(size_t nobj, size_t size)
{
int real_size;
void *p;
real_size = nobj * size;
p = PREFIX(malloc)(real_size);
liballoc_memset(p, 0, real_size);
return p;
}
void *PREFIX(realloc)(void *p, size_t size)
{
void *ptr;
struct liballoc_minor *min;
unsigned int real_size;
// Honour the case of size == 0 => free old and return NULL
if (size == 0)
{
PREFIX(free)
(p);
return NULL;
}
// In the case of a NULL pointer, return a simple malloc.
if (p == NULL)
return PREFIX(malloc)(size);
// Unalign the pointer if required.
ptr = p;
UNALIGN(ptr);
liballoc_lock(); // lockit
min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor));
// Ensure it is a valid structure.
if (min->magic != LIBALLOC_MAGIC)
{
l_errorCount += 1;
// Check for overrun errors. For all bytes of LIBALLOC_MAGIC
if (
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF)))
{
l_possibleOverruns += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: ERROR: Possible 1-3 byte overrun for magic %x != %x\n",
min->magic,
LIBALLOC_MAGIC);
FLUSH();
#endif
}
if (min->magic == LIBALLOC_DEAD)
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: ERROR: multiple PREFIX(free)() attempt on %x from %x.\n",
ptr,
__builtin_return_address(0));
FLUSH();
#endif
}
else
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
printf("liballoc: ERROR: Bad PREFIX(free)( %x ) called from %x\n",
ptr,
__builtin_return_address(0));
FLUSH();
#endif
}
// being lied to...
liballoc_unlock(); // release the lock
return NULL;
}
// Definitely a memory block.
real_size = min->req_size;
if (real_size >= size)
{
min->req_size = size;
liballoc_unlock();
return p;
}
liballoc_unlock();
// If we got here then we're reallocating to a block bigger than us.
ptr = PREFIX(malloc)(size); // We need to allocate new memory
liballoc_memcpy(ptr, p, real_size);
PREFIX(free)
(p);
return ptr;
}

View File

@@ -1,90 +0,0 @@
#ifndef _LIBALLOC_H
#define _LIBALLOC_H
#ifndef LYNX_LIBALLOC_TYPES_H
#define LYNX_LIBALLOC_TYPES_H
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __SIZE_TYPE__ size_t;
typedef __UINTPTR_TYPE__ uintptr_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
#define ALIGN_UP(x, align) ((__typeof__(x))(((uint64_t)(x) + ((align)-1)) & (~((align)-1))))
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1))))
#endif // !LYNX_LIBALLOC_TYPES_H
/** \defgroup ALLOCHOOKS liballoc hooks
*
* These are the OS specific functions which need to
* be implemented on any platform that the library
* is expected to work on.
*/
/** @{ */
// If we are told to not define our own size_t, then we skip the define.
//#define _HAVE_UINTPTR_T
// typedef unsigned long uintptr_t;
// This lets you prefix malloc and friends
#define PREFIX(func) kliballoc_##func
#ifdef __cplusplus
extern "C"
{
#endif
/** This function is supposed to lock the memory data structures. It
* could be as simple as disabling interrupts or acquiring a spinlock.
* It's up to you to decide.
*
* \return 0 if the lock was acquired successfully. Anything else is
* failure.
*/
extern int liballoc_lock();
/** This function unlocks what was previously locked by the liballoc_lock
* function. If it disabled interrupts, it enables interrupts. If it
* had acquiried a spinlock, it releases the spinlock. etc.
*
* \return 0 if the lock was successfully released.
*/
extern int liballoc_unlock();
/** This is the hook into the local system which allocates pages. It
* accepts an integer parameter which is the number of pages
* required. The page size was set up in the liballoc_init function.
*
* \return NULL if the pages were not allocated.
* \return A pointer to the allocated memory.
*/
extern void *liballoc_alloc(size_t);
/** This frees previously allocated memory. The void* parameter passed
* to the function is the exact same value returned from a previous
* liballoc_alloc call.
*
* The integer value is the number of pages to free.
*
* \return 0 if the memory was successfully freed.
*/
extern int liballoc_free(void *, size_t);
extern void *PREFIX(malloc)(size_t); ///< The standard function.
extern void *PREFIX(realloc)(void *, size_t); ///< The standard function.
extern void *PREFIX(calloc)(size_t, size_t); ///< The standard function.
extern void PREFIX(free)(void *); ///< The standard function.
#ifdef __cplusplus
}
#endif
/** @} */
#endif

View File

@@ -1,433 +0,0 @@
#ifndef __FENNIX_KERNEL_INTERNAL_MEMORY_H__
#define __FENNIX_KERNEL_INTERNAL_MEMORY_H__
#ifndef LYNX_MEMORY_TYPES_H
#define LYNX_MEMORY_TYPES_H
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __SIZE_TYPE__ size_t;
typedef __UINTPTR_TYPE__ uintptr_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
#define ALIGN_UP(x, align) ((__typeof__(x))(((uint64_t)(x) + ((align)-1)) & (~((align)-1))))
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1))))
#endif // !LYNX_MEMORY_TYPES_H
#include "../bitmap.hpp"
#include <efi.h>
#include <efilib.h>
#define PAGE_SIZE 0x1000
// to pages
#define TO_PAGES(d) (d / PAGE_SIZE + 1)
// from pages
#define FROM_PAGES(d) (d * PAGE_SIZE - 1)
#define NORMAL_VMA_OFFSET 0xFFFF800000000000
#define KERNEL_VMA_OFFSET 0xFFFFFFFF80000000
/**
* @brief KERNEL_HEAP_BASE is the base address of the kernel heap
*/
#define KERNEL_HEAP_BASE 0xFFFFC00000000000
/**
* @brief USER_HEAP_BASE is the base address of the user heap allocated by the kernel
*/
#define USER_HEAP_BASE 0xFFFFD00000000000
#ifdef __cplusplus
namespace Memory
{
/**
* @brief https://wiki.osdev.org/images/4/41/64-bit_page_tables1.png
* @brief https://wiki.osdev.org/images/6/6b/64-bit_page_tables2.png
*/
enum PTFlag
{
/** @brief Present */
P = 1 << 0,
/** @brief Read/Write */
RW = 1 << 1,
/** @brief User/Supervisor */
US = 1 << 2,
/** @brief Write-Through */
PWT = 1 << 3,
/** @brief Cache Disable */
PCD = 1 << 4,
/** @brief Accessed */
A = 1 << 5,
/** @brief Dirty */
D = 1 << 6,
/** @brief Page Size */
PS = 1 << 7,
/** @brief Global */
G = 1 << 8,
/** @brief Available 0 */
AVL0 = 1 << 9,
/** @brief Available 1 */
AVL1 = 1 << 10,
/** @brief Available 2 */
AVL2 = 1 << 11,
/** @brief Page Attribute Table */
PAT = 1 << 12,
/** @brief Available 3 */
AVL3 = (uint64_t)1 << 52,
/** @brief Available 4 */
AVL4 = (uint64_t)1 << 53,
/** @brief Available 5 */
AVL5 = (uint64_t)1 << 54,
/** @brief Available 6 */
AVL6 = (uint64_t)1 << 55,
/** @brief Available 7 */
AVL7 = (uint64_t)1 << 56,
/** @brief Available 8 */
AVL8 = (uint64_t)1 << 57,
/** @brief Available 9 */
AVL9 = (uint64_t)1 << 58,
/** @brief Protection Key 0 */
PK0 = (uint64_t)1 << 59,
/** @brief Protection Key 1 */
PK1 = (uint64_t)1 << 60,
/** @brief Protection Key 2 */
PK2 = (uint64_t)1 << 61,
/** @brief Protection Key 3 */
PK3 = (uint64_t)1 << 62,
/** @brief Execute Disable */
XD = (uint64_t)1 << 63
};
typedef union __attribute__((packed))
{
struct
{
bool Present : 1;
bool ReadWrite : 1;
bool UserSupervisor : 1;
bool WriteThrough : 1;
bool CacheDisable : 1;
bool Accessed : 1;
bool Dirty : 1;
bool PageSize : 1;
bool Global : 1;
uint8_t Available1 : 3;
bool PageAttributeTable : 1;
uint64_t Reserved : 39;
uint32_t Available2 : 7;
uint16_t ProtectionKey : 4;
bool ExecuteDisable : 1;
};
uint64_t raw;
} PDEData;
struct __attribute__((packed)) PageDirectoryEntry
{
PDEData Value;
void AddFlag(uint64_t Flag) { this->Value.raw |= Flag; }
void RemoveFlags(uint64_t Flag) { this->Value.raw &= ~Flag; }
void ClearFlags() { this->Value.raw = 0; }
void SetFlag(uint64_t Flag, bool Enabled)
{
this->Value.raw &= ~Flag;
if (Enabled)
this->Value.raw |= Flag;
}
bool GetFlag(uint64_t Flag) { return (this->Value.raw & Flag) > 0 ? true : false; }
uint64_t GetFlag() { return this->Value.raw; }
void SetAddress(uint64_t Address)
{
#if defined(__amd64__)
Address &= 0x000000FFFFFFFFFF;
this->Value.raw &= 0xFFF0000000000FFF;
this->Value.raw |= (Address << 12);
#elif defined(__i386__)
Address &= 0x000FFFFF;
this->Value.raw &= 0xFFC00003;
this->Value.raw |= (Address << 12);
#elif defined(__aarch64__)
Address &= 0x000000FFFFFFFFFF;
this->Value.raw &= 0xFFF0000000000FFF;
this->Value.raw |= (Address << 12);
#endif
}
uint64_t GetAddress()
{
#if defined(__amd64__)
return (this->Value.raw & 0x000FFFFFFFFFF000) >> 12;
#elif defined(__i386__)
return (this->Value.raw & 0x003FFFFF000) >> 12;
#elif defined(__aarch64__)
return (this->Value.raw & 0x000FFFFFFFFFF000) >> 12;
#endif
}
};
struct PageTable
{
PageDirectoryEntry Entries[512];
} __attribute__((aligned(0x1000)));
class Physical
{
private:
uint64_t TotalMemory = 0;
uint64_t FreeMemory = 0;
uint64_t ReservedMemory = 0;
uint64_t UsedMemory = 0;
uint64_t PageBitmapIndex = 0;
Bitmap PageBitmap;
void ReservePage(void *Address);
void ReservePages(void *Address, uint64_t PageCount);
void UnreservePage(void *Address);
void UnreservePages(void *Address, uint64_t PageCount);
public:
/**
* @brief Get Total Memory
*
* @return uint64_t
*/
uint64_t GetTotalMemory();
/**
* @brief Get Free Memory
*
* @return uint64_t
*/
uint64_t GetFreeMemory();
/**
* @brief Get Reserved Memory
*
* @return uint64_t
*/
uint64_t GetReservedMemory();
/**
* @brief Get Used Memory
*
* @return uint64_t
*/
uint64_t GetUsedMemory();
/**
* @brief Swap page
*
* @param Address Address of the page
* @return true if swap was successful
* @return false if swap was unsuccessful
*/
bool SwapPage(void *Address);
/**
* @brief Swap pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
* @return true if swap was successful
* @return false if swap was unsuccessful
*/
bool SwapPages(void *Address, uint64_t PageCount);
/**
* @brief Unswap page
*
* @param Address Address of the page
* @return true if unswap was successful
* @return false if unswap was unsuccessful
*/
bool UnswapPage(void *Address);
/**
* @brief Unswap pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
* @return true if unswap was successful
* @return false if unswap was unsuccessful
*/
bool UnswapPages(void *Address, uint64_t PageCount);
/**
* @brief Lock page
*
* @param Address Address of the page
*/
void LockPage(void *Address);
/**
* @brief Lock pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
*/
void LockPages(void *Address, uint64_t PageCount);
/**
* @brief Request page
*
* @return void* Allocated page address
*/
void *RequestPage();
/**
* @brief Request pages
*
* @param PageCount Number of pages
* @return void* Allocated pages address
*/
void *RequestPages(uint64_t Count);
/**
* @brief Free page
*
* @param Address Address of the page
*/
void FreePage(void *Address);
/**
* @brief Free pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
*/
void FreePages(void *Address, uint64_t Count);
/** @brief Do not use. */
void Init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
/** @brief Do not use. */
Physical();
/** @brief Do not use. */
~Physical();
};
class Virtual
{
private:
PageTable *Table = nullptr;
class PageMapIndexer
{
public:
uint64_t PDP_i;
uint64_t PD_i;
uint64_t PT_i;
uint64_t P_i;
PageMapIndexer(uint64_t VirtualAddress)
{
#if defined(__amd64__)
PDP_i = (VirtualAddress & ((uint64_t)0x1FF << 39)) >> 39;
PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30;
PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21;
P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12;
#elif defined(__i386__)
PD_i = (VirtualAddress & ((uint64_t)0x3FF << 22)) >> 22;
PT_i = (VirtualAddress & ((uint64_t)0x3FF << 12)) >> 12;
P_i = (VirtualAddress & ((uint64_t)0xFFF << 0)) >> 0;
#elif defined(__aarch64__)
PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30;
PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21;
P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12;
#endif
}
};
public:
/**
* @brief Map page.
*
* @param VirtualAddress Virtual address of the page.
* @param PhysicalAddress Physical address of the page.
* @param Flags Flags of the page. Check PTFlag enum.
*/
void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags);
/**
* @brief Map multiple pages.
*
* @param VirtualAddress First virtual address of the page.
* @param PhysicalAddress First physical address of the page.
* @param PageCount Number of pages.
* @param Flags Flags of the page. Check PTFlag enum.
*/
void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t PageCount, uint64_t Flags);
/**
* @brief Unmap page.
*
* @param VirtualAddress Virtual address of the page.
*/
void Unmap(void *VirtualAddress);
/**
* @brief Unmap multiple pages.
*
* @param VirtualAddress First virtual address of the page.
* @param PageCount Number of pages.
*/
void Unmap(void *VirtualAddress, uint64_t PageCount);
/**
* @brief Construct a new Virtual object
*
* @param Table Page table. If null, it will use the current page table.
*/
Virtual(PageTable *Table = nullptr);
/**
* @brief Destroy the Virtual object
*
*/
~Virtual();
};
}
void *operator new(uint64_t Size);
void *operator new[](uint64_t Size);
void operator delete(void *Pointer);
void operator delete[](void *Pointer);
void operator delete(void *Pointer, long unsigned int Size);
void operator delete[](void *Pointer, long unsigned int Size);
extern Memory::Physical KernelAllocator;
extern Memory::PageTable *KernelPageTable;
#endif // __cplusplus
EXTERNC void InitializeMemoryManagement(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
EXTERNC void *HeapMalloc(uint64_t Size);
EXTERNC void *HeapCalloc(uint64_t n, uint64_t Size);
EXTERNC void *HeapRealloc(void *Address, uint64_t Size);
EXTERNC void HeapFree(void *Address);
#define kmalloc(Size) HeapMalloc(Size)
#define kcalloc(n, Size) HeapCalloc(n, Size)
#define krealloc(Address, Size) HeapRealloc(Address, Size)
#define kfree(Address) HeapFree(Address)
#endif // !__FENNIX_KERNEL_INTERNAL_MEMORY_H__

View File

@@ -1,33 +0,0 @@
#pragma once
#ifndef LYNX_BITMAP_TYPES_H
#define LYNX_BITMAP_TYPES_H
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __SIZE_TYPE__ size_t;
typedef __UINTPTR_TYPE__ uintptr_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
#define ALIGN_UP(x, align) ((__typeof__(x))(((uint64_t)(x) + ((align)-1)) & (~((align)-1))))
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1))))
#endif // !LYNX_BITMAP_TYPES_H
#ifdef __cplusplus
class Bitmap
{
public:
size_t Size;
uint8_t *Buffer;
bool operator[](uint64_t index);
bool Set(uint64_t index, bool value);
bool Get(uint64_t index);
};
#endif // __cplusplus

View File

@@ -1,157 +0,0 @@
#ifndef LYNX_CXXABI_TYPES_H
#define LYNX_CXXABI_TYPES_H
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __SIZE_TYPE__ size_t;
typedef __UINTPTR_TYPE__ uintptr_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
#define ALIGN_UP(x, align) ((__typeof__(x))(((uint64_t)(x) + ((align)-1)) & (~((align)-1))))
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1))))
#endif // !LYNX_CXXABI_TYPES_H
extern "C" void printf(const char *format, ...);
// TODO: complete implementation for everything
// TODO: https://wiki.osdev.org/C%2B%2B
#define ATEXIT_MAX_FUNCS 128
typedef unsigned uarch_t;
struct atexit_func_entry_t
{
/*
* Each member is at least 4 bytes large. Such that each entry is 12bytes.
* 128 * 12 = 1.5KB exact.
**/
void (*destructor_func)(void *);
void *obj_ptr;
void *dso_handle;
};
typedef enum
{
_URC_NO_REASON = 0,
_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
_URC_FATAL_PHASE2_ERROR = 2,
_URC_FATAL_PHASE1_ERROR = 3,
_URC_NORMAL_STOP = 4,
_URC_END_OF_STACK = 5,
_URC_HANDLER_FOUND = 6,
_URC_INSTALL_CONTEXT = 7,
_URC_CONTINUE_UNWIND = 8
} _Unwind_Reason_Code;
struct _Unwind_Context;
typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
typedef unsigned _Unwind_Word __attribute__((__mode__(__unwind_word__)));
typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code, struct _Unwind_Exception *);
typedef int _Unwind_Action;
struct _Unwind_Exception
{
_Unwind_Exception_Class exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup;
#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__SEH__)
_Unwind_Word private_[6];
#else
_Unwind_Word private_1;
_Unwind_Word private_2;
#endif
} __attribute__((__aligned__));
extern void *__dso_handle = 0;
atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
uarch_t __atexit_func_count = 0;
extern "C" int __cxa_atexit(void (*f)(void *), void *objptr, void *dso)
{
printf("__cxa_atexit( %p %p %p ) triggered.", f, objptr, dso);
if (__atexit_func_count >= ATEXIT_MAX_FUNCS)
return -1;
__atexit_funcs[__atexit_func_count].destructor_func = f;
__atexit_funcs[__atexit_func_count].obj_ptr = objptr;
__atexit_funcs[__atexit_func_count].dso_handle = dso;
__atexit_func_count++;
return 0;
}
extern "C" void __cxa_finalize(void *f)
{
printf("__cxa_finalize( %p ) triggered.", f);
uarch_t i = __atexit_func_count;
if (!f)
{
while (i--)
if (__atexit_funcs[i].destructor_func)
(*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
return;
}
while (i--)
if (__atexit_funcs[i].destructor_func == f)
{
(*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
__atexit_funcs[i].destructor_func = 0;
}
}
extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action actions, _Unwind_Exception_Class exception_class, _Unwind_Exception *ue_header, _Unwind_Context *context)
{
printf("__gxx_personality_v0( %d %p %p %p %p ) triggered.", version, actions, exception_class, ue_header, context);
return _URC_NO_REASON;
}
extern "C" void _Unwind_Resume(struct _Unwind_Exception *exc) { printf("_Unwind_Resume( %p ) triggered.", exc); }
extern "C" void *__cxa_allocate_exception(uint64_t thrown_size) throw()
{
printf("__cxa_allocate_exception( %#llu ) triggered.", thrown_size);
return (void *)0;
}
extern "C" void __cxa_throw(void *thrown_object, void *tinfo, void (*dest)(void *)) { printf("__cxa_throw( %p %p %p ) triggered.", thrown_object, tinfo, dest); }
extern "C" void __cxa_rethrow() { printf("__cxa_rethrow() triggered."); }
extern "C" void __cxa_pure_virtual() { printf("__cxa_pure_virtual() triggered."); }
extern "C" void __cxa_throw_bad_array_new_length() { printf("__cxa_throw_bad_array_new_length() triggered."); }
extern "C" void __cxa_free_exception(void *thrown_exception) { printf("__cxa_free_exception( %p ) triggered.", thrown_exception); }
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
extern "C" void *__cxa_begin_catch(void *e) throw()
#else
extern "C" void *__cxa_begin_catch(void *e)
#endif
{
printf("__cxa_begin_catch( %p ) triggered.", e);
return (void *)0;
}
extern "C" void __cxa_end_catch() { printf("__cxa_end_catch() triggered."); }
__extension__ typedef int __guard __attribute__((mode(__DI__)));
extern "C" int __cxa_guard_acquire(__guard *g)
{
printf("__cxa_guard_acquire( %p ) triggered.", g);
return !*(char *)(g);
}
extern "C" void __cxa_guard_release(__guard *g)
{
printf("__cxa_guard_release( %p ) triggered.", g);
*(char *)g = 1;
}
extern "C" void __cxa_guard_abort(__guard *g) { printf("__cxa_guard_abort( %p ) triggered.", g); }

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +0,0 @@
/**
* @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
* 2021-2022, Haifa, Palestine/Israel
* @author (c) Marco Paland (info@paland.com)
* 2014-2019, PALANDesign Hannover, Germany
*
* @note Others have made smaller contributions to this file: see the
* contributors page at https://github.com/eyalroz/printf/graphs/contributors
* or ask one of the authors.
*
* @brief Small stand-alone implementation of the printf family of functions
* (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with
* a very limited resources.
*
* @note the implementations are thread-safe; re-entrant; use no functions from
* the standard library; and do not dynamically allocate any memory.
*
* @license The MIT License (MIT)
*
* 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.
*/
#ifndef PRINTF_H_
#define PRINTF_H_
#include <stdarg.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __GNUC__
#define ATTR_PRINTF(one_based_format_index, first_arg) \
__attribute__((format(__printf__, (one_based_format_index), (first_arg))))
#define ATTR_VPRINTF(one_based_format_index) ATTR_PRINTF((one_based_format_index), 0)
#else
#define ATTR_PRINTF((one_based_format_index), (first_arg))
#define ATTR_VPRINTF(one_based_format_index)
#endif
#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES 0
#endif
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
#define printf_ printf
#define sprintf_ sprintf
#define vsprintf_ vsprintf
#define snprintf_ snprintf
#define vsnprintf_ vsnprintf
#define vprintf_ vprintf
#endif
// If you want to include this implementation file directly rather than
// link against, this will let you control the functions' visibility,
// e.g. make them static so as not to clash with other objects also
// using them.
#ifndef PRINTF_VISIBILITY
#define PRINTF_VISIBILITY
#endif
/**
* Prints/send a single character to some opaque output entity
*
* @note This function is not implemented by the library, only declared; you must provide an
* implementation if you wish to use the @ref printf / @ref vprintf function (and possibly
* for linking against the library, if your toolchain does not support discarding unused functions)
*
* @note The output could be as simple as a wrapper for the `write()` system call on a Unix-like
* system, or even libc's @ref putchar , for replicating actual functionality of libc's @ref printf
* function; but on an embedded system it may involve interaction with a special output device,
* like a UART, etc.
*
* @note in libc's @ref putchar, the parameter type is an int; this was intended to support the
* representation of either a proper character or EOF in a variable - but this is really not
* meaningful to pass into @ref putchar and is discouraged today. See further discussion in:
* @link https://stackoverflow.com/q/17452847/1593077
*
* @param c the single character to print
*/
PRINTF_VISIBILITY
void putchar(char c);
/**
* An implementation of the C standard's printf/vprintf
*
* @note you must implement a @ref putchar_ function for using this function - it invokes @ref putchar_
* rather than directly performing any I/O (which insulates it from any dependence on the operating system
* and external libraries).
*
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each %-specifier in @p format string
* @return The number of characters written into @p s, not counting the terminating null character
*/
///@{
PRINTF_VISIBILITY
int printf_(const char *format, ...) ATTR_PRINTF(1, 2);
PRINTF_VISIBILITY
int vprintf_(const char *format, va_list arg) ATTR_VPRINTF(1);
///@}
/**
* An implementation of the C standard's sprintf/vsprintf
*
* @note For security considerations (the potential for exceeding the buffer bounds), please consider using
* the size-constrained variant, @ref snprintf / @ref vsnprintf , instead.
*
* @param s An array in which to store the formatted string. It must be large enough to fit the formatted
* output!
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each specifier in @p format
* @return The number of characters written into @p s, not counting the terminating null character
*/
///@{
PRINTF_VISIBILITY
int sprintf_(char *s, const char *format, ...) ATTR_PRINTF(2, 3);
PRINTF_VISIBILITY
int vsprintf_(char *s, const char *format, va_list arg) ATTR_VPRINTF(2);
///@}
/**
* An implementation of the C standard's snprintf/vsnprintf
*
* @param s An array in which to store the formatted string. It must be large enough to fit either the
* entire formatted output, or at least @p n characters. Alternatively, it can be NULL, in which case
* nothing will be printed, and only the number of characters which _could_ have been printed is
* tallied and returned.
* @param n The maximum number of characters to write to the array, including a terminating null character
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each specifier in @p format
* @return The number of characters that COULD have been written into @p s, not counting the terminating
* null character. A value equal or larger than @p n indicates truncation. Only when the returned value
* is non-negative and less than @p n, the null-terminated string has been fully and successfully printed.
*/
///@{
PRINTF_VISIBILITY
int snprintf_(char *s, size_t count, const char *format, ...) ATTR_PRINTF(3, 4);
PRINTF_VISIBILITY
int vsnprintf_(char *s, size_t count, const char *format, va_list arg) ATTR_VPRINTF(3);
///@}
/**
* printf/vprintf with user-specified output function
*
* An alternative to @ref printf_, in which the output function is specified dynamically
* (rather than @ref putchar_ being used)
*
* @param out An output function which takes one character and a type-erased additional parameters
* @param extra_arg The type-erased argument to pass to the output function @p out with each call
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each specifier in @p format
* @return The number of characters for which the output f unction was invoked, not counting the terminating null character
*
*/
PRINTF_VISIBILITY
int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...) ATTR_PRINTF(3, 4);
PRINTF_VISIBILITY
int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg) ATTR_VPRINTF(3);
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
#undef printf_
#undef sprintf_
#undef vsprintf_
#undef snprintf_
#undef vsnprintf_
#undef vprintf_
#endif
#ifdef __cplusplus
}
#endif
#endif // PRINTF_H_

View File

@@ -1,17 +0,0 @@
#ifndef LYNX_TYPES_H
#define LYNX_TYPES_H
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __SIZE_TYPE__ size_t;
typedef __UINTPTR_TYPE__ uintptr_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
#define ALIGN_UP(x, align) ((__typeof__(x))(((uint64_t)(x) + ((align)-1)) & (~((align)-1))))
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1))))
#endif // !LYNX_TYPES_H

View File

@@ -39,7 +39,7 @@ QEMUFLAGS += -device vmware-svga -M q35 \
-device AC97,audiodev=pa1 \ -device AC97,audiodev=pa1 \
-device intel-hda \ -device intel-hda \
-device ich9-intel-hda \ -device ich9-intel-hda \
-acpitable file=tools/SSDT1.dat -acpitable file=tools/acpi/SSDT1.dat
else ifeq ($(OSARCH), i386) else ifeq ($(OSARCH), i386)
QEMUFLAGS += -M q35 \ QEMUFLAGS += -M q35 \
-usb \ -usb \
@@ -63,7 +63,7 @@ QEMUFLAGS += -M q35 \
-device AC97,audiodev=pa1 \ -device AC97,audiodev=pa1 \
-device intel-hda \ -device intel-hda \
-device ich9-intel-hda \ -device ich9-intel-hda \
-acpitable file=tools/SSDT1.dat -acpitable file=tools/acpi/SSDT1.dat
else ifeq ($(OSARCH), aarch64) else ifeq ($(OSARCH), aarch64)
QEMUFLAGS += -M raspi3b \ QEMUFLAGS += -M raspi3b \
-cpu cortex-a57 \ -cpu cortex-a57 \
@@ -72,14 +72,13 @@ QEMUFLAGS += -M raspi3b \
-serial file:serial3.dmp \ -serial file:serial3.dmp \
-serial stdio \ -serial stdio \
-kernel $(OSNAME).img \ -kernel $(OSNAME).img \
-acpitable file=tools/SSDT1.dat -acpitable file=tools/acpi/SSDT1.dat
endif endif
doxygen: doxygen:
mkdir -p doxygen-doc mkdir -p doxygen-doc
doxygen Doxyfile doxygen Doxyfile
doxygen Kernel/Doxyfile doxygen Kernel/Doxyfile
doxygen Lynx/Doxyfile
doxygen Userspace/Doxyfile doxygen Userspace/Doxyfile
doxygen Drivers/Doxyfile doxygen Drivers/Doxyfile
@@ -94,11 +93,10 @@ endif
tools: tools:
make --quiet -C tools all make --quiet -C tools all
make --quiet -C Kernel prepare make --quiet -C Kernel prepare
make --quiet -C Lynx prepare
make --quiet -C Userspace prepare make --quiet -C Userspace prepare
make --quiet -C Drivers prepare make --quiet -C Drivers prepare
build: build_lynx build_kernel build_userspace build_drivers build_image build: build_kernel build_userspace build_drivers build_image
dump: dump:
make --quiet -C Kernel dump make --quiet -C Kernel dump
@@ -109,11 +107,6 @@ ifeq ($(QUIET_BUILD), 1)
MAKE_QUIET_FLAG = --quiet MAKE_QUIET_FLAG = --quiet
endif endif
build_lynx:
ifeq ($(BOOTLOADER), lynx)
make $(MAKE_QUIET_FLAG) -C Lynx build
endif
build_kernel: build_kernel:
ifeq ($(BUILD_KERNEL), 1) ifeq ($(BUILD_KERNEL), 1)
make -j$(shell nproc) $(MAKE_QUIET_FLAG) -C Kernel build make -j$(shell nproc) $(MAKE_QUIET_FLAG) -C Kernel build
@@ -143,22 +136,14 @@ endif
tar cf initrd.tar -C initrd_tmp_data/ ./ --format=ustar tar cf initrd.tar -C initrd_tmp_data/ ./ --format=ustar
cp Kernel/fennix.elf initrd.tar \ cp Kernel/fennix.elf initrd.tar \
iso_tmp_data/ iso_tmp_data/
ifeq ($(BOOTLOADER), lynx)
cp tools/lynx.cfg Lynx/loader.bin Lynx/efi-loader.bin iso_tmp_data/
xorriso -as mkisofs -b loader.bin \
-no-emul-boot -boot-load-size 4 -boot-info-table \
--efi-boot efi-loader.bin -V FENNIX \
-efi-boot-part --efi-boot-image --protective-msdos-label \
iso_tmp_data -o $(OSNAME).iso
endif
ifeq ($(BOOTLOADER), limine) ifeq ($(BOOTLOADER), limine)
cp tools/limine.cfg $(LIMINE_FOLDER)/limine-bios.sys \ cp tools/limine.cfg tools/limine/limine-bios.sys \
$(LIMINE_FOLDER)/limine-bios-cd.bin \ tools/limine/limine-bios-cd.bin \
$(LIMINE_FOLDER)/limine-uefi-cd.bin \ tools/limine/limine-uefi-cd.bin \
iso_tmp_data/ iso_tmp_data/
mkdir -p iso_tmp_data/EFI/BOOT mkdir -p iso_tmp_data/EFI/BOOT
cp $(LIMINE_FOLDER)/BOOTX64.EFI \ cp tools/limine/BOOTX64.EFI \
$(LIMINE_FOLDER)/BOOTIA32.EFI \ tools/limine/BOOTIA32.EFI \
iso_tmp_data/EFI/BOOT/ iso_tmp_data/EFI/BOOT/
xorriso -as mkisofs -quiet -b limine-bios-cd.bin \ xorriso -as mkisofs -quiet -b limine-bios-cd.bin \
-no-emul-boot -boot-load-size 4 -boot-info-table \ -no-emul-boot -boot-load-size 4 -boot-info-table \
@@ -216,7 +201,7 @@ clean_logs:
vscode_debug_only: clean_logs vscode_debug_only: clean_logs
$(QEMU) -S -gdb tcp::1234 -d cpu_reset,int -no-reboot -no-shutdown $(QEMU_UEFI_BIOS) -m 512M $(QEMUFLAGS) $(QEMU_SMP_DBG) $(QEMU) -S -gdb tcp::1234 -d cpu_reset,int -no-reboot -no-shutdown $(QEMU_UEFI_BIOS) -m 512M $(QEMUFLAGS) $(QEMU_SMP_DBG)
vscode_debug: build_lynx build_kernel build_userspace build_drivers build_image vscode_debug_only vscode_debug: build_kernel build_userspace build_drivers build_image vscode_debug_only
qemu: qemu_vdisk clean_logs qemu: qemu_vdisk clean_logs
touch serial.log parallel.log touch serial.log parallel.log
@@ -233,6 +218,5 @@ clean: clean_logs
rm -rf doxygen-doc iso_tmp_data initrd_tmp_data rm -rf doxygen-doc iso_tmp_data initrd_tmp_data
rm -f initrd.tar $(OSNAME).iso $(OSNAME).img rm -f initrd.tar $(OSNAME).iso $(OSNAME).img
make -C Kernel clean make -C Kernel clean
make -C Lynx clean
make -C Userspace clean make -C Userspace clean
make -C Drivers clean make -C Drivers clean

View File

@@ -13,13 +13,12 @@ KERNEL_VERSION = dev
# Which bootloader to use. # Which bootloader to use.
# Available bootloaders: # Available bootloaders:
# - lynx - Lynx (under development)
# - grub - GRUB # - grub - GRUB
# - limine - Limine # - limine - Limine
BOOTLOADER = grub BOOTLOADER = grub
BUILD_KERNEL = 1 BUILD_KERNEL = 1
BUILD_USERSPACE = 1 #BUILD_USERSPACE = 1
BUILD_DRIVERS = 1 BUILD_DRIVERS = 1
QUIET_BUILD = 1 QUIET_BUILD = 1
@@ -27,9 +26,6 @@ QUIET_BUILD = 1
# The path of the cross-compiler. # The path of the cross-compiler.
COMPILER_PATH = tools/cross/bin COMPILER_PATH = tools/cross/bin
# The path of the Limine bootloader.
LIMINE_FOLDER = tools/limine
# Qemu path. If you want to use the one # Qemu path. If you want to use the one
# you have installed in your system, change # you have installed in your system, change
# it to /usr/bin/qemu-system- # it to /usr/bin/qemu-system-

View File

@@ -8,7 +8,7 @@ Opeating System from scratch made in C and C++
- Clone repo using: - Clone repo using:
```bash ```bash
git clone --recurse-submodules https://github.com/Fennix-Project/Fennix.git git clone --recurse-submodules https://github.com/EnderIce2/Fennix.git
``` ```
- Build the cross-compiler and other tools: - Build the cross-compiler and other tools:
@@ -30,5 +30,3 @@ make run
```bash ```bash
make clean make clean
``` ```
More info about compiling and running [here](https://fennix.enderice2.software/).

View File

@@ -1,6 +1,3 @@
[submodule "apps/user/games/doomgeneric"]
path = apps/user/games/doomgeneric
url = https://github.com/Fennix-Project/doomgeneric.git
[submodule "musl"] [submodule "musl"]
path = musl path = musl
url = https://github.com/Fennix-Project/musl.git url = https://git.musl-libc.org/cgit/musl

View File

@@ -1,6 +1,6 @@
BSD 3-Clause License BSD 3-Clause License
Copyright (c) 2023, EnderIce2 Copyright (c) 2024, EnderIce2
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -30,23 +30,6 @@ ifeq ($(DEBUG), 1)
MUSL_CONFIGURE_FLAGS += --enable-debug MUSL_CONFIGURE_FLAGS += --enable-debug
endif endif
build_musl:
ifeq ($(wildcard cache/musl),)
mkdir -p cache/musl
cd cache/musl && \
../../musl/configure --prefix=$(PREFIX) \
--target=$(TARGET) --includedir=$(PREFIX)/include \
$(MUSL_CONFIGURE_FLAGS)
make -C cache/musl -j$(shell nproc)
endif
$(info Installing musl libc)
cd cache/musl && make TARGET=$(TARGET) install
# cp out/lib/crt1.o out/lib/crt0.o
cd out/lib && ln -s /lib/libc.so ./ld-musl-x86_64.so.1 && \
ln -s /lib/libc.so ./ld.so
mkdir -p out/include/fennix
cp ../Kernel/include/interface/syscalls.h out/include/fennix/syscall.h
create_out: create_out:
rm -rf out rm -rf out
mkdir -p out mkdir -p out
@@ -60,11 +43,7 @@ create_out:
mkdir -p out/usr/include mkdir -p out/usr/include
build: create_out build: create_out
ifeq ($(USE_LIBC), internal)
make -C libc build make -C libc build
else ifeq ($(USE_LIBC), musl)
$(MAKE) build_musl
endif
make -C libs build make -C libs build
make -C apps build make -C apps build

View File

@@ -1,11 +1 @@
# Userspace # Userspace
This repo contains the userspace programs that are part of the Fennix operating system.
---
Use `Fennix` repo to build the operating system.
```bash
git clone --recurse-submodules https://github.com/Fennix-Project/Fennix.git
```

View File

@@ -1,5 +1,5 @@
build: build:
make -C doomgeneric build # make -C doomgeneric build
clean: clean:
make -C doomgeneric clean # make -C doomgeneric clean

Submodule Userspace/apps/user/games/doomgeneric deleted from b961b5551b

Submodule Userspace/musl deleted from 718f363bc2

13
compose.yaml Normal file
View File

@@ -0,0 +1,13 @@
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Docker Compose reference guide at
# https://docs.docker.com/go/compose-spec-reference/
# Here the instructions define your application as a service called "app".
# This service is built from the Dockerfile in the current directory.
# You can add other services your application may depend on here, such as a
# database or a cache. For examples, see the Awesome Compose repository:
# https://github.com/docker/awesome-compose
services:
iso:
build:
context: .

View File

@@ -1,147 +0,0 @@
// FEX is a file format. Right now in development.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "../Kernel/Fex.hpp"
void DumpData(const char *Description, unsigned char *Address, unsigned long Length)
{
printf("-------------------------------------------------------------------------\n");
unsigned char Buffer[17];
unsigned long Iterate;
if (Description != NULL)
printf("%s:\n", Description);
for (Iterate = 0; Iterate < Length; Iterate++)
{
if ((Iterate % 16) == 0)
{
if (Iterate != 0)
printf(" %s\n", Buffer);
printf(" %04x ", Iterate);
}
printf(" %02x", Address[Iterate]);
if ((Address[Iterate] < 0x20) || (Address[Iterate] > 0x7e))
Buffer[Iterate % 16] = '.';
else
Buffer[Iterate % 16] = Address[Iterate];
Buffer[(Iterate % 16) + 1] = '\0';
}
while ((Iterate % 16) != 0)
{
printf(" ");
Iterate++;
}
printf(" %s\n", Buffer);
printf("-------------------------------------------------------------------------\n");
}
int main()
{
FILE *FilePointer;
char FileName[20];
unsigned char *Buffer;
char BufferChar;
struct stat st;
printf("--- FEX file viewer ---\n");
FileSelection:
printf("File Name: ");
fgets(FileName, 20, stdin);
FileName[strcspn(FileName, "\r\n")] = 0;
FilePointer = fopen(FileName, "r");
if (NULL == FilePointer)
{
printf("Error opening file %s. Try again...\n", FileName);
FileName[0] = 0;
goto FileSelection;
}
stat(FileName, &st);
Buffer = (unsigned char *)malloc(st.st_size);
fread(Buffer, 1, st.st_size, FilePointer);
DumpData(FileName, Buffer, st.st_size);
struct Fex *FexFile = Buffer;
if (FexFile->Magic[0] != 'F' || FexFile->Magic[1] != 'E' || FexFile->Magic[2] != 'X' || FexFile->Magic[3] != '\0')
{
printf("Invalid FEX header. Checking if it's in an ELF file...\n");
if (st.st_size > 0x1000)
{
struct Fex *FexFile = (struct Fex *)(Buffer + 0x1000);
if (FexFile->Magic[0] != 'F' || FexFile->Magic[1] != 'E' || FexFile->Magic[2] != 'X' || FexFile->Magic[3] != '\0')
{
printf("Invalid FEX header. Exiting...\n");
fclose(FilePointer);
free(Buffer);
return 1;
}
}
else
{
printf("Invalid FEX header. Exiting...\n");
fclose(FilePointer);
free(Buffer);
return 1;
}
}
struct FexExtended *FexExtendedFile = (struct FexExtended *)(Buffer + EXTENDED_SECTION_ADDRESS);
printf("┌FEX File:\n");
printf("├Magic: %c%c%c%c\n", FexFile->Magic[0], FexFile->Magic[1], FexFile->Magic[2], FexFile->Magic[3]);
printf("├Type: %d\n", FexFile->Type);
printf("├Operating System: %d\n", FexFile->OS);
printf("├Entry Point: %#lx\n", FexFile->EntryPoint);
printf("\n");
printf("├FEX Extended Header:\n");
printf("│ ├Executable:\n");
printf("│ │ └<not implemented>\n");
// TODO: Add more stuff to executable category.
printf("│ ├Driver:\n");
printf("│ │ ├Name: %s\n", FexExtendedFile->Driver.Name);
printf("│ │ ├Type: %d\n", FexExtendedFile->Driver.Type);
printf("│ │ ├Callback: %#lx\n", FexExtendedFile->Driver.Callback);
printf("│ │ ├Bind:\n");
printf("│ │ │ ├Type: %d\n", FexExtendedFile->Driver.Bind.Type);
printf("│ │ │ ├Interrupt:\n");
printf("│ │ │ │ └Vectors: ");
for (int i = 0; i < 16; i++)
printf("%#x ", FexExtendedFile->Driver.Bind.Interrupt.Vector[i]);
printf("\n");
printf("│ │ │ ├Process:\n");
printf("│ │ │ │ └Process IDs: ");
for (int i = 0; i < 16; i++)
printf("%d ", FexExtendedFile->Driver.Bind.Process.ProcessId[i]);
printf("\n");
printf("│ │ │ ├PCI:\n");
printf("│ │ │ │ ├Vendor IDs: ");
for (int i = 0; i < 16; i++)
printf("%#x ", FexExtendedFile->Driver.Bind.PCI.VendorID[i]);
printf("\n");
printf("│ │ │ │ ├Device IDs: ");
for (int i = 0; i < 16; i++)
printf("%#x ", FexExtendedFile->Driver.Bind.PCI.DeviceID[i]);
printf("\n");
printf("│ │ │ │ ├Class: %#x\n", FexExtendedFile->Driver.Bind.PCI.Class);
printf("│ │ │ │ ├SubClass: %#x\n", FexExtendedFile->Driver.Bind.PCI.SubClass);
printf("│ │ │ │ └ProgIF: %#x\n", FexExtendedFile->Driver.Bind.PCI.ProgIF);
printf("│ │ │ ├Input:\n");
printf("│ │ │ │ ├Attach to mouse: %s\n", FexExtendedFile->Driver.Bind.Input.AttachToMouse ? "true" : "false");
printf("│ │ │ │ └Attach to keyboard: %s\n", FexExtendedFile->Driver.Bind.Input.AttachToKeyboard ? "true" : "false");
printf("┊ ┊ ┊ ┊\n");
fclose(FilePointer);
free(Buffer);
return 0;
}

View File

@@ -1,82 +1,136 @@
WORKING_DIR = $(shell pwd) WORKING_DIR = $(CURDIR)
CROSS_DIR=$(WORKING_DIR)/cross CROSS_DIR=$(WORKING_DIR)/cross
export PATH := $(CROSS_DIR):$(PATH) export PATH := $(CROSS_DIR):$(PATH)
QEMU_VERSION = 8.1.2 QEMU_VERSION = 8.2.8
all: do_rep do_ep do_limine clone_all do_binutils_64 do_gcc_64 do_binutils_32 do_gcc_32 do_qemu all: do_tools do_limine __clone_all do_binutils do_gcc do_qemu
clean: clean:
rm -f rep ep fex rm -f rep ep
do_rep: do_tools:
gcc -w ReadEthernetPackets.c -o rep gcc -w ReadEthernetPackets.c -o rep
chmod +x rep
do_ep:
g++ -w ErrorParser.cpp -o ep g++ -w ErrorParser.cpp -o ep
chmod +x rep
chmod +x ep chmod +x ep
do_limine: do_limine:
git clone https://github.com/limine-bootloader/limine.git --branch=v6.x-branch-binary --depth=1 ifeq ("$(wildcard ./limine)", "")
git clone https://github.com/limine-bootloader/limine.git --branch=v6.x-branch-binary --depth=1 limine
else
$(info > TOOLS: Skipping cloning limine because directory already exists.)
endif
__clone_qemu: __clone_qemu:
ifeq ("$(wildcard ./qemu)", "")
wget https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz wget https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz
tar xvJf qemu-${QEMU_VERSION}.tar.xz tar xvJf qemu-${QEMU_VERSION}.tar.xz
rm -f qemu-${QEMU_VERSION}.tar.xz rm -f qemu-${QEMU_VERSION}.tar.xz
mv qemu-${QEMU_VERSION} qemu mv qemu-${QEMU_VERSION} qemu
else
$(info > TOOLS: Skipping downloading qemu because directory already exists.)
endif
__clone_all_no_qemu: .PHONY: all clean __clone_binutils __clone_gcc __prep_cross __patch_cross __patch_cross_binutils __patch_cross_gcc
git clone -b binutils-2_42-branch --single-branch https://github.com/Fennix-Project/binutils-gdb.git binutils-gdb
git clone -b releases/gcc-13 --single-branch https://github.com/Fennix-Project/gcc.git gcc __clone_binutils:
cd gcc && $(shell ./contrib/download_prerequisites) ifeq ("$(wildcard ./binutils-gdb)", "")
git clone --depth 1 -b binutils-2_43_1 --single-branch git://sourceware.org/git/binutils-gdb.git binutils-gdb
else
$(info > TOOLS: Reseting binutils-gdb...)
cd binutils-gdb && \
git fetch origin && \
git reset --hard binutils-2_43_1 && \
git clean -dfx
$(info > TOOLS: Operation completed for binutils-gdb)
endif
__clone_gcc:
ifeq ("$(wildcard ./gcc)", "")
git clone --depth 1 -b releases/gcc-14.2.0 --single-branch git://gcc.gnu.org/git/gcc.git gcc
else
$(info > TOOLS: Reseting gcc...)
cd gcc && \
git fetch origin && \
git reset --hard releases/gcc-14.2.0 && \
git clean -dfx
$(info > TOOLS: Operation completed for gcc)
endif
__patch_cross_binutils: __clone_binutils
$(info > TOOLS: Patching binutils-gcc)
cd binutils-gdb && git apply ../binutils-gdb.patch
$(info > TOOLS: Running automake for binutils-gdb/ld)
cd binutils-gdb/ld && automake
__patch_cross_gcc: __clone_gcc
$(info > TOOLS: Patching gcc)
cd gcc && git apply ../gcc.patch
cd gcc && ./contrib/download_prerequisites
$(info > TOOLS: Running autoconf for gcc/libstdc++-v3)
cd gcc/libstdc++-v3 && autoconf
__patch_cross: __patch_cross_binutils __patch_cross_gcc
__prep_cross:
mkdir -p cross mkdir -p cross
mkdir -p build-binutils64 mkdir -p binutils-gdb/__build
mkdir -p build-gcc64 mkdir -p gcc/__build
mkdir -p build-binutils32
mkdir -p build-gcc32
clone_all: __clone_qemu __clone_all_no_qemu __clone_all_no_qemu: __clone_binutils __clone_gcc
do_qemu: __clone_all: __clone_qemu __clone_all_no_qemu
do_qemu: __prep_cross
cd qemu && \ cd qemu && \
bash ./configure --target-list=x86_64-softmmu,i386-softmmu,aarch64-softmmu \ bash ./configure --target-list=x86_64-softmmu,i386-softmmu,aarch64-softmmu \
--prefix="$(CROSS_DIR)" \ --prefix="$(CROSS_DIR)" \
--enable-gtk --disable-tools \ --enable-gtk --disable-tools \
--disable-gio --disable-virtfs --disable-vnc \ --disable-gio --disable-virtfs --disable-vnc \
--disable-opengl && \ --disable-opengl && \
make -j$(shell nproc) && make install make --quiet -j$(shell nproc) && make --quiet install
do_binutils_64: do_binutils:
cd build-binutils64 && \ # x86_64
../binutils-gdb/configure --target=x86_64-fennix \ $(MAKE) __patch_cross_binutils
--prefix="$(CROSS_DIR)" --disable-nls \ $(MAKE) __prep_cross
cd binutils-gdb/__build && \
../configure --target=x86_64-fennix \
--prefix="$(CROSS_DIR)" --disable-nls --quiet \
--with-sysroot --enable-shared --disable-werror && \ --with-sysroot --enable-shared --disable-werror && \
make all -j$(shell nproc) && make install make --quiet all -j$(shell nproc) && \
make --quiet install
# i386
$(MAKE) __patch_cross_binutils
$(MAKE) __prep_cross
cd binutils-gdb/__build && \
../configure --target=i386-fennix \
--prefix="$(CROSS_DIR)" --disable-nls --quiet \
--with-sysroot --enable-shared --disable-werror && \
make --quiet all -j$(shell nproc) && \
make --quiet install
do_gcc_64: do_gcc:
cd build-gcc64 && \ # x86_64
../gcc/configure --target=x86_64-fennix \ $(MAKE) __patch_cross_gcc
$(MAKE) __prep_cross
cd gcc/__build && \
../configure --target=x86_64-fennix --quiet \
--prefix="$(CROSS_DIR)" --disable-nls --enable-default-pie \ --prefix="$(CROSS_DIR)" --disable-nls --enable-default-pie \
--enable-languages=c,c++ --enable-shared --without-headers && \ --enable-languages=c,c++ --enable-shared --without-headers && \
make all-gcc -j$(shell nproc) && \ make --quiet all-gcc -j$(shell nproc) && \
make all-target-libgcc -j$(shell nproc) && \ make --quiet all-target-libgcc -j$(shell nproc) && \
make install-gcc -j$(shell nproc) && \ make --quiet install-gcc -j$(shell nproc) && \
make install-target-libgcc -j$(shell nproc) make --quiet install-target-libgcc -j$(shell nproc)
# i386
do_binutils_32: $(MAKE) __patch_cross_gcc
cd build-binutils32 && \ $(MAKE) __prep_cross
../binutils-gdb/configure --target=i386-fennix \ cd gcc/__build && \
--prefix="$(CROSS_DIR)" --disable-nls \ ../configure --target=i386-fennix --quiet \
--with-sysroot --enable-shared --disable-werror && \
make all -j$(shell nproc) && make install
do_gcc_32:
cd build-gcc32 && \
../gcc/configure --target=i386-fennix \
--prefix="$(CROSS_DIR)" --disable-nls --enable-default-pie \ --prefix="$(CROSS_DIR)" --disable-nls --enable-default-pie \
--enable-languages=c,c++ --enable-shared --without-headers && \ --enable-languages=c,c++ --enable-shared --without-headers && \
make all-gcc -j$(shell nproc) && \ make --quiet all-gcc -j$(shell nproc) && \
make all-target-libgcc -j$(shell nproc) && \ make --quiet all-target-libgcc -j$(shell nproc) && \
make install-gcc -j$(shell nproc) && \ make --quiet install-gcc -j$(shell nproc) && \
make install-target-libgcc -j$(shell nproc) make --quiet install-target-libgcc -j$(shell nproc)

127
tools/binutils-gdb.patch Normal file
View File

@@ -0,0 +1,127 @@
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 6553aac1e99..40429e9bf43 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -1502,6 +1502,20 @@ case "${targ}" in
;;
#endif
+ i[3-7]86-*-fennix*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs=
+ targ64_selvecs=x86_64_elf64_vec
+ ;;
+
+#ifdef BFD64
+ x86_64-*-fennix*)
+ targ_defvec=x86_64_elf64_vec
+ targ_selvecs=i386_elf32_vec
+ want64=true
+ ;;
+#endif
+
# END OF targmatch.h
bpf-*-*)
echo "*** Configuration $targ is not fully supported." >&2
diff --git a/config.sub b/config.sub
index 2c6a07ab3c3..d279b50dc8b 100755
--- a/config.sub
+++ b/config.sub
@@ -1768,7 +1768,7 @@ case $os in
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* | mlibc* | cos* | mbr* | ironclad* )
+ | fiwix* | mlibc* | cos* | mbr* | ironclad* | fennix* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
diff --git a/gas/configure.tgt b/gas/configure.tgt
index d58f21873a3..fa4215b9cff 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -267,6 +267,7 @@ case ${generic_target} in
i386-*-*nt*) fmt=coff em=pe ;;
i386-*-rdos*) fmt=elf ;;
i386-*-darwin*) fmt=macho ;;
+ i386-*-fennix*) fmt=elf em=gnu ;;
ia16-*-elf*) fmt=elf ;;
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 6a9833e5775..fb4f866ef55 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -279,6 +279,7 @@ ALL_EMULATION_SOURCES = \
eelf_i386.c \
eelf_i386_be.c \
eelf_i386_fbsd.c \
+ eelf_i386_fennix.c \
eelf_i386_haiku.c \
eelf_i386_ldso.c \
eelf_i386_sol2.c \
@@ -463,6 +464,7 @@ ALL_64_EMULATION_SOURCES = \
eelf_x86_64.c \
eelf_x86_64_cloudabi.c \
eelf_x86_64_fbsd.c \
+ eelf_x86_64_fennix.c \
eelf_x86_64_haiku.c \
eelf_x86_64_sol2.c \
ehppa64linux.c \
diff --git a/ld/configure.tgt b/ld/configure.tgt
index f937f78b876..ea5491a1447 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -409,6 +409,11 @@ i[3-7]86-*-elf* | i[3-7]86-*-rtems* | i[3-7]86-*-genode*)
i[3-7]86-*-dragonfly*) targ_emul=elf_i386
targ_extra_emuls="elf_iamcu i386bsd"
;;
+i[3-7]86-*-fennix*)
+ targ_emul=elf_i386_fennix
+ targ_extra_emuls=elf_i386
+ targ64_extra_emuls="elf_x86_64_fennix elf_x86_64"
+ ;;
i[3-7]86-*-freebsd* | i[3-7]86-*-kfreebsd*-gnu)
targ_emul=elf_i386_fbsd
targ_extra_emuls="elf_i386 elf_iamcu i386bsd"
@@ -1045,6 +1050,9 @@ x86_64-*-elf* | x86_64-*-rtems* | x86_64-*-fuchsia* | x86_64-*-genode*)
x86_64-*-dragonfly*) targ_emul=elf_x86_64
targ_extra_emuls="elf_i386 elf_iamcu"
;;
+x86_64-*-fennix*) targ_emul=elf_x86_64_fennix
+ targ_extra_emuls="elf_i386_fennix elf_x86_64 elf_i386"
+ ;;
x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
targ_emul=elf_x86_64_fbsd
targ_extra_emuls="elf_i386_fbsd elf_x86_64 elf_i386 elf_iamcu"
@@ -1112,6 +1120,10 @@ case "${target}" in
NATIVE_LIB_DIRS='/lib /usr/lib /usr/pkg/lib /usr/local/lib'
;;
+*-*-fennix*)
+ NATIVE_LIB_DIRS='/lib /usr/lib'
+ ;;
+
*-*-freebsd*)
NATIVE_LIB_DIRS='/lib /usr/lib /usr/local/lib'
;;
diff --git a/ld/emulparams/elf_i386_fennix.sh b/ld/emulparams/elf_i386_fennix.sh
new file mode 100644
index 00000000000..19b75a06cf9
--- /dev/null
+++ b/ld/emulparams/elf_i386_fennix.sh
@@ -0,0 +1,4 @@
+source_sh ${srcdir}/emulparams/elf_i386.sh
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_PIE_SCRIPT=yes
+TEXT_START_ADDR=0x400000
diff --git a/ld/emulparams/elf_x86_64_fennix.sh b/ld/emulparams/elf_x86_64_fennix.sh
new file mode 100644
index 00000000000..1509ec7fe53
--- /dev/null
+++ b/ld/emulparams/elf_x86_64_fennix.sh
@@ -0,0 +1,4 @@
+source_sh ${srcdir}/emulparams/elf_x86_64.sh
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_PIE_SCRIPT=yes
+TEXT_START_ADDR=0x400000

157
tools/gcc.patch Normal file
View File

@@ -0,0 +1,157 @@
diff --git a/config.sub b/config.sub
index 38f3d037a78..e15a98ae991 100755
--- a/config.sub
+++ b/config.sub
@@ -1749,7 +1749,7 @@ case $os in
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* )
+ | fiwix* | fennix* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 95c91ee02be..2f3e3b006dd 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -825,6 +825,14 @@ case ${target} in
rust_target_objs="${rust_target_objs} dragonfly-rust.o"
target_has_targetrustm=yes
;;
+*-*-fennix*)
+ tmake_file="t-fennix "
+ gas=yes
+ gnu_ld=yes
+ default_use_cxa_atexit=yes
+ use_gcc_stdint=provide
+ native_system_header_dir=/include
+ ;;
*-*-freebsd*)
# This is the generic ELF configuration of FreeBSD. Later
# machine-specific sections may refine and add to this
@@ -1981,6 +1989,14 @@ x86_64-*-openbsd*)
gas=yes
gnu_ld=yes
;;
+i[34567]86-*-fennix*)
+ tmake_file="${tmake_file} i386/t-fennix"
+ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h fennix.h"
+ ;;
+x86_64-*-fennix*)
+ tmake_file="${tmake_file} i386/t-fennix"
+ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h i386/x86-64.h fennix.h"
+ ;;
i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu)
# Intel 80386's running GNU/*
# with ELF format using glibc 2
diff --git a/gcc/config/fennix.h b/gcc/config/fennix.h
new file mode 100644
index 00000000000..3739abe7983
--- /dev/null
+++ b/gcc/config/fennix.h
@@ -0,0 +1,59 @@
+
+#undef TARGET_FENNIX
+#define TARGET_FENNIX 1
+
+#undef LIB_SPEC
+#define LIB_SPEC "-lc"
+
+#undef CPP_SPEC
+#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_POSIX_THREADS}"
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "crti.o%s \
+ %{!shared: \
+ %{!static: \
+ crtbeginS.o%s Scrt1.o%s \
+ } \
+ } \
+ %{static:crtbegin.o%s crt1.o%s}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "crtn.o%s \
+ %{!shared: \
+ %{!static: \
+ crtendS.o%s \
+ } \
+ } \
+ %{static:crtend.o%s}"
+
+#undef STANDARD_STARTFILE_PREFIX
+#define STANDARD_STARTFILE_PREFIX "/lib/"
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "%{shared:-shared} \
+ %{static:-static} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ } \
+ } \
+ %{!static: \
+ %{!dynamic-linker: \
+ -dynamic-linker=/lib/ld.so \
+ } \
+ } \
+ -z max-page-size=4096"
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define("__fennix__"); \
+ builtin_define("__unix__"); \
+ builtin_assert("system=fennix"); \
+ builtin_assert("system=unix"); \
+ builtin_assert("system=posix"); \
+ } while (0);
diff --git a/gcc/config/i386/t-fennix b/gcc/config/i386/t-fennix
new file mode 100644
index 00000000000..8223e63c0c9
--- /dev/null
+++ b/gcc/config/i386/t-fennix
@@ -0,0 +1,2 @@
+MULTILIB_OPTIONS += mno-red-zone
+MULTILIB_DIRNAMES += no-red-zone
diff --git a/libgcc/config.host b/libgcc/config.host
index e75a7af647f..12ecba7be60 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -760,6 +760,14 @@ x86_64-*-dragonfly*)
tmake_file="${tmake_file} i386/t-dragonfly i386/t-crtstuff"
md_unwind_header=i386/dragonfly-unwind.h
;;
+i[34567]86-*-fennix*)
+ extra_parts="$extra_parts crti.o crtn.o crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
+ ;;
+x86_64-*-fennix*)
+ extra_parts="$extra_parts crti.o crtn.o crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
+ ;;
i[34567]86-*-freebsd*)
tmake_file="${tmake_file} i386/t-freebsd i386/t-crtstuff"
md_unwind_header=i386/freebsd-unwind.h
diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
index b3269cb88e0..de1f886b9a6 100644
--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -88,6 +88,13 @@ case "${host}" in
AC_DEFINE(HAVE_HYPOT)
;;
+ *-fennix*)
+ GLIBCXX_CHECK_COMPILER_FEATURES
+ GLIBCXX_CHECK_LINKER_FEATURES
+ GLIBCXX_CHECK_MATH_SUPPORT
+ GLIBCXX_CHECK_STDLIB_SUPPORT
+ ;;
+
*-freebsd*)
SECTION_FLAGS='-ffunction-sections -fdata-sections'
AC_SUBST(SECTION_FLAGS)

View File

@@ -23,7 +23,6 @@
<a class="hdrbtn" href="https://github.com/Fennix-Project/Fennix"><i class="fa-brands fa-git-alt"></i> <a class="hdrbtn" href="https://github.com/Fennix-Project/Fennix"><i class="fa-brands fa-git-alt"></i>
Contribute</a> Contribute</a>
<a class="hdrbtn" href="/fulldoc"><i class="fa-solid fa-book-bookmark"></i> Full Documentation</a> <a class="hdrbtn" href="/fulldoc"><i class="fa-solid fa-book-bookmark"></i> Full Documentation</a>
<a class="hdrbtn" href="/lynx"><i class="fa-solid fa-file-code"></i> Lynx Bootloader</a>
<a class="hdrbtn" href="/kernel"><i class="fa-solid fa-file-code"></i> Kernel</a> <a class="hdrbtn" href="/kernel"><i class="fa-solid fa-file-code"></i> Kernel</a>
<a class="hdrbtn" href="/drivers"><i class="fa-solid fa-file-code"></i> Drivers</a> <a class="hdrbtn" href="/drivers"><i class="fa-solid fa-file-code"></i> Drivers</a>
<a class="hdrbtn" href="/userspace"><i class="fa-solid fa-file-code"></i> Userspace</a> <a class="hdrbtn" href="/userspace"><i class="fa-solid fa-file-code"></i> Userspace</a>
@@ -90,7 +89,7 @@
<code class="panel">OSARCH</code> &#x2022; The architecture of the kernel. Supported values are: <code class="panel">amd64</code> <code class="panel">i386</code> <code class="panel">aarch64</code>.<br> <code class="panel">OSARCH</code> &#x2022; The architecture of the kernel. Supported values are: <code class="panel">amd64</code> <code class="panel">i386</code> <code class="panel">aarch64</code>.<br>
<code class="panel">KERNEL_VERSION</code> &#x2022; The version of the kernel. This can be anything.<br> <code class="panel">KERNEL_VERSION</code> &#x2022; The version of the kernel. This can be anything.<br>
<code class="panel">BOOTLOADER</code> &#x2022; The bootloader to be used. If set to <code class="panel">other</code>, the bootloader will be <a href="https://github.com/limine-bootloader/limine" target="_blank">Limine</a> for 64-bit, or <code class="panel">BOOTLOADER</code> &#x2022; The bootloader to be used. If set to <code class="panel">other</code>, the bootloader will be <a href="https://github.com/limine-bootloader/limine" target="_blank">Limine</a> for 64-bit, or
with <a href="https://www.gnu.org/software/grub/" target="_blank">GRUB</a> if 32-bit. <code class="panel">lynx</code> it's still under development.<br> with <a href="https://www.gnu.org/software/grub/" target="_blank">GRUB</a> if 32-bit.
<code class="panel">COMPILER_PATH</code> &#x2022; The path of the cross compiler. If you want to use your own cross compiler, change it to the path of the compiler.<br> <code class="panel">COMPILER_PATH</code> &#x2022; The path of the cross compiler. If you want to use your own cross compiler, change it to the path of the compiler.<br>
<code class="panel">LIMINE_FOLDER</code> &#x2022; The path of the Limine bootloader.<br> <code class="panel">LIMINE_FOLDER</code> &#x2022; The path of the Limine bootloader.<br>
<code class="panel">QEMU_PATH</code> &#x2022; Qemu path. If you want to use the one you have installed in your system, change it to /usr/bin/qemu-system- (do not include x86_64 or i386, it will be added automatically) <code class="panel">QEMU_PATH</code> &#x2022; Qemu path. If you want to use the one you have installed in your system, change it to /usr/bin/qemu-system- (do not include x86_64 or i386, it will be added automatically)

View File

@@ -2,5 +2,4 @@ User-agent: *
Disallow: /userspace/ Disallow: /userspace/
Disallow: /drivers/ Disallow: /drivers/
Disallow: /kernel/ Disallow: /kernel/
Disallow: /lynx/ Disallow: /fulldoc/
Disallow: /fulldoc/