74 Commits

Author SHA1 Message Date
04edfd46bb chore: rename workflow from 'Build OS' to 'Deploy Documentation'
[skip ci]

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 20:35:57 +02:00
082f2fb6f2 kernel: Fix release compilation on amd64
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 20:34:57 +02:00
94cdd71e1e chore: migrate documentation deployment to a new workflow
[skip ci]

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 20:30:14 +02:00
c22c079628 chore: todo
Some checks failed
Build OS / Build amd64 (push) Blocked by required conditions
Build OS / Build i386 (push) Blocked by required conditions
Build OS / Build aarch64 (push) Blocked by required conditions
CodeQL Advanced / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Failing after 3m8s
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 1m52s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 1h9m55s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 20:26:08 +02:00
6024a2347b chore: Add CodeQL advanced analysis workflow
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 20:23:34 +02:00
c723a5f82d chore: Allow aarch64 build job
[skip ci]

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 20:19:10 +02:00
a6d2d51870 chore: Remove CodeQL analysis steps from makefile.yml workflow
[skip ci]

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 20:03:08 +02:00
fb186f6615 chore: Remove Flawfinder analysis steps from makefile.yml workflow
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 19:55:35 +02:00
0160fa3c72 chore: Update flawfinder scan minimum level from 4 to 5 in makefile.yml
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 19:47:21 +02:00
d77d6892a0 chore: Enhance makefile.yml to recheck and install specific versions of automake and autoconf
Some checks failed
Build OS / Build i386 (push) Blocked by required conditions
Build OS / Build aarch64 (push) Blocked by required conditions
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 1m32s
Build OS / Build Cross-Compiler & Toolchain (push) Successful in 1h8m49s
Build OS / Flawfinder (push) Failing after 3m17s
Build OS / Analyze with CodeQL (cpp) (push) Failing after 3m27s
Build OS / Build amd64 (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:59:04 +02:00
2b1ec40dc3 chore: Add automake installation to makefile.yml workflow
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:49:43 +02:00
a1fa698bc3 chore: Update autoconf installation command to use dpkg with force option
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:46:40 +02:00
4c0cb59aa7 chore: Remove autoconf purge step and adjust installation method for autoconf
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 1m46s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 13m37s
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
Build OS / Flawfinder (push) Failing after 2m29s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:37:32 +02:00
f015ff606f chore: Update makefile.yml to install automake alongside autoconf
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 2m2s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 1m16s
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
Build OS / Flawfinder (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:33:52 +02:00
df0c17b50f chore: Update autoconf workflow to also purge and install automake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:30:46 +02:00
9a9ee7e571 chore: Update autoconf installation method in workflow to use Debian package
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:26:24 +02:00
e7e248bc3a chore: Fix typo in package installation command in makefile.yml
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 1m30s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 38s
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
Build OS / Flawfinder (push) Failing after 2m52s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:17:21 +02:00
bbc6212cfa chore: Enhance GCC installation workflow with autoconf recheck and libtool addition
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:15:58 +02:00
170922e1be chore: Purge autoconf before installing GCC dependencies in workflow
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:07:18 +02:00
100927547d chore: Update GCC dependencies in GitHub Actions workflow
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 18:03:09 +02:00
073f582752 website: Rewrite the website
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 2m45s
Build OS / Build Cross-Compiler & Toolchain (push) Failing after 14m7s
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
Build OS / Flawfinder (push) Failing after 6m46s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 08:09:57 +02:00
edd13c30c5 chore: Update markdown files
Added CODE_OF_CONDUCT.md
Added CONTRIBUTING.md
Moved CREDITS.md
Moved LICENSES.md
Added SECURITY.md
Added STYLE_GUIDE.md

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 07:52:29 +02:00
6dae34debd userspace: Rewrite everything
Everything.

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 06:27:54 +02:00
dea36a0228 chore: Update makefiles and doxygen
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 06:26:55 +02:00
8dd3179aaa chore: Delete tailprofiler.sh and tailserial.sh scripts
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 06:14:47 +02:00
0699d7962d docker: Remove .dockerignore, Dockerfile, and compose.yaml
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 06:14:20 +02:00
e4403cdbd6 vscode: Update configuration files
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 06:13:31 +02:00
5632c7cb10 drivers: Update syscalls.h
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 06:07:12 +02:00
efb3a80ffd signal: Remove redundant static assertions for signal flags
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 06:03:17 +02:00
5d3bb391a4 syscalls: Add syscall_clockid_t and fix enum names
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 04:35:02 +02:00
b3f304f2c5 linker: Remove .note section from discard list
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 04:20:27 +02:00
e23e793574 syscalls: Add signal_action_flags_t structure
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-04 04:19:31 +02:00
522158913f kernel: Add .note section
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-03 21:51:17 +02:00
12a768a592 chore: Update workflows
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-29 22:43:20 +02:00
9ea2f4266e chore: Add patch for qemu
Removed patch "Replace GDB exit calls with proper shutdown" so when we stop debugging in vscode, the qemu process is automatically killed.

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-28 08:49:12 +02:00
eb7c13dd45 drivers: Update syscalls.h
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 05:45:06 +02:00
8f04f8a374 kernel/idt: Keep #PF handling always enabled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 05:44:26 +02:00
1695418dcb kernel/syscalls: Implement sys_tell & sys_seek
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 03:20:27 +02:00
b208862de2 kernel/syscalls: Add conversion for syscall macros
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 03:06:54 +02:00
a8481d4260 kernel/syscalls: Fix doxygen documentation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 02:48:50 +02:00
c84757af48 kernel/syscalls: Add macros for syscalls
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 02:37:02 +02:00
80afbedf39 kernel/syscalls: Implement sys_kill syscall
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 02:23:30 +02:00
911caf7203 kernel/signals: Update headers for syscalls.h changes
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-26 02:23:12 +02:00
95a8d6fb6f kernel/idt: Fix ExceptionHandlerStub setting fs & gs to 0
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-25 04:49:01 +02:00
b471645743 kernel/syscalls: Implement sys_prctl syscall
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-25 04:47:26 +02:00
cc6ec04814 kernel/stack: Fix stack guard expansion
Kernel didn't mapped the pages correctly

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-24 03:54:13 +02:00
1dbee4660e drivers: Update include headers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-23 03:55:39 +02:00
81af8a48cb kernel/uart: Refactor code
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-23 03:52:26 +02:00
0807ea5a9a chore: Update TODO.md
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 04:11:42 +02:00
79d267631a kernel/syscalls: Add experimental native system calls
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 04:11:01 +02:00
cbd671292d kernel/fs: Implement usr_pread/pwrite in FDT
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 04:09:30 +02:00
37c3ee8e99 kernel: Update syscall header
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 04:07:34 +02:00
7d85dd5dd8 kernel: Update interface headers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 04:03:27 +02:00
17abdcaf1e kernel: Update elf.h
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 04:02:09 +02:00
f038f6110e chore: Update vscode config
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 04:01:33 +02:00
3798ec0f58 kernel: Add COM5-8 checks
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-20 03:58:31 +02:00
fe5e4e3eec chore: Update makefiles
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2024-12-11 05:52:22 +02:00
6f17b29963 kernel/elf: Update ELFObject()
Why did I wrote that?

The interpreter wants argv[0] to be the path of the program to be loaded.

Signed-off-by: EnderIce2 <enderice2@users.noreply.github.com>
2024-12-11 04:50:42 +02:00
8b026175bb chore: Update makefiles
https://stackoverflow.com/a/17845120/9352057
Signed-off-by: EnderIce2 <enderice2@users.noreply.github.com>
2024-12-11 04:48:16 +02:00
828dab1875 chore: Update driver makefiles 2024-11-29 05:05:49 +02:00
7948d0c6e5 chore: Update makefiles & macros 2024-11-29 04:24:27 +02:00
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
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
0dbdacb8df chore: General cleanup 2024-11-27 01:19:24 +02:00
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
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
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
1b1d3e68fd chore: Fix workflow error 2024-11-26 03:42:12 +02:00
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
ae07b07964 chore: Fix workflow error "this file was generated for autoconf 2.69" 2024-11-26 03:32:40 +02:00
23853cbb15 chore: Add experimental docker build 2024-11-26 03:27:25 +02:00
00a37325f6 chore: Fix build process 2024-11-26 03:27:08 +02:00
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
5806c4feaf Update .gitmodules 2024-11-20 05:47:19 +02:00
983 changed files with 107150 additions and 74497 deletions

2
.github/FUNDING.yml vendored
View File

@ -3,7 +3,7 @@
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: EnderIce2 # Replace with a single Ko-fi username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username

86
.github/workflows/codeql.yml vendored Normal file
View File

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

34
.github/workflows/docs.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: Deploy Documentation
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
deploydoc:
name: Deploy Documentation to GitHub Pages
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: recursive
- name: Update System
run: sudo apt update
- name: Install Doxygen
run: sudo apt -y install doxygen make
- name: Generate Documentation
run: make doxygen
- name: Copy GitHub Pages Website
run: cp -r tools/website/* doxygen-doc/
- name: Deploy documentation
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: doxygen-doc

View File

@ -7,29 +7,6 @@ on:
branches: [ master ]
jobs:
deploydoc:
name: Deploy Documentation to GitHub Pages
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install Doxygen
run: sudo apt-get install doxygen make -y
- name: Generate Documentation
run: make doxygen
- name: Copy GitHub Pages Website
run: cp -r tools/website/* doxygen-doc/
- name: Deploy documentation
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: doxygen-doc
buildcompiler:
name: Build Cross-Compiler & Toolchain
runs-on: ubuntu-latest
@ -47,129 +24,56 @@ jobs:
- name: Update System
if: steps.cache-cross.outputs.cache-hit != 'true'
run: sudo apt-get update
run: sudo apt update
- name: Install GCC Dependencies
if: steps.cache-cross.outputs.cache-hit != 'true'
run: sudo apt 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 -y
run: sudo apt -y install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo libzstd-dev libisl-dev m4 automake gettext gperf dejagnu guile-3.0 guile-3.0-dev expect tcl autogen tex-common sphinx-common git ssh diffutils patch autoconf2.69 libtool wget dpkg
- name: Check autoconf
if: steps.cache-cross.outputs.cache-hit != 'true'
run: |
if [ "$(autoconf --version | head -n 1 | awk '{print $NF}')" != "2.69" ]; then
echo "Autoconf version is not 2.69, performing additional steps..."
wget https://launchpad.net/ubuntu/+archive/primary/+files/autoconf_2.69-11.1_all.deb
sudo dpkg --force-all -i ./autoconf_2.69-11.1_all.deb
fi
- name: Check automake
if: steps.cache-cross.outputs.cache-hit != 'true'
run: |
if [ "$(automake --version | head -n 1 | awk '{print $NF}')" != "1.15.1" ]; then
echo "Automake version is not 1.15.1, performing additional steps..."
wget https://ftp.gnu.org/gnu/automake/automake-1.15.1.tar.gz
tar -xzf automake-1.15.1.tar.gz
cd automake-1.15.1
./configure
make
sudo make install
fi
- name: Clone All
if: steps.cache-cross.outputs.cache-hit != 'true'
run: make --quiet -C tools __clone_all_no_qemu
- name: Compile Binutils amd64
- name: Compile Binutils
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'
run: make --quiet -C tools do_binutils_32
- 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
run: make --quiet -C tools do_gcc
- name: Clean Up
if: steps.cache-cross.outputs.cache-hit != 'true'
run: |
cd tools
rm -rf binutils-gdb gcc build-binutils64 build-gcc64 build-binutils32 build-gcc32
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:
name: Analyze with CodeQL
runs-on: ubuntu-latest
needs: [buildcompiler, compilegnuefi]
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: recursive
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Install Packages
run: |
sudo apt-get 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
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare
- name: Cache cross
id: cache-cross
uses: actions/cache@v3
with:
path: tools/cross
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
- name: Cache gnuefi
id: cache-gnuefi
uses: actions/cache@v3
with:
path: Lynx/gnu-efi
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
- name: Build OS
run: |
make build_lynx
make build_userspace
make build_drivers
make build_kernel
make build_userspace
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
rm -rf binutils-gdb gcc
compile64:
name: Build amd64
runs-on: ubuntu-latest
needs: [buildcompiler, compilegnuefi]
needs: [buildcompiler]
steps:
- uses: actions/checkout@v3
with:
@ -177,12 +81,11 @@ jobs:
- name: Update & Install Required Packages
run: |
sudo apt-get 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 update
sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare
- name: Cache cross Folder
@ -192,22 +95,15 @@ jobs:
path: tools/cross
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
run: sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
- name: Configure config.mk
run: sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./config.mk && cat config.mk | grep OSARCH
- name: Compile Debug and Release ISO
run: |
make build
mv Fennix.iso Fennix-debug.iso
make clean
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
make build
mv Fennix.iso Fennix-release.iso
@ -226,7 +122,7 @@ jobs:
compile32:
name: Build i386
runs-on: ubuntu-latest
needs: [buildcompiler, compilegnuefi]
needs: [buildcompiler]
steps:
- uses: actions/checkout@v3
with:
@ -234,12 +130,11 @@ jobs:
- name: Update & Install Required Packages
run: |
sudo apt-get 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 update
sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare
- name: Cache cross Folder
@ -249,22 +144,15 @@ jobs:
path: tools/cross
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
run: sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
- name: Configure config.mk
run: sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./config.mk && cat config.mk | grep OSARCH
- name: Compile Debug and Release ISO
run: |
make build
mv Fennix.iso Fennix-debug.iso
make clean
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
make build
mv Fennix.iso Fennix-release.iso
@ -281,10 +169,9 @@ jobs:
path: Fennix-release.iso
compilearm64:
if: ${{ false }} # Disabled until we can get it to work
name: Build aarch64
runs-on: ubuntu-latest
needs: [buildcompiler, compilegnuefi]
needs: [buildcompiler]
steps:
- uses: actions/checkout@v3
with:
@ -292,12 +179,11 @@ jobs:
- name: Update & Install Required Packages
run: |
sudo apt-get 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 update
sudo apt install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
make --quiet -C tools do_limine
make --quiet -C Drivers prepare
make --quiet -C Userspace prepare
make --quiet -C Lynx prepare
make --quiet -C Kernel prepare
- name: Cache cross Folder
@ -307,22 +193,15 @@ jobs:
path: tools/cross
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
run: sed -i 's/.*OSARCH = .*/OSARCH = aarch64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
- name: Configure config.mk
run: sed -i 's/.*OSARCH = .*/OSARCH = aarch64/' ./config.mk && cat config.mk | grep OSARCH
- name: Compile Debug and Release ISO
run: |
make build
mv Fennix.iso Fennix-debug.iso
make clean
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
make build
mv Fennix.iso Fennix-release.iso

7
.gitignore vendored
View File

@ -6,14 +6,16 @@ tools/*
!tools/ExtMemDbg
!tools/stage2_eltorito
!tools/*.md
!tools/*.css
!tools/README.md
!tools/website
!tools/Makefile
!tools/*.c
!tools/*.patch
!tools/*.cpp
!tools/*.cfg
!tools/SSDT1.dat
!tools/acpi
!tools/doxygen
!tools/.gdbinit
doxygen-doc
initrd.tar
.dccache
@ -28,3 +30,4 @@ initrd.tar
*.so
*.o
*.dmp
*.pcap

View File

@ -87,11 +87,11 @@ build64:
- make --quiet -C Userspace prepare
- make --quiet -C Lynx prepare
- make --quiet -C Kernel prepare
- sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
- sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./config.mk && cat config.mk | grep OSARCH
- make build
- mv Fennix.iso Fennix-debug.iso
- make clean
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
- make build
- mv Fennix.iso Fennix-release.iso
artifacts:
@ -111,11 +111,11 @@ build32:
- make --quiet -C Userspace prepare
- make --quiet -C Lynx prepare
- make --quiet -C Kernel prepare
- sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
- sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./config.mk && cat config.mk | grep OSARCH
- make build
- mv Fennix.iso Fennix-debug.iso
- make clean
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
- make build
- mv Fennix.iso Fennix-release.iso
artifacts:
@ -134,11 +134,11 @@ buildarm64:
- make --quiet -C Userspace prepare
- make --quiet -C Lynx prepare
- make --quiet -C Kernel prepare
- sed -i 's/.*OSARCH = .*/OSARCH = arm64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
- sed -i 's/.*OSARCH = .*/OSARCH = arm64/' ./config.mk && cat config.mk | grep OSARCH
- make build
- mv Fennix.iso Fennix-debug.iso
- make clean
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
- make build
- mv Fennix.iso Fennix-release.iso
artifacts:

View File

@ -1,20 +0,0 @@
{
"Fennix Kernel Header": {
"scope": "c",
"prefix": [
"head",
],
"body": [
"#ifndef __FENNIX_KERNEL_${2:header}_H__",
"#define __FENNIX_KERNEL_${2:header}_H__",
"",
"#include <types.h>",
"",
"$0",
"",
"#endif // !__FENNIX_KERNEL_${2:header}_H__",
""
],
"description": "Create kernel header."
}
}

69
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,69 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch QEMU & debug the kernel",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/../Kernel/fennix.elf",
"cwd": "${workspaceFolder}",
"args": [],
"targetArchitecture": "x64",
"MIMode": "gdb",
"miDebuggerServerAddress": "/tmp/gdb-fennix",
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gdb",
"miDebuggerArgs": "",
"externalConsole": false,
"additionalSOLibSearchPath": "${workspaceFolder}",
"internalConsoleOptions": "neverOpen",
"customLaunchSetupCommands": [
// {
// "text": "target remote localhost:1234",
// "description": "Connect to QEMU remote debugger"
// }
],
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "file ${workspaceFolder}/../Kernel/fennix.elf",
"description": "Load binary"
},
{
"text": "add-symbol-file ${workspaceFolder}/../initrd_tmp_data/bin/utest",
"description": "Load /bin/utest",
"ignoreFailures": true
},
{
"text": "source ${workspaceFolder}/../tools/.gdbinit"
}
],
"preLaunchTask": "launch-qemu"
},
{
"type": "gdb",
"request": "attach",
"name": "Launch QEMU & attach to gdbserver",
"executable": "${workspaceFolder}/../Kernel/fennix.elf",
"target": "/tmp/gdb-fennix",
"remote": true,
"cwd": "${workspaceRoot}",
"valuesFormatting": "parseText",
"gdbpath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gdb",
"autorun": [
"set auto-load safe-path ${workspaceFolder}",
"source ${workspaceFolder}/../tools/.gdbinit",
],
"internalConsoleOptions": "neverOpen",
"printCalls": false,
"preLaunchTask": "launch-qemu"
},
]
}

10
.vscode/settings.json vendored
View File

@ -1,5 +1,5 @@
{
"C_Cpp.errorSquiggles": "Enabled",
"C_Cpp.errorSquiggles": "enabled",
"C_Cpp.autocompleteAddParentheses": true,
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
"C_Cpp.clang_format_style": "Visual Studio",
@ -11,16 +11,10 @@
"editor.cursorSmoothCaretAnimation": "on",
"files.watcherExclude": {
"**/tools/binutils-gdb/**": true,
"**/tools/build-binutilsamd64/**": true,
"**/tools/build-binutilsarm64/**": true,
"**/tools/build-binutilsi386/**": true,
"**/tools/build-gccamd64/**": true,
"**/tools/build-gccarm64/**": true,
"**/tools/build-gcci386/**": true,
"**/tools/cross/**": true,
"**/tools/gcc/**": true,
"**/tools/limine/**": true,
"**/tools/qemu/**": true,
"**/tools/cross/**": true,
"**/doxygen-doc/**": true,
}
}

28
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "launch-qemu",
"type": "shell",
"command": "make -C ../ build && make -C ../ vscode_debug_only",
"isBackground": true,
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"shell": {
"executable": "bash",
"args": [
"-c"
]
}
}
}
]
}

128
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
enderice2@protonmail.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

70
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,70 @@
# Contributing to Fennix
We welcome contributions to Fennix! Whether you are reporting a bug, suggesting a feature, or submitting a pull request, were excited to collaborate with you.
## Table of Contents
- [How to Contribute](#how-to-contribute)
- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Pull Request Guidelines](#pull-request-guidelines)
- [Reporting Issues](#reporting-issues)
- [Style Guide](#style-guide)
---
## How to Contribute
1. **Check existing issues or discussions** to see if your idea has already been mentioned or if someone is already working on it.
2. If youre new to the project, consider contributing to [good first issues](https://github.com/EnderIce2/Fennix/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
3. Fork the repository and create a new branch for your changes.
---
## Code of Conduct
By participating in this project, you agree to abide by our [Code of Conduct](CODE_OF_CONDUCT.md). Be respectful and inclusive while interacting with the community.
---
## Getting Started
1. Fork this repository and clone your fork.
2. Set up your development environment according to the [README.md](README.md) or any other setup guide provided.
3. Ensure all tests pass before submitting changes. Add tests for new features where applicable.
---
## Pull Request Guidelines
1. Keep pull requests focused on a single issue or feature.
2. Write clear, descriptive commit messages.
3. Ensure all tests pass before submitting your PR.
4. Include a detailed description of your changes and reference any relevant issue numbers.
5. Be open to feedback and revise your pull request if requested.
6. Mark your pull request as a draft if its still a work in progress.
---
## Reporting Issues
1. Check if the issue has already been reported.
2. Include a clear and descriptive title.
3. Provide detailed steps to reproduce the problem (if applicable).
4. Mention your environment details (e.g., OS, version, etc.).
5. Attach screenshots or logs if they help explain the issue.
---
## Style Guide
Follow the coding style used in the repository to ensure consistency. Adhere to:
- Use CamelCase for all names.
- Start function and global declaration names with an uppercase letter.
- Start local variable names with a lowercase letter.
- Maintain consistent formatting and commenting guidelines.
Refer to the [style guide document](STYLE_GUIDE.md) if available.
---
Thank you for contributing! Your effort makes Fennix better for everyone. If you have any questions, feel free to reach out by opening an issue or joining our discussions.

125
CREDITS.md Normal file
View File

@ -0,0 +1,125 @@
# Credits and References
This project has been influenced and inspired by other projects and resources.
License information can be found in the [LICENSES.md](LICENSES.md) file.
## General
- [OSDev Wiki](https://wiki.osdev.org/Main_Page)
- [GCC x86 Built-in Functions](https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html#x86-Built-in-Functions)
- [GCC Common Function Attributes](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes)
- [LemonOS Project](https://github.com/LemonOSProject/LemonOS)
- [ToaruOS](https://github.com/klange/toaruos)
- [Various SIMD functions](https://wiki.osdev.org/User:01000101/optlib/)
## C++ STL
- [cppreference.com](https://cppreference.com)
## Virtual terminal
- [vtconsole](https://github.com/sleepy-monax/vtconsole)
## Font
- [Tamsyn Font](http://www.fial.com/~scott/tamsyn-font/)
## CPU XCR0 Structure
- [CPU Registers x86 - XCR0](https://wiki.osdev.org/CPU_Registers_x86#XCR0)
## CPUID 0x7
- [CPUID](https://en.wikipedia.org/wiki/CPUID)
## Network
- [Beej's Guide to Network Programming](https://web.archive.org/web/20051210132103/http://users.pcnet.ro/dmoroian/beej/Beej.html)
- [UDP Socket Programming](https://web.archive.org/web/20060229214053/http://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html)
- [EtherType](https://en.wikipedia.org/wiki/EtherType)
- [Linux Network Packet Reception](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-network-packet-reception)
- [Linux Kernel Networking Labs](https://linux-kernel-labs.github.io/refs/heads/master/labs/networking.html)
- [smoltcp](https://github.com/smoltcp-rs/smoltcp)
- [Understanding Linux Network Internals](https://www.cs.unh.edu/~cruse/cs326f04/RTL8139D_DataSheet.pdf)
- [Address Resolution Protocol (ARP)](https://en.wikipedia.org/wiki/Address_Resolution_Protocol)
- [C++ Operators](https://en.cppreference.com/w/cpp/language/operators)
- [Dynamic Host Configuration Protocol (DHCP)](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol)
- [RTL8139 Programmer's Guide](https://www.cs.usfca.edu/~cruse/cs326f04/RTL8139_ProgrammersGuide.pdf)
- [RTL8139CP Datasheet](http://realtek.info/pdf/rtl8139cp.pdf)
- [IPv4](https://en.wikipedia.org/wiki/IPv4)
- [ICMP Parameters](https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml)
## Loading ELF Shared Libraries and Dynamic Linking
- [How To Write Shared Libraries](https://www.akkadia.org/drepper/dsohowto.pdf)
- [Dynamic Linker](https://wiki.osdev.org/Dynamic_Linker)
- [Nightingale OS](https://github.com/tyler569/nightingale)
- [PLT and GOT: The Key to Code Sharing and Dynamic Libraries](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html)
- [YouTube Video on Dynamic Linking](https://www.youtube.com/watch?v=kUk5pw4w0h4)
- [Oracle: Position Independent Code](https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html)
- [PLT and GOT Explained](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)
## Inter-Process Communication (IPC)
- [Oracle IPC](https://docs.oracle.com/cd/E19048-01/chorus5/806-6897/architecture-103/index.html)
- [Inter-Process Communication in OS](https://www.scaler.com/topics/operating-system/inter-process-communication-in-os/)
- [IPC on Wikipedia](https://en.wikipedia.org/wiki/Inter-process_communication)
- [GeeksforGeeks IPC Guide](https://www.geeksforgeeks.org/inter-process-communication-ipc/)
## PCI (Peripheral Component Interconnect)
- [OSDev PCI](https://wiki.osdev.org/PCI)
- [PCI Configuration Space](https://en.wikipedia.org/wiki/PCI_configuration_space)
## Audio
- [FFmpeg Audio Types](https://trac.ffmpeg.org/wiki/audio%20types)
- [AC97 on OSDev](https://wiki.osdev.org/AC97)
- [AC97 Revision 2.3 Specification](https://inst.eecs.berkeley.edu//~cs150/Documents/ac97_r23.pdf)
## Intrinsics (x86)
- [Microsoft x86 Intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/x86-intrinsics-list)
- [Intel Intrinsics Guide](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html)
## CPUID Information
- [AMD CPUID Instruction](https://www.amd.com/system/files/TechDocs/40332.pdf)
- [CPUID Instruction Note](https://www.scss.tcd.ie/~jones/CS4021/processor-identification-cpuid-instruction-note.pdf)
## SMBIOS (System Management BIOS)
- [DMTF DSP0134](https://www.dmtf.org/dsp/DSP0134)
- [DSP0134 Version 3.6.0](https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.6.0.pdf)
- [OSDev SMBIOS](https://wiki.osdev.org/System_Management_BIOS)
## EDBA (Effective Direct Bus Access)
- [Memory Map (x86)](https://wiki.osdev.org/Memory_Map_(x86))
## UMIP, SMAP, and SMEP
- [Control Register on Wikipedia](https://en.wikipedia.org/wiki/Control_register)
- [Control Register and UMIP](https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf)
- [Supervisor Mode Access Prevention (SMEP)](https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention)
## Atomic Operations
- [C++ Atomic Operations](https://en.cppreference.com/w/cpp/atomic/atomic)
## ELF (Executable and Linkable Format)
- [ELF Header Format](https://www.sco.com/developers/gabi/latest/ch4.eheader.html)
- [ELF File Format Specification](https://refspecs.linuxfoundation.org/elf/elf.pdf)
- [Oracle: Executable and Linkable Format](https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html)
- [Oracle: ELF Program Headers](https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html)
- [YouTube Video on ELF](https://www.youtube.com/watch?v=nC1U1LJQL8o)
- [Stevens' UNIX Network Programming](https://stevens.netmeister.org/631/elf.html)
- [Linux Kernel ELF Header](https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h)
## C++ ABI (Application Binary Interface)
- [GCC libstdc++ Source](https://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3)
- [Itanium C++ ABI](https://itanium-cxx-abi.github.io/cxx-abi/abi.html)
## signal.h
- [POSIX signal.h](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html)
- [Linux signal(7) Manual](https://man7.org/linux/man-pages/man7/signal.7.html)
## PS/2
- [Scan Codes](https://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html)
- [PS/2 Keyboard on OSDev](https://wiki.osdev.org/PS2_Keyboard)
- [PS/2 Mouse on OSDev](https://wiki.osdev.org/PS2_Mouse)
- [Mouse Input on OSDev](https://wiki.osdev.org/Mouse_Input)
- [I/O Ports on OSDev](https://wiki.osdev.org/I/O_ports)
- [PS/2 Controller on OSDev](https://wiki.osdev.org/%228042%22_PS/2_Controller)
- [AIP on OSDev](https://wiki.osdev.org/Advanced_Integrated_Peripheral)
## UART
- [Interfacing the Serial / RS232 Port V5.0](http://www.senet.com.au/~cpeacock)
---
Special thanks to all contributors and the creators of the referenced projects and resources!

View File

@ -44,14 +44,14 @@ PROJECT_NUMBER = 1.0.0
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF = "Opeating System from scratch made in C and C++"
PROJECT_BRIEF = "Full Documentation"
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO =
PROJECT_LOGO = tools/doxygen/favicon.ico
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
@ -246,7 +246,7 @@ INHERIT_DOCS = YES
# of the file/class/namespace that contains it.
# The default value is: NO.
SEPARATE_MEMBER_PAGES = YES
SEPARATE_MEMBER_PAGES = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
# uses this value to replace tabs by spaces in code fragments.
@ -424,7 +424,7 @@ SUBGROUPING = YES
# SEPARATE_MEMBER_PAGES.
# The default value is: NO.
INLINE_GROUPED_CLASSES = YES
INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
# with only public data fields or simple typedef fields will be shown inline in
@ -614,7 +614,7 @@ HIDE_COMPOUND_REFERENCE= NO
# the files that are included by a file in the documentation of that file.
# The default value is: YES.
SHOW_INCLUDE_FILES = YES
SHOW_INCLUDE_FILES = NO
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
# grouped member an include statement to the documentation, telling the reader
@ -794,7 +794,7 @@ CITE_BIB_FILES =
# messages are off.
# The default value is: NO.
QUIET = NO
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
@ -864,7 +864,14 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = Kernel Lynx Userspace Drivers tools/doxymds/main.md
INPUT = tools/doxygen/index.md \
tools/doxygen/api.md \
tools/doxygen/develop.md \
README \
Userspace/README.md \
Drivers/README.md \
Kernel/README.md \
Kernel/include/interface
# 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
@ -955,7 +962,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE = .vscode tools
EXCLUDE = .vscode .github
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@ -1064,7 +1071,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE = tools/doxymds/main.md
USE_MDFILE_AS_MAINPAGE = tools/doxygen/index.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
@ -1224,7 +1231,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = doxygen-doc/fulldoc
HTML_OUTPUT = doxygen-doc/docs
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
@ -1251,7 +1258,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER =
HTML_HEADER = tools/doxygen/header.html
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
@ -1286,7 +1293,8 @@ HTML_STYLESHEET =
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET = tools/doxygen-awesome.css tools/custom.css
HTML_EXTRA_STYLESHEET = tools/doxygen/theme/doxygen-awesome.css \
tools/doxygen/custom.css
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
@ -1296,7 +1304,11 @@ HTML_EXTRA_STYLESHEET = tools/doxygen-awesome.css tools/custom.css
# files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_FILES =
HTML_EXTRA_FILES = tools/doxygen/theme/doxygen-awesome-darkmode-toggle.js \
tools/doxygen/theme/doxygen-awesome-fragment-copy-button.js \
tools/doxygen/theme/doxygen-awesome-paragraph-link.js \
tools/doxygen/theme/doxygen-awesome-interactive-toc.js \
tools/doxygen/theme/doxygen-awesome-tabs.js
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
@ -1335,7 +1347,7 @@ HTML_COLORSTYLE_GAMMA = 80
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = NO
HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
@ -2071,7 +2083,7 @@ MAN_OUTPUT = man
# The default value is: .3.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_EXTENSION = .3
MAN_EXTENSION = .2
# The MAN_SUBDIR tag determines the name of the directory created within
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by

View File

@ -12,7 +12,6 @@
"KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"",
"a64",
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
@ -69,7 +68,6 @@
"KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"",
"a32",
"DEBUG=\"1\""
],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc",

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

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

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

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

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,3 +1,48 @@
default:
$(error Do not run this Makefile directly!)
export CC := $(__CONF_CC)
export CXX := $(__CONF_CXX)
export LD := $(__CONF_LD)
export AS := $(__CONF_AS)
export OBJDUMP := $(__CONF_OBJDUMP)
export OUTPUT_DIR := $(CURDIR)/out/
export INCLUDE_DIR := $(CURDIR)/include
DRIVER_LDFLAGS = -nostdlib -nodefaultlibs -nolibc -zmax-page-size=0x1000 \
-Wl,-Map file.map -fvisibility=hidden -Wl,--dynamic-linker=/boot/fennix.elf
ifeq ($(OSARCH), amd64)
DRIVER_CFLAGS = -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
-mno-red-zone -mno-sse -mno-sse2 \
-march=x86-64 -pipe -ffunction-sections \
-msoft-float -fno-builtin
else ifeq ($(OSARCH), i386)
DRIVER_CFLAGS = -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
-march=i386 -pipe -msoft-float -fno-builtin
else ifeq ($(OSARCH), aarch64)
DRIVER_CFLAGS = -pipe -fno-builtin -fPIC
endif
DRIVER_CFLAGS += -I$(CURDIR)/include
ifeq ($(DEBUG), 1)
DRIVER_CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
ifeq ($(OSARCH), amd64)
DRIVER_CFLAGS += -fverbose-asm
endif
ifneq ($(OSARCH), aarch64)
DRIVER_CFLAGS += -fstack-check
endif
DRIVER_LDFLAGS += -ggdb3 -O0
endif
export DRIVER_LDFLAGS
export DRIVER_CFLAGS
build:
cp -rf ../Kernel/include/interface/* include/
mkdir -p out

View File

@ -1,11 +1 @@
# 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

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

View File

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

View File

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

View File

@ -1,54 +0,0 @@
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
DRIVER_LDFLAGS := -nostdlib -nodefaultlibs -nolibc -zmax-page-size=0x1000 \
-Wl,-Map file.map -fvisibility=hidden -Wl,--dynamic-linker=/boot/fennix.elf
ifeq ($(OSARCH), amd64)
DRIVER_CFLAGS := -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
-mno-red-zone -mno-sse -mno-sse2 \
-march=x86-64 -pipe -ffunction-sections \
-msoft-float -fno-builtin
else ifeq ($(OSARCH), i386)
DRIVER_CFLAGS := -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
-march=i386 -pipe -msoft-float -fno-builtin
else ifeq ($(OSARCH), aarch64)
DRIVER_CFLAGS += -pipe -fno-builtin -fPIC
endif
DRIVER_CFLAGS += -I../../include
ifeq ($(DEBUG), 1)
DRIVER_CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
ifeq ($(OSARCH), amd64)
DRIVER_CFLAGS += -fverbose-asm
endif
ifneq ($(OSARCH), aarch64)
DRIVER_CFLAGS += -fstack-check
endif
DRIVER_LDFLAGS += -ggdb3 -O0
endif
WARNCFLAG = -Wall -Wextra
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CPP) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<

View File

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

View File

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

View File

@ -1,18 +1,18 @@
/*
This file is part of Fennix Drivers.
This file is part of Fennix Kernel.
Fennix Drivers is free software: you can redistribute it and/or
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Drivers is distributed in the hope that it will be useful,
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_API_AIP_H__

View File

@ -15,8 +15,8 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_ERRNO_H__
#define __FENNIX_KERNEL_ERRNO_H__
#ifndef __FENNIX_API_ERRNO_H__
#define __FENNIX_API_ERRNO_H__
/**
* The documentation for these error codes are from:
@ -416,8 +416,8 @@ typedef enum
* Not a directory. A component of the specified pathname exists, but
* it is not a directory, when a directory was expected; or an
* attempt was made to create a non-directory file, and the specified
* pathname contains at least one non- <slash> character and ends
* with one or more trailing <slash> characters.
* pathname contains at least one non- \<slash\> character and ends
* with one or more trailing \<slash\> characters.
*/
ENOTDIR = 57,
@ -588,17 +588,18 @@ typedef enum
__ERRNO_MAX
} KernelErrors;
#include <types.h>
EXTERNC int *__errno_location(void) __attribute__((const));
#define errno (*__errno_location())
#ifdef __cplusplus
extern "C"
{
#endif
int *__errno_location(void) __attribute__((const));
char *strerror(int errnum);
#ifdef __cplusplus
}
#endif
#endif // !__FENNIX_KERNEL_ERRNO_H__
#define errno (*__errno_location())
#endif // !__FENNIX_API_ERRNO_H__

View File

@ -348,6 +348,7 @@ struct SuperBlockOperations
* Write all pending changes to the disk.
*
* @param Info Inode to synchronize. If NULL, synchronize all inodes.
* @param Node Inode to synchronize.
*
* @return Zero on success, otherwise an error code.
*/

View File

@ -1,18 +1,18 @@
/*
This file is part of Fennix Drivers.
This file is part of Fennix Kernel.
Fennix Drivers is free software: you can redistribute it and/or
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Drivers is distributed in the hope that it will be useful,
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_API_PCI_H__

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1,21 +1,14 @@
# Config file
include ../../Makefile.conf
FILENAME = libkernel.so
CC = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
CPP = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
LD = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
AS = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./crt/*")
C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./crt/*")
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./crt/*")
HEADERS = $(sort $(dir $(wildcard ../include/*)))
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
INCLUDE_DIR = ../include
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./crt/*")
HEADERS = $(sort $(dir $(wildcard $(INCLUDE_DIR)/*)))
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
LDFLAGS := -fPIC -fPIE -pie -nostdlib -nodefaultlibs -nolibc \
-zmax-page-size=0x1000 -Wl,-Map libkernel.map -shared
@ -43,7 +36,7 @@ CFLAGS += -pipe -fno-builtin -fPIC
endif
CRT_CFLAGS := -fPIC -fPIE -pie -mno-red-zone -std=c++20 -I../include
CRT_CFLAGS := -fPIC -fPIE -pie -mno-red-zone -std=c++20 -I$(INCLUDE_DIR)
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
@ -60,12 +53,12 @@ endif
endif
build: $(FILENAME)
$(CPP) $(CRT_CFLAGS) -c crt/crt0.cpp -o dcrt0.o
mv dcrt0.o ../out/dcrt0.o
$(CXX) $(CRT_CFLAGS) -c crt/crt0.cpp -o dcrt0.o
mv dcrt0.o $(OUTPUT_DIR)dcrt0.o
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(LDFLAGS) $(OBJ) -o ../out/$(FILENAME)
$(CC) $(LDFLAGS) $(OBJ) -o $(OUTPUT_DIR)$(FILENAME)
%.o: %.c $(HEADERS)
$(info Compiling $<)
@ -73,7 +66,7 @@ $(FILENAME): $(OBJ)
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fexceptions -c $< -o $@
$(CXX) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fexceptions -c $< -o $@
%.o: %.S
$(info Compiling $<)

View File

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

View File

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

View File

@ -66,15 +66,14 @@ int DriverProbe()
* This function is to test if the driver is compatible
* with the hardware.
* Example: Like if there is a PCI device that the driver
* is for, or a CPU feature that etc.
* is for, or a CPU feature etc.
*
* Return 0 if the driver is compatible with the hardware.
* Otherwise, return a value that is not 0.
*
* Note: In this function you cannot use variables that
* have constructors or destructors. Before DriverEntry,
* the constructors are called and after DriverFinalize,
* the destructors are called.
* the destructors.
*/
return 0;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,108 +5,11 @@
}
],
"settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true,
"cSpell.words": [
"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"
}
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false
}
}
}

View File

@ -5,513 +5,8 @@
}
],
"settings": {
"terminal.integrated.cwd": "../",
"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",
"diffEditor.codeLens": true,
"editor.quickSuggestionsDelay": 100,
@ -527,6 +22,10 @@
"editor.cursorBlinking": "blink",
"editor.cursorSmoothCaretAnimation": "on",
"editor.cursorStyle": "line",
"editor.cursorWidth": 2
"editor.cursorWidth": 2,
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false
}
}
}

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,11 @@
}
],
"settings": {
"terminal.integrated.cwd": "../",
"debug.allowBreakpointsEverywhere": true,
"files.associations": {
"*.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"
]
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false
}
}
}

View File

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

View File

@ -6,30 +6,9 @@
],
"settings": {
"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"
}
"git.alwaysSignOff": true,
"git.defaultBranchName": "master",
"git.openRepositoryInParentFolders": "always",
"C_Cpp.autoAddFileAssociations": false
}
}

91
Kernel/.gdbinit Normal file
View File

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

View File

@ -1,38 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: flawfinder
on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '21 1 * * 1'
jobs:
flawfinder:
name: Flawfinder
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: flawfinder_scan
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
with:
arguments: '--sarif ./'
output: 'flawfinder_results.sarif'
- name: Upload analysis results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: ${{github.workspace}}/flawfinder_results.sarif

3
Kernel/.gitignore vendored
View File

@ -2,6 +2,5 @@
*.su
*.gcno
*.map
*.fsys
fennix.elf
*.log
.dccache

View File

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

View File

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

View File

@ -1,13 +0,0 @@
{
"recommendations": [
"ms-vscode.cpptools",
"wayou.vscode-todo-highlight",
"gruntfuggly.todo-tree",
"13xforever.language-x86-64-assembly",
"webfreak.debug",
"zixuanwang.linkerscript",
"maziac.hex-hover-converter",
"cschlosser.doxdocgen",
"streetsidesoftware.code-spell-checker"
]
}

View File

@ -1,40 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to a running VM instance",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/kernel.fsys",
"cwd": "${workspaceRoot}",
"args": [],
"targetArchitecture": "x64",
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"miDebuggerArgs": "",
"externalConsole": false,
"additionalSOLibSearchPath": "${workspaceRoot}",
"customLaunchSetupCommands": [
{
"text": "target remote localhost:1234",
"description": "Connect to QEMU remote debugger"
}
],
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "file ${workspaceRoot}/kernel.fsys",
"description": "Load binary."
},
]
}
]
}

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

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

14
Kernel/.vscode/preinclude.h vendored Normal file
View File

@ -0,0 +1,14 @@
#undef __linux__
#undef __WIN32__
#undef __WIN64__
#undef _WIN32
#undef _WIN64
#undef __APPLE__
#undef __clang__
#define __vscode__ 1
#define __kernel__ 1
#define KERNEL_NAME "Fennix"
#define KERNEL_ARCH "amd64"
#define KERNEL_VERSION "1.0"
#define GIT_COMMIT "0000000000000000000000000000000000000000"
#define GIT_COMMIT_SHORT "0000000"

View File

@ -1,5 +1,5 @@
{
"C_Cpp.errorSquiggles": "Enabled",
"C_Cpp.errorSquiggles": "enabled",
"C_Cpp.autocompleteAddParentheses": true,
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
"C_Cpp.clang_format_style": "Visual Studio",
@ -14,6 +14,10 @@
"clang-diagnostic-unknown-warning-option",
"clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling",
"clang-diagnostic-implicit-exception-spec-mismatch",
"clang-diagnostic-unknown-attributes"
"clang-diagnostic-unknown-attributes",
"clang-diagnostic-user-defined-literals",
"clang-diagnostic-non-pod-varargs",
"clang-diagnostic-non-pod-varargs",
"clang-diagnostic-non-pod-varargs"
]
}

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

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

View File

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

View File

@ -1,27 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <types.h>
#include <debug.h>
#include <cpu.hpp>
EXTERNC void arm64Entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3)
{
trace("Hello, World!");
CPU::Halt(true);
}

View File

@ -1,31 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <syscalls.hpp>
#include <cpu.hpp>
extern "C" __naked __used __no_stack_protector void SystemCallHandlerStub()
{
}
extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs);
void InitializeSystemCalls()
{
}

View File

@ -1,59 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <smp.hpp>
#include <ints.hpp>
#include <memory.hpp>
#include <cpu.hpp>
#include "../../../kernel.h"
volatile bool CPUEnabled = false;
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
static __aligned(0x1000) CPUData CPUs[MAX_CPU] = {0};
CPUData *GetCPU(uint64_t id) { return &CPUs[id]; }
CPUData *GetCurrentCPU()
{
uint64_t ret = 0;
if (!CPUs[ret].IsActive)
{
error("CPU %d is not active!", ret);
return &CPUs[0];
}
if (CPUs[ret].Checksum != CPU_DATA_CHECKSUM)
{
error("CPU %d data is corrupted!", ret);
return &CPUs[0];
}
return &CPUs[ret];
}
namespace SMP
{
int CPUCores = 0;
void Initialize(void *madt)
{
fixme("SMP::Initialize() is not implemented!");
}
}

View File

@ -1,83 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
ENTRY(_start)
SECTIONS
{
.text.boot :
{
*(.text.boot)
. += CONSTANT(MAXPAGESIZE);
_bss_start = .;
*(.text.bss)
_bss_end = .;
}
_kernel_start = .;
.text :
{
KEEP(*(.text.boot))
*(.text .text.*)
}
. = ALIGN(4096);
_kernel_text_end = .;
.data :
{
*(.data .data.*)
}
. = ALIGN(4096);
_kernel_data_end = .;
.rodata :
{
*(.rodata .rodata.*)
}
. = ALIGN(4096);
_kernel_rodata_end = .;
.init_array :
{
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(.init_array .ctors))
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN(__fini_array_start = .);
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP(*(.fini_array .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.bss :
{
*(.bss .bss.*)
}
. = ALIGN(4096);
_kernel_end = .;
_bss_size = _kernel_end - _kernel_rodata_end;
/DISCARD/ :
{
*(.comment*)
*(.note*)
}
}

View File

@ -1,17 +0,0 @@
// .section ".text.boot"
//
// .global _start
// .org 0x80000
// _start:
// ldr x5, =_start
// mov sp, x5
// ldr x5, =_kernel_rodata_end
// ldr w6, =_bss_size
// 1: cbz w6, 2f
// str xzr, [x5], #8
// sub w6, w6, #1
// cbnz w6, 1b
// 2: bl arm64Entry
// Halt:
// wfe
// b Halt

View File

@ -1,17 +0,0 @@
// .section ".text.boot"
// .global _start
// .org 0x80000
// _start:
// ldr x5, =_start
// mov sp, x5
// ldr x5, =_kernel_rodata_end
// ldr w6, =_bss_size
// 1: cbz w6, 2f
// str xzr, [x5], #8
// sub w6, w6, #1
// cbnz w6, 1b
// 2: bl arm64Entry
// Halt:
// wfe
// b Halt

View File

@ -1 +0,0 @@
// C++ constructor/destructor stuff

View File

@ -1 +0,0 @@
// C++ constructor/destructor stuff

View File

@ -1,13 +0,0 @@
// .section .init
// .global _init
// .type _init, @function
// _init:
// push %rbp
// movq %rsp, %rbp
// .section .fini
// .global _fini
// .type _fini, @function
// _fini:
// push %rbp
// movq %rsp, %rbp

View File

@ -1,7 +0,0 @@
.section .init
// popq %rbp
ret
.section .fini
// popq %rbp
ret

View File

@ -1,155 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include "acpi.hpp"
#include <debug.h>
#include <io.h>
#include "../../kernel.h"
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
namespace ACPI
{
void *ACPI::FindTable(ACPI::ACPIHeader *ACPIHeader, char *Signature)
{
for (uint64_t t = 0; t < ((ACPIHeader->Length - sizeof(ACPI::ACPIHeader)) / (XSDTSupported ? 8 : 4)); t++)
{
// TODO: Should I be concerned about unaligned memory access?
ACPI::ACPIHeader *SDTHdr = nullptr;
if (XSDTSupported)
SDTHdr = (ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 8)));
else
SDTHdr = (ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 4)));
for (int i = 0; i < 4; i++)
{
if (SDTHdr->Signature[i] != Signature[i])
break;
if (i == 3)
{
trace("%s found at address %p", Signature, (uintptr_t)SDTHdr);
return SDTHdr;
}
}
}
// warn("%s not found!", Signature);
return nullptr;
}
void ACPI::SearchTables(ACPIHeader *Header)
{
if (!Header)
return;
HPET = (HPETHeader *)FindTable(Header, (char *)"HPET");
FADT = (FADTHeader *)FindTable(Header, (char *)"FACP");
MCFG = (MCFGHeader *)FindTable(Header, (char *)"MCFG");
BGRT = (BGRTHeader *)FindTable(Header, (char *)"BGRT");
SRAT = (SRATHeader *)FindTable(Header, (char *)"SRAT");
TPM2 = (TPM2Header *)FindTable(Header, (char *)"TPM2");
TCPA = (TCPAHeader *)FindTable(Header, (char *)"TCPA");
WAET = (WAETHeader *)FindTable(Header, (char *)"WAET");
MADT = (MADTHeader *)FindTable(Header, (char *)"APIC");
HEST = (HESTHeader *)FindTable(Header, (char *)"HEST");
FindTable(Header, (char *)"BERT");
FindTable(Header, (char *)"CPEP");
FindTable(Header, (char *)"DSDT");
FindTable(Header, (char *)"ECDT");
FindTable(Header, (char *)"EINJ");
FindTable(Header, (char *)"ERST");
FindTable(Header, (char *)"FACS");
FindTable(Header, (char *)"MSCT");
FindTable(Header, (char *)"MPST");
FindTable(Header, (char *)"OEMx");
FindTable(Header, (char *)"PMTT");
FindTable(Header, (char *)"PSDT");
FindTable(Header, (char *)"RASF");
FindTable(Header, (char *)"RSDT");
FindTable(Header, (char *)"SBST");
FindTable(Header, (char *)"SLIT");
FindTable(Header, (char *)"SSDT");
FindTable(Header, (char *)"XSDT");
FindTable(Header, (char *)"DRTM");
FindTable(Header, (char *)"FPDT");
FindTable(Header, (char *)"GTDT");
FindTable(Header, (char *)"PCCT");
FindTable(Header, (char *)"S3PT");
FindTable(Header, (char *)"MATR");
FindTable(Header, (char *)"MSDM");
FindTable(Header, (char *)"WPBT");
FindTable(Header, (char *)"OSDT");
FindTable(Header, (char *)"RSDP");
FindTable(Header, (char *)"NFIT");
FindTable(Header, (char *)"ASF!");
FindTable(Header, (char *)"BOOT");
FindTable(Header, (char *)"CSRT");
FindTable(Header, (char *)"DBG2");
FindTable(Header, (char *)"DBGP");
FindTable(Header, (char *)"DMAR");
FindTable(Header, (char *)"IBFT");
FindTable(Header, (char *)"IORT");
FindTable(Header, (char *)"IVRS");
FindTable(Header, (char *)"LPIT");
FindTable(Header, (char *)"MCHI");
FindTable(Header, (char *)"MTMR");
FindTable(Header, (char *)"SLIC");
FindTable(Header, (char *)"SPCR");
FindTable(Header, (char *)"SPMI");
FindTable(Header, (char *)"UEFI");
FindTable(Header, (char *)"VRTC");
FindTable(Header, (char *)"WDAT");
FindTable(Header, (char *)"WDDT");
FindTable(Header, (char *)"WDRT");
FindTable(Header, (char *)"ATKG");
FindTable(Header, (char *)"GSCI");
FindTable(Header, (char *)"IEIT");
FindTable(Header, (char *)"HMAT");
FindTable(Header, (char *)"CEDT");
FindTable(Header, (char *)"AEST");
}
ACPI::ACPI()
{
trace("Initializing ACPI");
if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress)
{
debug("XSDT supported");
XSDTSupported = true;
XSDT = (ACPIHeader *)(bInfo.RSDP->XSDTAddress);
}
else
{
debug("RSDT supported");
XSDT = (ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress;
}
this->SearchTables(XSDT);
if (FADT)
{
outb(s_cst(uint16_t, FADT->SMI_CommandPort), FADT->AcpiEnable);
while (!(inw(s_cst(uint16_t, FADT->PM1aControlBlock)) & 1))
;
}
}
ACPI::~ACPI()
{
}
}

View File

@ -1,47 +0,0 @@
[bits 32]
section .bootstrap.text
align 32
global gdtr
gdtr:
dw GDT32_END - GDT32 - 1
dd GDT32
align 32
GDT32:
dq 0x0
dw 0xffff
dw 0x0000
db 0x00
dw 0xcf9a
db 0x00
dw 0xffff
dw 0x0000
db 0x00
dw 0xcf92
db 0x00
dw 0x0100
dw 0x1000
db 0x00
dw 0x4092
db 0x00
GDT32_END:
global LoadGDT32
LoadGDT32:
lgdt [gdtr]
jmp 0x8:ActivateGDT
ActivateGDT:
mov cx, 0x10
mov ss, cx
mov ds, cx
mov es, cx
mov fs, cx
mov cx, 0x18
mov gs, cx
ret

View File

@ -1,5 +0,0 @@
section .multiboot
align 4
dd 0x1BADB002
dd 1 << 0 | 1 << 1
dd -(0x1BADB002 + (1 << 0 | 1 << 1))

View File

@ -1,64 +0,0 @@
; https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html
section .multiboot2
align 4096
HEADER_START:
dd 0xE85250D6
dd 0
dd (HEADER_END - HEADER_START)
dd 0x100000000 - (HEADER_END - HEADER_START) - 0 - 0xE85250D6
align 8
MB2_INFO_REQUEST_TAG_START:
dw 1
dw 0
dd MB2_INFO_REQUEST_TAG_END - MB2_INFO_REQUEST_TAG_START
dd 1 ; Command Line
dd 2 ; Boot Loader Name
dd 3 ; Module
dd 4 ; Basic Memory Information
dd 5 ; BIOS Boot Device
dd 6 ; Memory Map
dd 7 ; VBE
dd 8 ; Framebuffer
dd 9 ; ELF Sections
dd 10 ; APM Table
dd 11 ; EFI 32-bit System Table Pointer
dd 12 ; EFI 64-bit System Table Pointer
; dd 13 ; SMBIOS
dd 14 ; ACPI Old
dd 15 ; ACPI New
dd 16 ; Network
dd 17 ; EFI Memory Map
dd 18 ; EFI Boot Services Notifier
dd 19 ; EFI 32-bit Image Handle Pointer
dd 20 ; EFI 64-bit Image Handle Pointer
dd 21 ; Load Base Address
MB2_INFO_REQUEST_TAG_END:
align 8
MB2_FRAMEBUFFER_TAG_START:
dw 5
dw 1
dd MB2_FRAMEBUFFER_TAG_END - MB2_FRAMEBUFFER_TAG_START
dd 0
dd 0
dd 32
MB2_FRAMEBUFFER_TAG_END:
align 8
MB2_EGA_SUPPORT_TAG_START:
dw 4
dw 0
dd MB2_EGA_SUPPORT_TAG_END - MB2_EGA_SUPPORT_TAG_START
dd 1 ; https://www.gnu.org/software/grub/manual/multiboot2/html_node/Console-header-tags.html
MB2_EGA_SUPPORT_TAG_END:
align 8
MB2_MODULE_ALIGN_TAG_START:
dw 6
dw 0
dd MB2_MODULE_ALIGN_TAG_END - MB2_MODULE_ALIGN_TAG_START
MB2_MODULE_ALIGN_TAG_END:
align 8
MB2_TAG_START:
dw 0
dw 0
dd MB2_TAG_END - MB2_TAG_START
MB2_TAG_END:
HEADER_END:

View File

@ -1,346 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <boot/binfo.h>
#include <types.h>
#include <debug.h>
#include <convert.h>
#include "../../../../tools/limine/limine.h"
#include "../../../kernel.h"
void InitLimine();
static volatile struct limine_entry_point_request EntryPointRequest = {
.id = LIMINE_ENTRY_POINT_REQUEST,
.revision = 0,
.response = NULL,
.entry = InitLimine};
static volatile struct limine_bootloader_info_request BootloaderInfoRequest = {
.id = LIMINE_BOOTLOADER_INFO_REQUEST,
.revision = 0};
static volatile struct limine_terminal_request TerminalRequest = {
.id = LIMINE_TERMINAL_REQUEST,
.revision = 0};
static volatile struct limine_framebuffer_request FramebufferRequest = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0};
static volatile struct limine_memmap_request MemmapRequest = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0};
static volatile struct limine_kernel_address_request KernelAddressRequest = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
.revision = 0};
static volatile struct limine_rsdp_request RsdpRequest = {
.id = LIMINE_RSDP_REQUEST,
.revision = 0};
static volatile struct limine_kernel_file_request KernelFileRequest = {
.id = LIMINE_KERNEL_FILE_REQUEST,
.revision = 0};
static volatile struct limine_module_request ModuleRequest = {
.id = LIMINE_MODULE_REQUEST,
.revision = 0};
static volatile struct limine_smbios_request SmbiosRequest = {
.id = LIMINE_SMBIOS_REQUEST,
.revision = 0};
void *TempStackPtr = NULL;
__naked __used __no_stack_protector void InitLimine()
{
asmv("mov %%rsp, %0"
: "=r"(TempStackPtr));
asmv("mov %0, %%rsp"
:
: "r"((uintptr_t)TempStackPtr - 0xFFFF800000000000));
asmv("mov $0, %rax\n"
"mov $0, %rbx\n"
"mov $0, %rcx\n"
"mov $0, %rdx\n"
"mov $0, %rsi\n"
"mov $0, %rdi\n"
"mov $0, %rbp\n"
"mov $0, %r8\n"
"mov $0, %r9\n"
"mov $0, %r10\n"
"mov $0, %r11\n"
"mov $0, %r12\n"
"mov $0, %r13\n"
"mov $0, %r14\n"
"mov $0, %r15");
asmv("jmp InitLimineAfterStack");
}
SafeFunction NIF void InitLimineAfterStack()
{
struct BootInfo binfo = {};
struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response;
info("Bootloader: %s %s", BootloaderInfoResponse->name, BootloaderInfoResponse->version);
struct limine_terminal_response *TerminalResponse = TerminalRequest.response;
if (TerminalResponse == NULL || TerminalResponse->terminal_count < 1)
{
warn("No terminal available.");
inf_loop asmv("hlt");
}
TerminalResponse->write(TerminalResponse->terminals[0], "\033[37mPlease wait... ", 20);
struct limine_framebuffer_response *FrameBufferResponse = FramebufferRequest.response;
struct limine_memmap_response *MemmapResponse = MemmapRequest.response;
struct limine_kernel_address_response *KernelAddressResponse = KernelAddressRequest.response;
struct limine_rsdp_response *RsdpResponse = RsdpRequest.response;
struct limine_kernel_file_response *KernelFileResponse = KernelFileRequest.response;
struct limine_module_response *ModuleResponse = ModuleRequest.response;
struct limine_smbios_response *SmbiosResponse = SmbiosRequest.response;
if (FrameBufferResponse == NULL || FrameBufferResponse->framebuffer_count < 1)
{
error("No framebuffer available [%#lx;%ld]", FrameBufferResponse,
(FrameBufferResponse == NULL) ? 0 : FrameBufferResponse->framebuffer_count);
TerminalResponse->write(TerminalResponse->terminals[0], "No framebuffer available", 24);
inf_loop asmv("hlt");
}
if (MemmapResponse == NULL || MemmapResponse->entry_count < 1)
{
error("No memory map available [%#lx;%ld]", MemmapResponse,
(MemmapResponse == NULL) ? 0 : MemmapResponse->entry_count);
TerminalResponse->write(TerminalResponse->terminals[0], "No memory map available", 23);
inf_loop asmv("hlt");
}
if (KernelAddressResponse == NULL)
{
error("No kernel address available [%#lx]", KernelAddressResponse);
TerminalResponse->write(TerminalResponse->terminals[0], "No kernel address available", 27);
inf_loop asmv("hlt");
}
if (RsdpResponse == NULL || RsdpResponse->address == 0)
{
error("No RSDP address available [%#lx;%#lx]", RsdpResponse,
(RsdpResponse == NULL) ? 0 : RsdpResponse->address);
TerminalResponse->write(TerminalResponse->terminals[0], "No RSDP address available", 25);
inf_loop asmv("hlt");
}
if (KernelFileResponse == NULL || KernelFileResponse->kernel_file == NULL)
{
error("No kernel file available [%#lx;%#lx]", KernelFileResponse,
(KernelFileResponse == NULL) ? 0 : KernelFileResponse->kernel_file);
TerminalResponse->write(TerminalResponse->terminals[0], "No kernel file available", 24);
inf_loop asmv("hlt");
}
if (ModuleResponse == NULL || ModuleResponse->module_count < 1)
{
error("No module information available [%#lx;%ld]", ModuleResponse,
(ModuleResponse == NULL) ? 0 : ModuleResponse->module_count);
TerminalResponse->write(TerminalResponse->terminals[0], "No module information available", 31);
inf_loop asmv("hlt");
}
/* Actual parsing starts here */
for (uint64_t i = 0; i < FrameBufferResponse->framebuffer_count; i++)
{
struct limine_framebuffer *framebuffer = FrameBufferResponse->framebuffers[i];
switch (framebuffer->memory_model)
{
case LIMINE_FRAMEBUFFER_RGB:
binfo.Framebuffer[i].Type = RGB;
break;
default:
{
error("Unsupported framebuffer memory model %d", framebuffer->memory_model);
TerminalResponse->write(TerminalResponse->terminals[0], "Unsupported framebuffer memory model", 37);
inf_loop asmv("hlt");
}
}
binfo.Framebuffer[i].BaseAddress = (void *)((uintptr_t)framebuffer->address - 0xFFFF800000000000);
binfo.Framebuffer[i].Width = (uint32_t)framebuffer->width;
binfo.Framebuffer[i].Height = (uint32_t)framebuffer->height;
binfo.Framebuffer[i].Pitch = (uint32_t)framebuffer->pitch;
binfo.Framebuffer[i].BitsPerPixel = framebuffer->bpp;
binfo.Framebuffer[i].RedMaskSize = framebuffer->red_mask_size;
binfo.Framebuffer[i].RedMaskShift = framebuffer->red_mask_shift;
binfo.Framebuffer[i].GreenMaskSize = framebuffer->green_mask_size;
binfo.Framebuffer[i].GreenMaskShift = framebuffer->green_mask_shift;
binfo.Framebuffer[i].BlueMaskSize = framebuffer->blue_mask_size;
binfo.Framebuffer[i].BlueMaskShift = framebuffer->blue_mask_shift;
binfo.Framebuffer[i].ExtendedDisplayIdentificationData = framebuffer->edid;
binfo.Framebuffer[i].EDIDSize = framebuffer->edid_size;
debug("Framebuffer %d: %dx%d %d bpp", i,
binfo.Framebuffer[i].Width,
binfo.Framebuffer[i].Height,
binfo.Framebuffer[i].BitsPerPixel);
debug("More info:\nAddress: %#lx\nPitch: %ld\nType: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d\nEDID: %#lx\nEDIDSize: %d",
binfo.Framebuffer[i].BaseAddress,
binfo.Framebuffer[i].Pitch,
binfo.Framebuffer[i].Type,
binfo.Framebuffer[i].RedMaskSize,
binfo.Framebuffer[i].RedMaskShift,
binfo.Framebuffer[i].GreenMaskSize,
binfo.Framebuffer[i].GreenMaskShift,
binfo.Framebuffer[i].BlueMaskSize,
binfo.Framebuffer[i].BlueMaskShift,
binfo.Framebuffer[i].ExtendedDisplayIdentificationData,
binfo.Framebuffer[i].EDIDSize);
}
binfo.Memory.Entries = MemmapResponse->entry_count;
for (uint64_t i = 0; i < MemmapResponse->entry_count; i++)
{
if (MemmapResponse->entry_count > MAX_MEMORY_ENTRIES)
{
warn("Too many memory entries, skipping the rest...");
break;
}
struct limine_memmap_entry *entry = MemmapResponse->entries[i];
if (!entry)
{
warn("Null memory entry %ld (%#lx), skipping...", i, entry);
continue;
}
binfo.Memory.Size += entry->length;
switch (entry->type)
{
case LIMINE_MEMMAP_USABLE:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = Usable;
break;
case LIMINE_MEMMAP_RESERVED:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = Reserved;
break;
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = ACPIReclaimable;
break;
case LIMINE_MEMMAP_ACPI_NVS:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = ACPINVS;
break;
case LIMINE_MEMMAP_BAD_MEMORY:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = BadMemory;
break;
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = BootloaderReclaimable;
break;
case LIMINE_MEMMAP_KERNEL_AND_MODULES:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = KernelAndModules;
break;
case LIMINE_MEMMAP_FRAMEBUFFER:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = Framebuffer;
break;
default:
binfo.Memory.Entry[i].BaseAddress = (void *)entry->base;
binfo.Memory.Entry[i].Length = entry->length;
binfo.Memory.Entry[i].Type = Unknown;
break;
}
}
for (uint64_t i = 0; i < ModuleResponse->module_count; i++)
{
if (i > MAX_MODULES)
{
warn("Too many modules, skipping the rest...");
break;
}
binfo.Modules[i].Address = (void *)((uint64_t)ModuleResponse->modules[i]->address - 0xFFFF800000000000);
binfo.Modules[i].Size = ModuleResponse->modules[i]->size;
strncpy(binfo.Modules[i].Path,
ModuleResponse->modules[i]->path,
strlen(ModuleResponse->modules[i]->path) + 1);
strncpy(binfo.Modules[i].CommandLine,
ModuleResponse->modules[i]->cmdline,
strlen(ModuleResponse->modules[i]->cmdline) + 1);
debug("Module %d:\nAddress: %#lx\nPath: \"%s\"\nCommand Line: \"%s\"\nSize: %ld",
i,
binfo.Modules[i].Address,
binfo.Modules[i].Path,
binfo.Modules[i].CommandLine,
binfo.Modules[i].Size);
}
binfo.RSDP = (struct RSDPInfo *)((uintptr_t)RsdpResponse->address - 0xFFFF800000000000);
debug("RSDP: %#lx [Signature: \"%.8s\"] [OEM: \"%.6s\"]",
binfo.RSDP, binfo.RSDP->Signature, binfo.RSDP->OEMID);
if (SmbiosResponse->entry_64 != NULL)
binfo.SMBIOSPtr = (void *)((uintptr_t)SmbiosResponse->entry_64 - 0xFFFF800000000000);
else if (SmbiosResponse->entry_32 != NULL)
binfo.SMBIOSPtr = (void *)((uintptr_t)SmbiosResponse->entry_32 - 0xFFFF800000000000);
else
binfo.SMBIOSPtr = NULL;
debug("SMBIOS: %#lx %#lx (binfo: %#lx)",
SmbiosResponse->entry_32,
SmbiosResponse->entry_64,
binfo.SMBIOSPtr);
binfo.Kernel.PhysicalBase = (void *)KernelAddressResponse->physical_base;
binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base;
binfo.Kernel.FileBase = (void *)((uintptr_t)KernelFileResponse->kernel_file->address - 0xFFFF800000000000);
binfo.Kernel.Size = KernelFileResponse->kernel_file->size;
strncpy(binfo.Kernel.CommandLine,
KernelFileResponse->kernel_file->cmdline,
strlen(KernelFileResponse->kernel_file->cmdline) + 1);
debug("Kernel physical address: %#lx", binfo.Kernel.PhysicalBase);
debug("Kernel virtual address: %#lx", binfo.Kernel.VirtualBase);
strncpy(binfo.Bootloader.Name,
BootloaderInfoResponse->name,
strlen(BootloaderInfoResponse->name) + 1);
strncpy(binfo.Bootloader.Version,
BootloaderInfoResponse->version,
strlen(BootloaderInfoResponse->version) + 1);
Entry(&binfo);
}

View File

@ -1,299 +0,0 @@
#include <types.h>
#include <boot/protocols/multiboot2.h>
#include <memory.hpp>
#include <io.h>
#include "../../../kernel.h"
EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
{
if (Info == NULL || Magic == NULL)
{
if (Magic == NULL)
error("Multiboot magic is NULL");
if (Info == NULL)
error("Multiboot info is NULL");
CPU::Stop();
}
else if (Magic != MULTIBOOT2_BOOTLOADER_MAGIC)
{
error("Multiboot magic is invalid (%#x != %#x)", Magic, MULTIBOOT2_BOOTLOADER_MAGIC);
CPU::Stop();
}
BootInfo mb2binfo{};
// Clear the BSS
// memset_unsafe(&_kernel_rodata_end, 0, &_kernel_end - &_kernel_rodata_end);
{
uint64_t div = 1193180 / 1000;
outb(0x43, 0xB6);
outb(0x42, (uint8_t)div);
outb(0x42, (uint8_t)(div >> 8));
uint8_t tmp = inb(0x61);
if (tmp != (tmp | 3))
outb(0x61, tmp | 3);
int pos = 0;
auto InfoAddress = Info;
for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8);
;
Tag = (struct multiboot_tag *)((multiboot_uint8_t *)Tag + ((Tag->size + 7) & ~7)))
{
if (Tag->type == MULTIBOOT_TAG_TYPE_END)
{
debug("End of multiboot2 tags");
break;
}
switch (Tag->type)
{
case MULTIBOOT_TAG_TYPE_CMDLINE:
{
strncpy(mb2binfo.Kernel.CommandLine,
((multiboot_tag_string *)Tag)->string,
strlen(((multiboot_tag_string *)Tag)->string));
debug("Kernel command line: %s", mb2binfo.Kernel.CommandLine);
break;
}
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
{
strncpy(mb2binfo.Bootloader.Name,
((multiboot_tag_string *)Tag)->string,
strlen(((multiboot_tag_string *)Tag)->string));
debug("Bootloader name: %s", mb2binfo.Bootloader.Name);
break;
}
case MULTIBOOT_TAG_TYPE_MODULE:
{
multiboot_tag_module *module = (multiboot_tag_module *)Tag;
static int module_count = 0;
mb2binfo.Modules[module_count].Address = (void *)(uint64_t)module->mod_start;
mb2binfo.Modules[module_count].Size = module->size;
strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6);
strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline,
strlen(module->cmdline));
debug("Module: %s", mb2binfo.Modules[module_count].Path);
module_count++;
break;
}
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
{
multiboot_tag_basic_meminfo *meminfo = (multiboot_tag_basic_meminfo *)Tag;
fixme("basic_meminfo->[mem_lower: %#x, mem_upper: %#x]",
meminfo->mem_lower, meminfo->mem_upper);
break;
}
case MULTIBOOT_TAG_TYPE_BOOTDEV:
{
multiboot_tag_bootdev *bootdev = (multiboot_tag_bootdev *)Tag;
fixme("bootdev->[biosdev: %#x, slice: %#x, part: %#x]",
bootdev->biosdev, bootdev->slice, bootdev->part);
break;
}
case MULTIBOOT_TAG_TYPE_MMAP:
{
multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag;
size_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry);
mb2binfo.Memory.Entries = EntryCount;
for (uint32_t i = 0; i < EntryCount; i++)
{
if (EntryCount > MAX_MEMORY_ENTRIES)
{
warn("Too many memory entries, skipping the rest...");
break;
}
multiboot_mmap_entry entry = mmap->entries[i];
mb2binfo.Memory.Size += entry.len;
switch (entry.type)
{
case MULTIBOOT_MEMORY_AVAILABLE:
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
mb2binfo.Memory.Entry[i].Length = entry.len;
mb2binfo.Memory.Entry[i].Type = Usable;
break;
case MULTIBOOT_MEMORY_RESERVED:
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
mb2binfo.Memory.Entry[i].Length = entry.len;
mb2binfo.Memory.Entry[i].Type = Reserved;
break;
case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE:
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
mb2binfo.Memory.Entry[i].Length = entry.len;
mb2binfo.Memory.Entry[i].Type = ACPIReclaimable;
break;
case MULTIBOOT_MEMORY_NVS:
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
mb2binfo.Memory.Entry[i].Length = entry.len;
mb2binfo.Memory.Entry[i].Type = ACPINVS;
break;
case MULTIBOOT_MEMORY_BADRAM:
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
mb2binfo.Memory.Entry[i].Length = entry.len;
mb2binfo.Memory.Entry[i].Type = BadMemory;
break;
default:
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
mb2binfo.Memory.Entry[i].Length = entry.len;
mb2binfo.Memory.Entry[i].Type = Unknown;
break;
}
debug("Memory entry: [BaseAddress: %#x, Length: %#x, Type: %d]",
mb2binfo.Memory.Entry[i].BaseAddress,
mb2binfo.Memory.Entry[i].Length,
mb2binfo.Memory.Entry[i].Type);
}
break;
}
case MULTIBOOT_TAG_TYPE_VBE:
{
multiboot_tag_vbe *vbe = (multiboot_tag_vbe *)Tag;
fixme("vbe->[vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x]",
vbe->vbe_mode, vbe->vbe_interface_seg, vbe->vbe_interface_off, vbe->vbe_interface_len);
break;
}
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
{
multiboot_tag_framebuffer *fb = (multiboot_tag_framebuffer *)Tag;
static int fb_count = 0;
mb2binfo.Framebuffer[fb_count].BaseAddress = (void *)fb->common.framebuffer_addr;
mb2binfo.Framebuffer[fb_count].Width = fb->common.framebuffer_width;
mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height;
mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch;
mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp;
switch (fb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
{
mb2binfo.Framebuffer[fb_count].Type = Indexed;
break;
}
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
{
mb2binfo.Framebuffer[fb_count].Type = RGB;
mb2binfo.Framebuffer[fb_count].RedMaskSize = fb->framebuffer_red_mask_size;
mb2binfo.Framebuffer[fb_count].RedMaskShift = fb->framebuffer_red_field_position;
mb2binfo.Framebuffer[fb_count].GreenMaskSize = fb->framebuffer_green_mask_size;
mb2binfo.Framebuffer[fb_count].GreenMaskShift = fb->framebuffer_green_field_position;
mb2binfo.Framebuffer[fb_count].BlueMaskSize = fb->framebuffer_blue_mask_size;
mb2binfo.Framebuffer[fb_count].BlueMaskShift = fb->framebuffer_blue_field_position;
break;
}
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
{
mb2binfo.Framebuffer[fb_count].Type = EGA;
break;
}
default:
{
mb2binfo.Framebuffer[fb_count].Type = Unknown_Framebuffer_Type;
break;
}
}
debug("Framebuffer %d: %dx%d %d bpp", fb_count, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp);
debug("More info:\nAddress: %p\nPitch: %lld\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d",
fb->common.framebuffer_addr, fb->common.framebuffer_pitch, fb->common.framebuffer_type,
fb->framebuffer_red_mask_size, fb->framebuffer_red_field_position, fb->framebuffer_green_mask_size,
fb->framebuffer_green_field_position, fb->framebuffer_blue_mask_size, fb->framebuffer_blue_field_position);
fb_count++;
break;
}
case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
{
multiboot_tag_elf_sections *elf = (multiboot_tag_elf_sections *)Tag;
fixme("elf_sections->[num=%d, size=%d, entsize=%d, shndx=%d]",
elf->num, elf->size, elf->entsize, elf->shndx);
break;
}
case MULTIBOOT_TAG_TYPE_APM:
{
multiboot_tag_apm *apm = (multiboot_tag_apm *)Tag;
fixme("apm->[version: %d, cseg: %d, offset: %d, cseg_16: %d, dseg: %d, flags: %d, cseg_len: %d, cseg_16_len: %d, dseg_len: %d]",
apm->version, apm->cseg, apm->offset, apm->cseg_16, apm->dseg, apm->flags, apm->cseg_len, apm->cseg_16_len, apm->dseg_len);
break;
}
case MULTIBOOT_TAG_TYPE_EFI32:
{
multiboot_tag_efi32 *efi32 = (multiboot_tag_efi32 *)Tag;
fixme("efi32->[pointer: %p, size: %d]", efi32->pointer, efi32->size);
break;
}
case MULTIBOOT_TAG_TYPE_EFI64:
{
multiboot_tag_efi64 *efi64 = (multiboot_tag_efi64 *)Tag;
fixme("efi64->[pointer: %p, size: %d]", efi64->pointer, efi64->size);
break;
}
case MULTIBOOT_TAG_TYPE_SMBIOS:
{
multiboot_tag_smbios *smbios = (multiboot_tag_smbios *)Tag;
fixme("smbios->[major: %d, minor: %d]", smbios->major, smbios->minor);
break;
}
case MULTIBOOT_TAG_TYPE_ACPI_OLD:
{
mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp;
debug("OLD ACPI RSDP: %p", mb2binfo.RSDP);
break;
}
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
{
mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp;
debug("NEW ACPI RSDP: %p", mb2binfo.RSDP);
break;
}
case MULTIBOOT_TAG_TYPE_NETWORK:
{
multiboot_tag_network *net = (multiboot_tag_network *)Tag;
fixme("network->[dhcpack: %p]", net->dhcpack);
break;
}
case MULTIBOOT_TAG_TYPE_EFI_MMAP:
{
multiboot_tag_efi_mmap *efi_mmap = (multiboot_tag_efi_mmap *)Tag;
fixme("efi_mmap->[descr_size: %d, descr_vers: %d, efi_mmap: %p]",
efi_mmap->descr_size, efi_mmap->descr_vers, efi_mmap->efi_mmap);
break;
}
case MULTIBOOT_TAG_TYPE_EFI_BS:
{
fixme("efi_bs->[%p] (unknown structure)", Tag);
break;
}
case MULTIBOOT_TAG_TYPE_EFI32_IH:
{
multiboot_tag_efi32_ih *efi32_ih = (multiboot_tag_efi32_ih *)Tag;
fixme("efi32_ih->[pointer: %p]", efi32_ih->pointer);
break;
}
case MULTIBOOT_TAG_TYPE_EFI64_IH:
{
multiboot_tag_efi64_ih *efi64_ih = (multiboot_tag_efi64_ih *)Tag;
fixme("efi64_ih->[pointer: %p]", efi64_ih->pointer);
break;
}
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
{
multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag;
mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr;
mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 0xFFFFFFFF80000000);
mb2binfo.Kernel.Size = ((uint64_t)&_kernel_end - (uint64_t)&_kernel_start) + ((uint64_t)&_bootstrap_end - (uint64_t)&_bootstrap_start);
debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase);
break;
}
default:
{
error("Unknown multiboot2 tag type: %d", Tag->type);
break;
}
}
}
tmp = inb(0x61) & 0xFC;
outb(0x61, tmp);
}
Entry(&mb2binfo);
}

View File

@ -1,287 +0,0 @@
#include <types.h>
union __attribute__((packed)) PageTableEntry
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Dirty : 1; // 6
bool PageAttributeTable : 1; // 7
bool Global : 1; // 8
uint8_t Available0 : 3; // 9-11
uint64_t Address : 40; // 12-51
uint32_t Available1 : 7; // 52-58
uint8_t ProtectionKey : 4; // 59-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageTableEntryPtr
{
PageTableEntry Entries[512];
};
union __attribute__((packed)) PageDirectoryEntry
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool PageSize : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageDirectoryEntryPtr
{
PageDirectoryEntry Entries[512];
};
union __attribute__((packed)) PageDirectoryPointerTableEntry
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool PageSize : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr
{
PageDirectoryPointerTableEntry Entries[512];
};
union __attribute__((packed)) PageMapLevel4
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool Reserved0 : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct PageTable4
{
PageMapLevel4 Entries[512];
} __attribute__((aligned(0x1000)));
extern "C" char BootPageTable[];
extern uintptr_t _kernel_start, _kernel_end;
__attribute__((section(".bootstrap.data"))) static PageTable4 *BPTable = (PageTable4 *)BootPageTable;
__attribute__((section(".bootstrap.data"))) static size_t BPT_Allocated = 0x4000;
__always_inline inline SafeFunction NIF void *RequestPage()
{
void *Page = (void *)(BootPageTable + BPT_Allocated);
BPT_Allocated += 0x1000;
if (BPT_Allocated >= 0x10000) /* The length of BootPageTable */
{
while (true)
;
}
return Page;
}
class PageMapIndexer
{
public:
uintptr_t PMLIndex = 0;
uintptr_t PDPTEIndex = 0;
uintptr_t PDEIndex = 0;
uintptr_t PTEIndex = 0;
__always_inline inline SafeFunction NIF PageMapIndexer(uintptr_t VirtualAddress)
{
uintptr_t Address = VirtualAddress;
Address >>= 12;
this->PTEIndex = Address & 0x1FF;
Address >>= 9;
this->PDEIndex = Address & 0x1FF;
Address >>= 9;
this->PDPTEIndex = Address & 0x1FF;
Address >>= 9;
this->PMLIndex = Address & 0x1FF;
}
};
__attribute__((section(".bootstrap.text"))) SafeFunction NIF void MB2_64_Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
{
PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress);
// Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only
uint64_t DirectoryFlags = Flags & 0x3F;
PageMapLevel4 PML4 = BPTable->Entries[Index.PMLIndex];
PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr;
if (!PML4.Present)
{
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)RequestPage();
if (PDPTEPtr == nullptr)
return;
{
void *ptr = PDPTEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PML4.Present = true;
PML4.SetAddress((uintptr_t)PDPTEPtr >> 12);
}
else
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
PML4.raw |= DirectoryFlags;
BPTable->Entries[Index.PMLIndex] = PML4;
PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex];
PageDirectoryEntryPtr *PDEPtr = nullptr;
if (!PDPTE.Present)
{
PDEPtr = (PageDirectoryEntryPtr *)RequestPage();
if (PDEPtr == nullptr)
return;
{
void *ptr = PDEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PDPTE.Present = true;
PDPTE.SetAddress((uintptr_t)PDEPtr >> 12);
}
else
PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.GetAddress() << 12);
PDPTE.raw |= DirectoryFlags;
PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE;
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
PageTableEntryPtr *PTEPtr = nullptr;
if (!PDE.Present)
{
PTEPtr = (PageTableEntryPtr *)RequestPage();
if (PTEPtr == nullptr)
return;
{
void *ptr = PTEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PDE.Present = true;
PDE.SetAddress((uintptr_t)PTEPtr >> 12);
}
else
PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.GetAddress() << 12);
PDE.raw |= DirectoryFlags;
PDEPtr->Entries[Index.PDEIndex] = PDE;
PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex];
PTE.Present = true;
PTE.raw |= Flags;
PTE.SetAddress((uintptr_t)PhysicalAddress >> 12);
PTEPtr->Entries[Index.PTEIndex] = PTE;
asmv("invlpg (%0)"
:
: "r"(VirtualAddress)
: "memory");
}
EXTERNC __attribute__((section(".bootstrap.text"))) SafeFunction NIF __attribute__((section(".bootstrap.text"))) void UpdatePageTable64()
{
BPTable = (PageTable4 *)BootPageTable;
// for (size_t i = 0; i < 0x10000000; i += 0x1000)
// MB2_64_Map((void *)i, (void *)i, 0x3);
uintptr_t KernelStart = (uintptr_t)&_kernel_start;
uintptr_t KernelEnd = (uintptr_t)&_kernel_end;
uintptr_t PhysicalStart = KernelStart - 0xFFFFFFFF80000000;
for (uintptr_t i = KernelStart; i < KernelEnd; i += 0x1000)
{
MB2_64_Map((void *)i, (void *)PhysicalStart, 0x3);
PhysicalStart += 0x1000;
}
asmv("mov %%cr3, %%rax\n"
"mov %%rax, %%cr3\n"
:
:
: "rax");
}

View File

@ -1,114 +0,0 @@
[bits 32]
KERNEL_STACK_SIZE equ 0x4000 ; 16KB
extern multiboot_main
extern LoadGDT32
extern BootPageTable
extern UpdatePageTable
section .bootstrap.data
MB_HeaderMagic:
dq 0
MB_HeaderInfo:
dq 0
section .bootstrap.text
global _start
_start:
cli
mov [MB_HeaderMagic], eax
mov [MB_HeaderInfo], ebx
mov ecx, cr4
or ecx, 0x00000010 ; Set PSE in CR4
or ecx, 0x00000020 ; Set PAE in CR4
mov cr4, ecx
call LoadGDT32
call UpdatePageTable
mov ecx, BootPageTable
mov cr3, ecx
mov ecx, 0xC0000080 ; EFER
rdmsr
or eax, 0x800 | 0x100 | 0x1 ; Set LME, LMA, SCE
wrmsr
mov ecx, cr0
or ecx, 0x80000000 | 0x1 ; Set PG and PE in CR0
mov cr0, ecx
lgdt [GDT64.Ptr]
jmp GDT64.code:HigherHalfStart
extern UpdatePageTable64
[bits 64]
HigherHalfStart:
mov ax, GDT64.data
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
call UpdatePageTable64
mov rsp, KernelStack + KERNEL_STACK_SIZE
mov rdi, [MB_HeaderMagic]
mov rsi, [MB_HeaderInfo]
push rsi
push rdi
call multiboot_main
.Hang:
hlt
jmp .Hang
; Access bits
PRESENT equ 1 << 7
NOT_SYS equ 1 << 4
EXEC equ 1 << 3
DC equ 1 << 2
RW equ 1 << 1
ACCESSED equ 1 << 0
; Flags bits
GRAN_4K equ 1 << 7
SZ_32 equ 1 << 6
LONG_MODE equ 1 << 5
section .bootstrap.data
GDT64:
.null: equ $ - GDT64
dq 0
.code: equ $ - GDT64
dd 0xFFFF
db 0
db PRESENT | NOT_SYS | EXEC | RW
db GRAN_4K | LONG_MODE | 0xF
db 0
.data: equ $ - GDT64
dd 0xFFFF
db 0
db PRESENT | NOT_SYS | RW
db GRAN_4K | SZ_32 | 0xF
db 0
.tss: equ $ - GDT64
dd 0x00000068
dd 0x00CF8900
.Ptr:
dw $ - GDT64 - 1
dq GDT64
section .bootstrap.bss
align 16
KernelStack:
resb KERNEL_STACK_SIZE

View File

@ -1,45 +0,0 @@
PAGE_TABLE_SIZE equ 0x4 ; 1GB
[bits 32]
section .bootstrap.data
align 0x1000
global BootPageTable
BootPageTable:
times (0x10000) dq 0 ; 0x4000
section .bootstrap.text
global UpdatePageTable
UpdatePageTable:
mov edi, (BootPageTable + 0x0000) ; First PML4E
mov eax, (BootPageTable + 0x1000) ; First PDPTE
or eax, 11b ; Bitwise OR on rax (PDPTE) with 11b (Present, Write)
mov dword [edi], eax ; Write 11b to PML4E
mov edi, (BootPageTable + 0x1000) ; First PDPTE
mov eax, (BootPageTable + 0x2000) ; First PDE
or eax, 11b ; Bitwise OR on rax (PDE) with 11b (Present, Write)
mov ecx, PAGE_TABLE_SIZE ; For loop instruction
mov ebx, 0x0 ; Value to store in the next 4 bytes
.FillPageTableLevel3:
mov dword [edi], eax ; Store modified PDE in PDPTE
mov dword [edi + 4], ebx ; Store the rbx value in the next 4 bytes
add eax, 0x1000 ; Increment (page size)
adc ebx, 0 ; Add 0 to carry flag
add edi, 8 ; Add 8 to rdi (next PDE)
loop .FillPageTableLevel3 ; Loop until rcx is 0
mov edi, (BootPageTable + 0x2000) ; First PDE
mov eax, 10000011b ; Present, Write, Large Page
mov ecx, (512 * PAGE_TABLE_SIZE) ; For loop instruction
mov ebx, 0x0 ; Value to store in the next 4 bytes
.FillPageTableLevel2:
mov dword [edi], eax ; Store modified PDE in PDPTE
mov dword [edi + 4], ebx ; Store the rbx value in the next 4 bytes
add eax, 1 << 21 ; Increment (page size)
adc ebx, 0 ; Add 0 (carry flag) to rbx to increment if there was a carry
add edi, 8 ; Add 8 to rdi (next PDE)
loop .FillPageTableLevel2 ; Loop until rcx is 0
ret

View File

@ -1,255 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include "acpi.hpp"
#include <time.hpp>
#include <debug.h>
#include <smp.hpp>
#include <io.h>
#include "cpu/apic.hpp"
#include "../../kernel.h"
#define ACPI_TIMER 0x0001
#define ACPI_BUSMASTER 0x0010
#define ACPI_GLOBAL 0x0020
#define ACPI_POWER_BUTTON 0x0100
#define ACPI_SLEEP_BUTTON 0x0200
#define ACPI_RTC_ALARM 0x0400
#define ACPI_PCIE_WAKE 0x4000
#define ACPI_WAKE 0x8000
namespace ACPI
{
__always_inline inline bool IsCanonical(uint64_t Address)
{
return ((Address <= 0x00007FFFFFFFFFFF) || ((Address >= 0xFFFF800000000000) && (Address <= 0xFFFFFFFFFFFFFFFF)));
}
#define ACPI_ENABLED 0x0001
#define ACPI_SLEEP 0x2000
#define ACPI_GAS_MMIO 0
#define ACPI_GAS_IO 1
#define ACPI_GAS_PCI 2
void DSDT::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
{
debug("SCI Handle Triggered");
uint16_t Event = 0;
{
uint16_t a = 0, b = 0;
if (acpi->FADT->PM1aEventBlock)
{
a = inw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock), a);
}
if (acpi->FADT->PM1bEventBlock)
{
b = inw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock), b);
}
Event = a | b;
}
debug("SCI Event: %#lx", Event);
if (Event & ACPI_BUSMASTER)
{
fixme("ACPI Busmaster");
}
else if (Event & ACPI_GLOBAL)
{
fixme("ACPI Global");
}
else if (Event & ACPI_POWER_BUTTON)
{
if (TaskManager)
{
TaskManager->CreateThread(TaskManager->CreateProcess(nullptr,
"Shutdown",
Tasking::TaskTrustLevel::Kernel),
(Tasking::IP)KST_Shutdown);
}
else
KernelShutdownThread(false);
}
else if (Event & ACPI_SLEEP_BUTTON)
{
fixme("ACPI Sleep Button");
}
else if (Event & ACPI_RTC_ALARM)
{
fixme("ACPI RTC Alarm");
}
else if (Event & ACPI_PCIE_WAKE)
{
fixme("ACPI PCIe Wake");
}
else if (Event & ACPI_WAKE)
{
fixme("ACPI Wake");
}
else if (Event & ACPI_TIMER)
{
fixme("ACPI Timer");
}
else
{
error("ACPI unknown event %#lx on CPU %d", Event, GetCurrentCPU()->ID);
CPU::Stop();
}
UNUSED(Frame);
}
void DSDT::Shutdown()
{
trace("Shutting down...");
if (SCI_EN == 1)
{
outw(s_cst(uint16_t, acpi->FADT->PM1aControlBlock),
s_cst(uint16_t,
(inw(s_cst(uint16_t,
acpi->FADT->PM1aControlBlock)) &
0xE3FF) |
((SLP_TYPa << 10) | ACPI_SLEEP)));
if (acpi->FADT->PM1bControlBlock)
outw(s_cst(uint16_t, acpi->FADT->PM1bControlBlock),
s_cst(uint16_t,
(inw(
s_cst(uint16_t, acpi->FADT->PM1bControlBlock)) &
0xE3FF) |
((SLP_TYPb << 10) | ACPI_SLEEP)));
outw(s_cst(uint16_t, PM1a_CNT), SLP_TYPa | SLP_EN);
if (PM1b_CNT)
outw(s_cst(uint16_t, PM1b_CNT), SLP_TYPb | SLP_EN);
}
}
void DSDT::Reboot()
{
trace("Rebooting...");
switch (acpi->FADT->ResetReg.AddressSpace)
{
case ACPI_GAS_MMIO:
{
*(uint8_t *)(acpi->FADT->ResetReg.Address) = acpi->FADT->ResetValue;
break;
}
case ACPI_GAS_IO:
{
outb(s_cst(uint16_t, acpi->FADT->ResetReg.Address), acpi->FADT->ResetValue);
break;
}
case ACPI_GAS_PCI:
{
fixme("ACPI_GAS_PCI not supported.");
/*
seg - 0
bus - 0
dev - (FADT->ResetReg.Address >> 32) & 0xFFFF
function - (FADT->ResetReg.Address >> 16) & 0xFFFF
offset - FADT->ResetReg.Address & 0xFFFF
value - FADT->ResetValue
*/
break;
}
default:
{
error("Unknown reset register address space: %d", acpi->FADT->ResetReg.AddressSpace);
break;
}
}
}
DSDT::DSDT(ACPI *acpi) : Interrupts::Handler(acpi->FADT->SCI_Interrupt)
{
this->acpi = acpi;
uint64_t Address = ((IsCanonical(acpi->FADT->X_Dsdt) && acpi->XSDTSupported) ? acpi->FADT->X_Dsdt : acpi->FADT->Dsdt);
uint8_t *S5Address = (uint8_t *)(Address) + 36;
ACPI::ACPI::ACPIHeader *Header = (ACPI::ACPI::ACPIHeader *)Address;
uint64_t Length = Header->Length;
while (Length-- > 0)
{
if (!memcmp(S5Address, "_S5_", 4))
break;
S5Address++;
}
if (Length <= 0)
{
warn("_S5 not present in ACPI");
return;
}
if ((*(S5Address - 1) == 0x08 || (*(S5Address - 2) == 0x08 && *(S5Address - 1) == '\\')) && *(S5Address + 4) == 0x12)
{
S5Address += 5;
S5Address += ((*S5Address & 0xC0) >> 6) + 2;
if (*S5Address == 0x0A)
S5Address++;
SLP_TYPa = s_cst(uint16_t, *(S5Address) << 10);
S5Address++;
if (*S5Address == 0x0A)
S5Address++;
SLP_TYPb = s_cst(uint16_t, *(S5Address) << 10);
SMI_CMD = acpi->FADT->SMI_CommandPort;
ACPI_ENABLE = acpi->FADT->AcpiEnable;
ACPI_DISABLE = acpi->FADT->AcpiDisable;
PM1a_CNT = acpi->FADT->PM1aControlBlock;
PM1b_CNT = acpi->FADT->PM1bControlBlock;
PM1_CNT_LEN = acpi->FADT->PM1ControlLength;
SLP_EN = 1 << 13;
SCI_EN = 1;
trace("ACPI Shutdown is supported");
ACPIShutdownSupported = true;
uint16_t value = ACPI_POWER_BUTTON | ACPI_SLEEP_BUTTON | ACPI_WAKE;
{
uint16_t a = s_cst(uint16_t, acpi->FADT->PM1aEventBlock + (acpi->FADT->PM1EventLength / 2));
uint16_t b = s_cst(uint16_t, acpi->FADT->PM1bEventBlock + (acpi->FADT->PM1EventLength / 2));
debug("SCI Event: %#llx [a:%#x b:%#x]", value, a, b);
if (acpi->FADT->PM1aEventBlock)
outw(a, value);
if (acpi->FADT->PM1bEventBlock)
outw(b, value);
}
{
uint16_t a = 0, b = 0;
if (acpi->FADT->PM1aEventBlock)
{
a = inw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock), a);
}
if (acpi->FADT->PM1bEventBlock)
{
b = inw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock), b);
}
}
((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, acpi->FADT->SCI_Interrupt, 1);
return;
}
warn("Failed to parse _S5 in ACPI");
SCI_EN = 0;
}
DSDT::~DSDT()
{
}
}

View File

@ -1,91 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include "acpi.hpp"
#include <memory.hpp>
#include <debug.h>
#include "../../kernel.h"
namespace ACPI
{
MADT::MADT(ACPI::MADTHeader *madt)
{
trace("Initializing MADT");
CPUCores = 0;
LAPICAddress = (LAPIC *)(uintptr_t)madt->LocalControllerAddress;
for (uint8_t *ptr = (uint8_t *)(madt->Entries);
(uintptr_t)(ptr) < (uintptr_t)(madt) + madt->Header.Length;
ptr += *(ptr + 1))
{
switch (*(ptr))
{
case 0:
{
if (ptr[4] & 1)
{
lapic.push_back((LocalAPIC *)ptr);
KPrint("Local APIC \e8888FF%d\eCCCCCC (APIC \e8888FF%d\eCCCCCC) found.", lapic.back()->ACPIProcessorId, lapic.back()->APICId);
CPUCores++;
}
break;
}
case 1:
{
ioapic.push_back((MADTIOApic *)ptr);
KPrint("I/O APIC \e8888FF%d\eCCCCCC (Address \e8888FF%#lx\eCCCCCC) found.", ioapic.back()->APICID, ioapic.back()->Address);
Memory::Virtual(KernelPageTable).Map((void *)(uintptr_t)ioapic.back()->Address, (void *)(uintptr_t)ioapic.back()->Address, Memory::PTFlag::RW | Memory::PTFlag::PCD); // Make sure that the address is mapped.
break;
}
case 2:
{
iso.push_back((MADTIso *)ptr);
KPrint("ISO (IRQ:\e8888FF%#lx\eCCCCCC, BUS:\e8888FF%#lx\eCCCCCC, GSI:\e8888FF%#lx\eCCCCCC, %s\eCCCCCC/%s\eCCCCCC) found.",
iso.back()->IRQSource, iso.back()->BuSSource, iso.back()->GSI,
iso.back()->Flags & 0x00000004 ? "\e1770FFActive High" : "\e475EFFActive Low",
iso.back()->Flags & 0x00000100 ? "\e00962DEdge Triggered" : "\e008F58Level Triggered");
break;
}
case 4:
{
nmi.push_back((MADTNmi *)ptr);
KPrint("NMI \e8888FF%#lx\eCCCCCC (lint:\e8888FF%#lx\eCCCCCC) found.", nmi.back()->processor, nmi.back()->lint);
break;
}
case 5:
{
LAPICAddress = (LAPIC *)ptr;
KPrint("APIC found at \e8888FF%#lx\eCCCCCC", LAPICAddress);
break;
}
default:
{
KPrint("Unknown MADT entry \e8888FF%#lx\eCCCCCC", *(ptr));
break;
}
}
Memory::Virtual(KernelPageTable).Map((void *)LAPICAddress, (void *)LAPICAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD); // I should map more than one page?
}
CPUCores--; // We start at 0 (BSP) and end at 11 (APs), so we have 12 cores.
KPrint("Total CPU cores: %d", CPUCores + 1);
}
MADT::~MADT()
{
}
}

View File

@ -1,92 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <syscalls.hpp>
#include <cpu.hpp>
#include "cpu/gdt.hpp"
// https://supercip971.github.io/02-wingos-syscalls.html
using namespace CPU::x64;
// "Core/SystemCalls.cpp"
extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs);
extern "C" void SystemCallHandlerStub();
extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHandlerStub()
{
asmv("swapgs\n"
"mov %rsp, %gs:0x8\n" // CPUData->TempStack
"mov %gs:0x0, %rsp\n" // CPUData->SystemCallStack
"push $0x1b\n" // user data segment
"push %gs:0x8\n" // saved stack
"push %r11\n" // saved rflags
"push $0x23\n" // user code segment
"push %rcx\n" // Current RIP
"push %rax\n"
"push %rbx\n"
"push %rcx\n"
"push %rdx\n"
"push %rsi\n"
"push %rdi\n"
"push %rbp\n"
"push %r8\n"
"push %r9\n"
"push %r10\n"
"push %r11\n"
"push %r12\n"
"push %r13\n"
"push %r14\n"
"push %r15\n"
"mov %rsp, %rdi\n"
"mov $0, %rbp\n"
"call SystemCallsHandler\n"
"pop %r15\n"
"pop %r14\n"
"pop %r13\n"
"pop %r12\n"
"pop %r11\n"
"pop %r10\n"
"pop %r9\n"
"pop %r8\n"
"pop %rbp\n"
"pop %rdi\n"
"pop %rsi\n"
"pop %rdx\n"
"pop %rcx\n"
"pop %rbx\n"
"mov %gs:0x8, %rsp\n" // CPUData->TempStack
"swapgs\n"
"sti\n"
"sysretq\n");
}
void InitializeSystemCalls()
{
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | 1);
wrmsr(MSR_STAR, ((uint64_t)(GDT_KERNEL_CODE) << 32) | ((uint64_t)(GDT_KERNEL_DATA | 3) << 48));
wrmsr(MSR_LSTAR, (uint64_t)SystemCallHandlerStub);
wrmsr(MSR_SYSCALL_MASK, (uint64_t)(1 << 9));
}

View File

@ -1,294 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_ACPI_H__
#define __FENNIX_KERNEL_ACPI_H__
#include <types.h>
#include <boot/binfo.h>
#include <ints.hpp>
#include <cpu.hpp>
#include <vector>
namespace ACPI
{
class ACPI
{
public:
struct ACPIHeader
{
unsigned char Signature[4];
uint32_t Length;
uint8_t Revision;
uint8_t Checksum;
uint8_t OEMID[6];
uint8_t OEMTableID[8];
uint32_t OEMRevision;
uint32_t CreatorID;
uint32_t CreatorRevision;
} __packed;
struct GenericAddressStructure
{
uint8_t AddressSpace;
uint8_t BitWidth;
uint8_t BitOffset;
uint8_t AccessSize;
uint64_t Address;
} __packed;
struct MCFGHeader
{
struct ACPIHeader Header;
uint64_t Reserved;
} __packed;
struct HPETHeader
{
ACPIHeader Header;
uint8_t HardwareRevID;
uint8_t ComparatorCount : 5;
uint8_t CounterSize : 1;
uint8_t Reserved : 1;
uint8_t LegacyReplacement : 1;
uint16_t PCIVendorID;
struct GenericAddressStructure Address;
uint8_t HPETNumber;
uint16_t MinimumTick;
uint8_t PageProtection;
} __packed;
struct FADTHeader
{
ACPIHeader Header;
uint32_t FirmwareCtrl;
uint32_t Dsdt;
uint8_t Reserved;
uint8_t PreferredPowerManagementProfile;
uint16_t SCI_Interrupt;
uint32_t SMI_CommandPort;
uint8_t AcpiEnable;
uint8_t AcpiDisable;
uint8_t S4BIOS_REQ;
uint8_t PSTATE_Control;
uint32_t PM1aEventBlock;
uint32_t PM1bEventBlock;
uint32_t PM1aControlBlock;
uint32_t PM1bControlBlock;
uint32_t PM2ControlBlock;
uint32_t PMTimerBlock;
uint32_t GPE0Block;
uint32_t GPE1Block;
uint8_t PM1EventLength;
uint8_t PM1ControlLength;
uint8_t PM2ControlLength;
uint8_t PMTimerLength;
uint8_t GPE0Length;
uint8_t GPE1Length;
uint8_t GPE1Base;
uint8_t CStateControl;
uint16_t WorstC2Latency;
uint16_t WorstC3Latency;
uint16_t FlushSize;
uint16_t FlushStride;
uint8_t DutyOffset;
uint8_t DutyWidth;
uint8_t DayAlarm;
uint8_t MonthAlarm;
uint8_t Century;
uint16_t BootArchitectureFlags;
uint8_t Reserved2;
uint32_t Flags;
struct GenericAddressStructure ResetReg;
uint8_t ResetValue;
uint8_t Reserved3[3];
uint64_t X_FirmwareControl;
uint64_t X_Dsdt;
struct GenericAddressStructure X_PM1aEventBlock;
struct GenericAddressStructure X_PM1bEventBlock;
struct GenericAddressStructure X_PM1aControlBlock;
struct GenericAddressStructure X_PM1bControlBlock;
struct GenericAddressStructure X_PM2ControlBlock;
struct GenericAddressStructure X_PMTimerBlock;
struct GenericAddressStructure X_GPE0Block;
struct GenericAddressStructure X_GPE1Block;
} __packed;
struct BGRTHeader
{
ACPIHeader Header;
uint16_t Version;
uint8_t Status;
uint8_t ImageType;
uint64_t ImageAddress;
uint32_t ImageOffsetX;
uint32_t ImageOffsetY;
};
struct SRATHeader
{
ACPIHeader Header;
uint32_t TableRevision; // Must be value 1
uint64_t Reserved; // Reserved, must be zero
};
struct TPM2Header
{
ACPIHeader Header;
uint32_t Flags;
uint64_t ControlAddress;
uint32_t StartMethod;
};
struct TCPAHeader
{
ACPIHeader Header;
uint16_t Reserved;
uint32_t MaxLogLength;
uint64_t LogAddress;
};
struct WAETHeader
{
ACPIHeader Header;
uint32_t Flags;
};
struct HESTHeader
{
ACPIHeader Header;
uint32_t ErrorSourceCount;
};
struct MADTHeader
{
ACPIHeader Header;
uint32_t LocalControllerAddress;
uint32_t Flags;
char Entries[];
} __packed;
ACPIHeader *XSDT = nullptr;
MCFGHeader *MCFG = nullptr;
HPETHeader *HPET = nullptr;
FADTHeader *FADT = nullptr;
BGRTHeader *BGRT = nullptr;
SRATHeader *SRAT = nullptr;
TPM2Header *TPM2 = nullptr;
TCPAHeader *TCPA = nullptr;
WAETHeader *WAET = nullptr;
MADTHeader *MADT = nullptr;
HESTHeader *HEST = nullptr;
bool XSDTSupported = false;
void *FindTable(ACPIHeader *ACPIHeader, char *Signature);
void SearchTables(ACPIHeader *Header);
ACPI();
~ACPI();
};
class MADT
{
public:
struct APICHeader
{
uint8_t Type;
uint8_t Length;
} __packed;
struct MADTIOApic
{
struct APICHeader Header;
uint8_t APICID;
uint8_t reserved;
uint32_t Address;
uint32_t GSIBase;
} __packed;
struct MADTIso
{
struct APICHeader Header;
uint8_t BuSSource;
uint8_t IRQSource;
uint32_t GSI;
uint16_t Flags;
} __packed;
struct MADTNmi
{
struct APICHeader Header;
uint8_t processor;
uint16_t flags;
uint8_t lint;
} __packed;
struct LocalAPIC
{
struct APICHeader Header;
uint8_t ACPIProcessorId;
uint8_t APICId;
uint32_t Flags;
} __packed;
struct LAPIC
{
uint8_t id;
uintptr_t PhysicalAddress;
void *VirtualAddress;
};
std::vector<MADTIOApic *> ioapic;
std::vector<MADTIso *> iso;
std::vector<MADTNmi *> nmi;
std::vector<LocalAPIC *> lapic;
struct LAPIC *LAPICAddress;
uint16_t CPUCores;
MADT(ACPI::MADTHeader *madt);
~MADT();
};
class DSDT : public Interrupts::Handler
{
private:
uint32_t SMI_CMD = 0;
uint8_t ACPI_ENABLE = 0;
uint8_t ACPI_DISABLE = 0;
uint32_t PM1a_CNT = 0;
uint32_t PM1b_CNT = 0;
uint16_t SLP_TYPa = 0;
uint16_t SLP_TYPb = 0;
uint16_t SLP_EN = 0;
uint16_t SCI_EN = 0;
uint8_t PM1_CNT_LEN = 0;
ACPI *acpi;
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
public:
bool ACPIShutdownSupported = false;
void Reboot();
void Shutdown();
DSDT(ACPI *acpi);
~DSDT();
};
}
#endif // !__FENNIX_KERNEL_ACPI_H__

View File

@ -1,403 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include "apic.hpp"
#include <memory.hpp>
#include <uart.hpp>
#include <lock.hpp>
#include <cpu.hpp>
#include <smp.hpp>
#include <io.h>
#include "../../../kernel.h"
#include "../acpi.hpp"
NewLock(APICLock);
using namespace CPU::x64;
using namespace CPU::x86;
/*
In constructor APIC::APIC::APIC(int):
warning: left shift count >= width of type
| APICBaseAddress = BaseStruct.ApicBaseLo << 12u | BaseStruct.ApicBaseHi << 32u;
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
*/
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
namespace APIC
{
// headache
// https://www.amd.com/system/files/TechDocs/24593.pdf
// https://www.naic.edu/~phil/software/intel/318148.pdf
uint32_t APIC::Read(uint32_t Register)
{
#ifdef DEBUG
if (Register != APIC_ICRLO &&
Register != APIC_ICRHI &&
Register != APIC_ID)
debug("APIC::Read(%#lx) [x2=%d]", Register, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported)
{
if (Register != APIC_ICRHI)
return s_cst(uint32_t, rdmsr((Register >> 4) + 0x800));
else
return s_cst(uint32_t, rdmsr(0x30 + 0x800));
}
else
{
CPU::MemBar::Barrier();
uint32_t ret = *((volatile uint32_t *)((uintptr_t)APICBaseAddress + Register));
CPU::MemBar::Barrier();
return ret;
}
}
void APIC::Write(uint32_t Register, uint32_t Value)
{
#ifdef DEBUG
if (Register != APIC_EOI &&
Register != APIC_TDCR &&
Register != APIC_TIMER &&
Register != APIC_TICR &&
Register != APIC_ICRLO &&
Register != APIC_ICRHI)
debug("APIC::Write(%#lx, %#lx) [x2=%d]", Register, Value, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported)
{
if (Register != APIC_ICRHI)
wrmsr((Register >> 4) + 0x800, Value);
else
wrmsr(MSR_X2APIC_ICR, Value);
}
else
{
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)APICBaseAddress) + Register)) = Value;
CPU::MemBar::Barrier();
}
}
void APIC::IOWrite(uint64_t Base, uint32_t Register, uint32_t Value)
{
debug("APIC::IOWrite(%#lx, %#lx, %#lx)", Base, Register, Value);
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)Base))) = Register;
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)Base + 16))) = Value;
CPU::MemBar::Barrier();
}
uint32_t APIC::IORead(uint64_t Base, uint32_t Register)
{
debug("APIC::IORead(%#lx, %#lx)", Base, Register);
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)Base))) = Register;
CPU::MemBar::Barrier();
uint32_t ret = *((volatile uint32_t *)(((uintptr_t)Base + 16)));
CPU::MemBar::Barrier();
return ret;
}
void APIC::EOI() { this->Write(APIC_EOI, 0); }
void APIC::WaitForIPI()
{
InterruptCommandRegisterLow icr = {.raw = 0};
do
{
icr.raw = this->Read(APIC_ICRLO);
} while (icr.DeliveryStatus != Idle);
}
void APIC::IPI(int CPU, InterruptCommandRegisterLow icr)
{
SmartCriticalSection(APICLock);
if (x2APICSupported)
{
wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
else
{
this->Write(APIC_ICRHI, (CPU << 24));
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
}
void APIC::SendInitIPI(int CPU)
{
SmartCriticalSection(APICLock);
if (x2APICSupported)
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.DeliveryMode = INIT;
icr.Level = Assert;
wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
else
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.DeliveryMode = INIT;
icr.Level = Assert;
this->Write(APIC_ICRHI, (CPU << 24));
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
}
void APIC::SendStartupIPI(int CPU, uint64_t StartupAddress)
{
SmartCriticalSection(APICLock);
if (x2APICSupported)
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.Vector = s_cst(uint8_t, StartupAddress >> 12);
icr.DeliveryMode = Startup;
icr.Level = Assert;
wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
else
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.Vector = s_cst(uint8_t, StartupAddress >> 12);
icr.DeliveryMode = Startup;
icr.Level = Assert;
this->Write(APIC_ICRHI, (CPU << 24));
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
}
uint32_t APIC::IOGetMaxRedirect(uint32_t APICID)
{
uint32_t TableAddress = (this->IORead((((ACPI::MADT *)PowerManager->GetMADT())->ioapic[APICID]->Address), GetIOAPICVersion));
return ((IOAPICVersion *)&TableAddress)->MaximumRedirectionEntry;
}
void APIC::RawRedirectIRQ(uint16_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status)
{
uint64_t Value = Vector;
int64_t IOAPICTarget = -1;
for (uint64_t i = 0; ((ACPI::MADT *)PowerManager->GetMADT())->ioapic[i] != 0; i++)
if (((ACPI::MADT *)PowerManager->GetMADT())->ioapic[i]->GSIBase <= GSI)
if (((ACPI::MADT *)PowerManager->GetMADT())->ioapic[i]->GSIBase + IOGetMaxRedirect(s_cst(uint32_t, i)) > GSI)
{
IOAPICTarget = i;
break;
}
if (IOAPICTarget == -1)
{
error("No ISO table found for I/O APIC");
return;
}
// TODO: IOAPICRedirectEntry Entry = {.raw = 0};
if (Flags & ActiveHighLow)
Value |= (1 << 13);
if (Flags & EdgeLevel)
Value |= (1 << 15);
if (!Status)
Value |= (1 << 16);
Value |= (((uintptr_t)CPU) << 56);
uint32_t IORegister = (GSI - ((ACPI::MADT *)PowerManager->GetMADT())->ioapic[IOAPICTarget]->GSIBase) * 2 + 16;
this->IOWrite(((ACPI::MADT *)PowerManager->GetMADT())->ioapic[IOAPICTarget]->Address, IORegister, (uint32_t)Value);
this->IOWrite(((ACPI::MADT *)PowerManager->GetMADT())->ioapic[IOAPICTarget]->Address, IORegister + 1, (uint32_t)(Value >> 32));
}
void APIC::RedirectIRQ(int CPU, uint16_t IRQ, int Status)
{
for (uint64_t i = 0; i < ((ACPI::MADT *)PowerManager->GetMADT())->iso.size(); i++)
if (((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->IRQSource == IRQ)
{
debug("[ISO %d] Mapping to source IRQ%#d GSI:%#lx on CPU %d",
i, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->IRQSource, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->GSI, CPU);
this->RawRedirectIRQ(((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->IRQSource + 0x20, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->GSI, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->Flags, CPU, Status);
return;
}
debug("Mapping IRQ%d on CPU %d", IRQ, CPU);
this->RawRedirectIRQ(IRQ + 0x20, IRQ, 0, CPU, Status);
}
void APIC::RedirectIRQs(int CPU)
{
SmartCriticalSection(APICLock);
debug("Redirecting IRQs...");
for (uint8_t i = 0; i < 16; i++)
this->RedirectIRQ(CPU, i, 1);
debug("Redirecting IRQs completed.");
}
APIC::APIC(int Core)
{
SmartCriticalSection(APICLock);
APIC_BASE BaseStruct = {.raw = rdmsr(MSR_APIC_BASE)};
uint64_t BaseLow = BaseStruct.ApicBaseLo;
uint64_t BaseHigh = BaseStruct.ApicBaseHi;
this->APICBaseAddress = BaseLow << 12u | BaseHigh << 32u;
trace("APIC Address: %#lx", this->APICBaseAddress);
Memory::Virtual().Map((void *)this->APICBaseAddress, (void *)this->APICBaseAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD);
bool x2APICSupported = false;
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
{
CPU::x86::AMD::CPUID0x00000001 cpuid;
cpuid.Get();
if (cpuid.ECX.x2APIC)
{
// x2APICSupported = cpuid.ECX.x2APIC;
fixme("x2APIC is supported");
}
}
else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
{
CPU::x86::Intel::CPUID0x00000001 cpuid;
cpuid.Get();
if (cpuid.ECX.x2APIC)
{
// x2APICSupported = cpuid.ECX.x2APIC;
fixme("x2APIC is supported");
}
}
if (x2APICSupported)
{
this->x2APICSupported = true;
wrmsr(MSR_APIC_BASE, (rdmsr(MSR_APIC_BASE) | (1 << 11)) & ~(1 << 10));
BaseStruct.EN = 1;
wrmsr(MSR_APIC_BASE, BaseStruct.raw);
}
else
{
BaseStruct.EN = 1;
wrmsr(MSR_APIC_BASE, BaseStruct.raw);
}
this->Write(APIC_TPR, 0x0);
// this->Write(APIC_SVR, this->Read(APIC_SVR) | 0x100); // 0x1FF or 0x100 ? on https://wiki.osdev.org/APIC is 0x100
if (!this->x2APICSupported)
{
this->Write(APIC_DFR, 0xF0000000);
this->Write(APIC_LDR, this->Read(APIC_ID));
}
ACPI::MADT *madt = (ACPI::MADT *)PowerManager->GetMADT();
for (size_t i = 0; i < madt->nmi.size(); i++)
{
if (madt->nmi[i]->processor != 0xFF && Core != madt->nmi[i]->processor)
return;
uint32_t nmi = 0x402;
if (madt->nmi[i]->flags & 2)
nmi |= 1 << 13;
if (madt->nmi[i]->flags & 8)
nmi |= 1 << 15;
if (madt->nmi[i]->lint == 0)
this->Write(APIC_LINT0, nmi);
else if (madt->nmi[i]->lint == 1)
this->Write(APIC_LINT1, nmi);
}
// Setup the spurrious interrupt vector
Spurious Spurious = {.raw = this->Read(APIC_SVR)};
Spurious.Vector = IRQ223; // TODO: Should I map the IRQ to something?
Spurious.Software = 1;
this->Write(APIC_SVR, s_cst(uint32_t, Spurious.raw));
static int once = 0;
if (!once++)
{
// Disable PIT
outb(0x43, 0x28);
outb(0x40, 0x0);
// Disable PIC
outb(0x21, 0xFF);
outb(0xA1, 0xFF);
}
}
APIC::~APIC() {}
void Timer::OnInterruptReceived(TrapFrame *Frame) { UNUSED(Frame); }
void Timer::OneShot(uint32_t Vector, uint64_t Miliseconds)
{
SmartCriticalSection(APICLock);
LVTTimer timer = {.raw = 0};
timer.Vector = s_cst(uint8_t, Vector);
timer.TimerMode = 0;
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
this->lapic->Write(APIC_TDCR, DivideBy128);
else
this->lapic->Write(APIC_TDCR, DivideBy16);
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks * Miliseconds));
this->lapic->Write(APIC_TIMER, s_cst(uint32_t, timer.raw));
}
Timer::Timer(APIC *apic) : Interrupts::Handler(0) /* IRQ0 */
{
SmartCriticalSection(APICLock);
this->lapic = apic;
LVTTimerDivide Divider = DivideBy16;
trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID);
this->lapic->Write(APIC_TDCR, Divider);
this->lapic->Write(APIC_TICR, 0xFFFFFFFF);
TimeManager->Sleep(1, Time::Units::Milliseconds);
// Mask the timer
this->lapic->Write(APIC_TIMER, 0x10000 /* LVTTimer.Mask flag */);
Ticks = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR);
// Config for IRQ0 timer
LVTTimer timer = {.raw = 0};
timer.Vector = IRQ0;
timer.Mask = Unmasked;
timer.TimerMode = LVTTimerMode::OneShot;
// Initialize APIC timer
this->lapic->Write(APIC_TDCR, Divider);
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks));
this->lapic->Write(APIC_TIMER, s_cst(uint32_t, timer.raw));
trace("%d APIC Timer %d ticks in.", GetCurrentCPU()->ID, Ticks);
KPrint("APIC Timer: \e8888FF%ld\eCCCCCC ticks.", Ticks);
}
Timer::~Timer()
{
}
}

View File

@ -1,214 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include "gdt.hpp"
#include <memory.hpp>
#include <smp.hpp>
#include <cpu.hpp>
#include <debug.h>
namespace GlobalDescriptorTable
{
static GlobalDescriptorTableEntries GDTEntriesTemplate = {
.Null =
{
.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {.Raw = 0x0},
.Flags = {.Raw = 0x0},
.BaseHigh = 0x0,
},
.Code =
{
.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {
.A = 0,
.RW = 1,
.DC = 0,
.E = 1,
.S = 1,
.DPL = 0,
.P = 1,
},
.Flags = {
.Unknown = 0x0,
.L = 1,
},
.BaseHigh = 0x0,
},
.Data = {
.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {
.A = 0,
.RW = 1,
.DC = 0,
.E = 0,
.S = 1,
.DPL = 0,
.P = 1,
},
.Flags = {.Raw = 0x0},
.BaseHigh = 0x0,
},
.UserData = {
.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {
.A = 0,
.RW = 1,
.DC = 0,
.E = 0,
.S = 1,
.DPL = 3,
.P = 1,
},
.Flags = {
.Raw = 0x0,
},
.BaseHigh = 0x0,
},
.UserCode = {
.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {
.A = 0,
.RW = 1,
.DC = 0,
.E = 1,
.S = 1,
.DPL = 3,
.P = 1,
},
.Flags = {
.Unknown = 0x0,
.L = 1,
},
.BaseHigh = 0x0,
},
.TaskStateSegment = {},
};
GlobalDescriptorTableEntries GDTEntries[MAX_CPU] __aligned(16);
GlobalDescriptorTableDescriptor gdt[MAX_CPU] __aligned(16);
TaskStateSegment tss[MAX_CPU] = {
0,
{0, 0, 0},
0,
{0, 0, 0, 0, 0, 0, 0},
0,
0,
0,
};
void *CPUStackPointer[MAX_CPU];
SafeFunction void Init(int Core)
{
memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]};
debug("Kernel: Code Access: %ld; Data Access: %ld", GDTEntries[Core].Code.Access.Raw, GDTEntries[Core].Data.Access.Raw);
debug("Kernel: Code Flags: %ld; Data Flags: %ld", GDTEntries[Core].Code.Flags.Raw, GDTEntries[Core].Data.Flags.Raw);
debug("User: Code Access: %ld; Data Access: %ld", GDTEntries[Core].UserCode.Access.Raw, GDTEntries[Core].UserData.Access.Raw);
debug("User: Code Flags: %ld; Data Flags: %ld", GDTEntries[Core].UserCode.Flags.Raw, GDTEntries[Core].UserData.Flags.Raw);
CPU::x64::lgdt(&gdt[Core]);
asmv("movq %%rsp, %%rax\n"
"pushq $16\n"
"pushq %%rax\n"
"pushfq\n"
"pushq $8\n"
"pushq $1f\n"
"iretq\n"
"1:\n"
"movw $16, %%ax\n"
"movw %%ax, %%ds\n"
"movw %%ax, %%es\n" ::
: "memory", "rax");
CPUStackPointer[Core] = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1));
memset(CPUStackPointer[Core], 0, STACK_SIZE);
debug("CPU %d Stack Pointer: %#lx-%#lx (%d pages)", Core,
CPUStackPointer[Core], (uintptr_t)CPUStackPointer[Core] + STACK_SIZE,
TO_PAGES(STACK_SIZE + 1));
uintptr_t Base = (uintptr_t)&tss[Core];
size_t Limit = Base + sizeof(TaskStateSegment);
gdt[Core].Entries->TaskStateSegment.Length = Limit & 0xFFFF;
gdt[Core].Entries->TaskStateSegment.BaseLow = Base & 0xFFFF;
gdt[Core].Entries->TaskStateSegment.BaseMiddle = (Base >> 16) & 0xFF;
gdt[Core].Entries->TaskStateSegment.BaseHigh = (Base >> 24) & 0xFF;
gdt[Core].Entries->TaskStateSegment.BaseUpper = s_cst(uint32_t, (Base >> 32) & 0xFFFFFFFF);
gdt[Core].Entries->TaskStateSegment.Flags = {.A = 1, .RW = 0, .DC = 0, .E = 1, .S = 0, .DPL = 0, .P = 1};
gdt[Core].Entries->TaskStateSegment.Granularity = (0 << 4) | ((Limit >> 16) & 0xF);
tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment);
tss[Core].StackPointer[0] = (uint64_t)CPUStackPointer[Core] + STACK_SIZE;
for (size_t i = 0; i < sizeof(tss[Core].InterruptStackTable) / sizeof(tss[Core].InterruptStackTable[7]); i++)
{
void *NewStack = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1));
tss[Core].InterruptStackTable[i] = (uint64_t)NewStack + STACK_SIZE;
memset((void *)(tss[Core].InterruptStackTable[i] - STACK_SIZE), 0, STACK_SIZE);
debug("IST-%d: %#lx-%#lx", i, NewStack, (uintptr_t)NewStack + STACK_SIZE);
}
CPU::x64::ltr(GDT_TSS);
debug("GDT_KERNEL_CODE: %#lx", GDT_KERNEL_CODE);
debug("GDT_KERNEL_DATA: %#lx", GDT_KERNEL_DATA);
debug("GDT_USER_CODE: %#lx", GDT_USER_CODE);
debug("GDT_USER_DATA: %#lx", GDT_USER_DATA);
debug("GDT_TSS: %#lx", GDT_TSS);
debug("Global Descriptor Table initialized");
}
SafeFunction void SetKernelStack(void *Stack)
{
long CPUID = GetCurrentCPU()->ID;
if (Stack != nullptr)
tss[CPUID].StackPointer[0] = (uint64_t)Stack;
else
tss[CPUID].StackPointer[0] = (uint64_t)CPUStackPointer[CPUID] + STACK_SIZE;
/*
FIXME: There's a bug in kernel which if
we won't update "tss[CPUID].StackPointer[0]"
with the current stack pointer, the kernel
will crash.
*/
asmv("mov %%rsp, %0"
: "=r"(tss[CPUID].StackPointer[0]));
}
void *GetKernelStack() { return (void *)tss[GetCurrentCPU()->ID].StackPointer[0]; }
}

View File

@ -1,757 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include "idt.hpp"
#include <memory.hpp>
#include <cpu.hpp>
#include <debug.h>
#include <io.h>
#include "gdt.hpp"
#include "../../../kernel.h"
/* conversion from uint64_t {aka long unsigned int} to unsigned char:2 may change value */
#pragma GCC diagnostic ignored "-Wconversion"
extern "C" void MainInterruptHandler(void *Data);
extern "C" void ExceptionHandler(void *Data);
namespace InterruptDescriptorTable
{
static InterruptDescriptorTableEntry Entries[0x100];
InterruptDescriptorTableDescriptor idtd = {
.Length = sizeof(Entries) - 1,
.Entries = Entries,
};
void SetEntry(uint8_t Index,
void (*Base)(),
InterruptStackTableType InterruptStackTable,
InterruptGateType Gate,
InterruptRingType Ring,
bool Present,
uint16_t SegmentSelector)
{
Entries[Index].BaseLow = s_cst(uint16_t, ((uint64_t)Base & 0xFFFF));
Entries[Index].BaseHigh = s_cst(uint64_t, ((uint64_t)Base >> 16 /* & 0xFFFF */));
Entries[Index].SegmentSelector = SegmentSelector;
Entries[Index].Flags = Gate;
Entries[Index].Reserved1 = 0;
Entries[Index].Reserved2 = 0;
Entries[Index].Reserved3 = 0;
Entries[Index].InterruptStackTable = InterruptStackTable;
Entries[Index].Ring = Ring;
Entries[Index].Present = Present;
}
extern "C" __naked __used __no_stack_protector __aligned(16) void ExceptionHandlerStub()
{
asm("cld\n"
"cli\n"
"pushq %rax\n"
"pushq %rbx\n"
"pushq %rcx\n"
"pushq %rdx\n"
"pushq %rsi\n"
"pushq %rdi\n"
"pushq %rbp\n"
"pushq %r8\n"
"pushq %r9\n"
"pushq %r10\n"
"pushq %r11\n"
"pushq %r12\n"
"pushq %r13\n"
"pushq %r14\n"
"pushq %r15\n"
"movq %rsp, %rdi\n"
"call ExceptionHandler\n"
"popq %r15\n"
"popq %r14\n"
"popq %r13\n"
"popq %r12\n"
"popq %r11\n"
"popq %r10\n"
"popq %r9\n"
"popq %r8\n"
"popq %rbp\n"
"popq %rdi\n"
"popq %rsi\n"
"popq %rdx\n"
"popq %rcx\n"
"popq %rbx\n"
"popq %rax\n"
"addq $16, %rsp\n"
"iretq"); // pop CS RIP RFLAGS SS RSP
}
extern "C" __naked __used __no_stack_protector __aligned(16) void InterruptHandlerStub()
{
asm("cld\n"
"cli\n"
"pushq %rax\n"
"pushq %rbx\n"
"pushq %rcx\n"
"pushq %rdx\n"
"pushq %rsi\n"
"pushq %rdi\n"
"pushq %rbp\n"
"pushq %r8\n"
"pushq %r9\n"
"pushq %r10\n"
"pushq %r11\n"
"pushq %r12\n"
"pushq %r13\n"
"pushq %r14\n"
"pushq %r15\n"
"movq %rsp, %rdi\n"
"call MainInterruptHandler\n"
"popq %r15\n"
"popq %r14\n"
"popq %r13\n"
"popq %r12\n"
"popq %r11\n"
"popq %r10\n"
"popq %r9\n"
"popq %r8\n"
"popq %rbp\n"
"popq %rdi\n"
"popq %rsi\n"
"popq %rdx\n"
"popq %rcx\n"
"popq %rbx\n"
"popq %rax\n"
"addq $16, %rsp\n"
"sti\n"
"iretq"); // pop CS RIP RFLAGS SS RSP
}
#pragma region Exceptions
#define EXCEPTION_HANDLER(num) \
__naked __used __no_stack_protector __aligned(16) static void InterruptHandler_##num() \
{ \
asm("pushq $0\npushq $" #num "\n" \
"jmp ExceptionHandlerStub"); \
}
#define EXCEPTION_ERROR_HANDLER(num) \
__naked __used __no_stack_protector __aligned(16) static void InterruptHandler_##num() \
{ \
asm("pushq $" #num "\n" \
"jmp ExceptionHandlerStub"); \
}
#define INTERRUPT_HANDLER(num) \
__naked __used __no_stack_protector __aligned(16) void InterruptHandler_##num() \
{ \
asm("pushq $0\npushq $" #num "\n" \
"jmp InterruptHandlerStub\n"); \
}
/* ISR */
EXCEPTION_HANDLER(0x0);
EXCEPTION_HANDLER(0x1);
EXCEPTION_HANDLER(0x2);
EXCEPTION_HANDLER(0x3);
EXCEPTION_HANDLER(0x4);
EXCEPTION_HANDLER(0x5);
EXCEPTION_HANDLER(0x6);
EXCEPTION_HANDLER(0x7);
EXCEPTION_ERROR_HANDLER(0x8);
EXCEPTION_HANDLER(0x9);
EXCEPTION_ERROR_HANDLER(0xa);
EXCEPTION_ERROR_HANDLER(0xb);
EXCEPTION_ERROR_HANDLER(0xc);
EXCEPTION_ERROR_HANDLER(0xd);
EXCEPTION_ERROR_HANDLER(0xe);
EXCEPTION_HANDLER(0xf);
EXCEPTION_ERROR_HANDLER(0x10);
EXCEPTION_HANDLER(0x11);
EXCEPTION_HANDLER(0x12);
EXCEPTION_HANDLER(0x13);
EXCEPTION_HANDLER(0x14);
EXCEPTION_HANDLER(0x15);
EXCEPTION_HANDLER(0x16);
EXCEPTION_HANDLER(0x17);
EXCEPTION_HANDLER(0x18);
EXCEPTION_HANDLER(0x19);
EXCEPTION_HANDLER(0x1a);
EXCEPTION_HANDLER(0x1b);
EXCEPTION_HANDLER(0x1c);
EXCEPTION_HANDLER(0x1d);
EXCEPTION_HANDLER(0x1e);
EXCEPTION_HANDLER(0x1f);
/* IRQ */
INTERRUPT_HANDLER(0x20)
INTERRUPT_HANDLER(0x21)
INTERRUPT_HANDLER(0x22)
INTERRUPT_HANDLER(0x23)
INTERRUPT_HANDLER(0x24)
INTERRUPT_HANDLER(0x25)
INTERRUPT_HANDLER(0x26)
INTERRUPT_HANDLER(0x27)
INTERRUPT_HANDLER(0x28)
INTERRUPT_HANDLER(0x29)
INTERRUPT_HANDLER(0x2a)
INTERRUPT_HANDLER(0x2b)
INTERRUPT_HANDLER(0x2c)
INTERRUPT_HANDLER(0x2d)
INTERRUPT_HANDLER(0x2e)
INTERRUPT_HANDLER(0x2f)
/* Reserved by OS */
INTERRUPT_HANDLER(0x30)
INTERRUPT_HANDLER(0x31)
INTERRUPT_HANDLER(0x32)
INTERRUPT_HANDLER(0x33)
INTERRUPT_HANDLER(0x34)
INTERRUPT_HANDLER(0x35)
INTERRUPT_HANDLER(0x36)
INTERRUPT_HANDLER(0x37)
INTERRUPT_HANDLER(0x38)
INTERRUPT_HANDLER(0x39)
INTERRUPT_HANDLER(0x3a)
INTERRUPT_HANDLER(0x3b)
INTERRUPT_HANDLER(0x3c)
INTERRUPT_HANDLER(0x3d)
/* Free */
INTERRUPT_HANDLER(0x3e)
INTERRUPT_HANDLER(0x3f)
INTERRUPT_HANDLER(0x40)
INTERRUPT_HANDLER(0x41)
INTERRUPT_HANDLER(0x42)
INTERRUPT_HANDLER(0x43)
INTERRUPT_HANDLER(0x44)
INTERRUPT_HANDLER(0x45)
INTERRUPT_HANDLER(0x46)
INTERRUPT_HANDLER(0x47)
INTERRUPT_HANDLER(0x48)
INTERRUPT_HANDLER(0x49)
INTERRUPT_HANDLER(0x4a)
INTERRUPT_HANDLER(0x4b)
INTERRUPT_HANDLER(0x4c)
INTERRUPT_HANDLER(0x4d)
INTERRUPT_HANDLER(0x4e)
INTERRUPT_HANDLER(0x4f)
INTERRUPT_HANDLER(0x50)
INTERRUPT_HANDLER(0x51)
INTERRUPT_HANDLER(0x52)
INTERRUPT_HANDLER(0x53)
INTERRUPT_HANDLER(0x54)
INTERRUPT_HANDLER(0x55)
INTERRUPT_HANDLER(0x56)
INTERRUPT_HANDLER(0x57)
INTERRUPT_HANDLER(0x58)
INTERRUPT_HANDLER(0x59)
INTERRUPT_HANDLER(0x5a)
INTERRUPT_HANDLER(0x5b)
INTERRUPT_HANDLER(0x5c)
INTERRUPT_HANDLER(0x5d)
INTERRUPT_HANDLER(0x5e)
INTERRUPT_HANDLER(0x5f)
INTERRUPT_HANDLER(0x60)
INTERRUPT_HANDLER(0x61)
INTERRUPT_HANDLER(0x62)
INTERRUPT_HANDLER(0x63)
INTERRUPT_HANDLER(0x64)
INTERRUPT_HANDLER(0x65)
INTERRUPT_HANDLER(0x66)
INTERRUPT_HANDLER(0x67)
INTERRUPT_HANDLER(0x68)
INTERRUPT_HANDLER(0x69)
INTERRUPT_HANDLER(0x6a)
INTERRUPT_HANDLER(0x6b)
INTERRUPT_HANDLER(0x6c)
INTERRUPT_HANDLER(0x6d)
INTERRUPT_HANDLER(0x6e)
INTERRUPT_HANDLER(0x6f)
INTERRUPT_HANDLER(0x70)
INTERRUPT_HANDLER(0x71)
INTERRUPT_HANDLER(0x72)
INTERRUPT_HANDLER(0x73)
INTERRUPT_HANDLER(0x74)
INTERRUPT_HANDLER(0x75)
INTERRUPT_HANDLER(0x76)
INTERRUPT_HANDLER(0x77)
INTERRUPT_HANDLER(0x78)
INTERRUPT_HANDLER(0x79)
INTERRUPT_HANDLER(0x7a)
INTERRUPT_HANDLER(0x7b)
INTERRUPT_HANDLER(0x7c)
INTERRUPT_HANDLER(0x7d)
INTERRUPT_HANDLER(0x7e)
INTERRUPT_HANDLER(0x7f)
INTERRUPT_HANDLER(0x80)
INTERRUPT_HANDLER(0x81)
INTERRUPT_HANDLER(0x82)
INTERRUPT_HANDLER(0x83)
INTERRUPT_HANDLER(0x84)
INTERRUPT_HANDLER(0x85)
INTERRUPT_HANDLER(0x86)
INTERRUPT_HANDLER(0x87)
INTERRUPT_HANDLER(0x88)
INTERRUPT_HANDLER(0x89)
INTERRUPT_HANDLER(0x8a)
INTERRUPT_HANDLER(0x8b)
INTERRUPT_HANDLER(0x8c)
INTERRUPT_HANDLER(0x8d)
INTERRUPT_HANDLER(0x8e)
INTERRUPT_HANDLER(0x8f)
INTERRUPT_HANDLER(0x90)
INTERRUPT_HANDLER(0x91)
INTERRUPT_HANDLER(0x92)
INTERRUPT_HANDLER(0x93)
INTERRUPT_HANDLER(0x94)
INTERRUPT_HANDLER(0x95)
INTERRUPT_HANDLER(0x96)
INTERRUPT_HANDLER(0x97)
INTERRUPT_HANDLER(0x98)
INTERRUPT_HANDLER(0x99)
INTERRUPT_HANDLER(0x9a)
INTERRUPT_HANDLER(0x9b)
INTERRUPT_HANDLER(0x9c)
INTERRUPT_HANDLER(0x9d)
INTERRUPT_HANDLER(0x9e)
INTERRUPT_HANDLER(0x9f)
INTERRUPT_HANDLER(0xa0)
INTERRUPT_HANDLER(0xa1)
INTERRUPT_HANDLER(0xa2)
INTERRUPT_HANDLER(0xa3)
INTERRUPT_HANDLER(0xa4)
INTERRUPT_HANDLER(0xa5)
INTERRUPT_HANDLER(0xa6)
INTERRUPT_HANDLER(0xa7)
INTERRUPT_HANDLER(0xa8)
INTERRUPT_HANDLER(0xa9)
INTERRUPT_HANDLER(0xaa)
INTERRUPT_HANDLER(0xab)
INTERRUPT_HANDLER(0xac)
INTERRUPT_HANDLER(0xad)
INTERRUPT_HANDLER(0xae)
INTERRUPT_HANDLER(0xaf)
INTERRUPT_HANDLER(0xb0)
INTERRUPT_HANDLER(0xb1)
INTERRUPT_HANDLER(0xb2)
INTERRUPT_HANDLER(0xb3)
INTERRUPT_HANDLER(0xb4)
INTERRUPT_HANDLER(0xb5)
INTERRUPT_HANDLER(0xb6)
INTERRUPT_HANDLER(0xb7)
INTERRUPT_HANDLER(0xb8)
INTERRUPT_HANDLER(0xb9)
INTERRUPT_HANDLER(0xba)
INTERRUPT_HANDLER(0xbb)
INTERRUPT_HANDLER(0xbc)
INTERRUPT_HANDLER(0xbd)
INTERRUPT_HANDLER(0xbe)
INTERRUPT_HANDLER(0xbf)
INTERRUPT_HANDLER(0xc0)
INTERRUPT_HANDLER(0xc1)
INTERRUPT_HANDLER(0xc2)
INTERRUPT_HANDLER(0xc3)
INTERRUPT_HANDLER(0xc4)
INTERRUPT_HANDLER(0xc5)
INTERRUPT_HANDLER(0xc6)
INTERRUPT_HANDLER(0xc7)
INTERRUPT_HANDLER(0xc8)
INTERRUPT_HANDLER(0xc9)
INTERRUPT_HANDLER(0xca)
INTERRUPT_HANDLER(0xcb)
INTERRUPT_HANDLER(0xcc)
INTERRUPT_HANDLER(0xcd)
INTERRUPT_HANDLER(0xce)
INTERRUPT_HANDLER(0xcf)
INTERRUPT_HANDLER(0xd0)
INTERRUPT_HANDLER(0xd1)
INTERRUPT_HANDLER(0xd2)
INTERRUPT_HANDLER(0xd3)
INTERRUPT_HANDLER(0xd4)
INTERRUPT_HANDLER(0xd5)
INTERRUPT_HANDLER(0xd6)
INTERRUPT_HANDLER(0xd7)
INTERRUPT_HANDLER(0xd8)
INTERRUPT_HANDLER(0xd9)
INTERRUPT_HANDLER(0xda)
INTERRUPT_HANDLER(0xdb)
INTERRUPT_HANDLER(0xdc)
INTERRUPT_HANDLER(0xdd)
INTERRUPT_HANDLER(0xde)
INTERRUPT_HANDLER(0xdf)
INTERRUPT_HANDLER(0xe0)
INTERRUPT_HANDLER(0xe1)
INTERRUPT_HANDLER(0xe2)
INTERRUPT_HANDLER(0xe3)
INTERRUPT_HANDLER(0xe4)
INTERRUPT_HANDLER(0xe5)
INTERRUPT_HANDLER(0xe6)
INTERRUPT_HANDLER(0xe7)
INTERRUPT_HANDLER(0xe8)
INTERRUPT_HANDLER(0xe9)
INTERRUPT_HANDLER(0xea)
INTERRUPT_HANDLER(0xeb)
INTERRUPT_HANDLER(0xec)
INTERRUPT_HANDLER(0xed)
INTERRUPT_HANDLER(0xee)
INTERRUPT_HANDLER(0xef)
INTERRUPT_HANDLER(0xf0)
INTERRUPT_HANDLER(0xf1)
INTERRUPT_HANDLER(0xf2)
INTERRUPT_HANDLER(0xf3)
INTERRUPT_HANDLER(0xf4)
INTERRUPT_HANDLER(0xf5)
INTERRUPT_HANDLER(0xf6)
INTERRUPT_HANDLER(0xf7)
INTERRUPT_HANDLER(0xf8)
INTERRUPT_HANDLER(0xf9)
INTERRUPT_HANDLER(0xfa)
INTERRUPT_HANDLER(0xfb)
INTERRUPT_HANDLER(0xfc)
INTERRUPT_HANDLER(0xfd)
INTERRUPT_HANDLER(0xfe)
INTERRUPT_HANDLER(0xff)
#pragma endregion Exceptions
void Init(int Core)
{
if (Core == 0) /* Disable PIC using BSP */
{
// PIC
outb(0x20, 0x10 | 0x1);
outb(0x80, 0);
outb(0xA0, 0x10 | 0x10);
outb(0x80, 0);
outb(0x21, 0x20);
outb(0x80, 0);
outb(0xA1, 0x28);
outb(0x80, 0);
outb(0x21, 0x04);
outb(0x80, 0);
outb(0xA1, 0x02);
outb(0x80, 0);
outb(0x21, 1);
outb(0x80, 0);
outb(0xA1, 1);
outb(0x80, 0);
// Masking and disabling PIC
outb(0x21, 0xff);
outb(0x80, 0);
outb(0xA1, 0xff);
}
/* ISR */
#ifdef DEBUG
// if (!DebuggerIsAttached)
if (true)
{
#endif
SetEntry(0x0, InterruptHandler_0x0, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1, InterruptHandler_0x1, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2, InterruptHandler_0x2, IST2, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3, InterruptHandler_0x3, IST1, TRAP_32BIT, RING3, (!DebuggerIsAttached), GDT_KERNEL_CODE); /* Do not handle breakpoints if we are debugging the kernel. */
SetEntry(0x4, InterruptHandler_0x4, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5, InterruptHandler_0x5, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6, InterruptHandler_0x6, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7, InterruptHandler_0x7, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8, InterruptHandler_0x8, IST3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9, InterruptHandler_0x9, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa, InterruptHandler_0xa, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb, InterruptHandler_0xb, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc, InterruptHandler_0xc, IST3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd, InterruptHandler_0xd, IST3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe, InterruptHandler_0xe, IST3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf, InterruptHandler_0xf, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x10, InterruptHandler_0x10, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x11, InterruptHandler_0x11, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x12, InterruptHandler_0x12, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x13, InterruptHandler_0x13, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x14, InterruptHandler_0x14, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x15, InterruptHandler_0x15, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x16, InterruptHandler_0x16, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x17, InterruptHandler_0x17, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x18, InterruptHandler_0x18, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x19, InterruptHandler_0x19, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1a, InterruptHandler_0x1a, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1b, InterruptHandler_0x1b, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1c, InterruptHandler_0x1c, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1d, InterruptHandler_0x1d, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1e, InterruptHandler_0x1e, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1f, InterruptHandler_0x1f, IST1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
#ifdef DEBUG
}
else
KPrint("\eFFA500The debugger is attached, not setting up the ISR.");
#endif
/* IRQ */
SetEntry(0x20, InterruptHandler_0x20, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x21, InterruptHandler_0x21, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x22, InterruptHandler_0x22, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x23, InterruptHandler_0x23, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x24, InterruptHandler_0x24, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x25, InterruptHandler_0x25, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x26, InterruptHandler_0x26, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x27, InterruptHandler_0x27, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x28, InterruptHandler_0x28, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x29, InterruptHandler_0x29, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2a, InterruptHandler_0x2a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2b, InterruptHandler_0x2b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2c, InterruptHandler_0x2c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2d, InterruptHandler_0x2d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2e, InterruptHandler_0x2e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2f, InterruptHandler_0x2f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
/* Reserved by OS */
SetEntry(0x30, InterruptHandler_0x30, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x31, InterruptHandler_0x31, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x32, InterruptHandler_0x32, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x33, InterruptHandler_0x33, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x34, InterruptHandler_0x34, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x35, InterruptHandler_0x35, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x36, InterruptHandler_0x36, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x37, InterruptHandler_0x37, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x38, InterruptHandler_0x38, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x39, InterruptHandler_0x39, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3a, InterruptHandler_0x3a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3b, InterruptHandler_0x3b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3c, InterruptHandler_0x3c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3d, InterruptHandler_0x3d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
/* Free */
SetEntry(0x3e, InterruptHandler_0x3e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3f, InterruptHandler_0x3f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x40, InterruptHandler_0x40, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x41, InterruptHandler_0x41, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x42, InterruptHandler_0x42, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x43, InterruptHandler_0x43, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x44, InterruptHandler_0x44, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x45, InterruptHandler_0x45, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x46, InterruptHandler_0x46, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x47, InterruptHandler_0x47, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x48, InterruptHandler_0x48, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x49, InterruptHandler_0x49, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4a, InterruptHandler_0x4a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4b, InterruptHandler_0x4b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4c, InterruptHandler_0x4c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4d, InterruptHandler_0x4d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4e, InterruptHandler_0x4e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4f, InterruptHandler_0x4f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x50, InterruptHandler_0x50, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x51, InterruptHandler_0x51, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x52, InterruptHandler_0x52, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x53, InterruptHandler_0x53, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x54, InterruptHandler_0x54, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x55, InterruptHandler_0x55, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x56, InterruptHandler_0x56, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x57, InterruptHandler_0x57, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x58, InterruptHandler_0x58, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x59, InterruptHandler_0x59, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5a, InterruptHandler_0x5a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5b, InterruptHandler_0x5b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5c, InterruptHandler_0x5c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5d, InterruptHandler_0x5d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5e, InterruptHandler_0x5e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5f, InterruptHandler_0x5f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x60, InterruptHandler_0x60, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x61, InterruptHandler_0x61, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x62, InterruptHandler_0x62, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x63, InterruptHandler_0x63, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x64, InterruptHandler_0x64, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x65, InterruptHandler_0x65, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x66, InterruptHandler_0x66, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x67, InterruptHandler_0x67, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x68, InterruptHandler_0x68, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x69, InterruptHandler_0x69, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6a, InterruptHandler_0x6a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6b, InterruptHandler_0x6b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6c, InterruptHandler_0x6c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6d, InterruptHandler_0x6d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6e, InterruptHandler_0x6e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6f, InterruptHandler_0x6f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x70, InterruptHandler_0x70, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x71, InterruptHandler_0x71, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x72, InterruptHandler_0x72, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x73, InterruptHandler_0x73, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x74, InterruptHandler_0x74, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x75, InterruptHandler_0x75, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x76, InterruptHandler_0x76, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x77, InterruptHandler_0x77, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x78, InterruptHandler_0x78, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x79, InterruptHandler_0x79, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7a, InterruptHandler_0x7a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7b, InterruptHandler_0x7b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7c, InterruptHandler_0x7c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7d, InterruptHandler_0x7d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7e, InterruptHandler_0x7e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7f, InterruptHandler_0x7f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x80, InterruptHandler_0x80, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x81, InterruptHandler_0x81, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x82, InterruptHandler_0x82, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x83, InterruptHandler_0x83, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x84, InterruptHandler_0x84, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x85, InterruptHandler_0x85, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x86, InterruptHandler_0x86, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x87, InterruptHandler_0x87, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x88, InterruptHandler_0x88, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x89, InterruptHandler_0x89, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8a, InterruptHandler_0x8a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8b, InterruptHandler_0x8b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8c, InterruptHandler_0x8c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8d, InterruptHandler_0x8d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8e, InterruptHandler_0x8e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8f, InterruptHandler_0x8f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x90, InterruptHandler_0x90, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x91, InterruptHandler_0x91, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x92, InterruptHandler_0x92, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x93, InterruptHandler_0x93, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x94, InterruptHandler_0x94, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x95, InterruptHandler_0x95, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x96, InterruptHandler_0x96, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x97, InterruptHandler_0x97, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x98, InterruptHandler_0x98, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x99, InterruptHandler_0x99, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9a, InterruptHandler_0x9a, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9b, InterruptHandler_0x9b, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9c, InterruptHandler_0x9c, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9d, InterruptHandler_0x9d, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9e, InterruptHandler_0x9e, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9f, InterruptHandler_0x9f, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa0, InterruptHandler_0xa0, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa1, InterruptHandler_0xa1, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa2, InterruptHandler_0xa2, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa3, InterruptHandler_0xa3, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa4, InterruptHandler_0xa4, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa5, InterruptHandler_0xa5, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa6, InterruptHandler_0xa6, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa7, InterruptHandler_0xa7, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa8, InterruptHandler_0xa8, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa9, InterruptHandler_0xa9, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xaa, InterruptHandler_0xaa, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xab, InterruptHandler_0xab, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xac, InterruptHandler_0xac, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xad, InterruptHandler_0xad, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xae, InterruptHandler_0xae, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xaf, InterruptHandler_0xaf, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb0, InterruptHandler_0xb0, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb1, InterruptHandler_0xb1, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb2, InterruptHandler_0xb2, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb3, InterruptHandler_0xb3, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb4, InterruptHandler_0xb4, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb5, InterruptHandler_0xb5, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb6, InterruptHandler_0xb6, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb7, InterruptHandler_0xb7, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb8, InterruptHandler_0xb8, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb9, InterruptHandler_0xb9, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xba, InterruptHandler_0xba, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbb, InterruptHandler_0xbb, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbc, InterruptHandler_0xbc, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbd, InterruptHandler_0xbd, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbe, InterruptHandler_0xbe, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbf, InterruptHandler_0xbf, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc0, InterruptHandler_0xc0, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc1, InterruptHandler_0xc1, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc2, InterruptHandler_0xc2, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc3, InterruptHandler_0xc3, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc4, InterruptHandler_0xc4, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc5, InterruptHandler_0xc5, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc6, InterruptHandler_0xc6, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc7, InterruptHandler_0xc7, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc8, InterruptHandler_0xc8, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc9, InterruptHandler_0xc9, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xca, InterruptHandler_0xca, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcb, InterruptHandler_0xcb, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcc, InterruptHandler_0xcc, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcd, InterruptHandler_0xcd, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xce, InterruptHandler_0xce, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcf, InterruptHandler_0xcf, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd0, InterruptHandler_0xd0, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd1, InterruptHandler_0xd1, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd2, InterruptHandler_0xd2, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd3, InterruptHandler_0xd3, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd4, InterruptHandler_0xd4, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd5, InterruptHandler_0xd5, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd6, InterruptHandler_0xd6, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd7, InterruptHandler_0xd7, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd8, InterruptHandler_0xd8, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd9, InterruptHandler_0xd9, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xda, InterruptHandler_0xda, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdb, InterruptHandler_0xdb, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdc, InterruptHandler_0xdc, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdd, InterruptHandler_0xdd, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xde, InterruptHandler_0xde, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdf, InterruptHandler_0xdf, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe0, InterruptHandler_0xe0, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe1, InterruptHandler_0xe1, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe2, InterruptHandler_0xe2, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe3, InterruptHandler_0xe3, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe4, InterruptHandler_0xe4, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe5, InterruptHandler_0xe5, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe6, InterruptHandler_0xe6, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe7, InterruptHandler_0xe7, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe8, InterruptHandler_0xe8, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe9, InterruptHandler_0xe9, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xea, InterruptHandler_0xea, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xeb, InterruptHandler_0xeb, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xec, InterruptHandler_0xec, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xed, InterruptHandler_0xed, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xee, InterruptHandler_0xee, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xef, InterruptHandler_0xef, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf0, InterruptHandler_0xf0, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf1, InterruptHandler_0xf1, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf2, InterruptHandler_0xf2, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf3, InterruptHandler_0xf3, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf4, InterruptHandler_0xf4, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf5, InterruptHandler_0xf5, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf6, InterruptHandler_0xf6, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf7, InterruptHandler_0xf7, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf8, InterruptHandler_0xf8, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf9, InterruptHandler_0xf9, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfa, InterruptHandler_0xfa, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfb, InterruptHandler_0xfb, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfc, InterruptHandler_0xfc, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfd, InterruptHandler_0xfd, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfe, InterruptHandler_0xfe, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xff, InterruptHandler_0xff, IST0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
CPU::x64::lidt(&idtd);
}
}

View File

@ -1,136 +0,0 @@
; This file is part of Fennix Kernel.
;
; Fennix Kernel is free software: you can redistribute it and/or
; modify it under the terms of the GNU General Public License as
; published by the Free Software Foundation, either version 3 of
; the License, or (at your option) any later version.
;
; Fennix Kernel is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
; This has to be the same as enum SMPTrampolineAddress.
TRAMPOLINE_PAGE_TABLE equ 0x500
TRAMPOLINE_START_ADDR equ 0x520
TRAMPOLINE_STACK equ 0x570
TRAMPOLINE_GDT equ 0x580
TRAMPOLINE_IDT equ 0x590
TRAMPOLINE_CORE equ 0x600
TRAMPOLINE_START equ 0x2000
[bits 16]
extern StartCPU
global _trampoline_start
_trampoline_start:
cli
mov ax, 0x0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
o32 lgdt [ProtectedMode_gdtr - _trampoline_start + TRAMPOLINE_START]
mov eax, cr0
or al, 0x1
mov cr0, eax
jmp 0x8:(Trampoline32 - _trampoline_start + TRAMPOLINE_START)
[bits 32]
section .text
Trampoline32:
mov bx, 0x10
mov ds, bx
mov es, bx
mov ss, bx
mov eax, dword [TRAMPOLINE_PAGE_TABLE]
mov cr3, eax
mov eax, cr4
or eax, 1 << 5 ; Set the PAE-bit, which is the 6th bit (bit 5).
or eax, 1 << 7
mov cr4, eax
mov ecx, 0xc0000080
rdmsr
or eax,1 << 8 ; LME
wrmsr
mov eax, cr0
or eax, 1 << 31
mov cr0, eax
lgdt [LongMode_gdtr - _trampoline_start + TRAMPOLINE_START]
jmp 0x8:(Trampoline64 - _trampoline_start + TRAMPOLINE_START)
[bits 64]
Trampoline64:
mov ax, 0x10
mov ds, ax
mov es, ax
mov ss, ax
mov ax, 0x0
mov fs, ax
mov gs, ax
lgdt [TRAMPOLINE_GDT]
lidt [TRAMPOLINE_IDT]
mov rsp, [TRAMPOLINE_STACK]
mov rbp, 0x0 ; Terminate stack traces here.
; Reset RFLAGS.
push 0x0
popf
mov rax, qword vcode64
call vcode64
vcode64:
push rbp
; Set up SSE
mov rax, cr0
; btr eax, 2
; bts eax, 1
; mov cr0, rax
mov rax, cr4
bts eax, 9
bts eax, 10
mov cr4, rax
mov rax, qword TrampolineExit
call rax
align 16
LongMode_gdtr:
dw LongModeGDTEnd - LongModeGDTStart - 1
dq LongModeGDTStart - _trampoline_start + TRAMPOLINE_START
align 16
LongModeGDTStart:
dq 0 ; NULL segment
dq 0x00AF98000000FFFF ; Code segment
dq 0x00CF92000000FFFF ; Data segment
LongModeGDTEnd:
align 16
ProtectedMode_gdtr:
dw ProtectedModeGDTEnd - ProtectedModeGDTStart - 1
dd ProtectedModeGDTStart - _trampoline_start + TRAMPOLINE_START
align 16
ProtectedModeGDTStart:
dq 0 ; NULL segment
dq 0x00CF9A000000FFFF ; Code segment
dq 0x00CF92000000FFFF ; Data segment
ProtectedModeGDTEnd:
align 16
ProtectedMode_idtr:
dw 0
dd 0
dd 0
align 16
global _trampoline_end
_trampoline_end:
TrampolineExit:
call StartCPU
times 512 - ($-$$) db 0

View File

@ -1,141 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <smp.hpp>
#include <memory.hpp>
#include <ints.hpp>
#include <assert.h>
#include <cpu.hpp>
#include <atomic>
#include "../../../kernel.h"
#include "../acpi.hpp"
#include "apic.hpp"
extern "C" uint64_t _trampoline_start, _trampoline_end;
/* https://wiki.osdev.org/Memory_Map_(x86) */
enum SMPTrampolineAddress
{
PAGE_TABLE = 0x500,
START_ADDR = 0x520,
STACK = 0x570,
GDT = 0x580,
IDT = 0x590,
CORE = 0x600,
TRAMPOLINE_START = 0x2000
};
std::atomic_bool CPUEnabled = false;
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
static __aligned(PAGE_SIZE) CPUData CPUs[MAX_CPU] = {0};
SafeFunction CPUData *GetCPU(long id) { return &CPUs[id]; }
SafeFunction CPUData *GetCurrentCPU()
{
if (unlikely(!Interrupts::apic[0]))
return &CPUs[0]; /* No APIC means we are on the BSP. */
int CoreID = ((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24;
if (unlikely((&CPUs[CoreID])->IsActive != true))
{
error("CPU %d is not active!", CoreID);
assert((&CPUs[0])->IsActive == true); /* We can't continue without the BSP. */
return &CPUs[0];
}
assert((&CPUs[CoreID])->Checksum == CPU_DATA_CHECKSUM); /* This should never happen. */
return &CPUs[CoreID];
}
extern "C" void StartCPU()
{
CPU::Interrupts(CPU::Disable);
int CoreID = (int)*reinterpret_cast<int *>(CORE);
CPU::InitializeFeatures(CoreID);
// Initialize GDT and IDT
Interrupts::Initialize(CoreID);
Interrupts::Enable(CoreID);
Interrupts::InitializeTimer(CoreID);
asmv("mov %0, %%rsp" ::"r"((&CPUs[CoreID])->Stack));
CPU::Interrupts(CPU::Enable);
KPrint("\e058C19CPU \e8888FF%d \e058C19is online", CoreID);
CPUEnabled.store(true, std::memory_order_release);
CPU::Halt(true);
}
namespace SMP
{
int CPUCores = 0;
void Initialize(void *madt)
{
int Cores = ((ACPI::MADT *)madt)->CPUCores + 1;
if (Config.Cores > ((ACPI::MADT *)madt)->CPUCores + 1)
KPrint("More cores requested than available. Using %d cores", ((ACPI::MADT *)madt)->CPUCores + 1);
else if (Config.Cores != 0)
Cores = Config.Cores;
CPUCores = Cores;
uint64_t TrampolineLength = (uintptr_t)&_trampoline_end - (uintptr_t)&_trampoline_start;
Memory::Virtual().Map(0x0, 0x0, Memory::PTFlag::RW);
/* We reserved the TRAMPOLINE_START address inside Physical class. */
Memory::Virtual().Map((void *)TRAMPOLINE_START, (void *)TRAMPOLINE_START, TrampolineLength, Memory::PTFlag::RW);
memcpy((void *)TRAMPOLINE_START, &_trampoline_start, TrampolineLength);
debug("Trampoline address: %#lx-%#lx", TRAMPOLINE_START, TRAMPOLINE_START + TrampolineLength);
void *CPUTmpStack = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1));
asmv("sgdt [0x580]\n"
"sidt [0x590]\n");
VPOKE(uintptr_t, STACK) = (uintptr_t)CPUTmpStack + STACK_SIZE;
VPOKE(uintptr_t, PAGE_TABLE) = (uintptr_t)KernelPageTable;
VPOKE(uint64_t, START_ADDR) = (uintptr_t)&StartCPU;
for (int i = 0; i < Cores; i++)
{
debug("Initializing CPU %d", i);
if ((((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24) != ((ACPI::MADT *)madt)->lapic[i]->ACPIProcessorId)
{
VPOKE(int, CORE) = i;
((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRHI, (((ACPI::MADT *)madt)->lapic[i]->APICId << 24));
((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRLO, 0x500);
((APIC::APIC *)Interrupts::apic[0])->SendInitIPI(((ACPI::MADT *)madt)->lapic[i]->APICId);
((APIC::APIC *)Interrupts::apic[0])->SendStartupIPI(((ACPI::MADT *)madt)->lapic[i]->APICId, TRAMPOLINE_START);
while (!CPUEnabled.load(std::memory_order_acquire))
CPU::Pause();
CPUEnabled.store(false, std::memory_order_release);
trace("CPU %d loaded.", ((ACPI::MADT *)madt)->lapic[i]->APICId);
}
else
KPrint("\e058C19CPU \e8888FF%d \e058C19is the BSP", ((ACPI::MADT *)madt)->lapic[i]->APICId);
}
KernelAllocator.FreePages(CPUTmpStack, TO_PAGES(STACK_SIZE + 1));
/* We are going to unmap the page after we are done with it. */
Memory::Virtual().Unmap(0x0);
}
}

View File

@ -1,354 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_APIC_H__
#define __FENNIX_KERNEL_APIC_H__
#include <types.h>
#include <ints.hpp>
#include <cpu.hpp>
namespace APIC
{
enum APICRegisters
{
// source from: https://github.com/pdoane/osdev/blob/master/intr/local_apic.c
APIC_ID = 0x20, // Local APIC ID
APIC_VER = 0x30, // Local APIC Version
APIC_TPR = 0x80, // Task Priority
APIC_APR = 0x90, // Arbitration Priority
APIC_PPR = 0xA0, // Processor Priority
APIC_EOI = 0xB0, // EOI
APIC_RRD = 0xC0, // Remote Read
APIC_LDR = 0xD0, // Logical Destination
APIC_DFR = 0xE0, // Destination Format
APIC_SVR = 0xF0, // Spurious Interrupt Vector
APIC_ISR = 0x100, // In-Service (8 registers)
APIC_TMR = 0x180, // Trigger Mode (8 registers)
APIC_IRR = 0x200, // Interrupt Request (8 registers)
APIC_ESR = 0x280, // Error Status
APIC_ICRLO = 0x300, // Interrupt Command
APIC_ICRHI = 0x310, // Interrupt Command [63:32]
APIC_TIMER = 0x320, // LVT Timer
APIC_THERMAL = 0x330, // LVT Thermal Sensor
APIC_PERF = 0x340, // LVT Performance Counter
APIC_LINT0 = 0x350, // LVT LINT0
APIC_LINT1 = 0x360, // LVT LINT1
APIC_ERROR = 0x370, // LVT Error
APIC_TICR = 0x380, // Initial Count (for Timer)
APIC_TCCR = 0x390, // Current Count (for Timer)
APIC_TDCR = 0x3E0, // Divide Configuration (for Timer)
};
enum IOAPICRegisters
{
GetIOAPICVersion = 0x1
};
enum IOAPICFlags
{
ActiveHighLow = 2,
EdgeLevel = 8
};
enum APICDeliveryMode
{
Fixed = 0b000,
LowestPriority = 0b001, /* Reserved */
SMI = 0b010,
APIC_DELIVERY_MODE_RESERVED0 = 0b011, /* Reserved */
NMI = 0b100,
INIT = 0b101,
Startup = 0b110,
ExtINT = 0b111 /* Reserved */
};
enum APICDestinationMode
{
Physical = 0b0,
Logical = 0b1
};
enum APICDeliveryStatus
{
Idle = 0b0,
SendPending = 0b1
};
enum APICLevel
{
DeAssert = 0b0,
Assert = 0b1
};
enum APICTriggerMode
{
Edge = 0b0,
Level = 0b1
};
enum APICDestinationShorthand
{
NoShorthand = 0b00,
Self = 0b01,
AllIncludingSelf = 0b10,
AllExcludingSelf = 0b11
};
enum LVTTimerDivide
{
DivideBy2 = 0b000,
DivideBy4 = 0b001,
DivideBy8 = 0b010,
DivideBy16 = 0b011,
DivideBy32 = 0b100,
DivideBy64 = 0b101,
DivideBy128 = 0b110,
DivideBy1 = 0b111
};
enum LVTTimerMask
{
Unmasked = 0b0,
Masked = 0b1
};
enum LVTTimerMode
{
OneShot = 0b00,
Periodic = 0b01,
TSCDeadline = 0b10
};
typedef union
{
struct
{
/** @brief Interrupt Vector */
uint64_t Vector : 8;
/** @brief Reserved */
uint64_t Reserved0 : 4;
/**
* @brief Delivery Status
*
* 0: Idle
* 1: Send Pending
*/
uint64_t DeliveryStatus : 1;
/** @brief Reserved */
uint64_t Reserved1 : 3;
/**
* @brief Mask
*
* 0: Not masked
* 1: Masked
*/
uint64_t Mask : 1;
/** @brief Timer Mode
*
* 0: One-shot
* 1: Periodic
* 2: TSC-Deadline
*/
uint64_t TimerMode : 1;
/** @brief Reserved */
uint64_t Reserved2 : 14;
};
uint64_t raw;
} __packed LVTTimer;
typedef union
{
struct
{
/** @brief Spurious Vector */
uint64_t Vector : 8;
/** @brief Enable or disable APIC software */
uint64_t Software : 1;
/** @brief Focus Processor Checking */
uint64_t FocusProcessorChecking : 1;
/** @brief Reserved */
uint64_t Reserved : 2;
/** @brief Disable EOI Broadcast */
uint64_t DisableEOIBroadcast : 1;
/** @brief Reserved */
uint64_t Reserved1 : 19;
};
uint64_t raw;
} __packed Spurious;
typedef union
{
struct
{
/** @brief Interrupt Vector */
uint64_t Vector : 8;
/** @brief Delivery Mode */
uint64_t DeliveryMode : 3;
/** @brief Destination Mode
*
* 0: Physical
* 1: Logical
*/
uint64_t DestinationMode : 1;
/** @brief Delivery Status
*
* @note Reserved when in x2APIC mode
*/
uint64_t DeliveryStatus : 1;
/** @brief Reserved */
uint64_t Reserved0 : 1;
/** @brief Level
*
* 0: Deassert
* 1: Assert
*/
uint64_t Level : 1;
/** @brief Trigger Mode
*
* 0: Edge
* 1: Level
*/
uint64_t TriggerMode : 1;
/** @brief Reserved */
uint64_t Reserved1 : 2;
/** @brief Destination Shorthand
*
* 0: No shorthand
* 1: Self
* 2: All including self
* 3: All excluding self
*/
uint64_t DestinationShorthand : 2;
/** @brief Reserved */
uint64_t Reserved2 : 12;
};
uint64_t raw;
} __packed InterruptCommandRegisterLow;
typedef union
{
struct
{
/** @brief Reserved */
uint64_t Reserved0 : 24;
/** @brief Destination */
uint64_t Destination : 8;
};
uint64_t raw;
} __packed InterruptCommandRegisterHigh;
typedef union
{
struct
{
/** @brief Interrupt Vector */
uint64_t Vector : 8;
/** @brief Delivery Mode */
uint64_t DeliveryMode : 3;
/** @brief Destination Mode
*
* 0: Physical
* 1: Logical
*/
uint64_t DestinationMode : 1;
/** @brief Delivery Status */
uint64_t DeliveryStatus : 1;
/** @brief Interrupt Input Pin Polarity
*
* 0: Active High
* 1: Active Low
*/
uint64_t Polarity : 1;
/** @brief Remote IRR */
uint64_t RemoteIRR : 1;
/** @brief Trigger Mode
*
* 0: Edge
* 1: Level
*/
uint64_t TriggerMode : 1;
/** @brief Mask */
uint64_t Mask : 1;
/** @brief Reserved */
uint64_t Reserved0 : 15;
/** @brief Reserved */
uint64_t Reserved1 : 24;
/** @brief Destination */
uint64_t DestinationID : 8;
};
struct
{
uint64_t Low;
uint64_t High;
} split;
uint64_t raw;
} __packed IOAPICRedirectEntry;
typedef union
{
struct
{
uint64_t Version : 8;
uint64_t Reserved : 8;
uint64_t MaximumRedirectionEntry : 8;
uint64_t Reserved2 : 8;
};
uint64_t raw;
} __packed IOAPICVersion;
class APIC
{
private:
bool x2APICSupported = false;
uint64_t APICBaseAddress = 0;
public:
uint32_t Read(uint32_t Register);
void Write(uint32_t Register, uint32_t Value);
void IOWrite(uint64_t Base, uint32_t Register, uint32_t Value);
uint32_t IORead(uint64_t Base, uint32_t Register);
void EOI();
void RedirectIRQs(int CPU = 0);
void WaitForIPI();
void IPI(int CPU, InterruptCommandRegisterLow icr);
void SendInitIPI(int CPU);
void SendStartupIPI(int CPU, uint64_t StartupAddress);
uint32_t IOGetMaxRedirect(uint32_t APICID);
void RawRedirectIRQ(uint16_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status);
void RedirectIRQ(int CPU, uint16_t IRQ, int Status);
APIC(int Core);
~APIC();
};
class Timer : public Interrupts::Handler
{
private:
APIC *lapic;
uint64_t Ticks = 0;
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
public:
uint64_t GetTicks() { return Ticks; }
void OneShot(uint32_t Vector, uint64_t Miliseconds);
Timer(APIC *apic);
~Timer();
};
}
#endif // !__FENNIX_KERNEL_APIC_H__

View File

@ -1,164 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_GDT_H__
#define __FENNIX_KERNEL_GDT_H__
#include <types.h>
namespace GlobalDescriptorTable
{
/** @brief The GDT Access Table
* @details For more information, see https://wiki.osdev.org/Global_Descriptor_Table
*/
union GlobalDescriptorTableAccess
{
struct
{
/** @brief Access bit.
* @note The CPU sets this bit to 1 when the segment is accessed.
*/
uint64_t A : 1;
/** @brief Readable bit for code segments, writable bit for data segments.
* @details For code segments, this bit must be 1 for the segment to be readable.
* @details For data segments, this bit must be 1 for the segment to be writable.
*/
uint64_t RW : 1;
/** @brief Direction bit for data segments, conforming bit for code segments.
* @details For data segments, this bit must be 1 for the segment to grow up (higher addresses).
* @details For code segments, this bit must be 1 for code in the segment to be able to be executed from an equal or lower privilege level.
*/
uint64_t DC : 1;
/** @brief Executable bit.
* @details This bit must be 1 for code-segment descriptors.
* @details This bit must be 0 for data-segment and system descriptors.
*/
uint64_t E : 1;
/** @brief Descriptor type.
* @details This bit must be 0 for system descriptors.
* @details This bit must be 1 for code or data segment descriptor.
*/
uint64_t S : 1;
/** @brief Descriptor privilege level.
* @details This field determines the privilege level of the segment.
* @details 0 = kernel mode, 3 = user mode.
*/
uint64_t DPL : 2;
/** @brief Present bit.
* @details This bit must be 1 for all valid descriptors.
*/
uint64_t P : 1;
} __packed;
uint8_t Raw;
};
union GlobalDescriptorTableFlags
{
// TODO: Add more flags.
struct
{
/** @brief Unknown. */
uint64_t Unknown : 5;
/** @brief Long mode.
* @details If the long mode bit is clear, the segment is in 32-bit protected mode.
* @details If the long mode bit is set, the segment is in 64-bit long mode.
*/
uint64_t L : 1;
} __packed;
uint8_t Raw;
};
typedef struct _TaskStateSegmentEntry
{
/* LOW */
uint16_t Length;
uint16_t BaseLow;
uint8_t BaseMiddle;
GlobalDescriptorTableAccess Flags;
uint8_t Granularity;
uint8_t BaseHigh;
/* HIGH */
uint32_t BaseUpper;
uint32_t Reserved;
} __packed TaskStateSegmentEntry;
typedef struct _TaskStateSegment
{
uint32_t Reserved0 __aligned(16);
uint64_t StackPointer[3];
uint64_t Reserved1;
uint64_t InterruptStackTable[7];
uint64_t Reserved2;
uint16_t Reserved3;
uint16_t IOMapBaseAddressOffset;
} __packed TaskStateSegment;
typedef struct _GlobalDescriptorTableEntry
{
/** @brief Length */
uint16_t Length;
/** @brief Low Base */
uint16_t BaseLow;
/** @brief Middle Base */
uint8_t BaseMiddle;
/** @brief Access */
GlobalDescriptorTableAccess Access;
/** @brief Flags */
GlobalDescriptorTableFlags Flags;
/** @brief High Base */
uint8_t BaseHigh;
} __packed GlobalDescriptorTableEntry;
typedef struct _GlobalDescriptorTableEntries
{
GlobalDescriptorTableEntry Null;
GlobalDescriptorTableEntry Code;
GlobalDescriptorTableEntry Data;
GlobalDescriptorTableEntry UserData;
GlobalDescriptorTableEntry UserCode;
TaskStateSegmentEntry TaskStateSegment;
} __packed GlobalDescriptorTableEntries;
typedef struct _GlobalDescriptorTableDescriptor
{
/** @brief GDT entries length */
uint16_t Length;
/** @brief GDT entries address */
GlobalDescriptorTableEntries *Entries;
} __packed GlobalDescriptorTableDescriptor;
extern void *CPUStackPointer[];
extern TaskStateSegment tss[];
void Init(int Core);
void SetKernelStack(void *Stack);
void *GetKernelStack();
}
#define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code)
#define GDT_KERNEL_DATA offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Data)
#define GDT_USER_CODE (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserCode) | 3)
#define GDT_USER_DATA (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserData) | 3)
#define GDT_TSS (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, TaskStateSegment) | 3)
#endif // !__FENNIX_KERNEL_GDT_H__

View File

@ -1,84 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_IDT_H__
#define __FENNIX_KERNEL_IDT_H__
#include <types.h>
namespace InterruptDescriptorTable
{
typedef enum _InterruptGateType
{
TASK = 0b101,
INT_16BIT = 0b110,
TRAP_16BIT = 0b111,
INT_32BIT = 0b1110,
TRAP_32BIT = 0b1111,
} InterruptGateType;
typedef enum _InterruptRingType
{
RING0 = 0b0,
RING1 = 0b1,
RING2 = 0b10,
RING3 = 0b11,
} InterruptRingType;
typedef enum _InterruptStackTableType
{
IST0 = 0b0,
IST1 = 0b1,
IST2 = 0b10,
IST3 = 0b11,
IST4 = 0b100,
IST5 = 0b101,
IST6 = 0b110,
} InterruptStackTableType;
typedef struct _InterruptDescriptorTableEntry
{
uint64_t BaseLow : 16;
uint64_t SegmentSelector : 16;
uint64_t InterruptStackTable : 3;
uint64_t Reserved1 : 5;
uint64_t Flags : 4;
uint64_t Reserved2 : 1;
uint64_t Ring : 2;
uint64_t Present : 1;
uint64_t BaseHigh : 48;
uint64_t Reserved3 : 32;
} __packed InterruptDescriptorTableEntry;
typedef struct _InterruptDescriptorTableDescriptor
{
uint16_t Length;
InterruptDescriptorTableEntry *Entries;
} __packed InterruptDescriptorTableDescriptor;
void SetEntry(uint8_t Index,
void (*Base)(),
InterruptStackTableType InterruptStackTable,
InterruptGateType Gate,
InterruptRingType Ring,
bool Present,
uint16_t SegmentSelector);
void Init(int Core);
}
#endif // !__FENNIX_KERNEL_IDT_H__

View File

@ -1,92 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
OUTPUT_FORMAT(elf64-x86-64)
OUTPUT_ARCH(i386:x86-64)
KERNEL_VMA = 0xFFFFFFFF80000000;
ENTRY(_start)
SECTIONS
{
. = 0x100000;
_bootstrap_start = .;
.bootstrap :
{
*(.multiboot)
*(.multiboot2)
*(.bootstrap .bootstrap.*)
}
. += CONSTANT(MAXPAGESIZE);
_bootstrap_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += KERNEL_VMA;
. += CONSTANT(MAXPAGESIZE);
_kernel_start = ALIGN(CONSTANT(MAXPAGESIZE));
.text : AT(ADDR(.text) - KERNEL_VMA)
{
*(.text .text.*)
}
_kernel_text_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += CONSTANT(MAXPAGESIZE);
.data : AT(ADDR(.data) - KERNEL_VMA)
{
*(.data .data.*)
}
_kernel_data_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += CONSTANT(MAXPAGESIZE);
.rodata : AT(ADDR(.rodata) - KERNEL_VMA)
{
*(.rodata .rodata.*)
}
.init_array : AT(ADDR(.init_array) - KERNEL_VMA)
{
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(.init_array .ctors))
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array : AT(ADDR(.fini_array) - KERNEL_VMA)
{
PROVIDE_HIDDEN(__fini_array_start = .);
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP(*(.fini_array .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
_kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += CONSTANT(MAXPAGESIZE);
.bss : AT(ADDR(.bss) - KERNEL_VMA)
{
*(COMMON)
*(.bss .bss.*)
}
. += CONSTANT(MAXPAGESIZE);
_kernel_end = ALIGN(CONSTANT(MAXPAGESIZE));
/DISCARD/ :
{
*(.comment*)
*(.note*)
}
}

View File

@ -1,15 +0,0 @@
// #include <types.h>
// #include <debug.h>
// int Entry(void *Info);
// void _start(void *Raw)
// {
// error("Todo");
// while (1)
// asmv("hlt");
// Entry(NULL);
// return;
// }
// C stuff

View File

@ -1,15 +0,0 @@
#include <types.h>
#include <debug.h>
int Entry(void *Info);
// void _start(void *Raw)
// {
// UNUSED(Raw);
// error("ERROR! INVALID BOOT PROTOCOL!");
// while (1)
// asmv("hlt");
// Entry(NULL);
// return;
// }

View File

@ -1 +0,0 @@
// C++ constructor/destructor stuff

View File

@ -1 +0,0 @@
// C++ constructor/destructor stuff

View File

@ -1,13 +0,0 @@
.section .init
.global _init
.type _init, @function
_init:
push %rbp
movq %rsp, %rbp
.section .fini
.global _fini
.type _fini, @function
_fini:
push %rbp
movq %rsp, %rbp

View File

@ -1,7 +0,0 @@
.section .init
popq %rbp
ret
.section .fini
popq %rbp
ret

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