diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE
index 204f577..00b7db7 100644
--- a/.github/ISSUE_TEMPLATE
+++ b/.github/ISSUE_TEMPLATE
@@ -4,7 +4,8 @@
**Actual behavior**: [describe the actual behavior, which is presented through the repro.].
-**Build information**: [output of `rustc -V`, `git rev-parse HEAD`, `qemu-i386 -version`, `uname -a`, etc.]
+**Build information**: [only when using a self build version: output of `rustc -V`, `git rev-parse HEAD` `qemu-i386 -version`, `uname -a`, etc.]
+**Redox release**: [only when using a prebuild version: redox version]
**Blocking/related**: [issues or PRs blocking or being related to this issue.]
diff --git a/.gitignore b/.gitignore
index a8b6ee3..378eac2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1 @@
-Cargo.lock
build
-target
-initfs/bin
-filesystem/bin
-filesystem/ref
-filesystem/sbin
diff --git a/.gitmodules b/.gitmodules
index 7c83399..ffbef5c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,60 +1,21 @@
-[submodule "rust"]
- path = rust
- url = https://github.com/redox-os/rust.git
-[submodule "ion"]
- path = programs/ion
- url = https://github.com/redox-os/ion.git
-[submodule "programs/coreutils"]
- path = programs/coreutils
- url = https://github.com/redox-os/coreutils.git
-[submodule "schemes/redoxfs"]
- path = schemes/redoxfs
- url = https://github.com/redox-os/redoxfs
-[submodule "programs/extrautils"]
- path = programs/extrautils
- url = https://github.com/redox-os/extrautils.git
-[submodule "programs/smith"]
- path = programs/smith
- url = https://github.com/IGI-111/Smith.git
-[submodule "programs/userutils"]
- path = programs/userutils
- url = https://github.com/redox-os/userutils.git
-[submodule "programs/netutils"]
- path = programs/netutils
- url = https://github.com/redox-os/netutils.git
-[submodule "schemes/orbital"]
- path = schemes/orbital
- url = https://github.com/redox-os/orbital.git
-[submodule "programs/orbutils"]
- path = programs/orbutils
- url = https://github.com/redox-os/orbutils.git
-[submodule "filesystem/ui"]
- path = filesystem/ui
- url = https://github.com/redox-os/orbdata.git
-[submodule "programs/acid"]
- path = programs/acid
- url = https://github.com/redox-os/acid.git
-[submodule "programs/tar"]
- path = programs/tar
- url = https://github.com/redox-os/tar-rs.git
-[submodule "programs/pkgutils"]
- path = programs/pkgutils
- url = https://github.com/redox-os/pkgutils.git
+[submodule "bootloader"]
+ path = bootloader
+ url = https://github.com/redox-os/bootloader.git
+[submodule "cookbook"]
+ path = cookbook
+ url = https://github.com/redox-os/cookbook.git
[submodule "installer"]
path = installer
url = https://github.com/redox-os/installer.git
-[submodule "syscall"]
- path = syscall
- url = https://github.com/redox-os/syscall.git
-[submodule "crates/docgen"]
- path = crates/docgen
- url = https://github.com/redox-os/docgen.git
-[submodule "programs/binutils"]
- path = programs/binutils
- url = https://github.com/redox-os/binutils.git
-[submodule "libc-artifacts"]
- path = libc-artifacts
- url = https://github.com/redox-os/libc-artifacts.git
-[submodule "programs/games"]
- path = programs/games
- url = https://github.com/redox-os/games.git
+[submodule "isolinux"]
+ path = isolinux
+ url = https://github.com/redox-os/isolinux.git
+[submodule "kernel"]
+ path = kernel
+ url = https://github.com/redox-os/kernel.git
+[submodule "rust"]
+ path = rust
+ url = https://github.com/redox-os/rust.git
+[submodule "redoxfs"]
+ path = redoxfs
+ url = https://github.com/redox-os/redoxfs.git
diff --git a/.travis.yml b/.travis.yml
index 22670b6..c438058 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,23 +5,30 @@ rust:
cache: cargo
os:
- linux
+#- osx
+#matrix:
+# allow_failures:
+# - os: osx
dist: trusty
before_install:
-- if [ `uname` = "Linux" ]; then
- sudo apt-get install -qq nasm pkg-config fuse libfuse-dev genisoimage syslinux &&
+- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
+ sudo apt-key adv -q --batch --yes --keyserver keyserver.ubuntu.com --recv-keys AA12E97F0881517F &&
+ sudo add-apt-repository 'deb https://static.redox-os.org/toolchain/apt ./' &&
+ sudo apt-get update -qq &&
+ sudo apt-get purge -qq binutils-doc &&
+ sudo apt-get install -qq nasm pkg-config fuse libfuse-dev genisoimage syslinux x86-64-unknown-redox-gcc &&
sudo modprobe fuse &&
sudo chmod 666 /dev/fuse &&
sudo chown root:$USER /etc/fuse.conf;
fi
-- if [ `uname` = "Darwin" ]; then brew update &&
- brew install nasm gcc49 pkg-config Caskroom/cask/osxfuse &&
- brew tap glendc/gcc_cross_compilers &&
- brew install glendc/gcc_cross_compilers/x64-elf-binutils glendc/gcc_cross_compilers/x64-elf-gcc;
+- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
+ brew update &&
+ brew install nasm pkg-config Caskroom/cask/osxfuse &&
+ travis_wait 30 brew install redox-os/gcc_cross_compilers/x86_64-elf-gcc;
fi
+- cd cookbook && ./setup.sh && cd ..
script:
-- make clean &&
- make update &&
- make build/harddrive.bin.gz build/livedisk.bin.gz build/livedisk.iso -j 2
+- make clean && make travis
notifications:
email: false
webhooks: http://37.139.9.28:54863/travis
@@ -29,11 +36,10 @@ deploy:
provider: releases
api_key:
secure: E5w3mgFbW4fAFNJn0FGcvwGKK33d+StC4izDX7dsGPxX/gwAsMnZqabDWpsrj8n/jFI5NdPzuyz4Ojkip4AXrEs0DWfX96d9CSWvJmWIirwwKhALnxZ5cqnHnBXY3wpk9k8MKpdODzKs3ZjM3pPug2jjjp2EHdrEV6iyc8LlnLAJutbtPpNJv0rJrx/TfCZRx70YWKQyx2Lfx5P6Vj+5yoYsKk+SHmKZlIQfj2E1cfC8+/w+fzc9CRTNhM9XFBisKnu9qql3nNhEW8VUNQ9FnltGpunmcTnCmsKzHPfs8Zv6kM/6y3wuoqxwPnIwRu+zsntkjM/eT7Zy3DtTBqJDjq+L5jov50QWOxzjUuFYMv0lAMeMC0PIGn0ECpFs546M+Wqvd7HKgabac0UhilEBPbinOdW+6aOOhbo+Fe2I2ec0XIGxlQpccQeWQUsjjOQ+6QuvnpPE+CbvQaVyrx27rVAkqD44cOP8xqOq2Es651J+Dt0O1OIhLdPB3FxOLCDpEIHU5Ojci1QbUxZgGKjShpo44nNqcTv7v71JrfzFSVG2pF9a35Mpo6bFEkzyQprOyrwH2fcnN+4jyxdJXzdNsgraXsQopWAB5cL/8i7SXMwHy9ivpFaX/zgoHQqpc1a4VjrmTtPA08rLORIllw9CplfvJNsmNmCi2aSeTXR06Xk=
- file:
- - build/harddrive.bin.gz
- - build/livedisk.bin.gz
- - build/livedisk.iso
+ file_glob: true
+ file: build/travis/*
on:
repo: redox-os/redox
tags: true
+ condition: $TRAVIS_OS_NAME = linux
skip_cleanup: true
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a73625f..4c27589 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,17 +1,18 @@
# Contributing to Redox
-Thank you for your interest in contributing to Redox! This document is a guide to help newcomers contribute!
-There are many ways to help us out and we appreciate all of them.
+Thank you for your interest in contributing to Redox! This document will outline the basics of where to start if you wish to contribute to the project. There are many ways to help us out and and we appreciate all of them. We look forward to your contribution!
## Index
* [Communication](#communication)
* [Chat](#chat)
- * [Reddit](#reddit)
-* [Direct Contributing](#direct-contributing)
- * [Low-Hanging Fruit - Easy Targets for Newbies](#easy-targets)
- * [GitHub Issues](#gh-issues)
+ * [GitHub Issues](#issues)
* [Pull Requests](#prs)
+ * [Discourse](#discourse)
+ * [Reddit](#reddit)
+ * [News](#news)
+* [Code Contributions](#code-contributions)
+ * [Low-Hanging Fruit - Easy Targets for Newbies](#easy-targets)
* [Creating a Pull Request](#creating-a-pr)
* [Best Practices/Guidelines](#best-practices)
* [General](#general)
@@ -22,10 +23,11 @@ There are many ways to help us out and we appreciate all of them.
* [Git](#git-style-guidelines)
* [Other Ways to Contribute](#other)
* [Graphic Design](#graphic-design)
+ * [Patreon](#patreon)
## Other External Links
-* [redox-os.org](http://redox-os.org)
+* [redox-os.org](https://redox-os.org)
* [rust-os-comparison](https://github.com/flosse/rust-os-comparison)
* [rust-lang.org](http://rust-lang.org)
@@ -33,70 +35,77 @@ There are many ways to help us out and we appreciate all of them.
### Chat
-The quickest and most open way to communicate with the Redox team is on our chat server. Currently, the only way to join it is by sending an email to [info@redox-os.org](mailto:info@redox-os.org), which might take a little while, since it's not automated. We're currently working on an easier way to do this, but this is the most convenient way right now.
+The quickest and most open way to communicate with the Redox team is on our chat server. Currently, you can only get an invite by sending an email request to [info@redox-os.org](mailto:info@redox-os.org), which might take a little while, since it's not automated. Simply say you'd like to join the chat. We're working on an better way to do this, but this is the best way right now.
+
+### GitHub Issues
+
+A bit more formal way of communication with fellow Redox devs, but a little less quick and convenient like the chat. Submit an issue when you run into problems compiling, testing, or just would like to discuss a certain topic, be it features, code style, code inconsistencies, minor changes and fixes, etc.
+
+### Pull Requests
+
+It's fine to just submit a small pull request without first making an issue or asking in the chat, but if it's a significant change that will require a lot of planning and reviewing. Also see [Creating a Pull Request](#creating-a-pr) and [Git Style Guidelines](#git-style-guidelines).
+
+### Discourse
+
+We have a discourse forum at [discourse.redox-os.org](https://discourse.redox-os.org). This is the best way to discuss more general topics that aren't about specific things that need to be addressed one way or another. You can sign up like any other website.
### Reddit
-You can find Redox on Reddit in [/r/rust/](https://www.reddit.com/r/rust) and [/r/redox/](https://www.reddit.com/r/redox). The weekly update news is posted on the former.
+You can also find Redox on Reddit in [/r/rust/](https://www.reddit.com/r/rust) and [/r/redox/](https://www.reddit.com/r/redox). Redox news and discussion is posted on the latter, and Rust news and discussion, as well as some Redox posts, is on the former.
-## Direct Contributing
+### News
+
+News and updates for Redox are posted at [redox-os.org/news](https://redox-os.org/news). It's more one-way than the other things on this list, but it should provide a good summary of what's been going on with the project lately. It's usually updated weekly, but with some exceptions. A mailing list may be included eventually, but it's not set up right now.
+
+## Code Contributions
### Low-Hanging Fruit - Easy Targets for Newbies
-* If you're not fluent in Rust:
+#### If you're not fluent in Rust:
* Writing documentation
* Using/testing Redox, filing issues for bugs and needed features
* Web development ([Redox website, separate repo](https://github.com/redox-os/website))
* Writing unit tests (may require minimal knowledge of rust)
-* If you are fluent in Rust, but not OS Development:
+#### If you are fluent in Rust, but not OS Development:
* Apps development
* Shell ([Ion](https://github.com/redox-os/ion)) development
- * Package manager ([Magnet](https://github.com/redox-os/magnet)) development
+ * Package management ([pkgutils](https://github.com/redox-os/pkgutils)) development
* Other high-level code tasks
-* If you are fluent in Rust, and have experience with OS Dev:
+#### If you are fluent in Rust, and have experience with OS Dev:
* Familiarize yourself with the repository and codebase
* Grep for `TODO`, `FIXME`, `BUG`, `UNOPTIMIZED`, `REWRITEME`, `DOCME`, and `PRETTYFYME` and fix the code you find.
* Improve and optimize code, especially in the kernel
-### GitHub Issues
-
-A bit more formal way of communication with fellow Redox devs, but a little less quick and convenient like the chat (unless of course you aren't in it yet, which if you're going to be involved in this project really at all, it is recommended that you request to join). These are for more specific topics.
-
-### Pull Requests
-
-It's completely okay to just submit a small pull request without first making an issue or something, but if it's a significant change that will require a lot of planning and reviewing, it's best you start with writing an issue first. Also see [git guidelines](#git-style-guidelines)
-
### Creating a Pull Request
1. Fork the repository
2. Clone the original repository to your local PC using one of the following commands based on the protocol you are using:
* HTTPS:`git clone https://github.com/redox-os/redox.git --origin upstream --recursive`
* SSH:`git clone git@github.com:redox-os/redox.git --origin upstream --recursive`
- * Then rebase: `git rebase upstream master`
- Use HTTPS if you don't know which one to use. (Recommended: learn about SSH if you don't want to have to log in every time you push/pull!)
+ * Then rebase: `git rebase upstream master`
+ If you use HTTPS, you will have to log in each time when pushing to your fork. (Recommended: learn about git SSH support, it logs in automatically using SSH keys)
3. Add your fork with
* HTTPS:`git remote add origin https://github.com/your-username/redox.git`
* SSH:`git remote add origin git@github.com:your-username/redox.git`
4. Alternatively, if you already have a fork and copy of the repo, you can simply check to make sure you're up-to-date
- * Fetch the upstream:`git fetch upstream master`
- * Rebase with local commits:`git rebase upstream/master`
- * Update the submodules:`git submodule update --init`
-5. Optionally create a separate branch (recommended if you're making multiple changes simultaneously) (`git checkout -b my-branch`)
+ * Pull the upstream:`git pull upstream --rebase`
+ * Update the submodules:`git submodule update --recursive --init`
+5. Create a separate branch (recommended if you're making multiple changes simultaneously) (`git checkout -b my-branch`)
6. Make changes
-7. Commit (`git add . --all; git commit -m "my commit"`)
+7. Commit (`git add ; git commit`) and write your commit message
8. Optionally run [rustfmt](https://github.com/rust-lang-nursery/rustfmt) on the files you changed and commit again if it did anything (check with `git diff` first)
-9. Test your changes with `make qemu` or `make virtualbox` (you might have to use `make qemu kvm=no`, formerly `make qemu_no_kvm`)
+9. Test your changes by cleaning (`make clean; git clean -Xfd`) and building with `make qemu` (you might have to use `make qemu kvm=no`) or `make virtualbox`.
(see [Best Practices and Guidelines](#best-practices))
-10. Pull from upstream (`git fetch upstream; git rebase upstream/master`) (Note: try not to use `git pull`, it is equivalent to doing `git fetch upstream; git merge master upstream/master`, which is not usually preferred for local/fork repositories, although it is fine in some cases.)
+10. Pull from upstream (`git pull upstream --rebase`) (Note: Make sure to include `--rebase`, as it will apply your changes on top of the changes you just pulled, allowing for a much cleaner merge)
11. Repeat step 9 to make sure the rebase still builds and starts
-12. Push to your fork (`git push origin my-branch`)
+12. Push to your fork (`git push origin `), `` being the branch you created earlier
13. Create a pull request
-14. Describe your changes
+14. If your changes are minor, you can just describe them in a paragraph or less. If they're major, please fill out the provided form.
15. Submit!
## Best Practices and Guidelines
@@ -105,36 +114,36 @@ It's completely okay to just submit a small pull request without first making an
* **Remember to do a `git rebase -i upstream/master` before you send your patch!**
* **Make sure your code is readable, commented, and well-documented.**
-* **Don't hesitate to ask for help!**
-* **Before implementing something, discuss it! Open an issue, or join the chat.**
+* **Don't hesitate to ask for help, comments or suggestions!**
+* **Before implementing something, discuss it! Open an issue, or ask in the chat.**
##### On the more technical side:
* Test, test, and test!
-* Follow the style conventions
+* Follow the style conventions (See [rust style guidelines](#rust-style-guidelines))
* Use `std::mem::replace` and `std::mem::swap` when you can.
* `libredox` should be 1-to-1 with the official `libstd`.
-* Use `.into()` and `.to_owned()` over `.to_string()`.
+* Prefer `.into()` and `.to_owned()` over `.to_string()`.
* Prefer passing references to the data over owned data. (Don't take `String`, take `&str`. Don't take `Vec` take `&[T]`).
* Use generics, traits, and other abstractions Rust provides.
* Avoid using lossy conversions (for example: don't do `my_u32 as u16 == my_u16`, prefer `my_u32 == my_u16 as my_u32`).
* Prefer in place (`box` keyword) when doing heap allocations.
* Prefer platform independently sized integer over pointer sized integer (`u32` over `usize`, for example).
* Follow the usual idioms of programming, such as "composition over inheritance", "let your program be divided in smaller pieces", and "resource acquisition is initialization".
-* When `unsafe` is unnecessary, don't use it. 10 lines longer safe code is better than more compact unsafe code!
-* Be sure to mark parts that need work with `TODO`, `FIXME`, `BUG`, `UNOPTIMIZED`, `REWRITEME`, `DOCME`, and `PRETTYFYME`.
+* When `unsafe` is unnecessary, don't use it. **Longer safe code is better than shorter unsafe code!**
+* Be sure to mark parts that need work with `TODO`, `FIXME`, `BUG`, `UNOPTIMIZED`, `REWRITEME`, `DOCME`, and `PRETTYFYME`. Always elaborate on these messages, too. Nothing is more annoying than seeing a `TODO` and not knowing how to actually fix it.
* Use the compiler hint attributes, such as `#[inline]`, `#[cold]`, etc. when it makes sense to do so.
-* Check the [chat](#chat), [the Website](http://redox-os.org), and [the Rust subreddit](https://www.reddit.com/r/rust) frequently.
+* Check the [chat](#chat), [the website](http://redox-os.org/news), and [the Rust subreddit](https://www.reddit.com/r/rust) frequently.
### Kernel
-* When trying to access a slice, **always** use the `common::GetSlice` trait and the `.get_slice()` method to get a slice without causing the kernel to panic.
- The problem with slicing in regular Rust, e.g. `foo[a..b]`, is that if someone tries to access with a range that is out of bounds of an array/string/slice, it will cause a panic at runtime, as a safety measure. Same thing when accessing an element.
+* When trying to access a slice, **always** use the `common::GetSlice` trait and the `.get_slice()` method to get a slice without causing the kernel to panic.
+ The problem with slicing in regular Rust, e.g. `foo[a..b]`, is that if someone tries to access with a range that is out of bounds of an array/string/slice, it will cause a panic at runtime, as a safety measure. Same thing when accessing an element.
Always use `foo.get(n)` instead of `foo[n]` and try to cover for the possibility of `Option::None`. Doing the regular way may work fine for applications, but never in the kernel. No possible panics should ever exist in kernel space, because then the whole OS would just stop working.
### Testing Practices
-* It's always better to test boot (`make qemu` or `make virtualbox`) every time you make a change, because it is important to see how the OS boots and works after it compiles.
- Even though Rust is a safety-oriented language, something as unstable as an in-dev operating system will have problems in many cases and may completely break on even the slightest critical change.
+* It's always better to test boot (`make qemu` or `make virtualbox`) every time you make a change, because it is important to see how the OS boots and works after it compiles.
+ Even though Rust is a safety-oriented language, something as unstable and low-level as an in-dev operating system will almost certainly have problems in many cases and may completely break on even the slightest critical change.
Also, make sure you check how the unmodified version runs on your machine before making any changes. Else, you won't have anything to compare to, and it will generally just lead to confusion. TLDR: Rebuild and test boot often.
* To run the ZFS tests:
@@ -150,14 +159,33 @@ Since Rust is a relatively small and new language compared to others like C, the
### Git
-* Commit messages should describe their changes in present tense, e.g. "`Add stuff to file.ext`" instead of "`added stuff to file.ext`".
-* Try to remove useless duplicate/merge commits from PRs as these clutter up history, and may make it hard to read.
-* Usually, when syncing your local copy with the master branch, you will want to rebase instead of merge. This is because it will create duplicate commits that don't actually do anything when merged into the master branch.
-* When you start to make changes, you will want to create a separate branch, and keep the `master` branch of your fork identical to the main repository, so that you can compare your changes with the main branch and test out a more stable build if you need to.
* You should have a fork of the repository on GitHub and a local copy on your computer. The local copy should have two remotes; `upstream` and `origin`, `upstream` should be set to the main repository and `origin` should be your fork.
+* When you start to make changes, you will want to create a separate branch, and keep the `master` branch of your fork identical to the main repository, so that you can compare your changes with the main branch and test out a more stable build if you need to.
+* Usually, when syncing your local copy with the master branch, you'll want to rebase instead of merge. This is because it will create duplicate commits that don't actually do anything when merged into the master branch. You can do this in one command with `git pull upstream --rebase`. This will pull from the upstream, then roll back to the current state of the upstream, and "replay" your changes on top of it. Make sure you commit before doing this, though. Git won't be able to rebase if you don't.
+* Prefer to omit the `-m` when using `git commit`. This opens your editor and should help get you in the habit of writing longer commit messages.
+* Commit messages should describe their changes in present tense, e.g. "`Add stuff to file.ext`" instead of "`added stuff to file.ext`". This makes sense as sometimes when you revert back, then run through commits one-by-one, you want to see what a commit will do, instead of just what the person did when they made the commit. It's also just being consistent.
+* Try to remove useless duplicate/merge commits from PRs as these don't do anything except clutter up history and make it harder to read.
## Other Ways to Contribute
-### Graphic Design
+If you're not big on coding, but you still want to help keep the project going, you can still contribute/support in a variety of ways! We'll try to find a way to use anything you have to offer.
+
+### Design
+
+If you're a good designer, whether it's 2D graphics, 3D graphics, interfaces, web design, you can help. We need logos, UI design, UI skins, app icons, desktop backgrounds, etc. More information to come on this in the future, for now just join [the chat](#chat) and ask about graphic design.
+
+### Patreon
+
+Our BDFL, [jackpot51](https://github.com/jackpot51), has a [Patreon campaign](https://www.patreon.com/redox_os)! All money recieved will go towards Redox OS development. If you donate, you will be listed in the Redox credits as one of the people that made Redox OS possible. You'll also get other rewards the more you donate. However, please don't donate if you can't afford it.
+
+
-If you're a good designer, you can help with logos, UI design, app icons, other graphics (e.g. stock desktop backgrounds), etc. More information to come on this, for now just join [the chat](#chat) and ask about graphic design.
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644
index 5c3c138..0000000
--- a/Cargo.toml
+++ /dev/null
@@ -1,37 +0,0 @@
-[package]
-name = "kernel"
-version = "0.1.0"
-
-[lib]
-name = "kernel"
-path = "kernel/lib.rs"
-crate-type = ["staticlib"]
-
-[dependencies]
-bitflags = "*"
-spin = "*"
-redox_syscall = { path = "syscall/" }
-
-[dependencies.goblin]
-git = "https://github.com/m4b/goblin.git"
-default-features = false
-features = ["elf32", "elf64"]
-
-[dev-dependencies]
-arch_test = { path = "arch/test" }
-
-[target.'cfg(target_arch = "arm")'.dependencies]
-arch_arm = { path = "arch/arm" }
-
-[target.'cfg(target_arch = "x86_64")'.dependencies]
-arch_x86_64 = { path = "arch/x86_64" }
-
-[features]
-default = []
-live = []
-
-[profile.dev]
-panic = "unwind"
-
-[profile.release]
-panic = "abort"
diff --git a/Makefile b/Makefile
index 1329ee8..1ccb277 100644
--- a/Makefile
+++ b/Makefile
@@ -1,31 +1,5 @@
-ARCH?=x86_64
-
-ROOT=$(PWD)
-export RUST_TARGET_PATH=$(ROOT)/targets
-
-#TODO: Use libssp
-export CFLAGS=-fno-stack-protector -U_FORTIFY_SOURCE
-
-# Kernel variables
-KTARGET=$(ARCH)-unknown-none
-KBUILD=build/kernel
-KRUSTC=./krustc.sh
-KRUSTCFLAGS=--target $(KTARGET) -C opt-level=2 -C debuginfo=0 -C soft-float
-KRUSTDOC=./krustdoc.sh
-KCARGO=RUSTC="$(KRUSTC)" RUSTDOC="$(KRUSTDOC)" cargo
-KCARGOFLAGS=--target $(KTARGET) --release -- -C soft-float
-
-# Userspace variables
-TARGET=$(ARCH)-unknown-redox
-BUILD=build/userspace
-RUSTC=./rustc.sh
-RUSTCFLAGS=--target $(TARGET).json -C opt-level=2 -C debuginfo=0
-RUSTDOC=./rustdoc.sh
-CARGO=RUSTC="$(RUSTC)" RUSTDOC="$(RUSTDOC)" cargo
-CARGOFLAGS=--target $(TARGET).json --release --
-
-# Default targets
-.PHONY: all live iso clean doc ref test update pull qemu bochs drivers schemes binutils coreutils extrautils netutils userutils wireshark FORCE
+# Configuration and variables
+include mk/config.mk
all: build/harddrive.bin
@@ -33,130 +7,15 @@ live: build/livedisk.bin
iso: build/livedisk.iso
-FORCE:
-
clean:
- cargo clean
- cargo clean --manifest-path rust/src/libstd/Cargo.toml
- cargo clean --manifest-path drivers/ahcid/Cargo.toml
- cargo clean --manifest-path drivers/e1000d/Cargo.toml
- cargo clean --manifest-path drivers/ps2d/Cargo.toml
- cargo clean --manifest-path drivers/pcid/Cargo.toml
- cargo clean --manifest-path drivers/rtl8168d/Cargo.toml
- cargo clean --manifest-path drivers/vesad/Cargo.toml
- cargo clean --manifest-path programs/acid/Cargo.toml
- cargo clean --manifest-path programs/contain/Cargo.toml
- cargo clean --manifest-path programs/init/Cargo.toml
- cargo clean --manifest-path programs/ion/Cargo.toml
- cargo clean --manifest-path programs/binutils/Cargo.toml
- cargo clean --manifest-path programs/coreutils/Cargo.toml
- cargo clean --manifest-path programs/extrautils/Cargo.toml
- cargo clean --manifest-path programs/games/Cargo.toml
- cargo clean --manifest-path programs/netutils/Cargo.toml
- cargo clean --manifest-path programs/orbutils/Cargo.toml
- cargo clean --manifest-path programs/pkgutils/Cargo.toml
- cargo clean --manifest-path programs/userutils/Cargo.toml
- cargo clean --manifest-path programs/smith/Cargo.toml
- cargo clean --manifest-path programs/tar/Cargo.toml
- cargo clean --manifest-path schemes/ethernetd/Cargo.toml
- cargo clean --manifest-path schemes/example/Cargo.toml
- cargo clean --manifest-path schemes/ipd/Cargo.toml
- cargo clean --manifest-path schemes/orbital/Cargo.toml
- cargo clean --manifest-path schemes/ptyd/Cargo.toml
- cargo clean --manifest-path schemes/randd/Cargo.toml
- cargo clean --manifest-path schemes/redoxfs/Cargo.toml
- cargo clean --manifest-path schemes/tcpd/Cargo.toml
- cargo clean --manifest-path schemes/udpd/Cargo.toml
- -$(FUMOUNT) build/filesystem/
- rm -rf initfs/bin
- rm -rf filesystem/bin filesystem/sbin filesystem/ui/bin
+ cd cookbook && ./clean.sh
+ cargo clean --manifest-path cookbook/pkgutils/Cargo.toml
+ cargo clean --manifest-path installer/Cargo.toml
+ cargo clean --manifest-path kernel/Cargo.toml
+ cargo clean --manifest-path redoxfs/Cargo.toml
+ -$(FUMOUNT) build/filesystem/ || true
rm -rf build
-doc: \
- doc-kernel \
- doc-std
-
-#FORCE to let cargo decide if docs need updating
-doc-kernel: $(KBUILD)/libkernel.a FORCE
- $(KCARGO) doc --target $(KTARGET).json
-
-doc-std: $(BUILD)/libstd.rlib FORCE
- $(CARGO) doc --target $(TARGET).json --manifest-path rust/src/libstd/Cargo.toml
-
-ref: FORCE
- rm -rf filesystem/ref/
- mkdir -p filesystem/ref/
- cargo run --manifest-path crates/docgen/Cargo.toml -- programs/binutils/src/bin/ filesystem/ref/
- cargo run --manifest-path crates/docgen/Cargo.toml -- programs/coreutils/src/bin/ filesystem/ref/
- cargo run --manifest-path crates/docgen/Cargo.toml -- programs/extrautils/src/bin/ filesystem/ref/
- cargo run --manifest-path crates/docgen/Cargo.toml -- programs/netutils/src/ filesystem/ref/
-
-test:
- cargo test
- cargo test --manifest-path rust/src/libstd/Cargo.toml
- cargo test --manifest-path drivers/ahcid/Cargo.toml
- cargo test --manifest-path drivers/e1000d/Cargo.toml
- cargo test --manifest-path drivers/ps2d/Cargo.toml
- cargo test --manifest-path drivers/pcid/Cargo.toml
- cargo test --manifest-path drivers/rtl8168d/Cargo.toml
- cargo test --manifest-path drivers/vesad/Cargo.toml
- cargo test --manifest-path programs/acid/Cargo.toml
- cargo test --manifest-path programs/contain/Cargo.toml
- cargo test --manifest-path programs/init/Cargo.toml
- cargo test --manifest-path programs/ion/Cargo.toml
- cargo test --manifest-path programs/binutils/Cargo.toml
- cargo test --manifest-path programs/coreutils/Cargo.toml
- cargo test --manifest-path programs/extrautils/Cargo.toml
- cargo test --manifest-path programs/games/Cargo.toml
- cargo test --manifest-path programs/netutils/Cargo.toml
- cargo test --manifest-path programs/orbutils/Cargo.toml
- cargo test --manifest-path programs/pkgutils/Cargo.toml
- cargo test --manifest-path programs/userutils/Cargo.toml
- cargo test --manifest-path programs/smith/Cargo.toml
- cargo test --manifest-path programs/tar/Cargo.toml
- cargo test --manifest-path schemes/ethernetd/Cargo.toml
- cargo test --manifest-path schemes/example/Cargo.toml
- cargo test --manifest-path schemes/ipd/Cargo.toml
- cargo test --manifest-path schemes/orbital/Cargo.toml
- cargo test --manifest-path schemes/ptyd/Cargo.toml
- cargo test --manifest-path schemes/randd/Cargo.toml
- cargo test --manifest-path schemes/redoxfs/Cargo.toml
- cargo test --manifest-path schemes/tcpd/Cargo.toml
- cargo test --manifest-path schemes/udpd/Cargo.toml
-
-update:
- cargo update
- cargo update --manifest-path rust/src/libstd/Cargo.toml
- cargo update --manifest-path drivers/ahcid/Cargo.toml
- cargo update --manifest-path drivers/e1000d/Cargo.toml
- cargo update --manifest-path drivers/ps2d/Cargo.toml
- cargo update --manifest-path drivers/pcid/Cargo.toml
- cargo update --manifest-path drivers/rtl8168d/Cargo.toml
- cargo update --manifest-path drivers/vesad/Cargo.toml
- cargo update --manifest-path programs/acid/Cargo.toml
- cargo update --manifest-path programs/contain/Cargo.toml
- cargo update --manifest-path programs/init/Cargo.toml
- cargo update --manifest-path programs/ion/Cargo.toml
- cargo update --manifest-path programs/binutils/Cargo.toml
- cargo update --manifest-path programs/coreutils/Cargo.toml
- cargo update --manifest-path programs/extrautils/Cargo.toml
- cargo update --manifest-path programs/games/Cargo.toml
- cargo update --manifest-path programs/netutils/Cargo.toml
- cargo update --manifest-path programs/orbutils/Cargo.toml
- cargo update --manifest-path programs/pkgutils/Cargo.toml
- cargo update --manifest-path programs/userutils/Cargo.toml
- cargo update --manifest-path programs/smith/Cargo.toml
- cargo update --manifest-path programs/tar/Cargo.toml
- cargo update --manifest-path schemes/ethernetd/Cargo.toml
- cargo update --manifest-path schemes/example/Cargo.toml
- cargo update --manifest-path schemes/ipd/Cargo.toml
- cargo update --manifest-path schemes/orbital/Cargo.toml
- cargo update --manifest-path schemes/ptyd/Cargo.toml
- cargo update --manifest-path schemes/randd/Cargo.toml
- cargo update --manifest-path schemes/redoxfs/Cargo.toml
- cargo update --manifest-path schemes/tcpd/Cargo.toml
- cargo update --manifest-path schemes/udpd/Cargo.toml
-
pull:
git pull --rebase --recurse-submodules
git submodule sync
@@ -165,472 +24,49 @@ pull:
make clean
make update
-# Emulation
-QEMU=SDL_VIDEO_X11_DGAMOUSE=0 qemu-system-$(ARCH)
-QEMUFLAGS=-serial mon:stdio -d cpu_reset -d guest_errors
-ifeq ($(ARCH),arm)
- QEMUFLAGS+=-cpu arm1176 -machine integratorcp
- QEMUFLAGS+=-nographic
+update:
+ cd cookbook; \
+ ./update.sh "$$(cargo run --manifest-path ../installer/Cargo.toml -- --list-packages ../initfs.toml ../filesystem.toml)"
+ cargo update --manifest-path cookbook/pkgutils/Cargo.toml
+ cargo update --manifest-path installer/Cargo.toml
+ cargo update --manifest-path kernel/Cargo.toml
+ cargo update --manifest-path redoxfs/Cargo.toml
- export CC=$(ARCH)-none-eabi-gcc
- export CXX=$(ARCH)-none-eabi-g++
- export LD=$(ARCH)-none-eabi-ld
+fetch:
+ cd cookbook; \
+ ./fetch.sh "$$(cargo run --manifest-path ../installer/Cargo.toml -- --list-packages ../initfs.toml ../filesystem.toml)"
- KRUSTCFLAGS+=-C linker=$(CC)
- KCARGOFLAGS+=-C linker=$(CC)
- RUSTCFLAGS+=-C linker=$(CC)
- CARGOFLAGS+=-C linker=$(CC)
+# Emulation recipes
+include mk/qemu.mk
+include mk/bochs.mk
+include mk/virtualbox.mk
-%.list: %
- $(ARCH)-none-eabi-objdump -C -D $< > $@
+# Kernel recipes
+include mk/kernel.mk
-build/harddrive.bin: $(KBUILD)/kernel
- cp $< $@
+# Filesystem recipes
+include mk/initfs.mk
+include mk/filesystem.mk
-qemu: build/harddrive.bin
- $(QEMU) $(QEMUFLAGS) -kernel $<
-else
- QEMUFLAGS+=-smp 4 -m 1024
- ifeq ($(iommu),yes)
- QEMUFLAGS+=-machine q35,iommu=on
- else
- QEMUFLAGS+=-machine q35
- endif
- ifeq ($(net),no)
- QEMUFLAGS+=-net none
- else
- QEMUFLAGS+=-net nic,model=e1000 -net user -net dump,file=build/network.pcap
- ifeq ($(net),redir)
- QEMUFLAGS+=-redir tcp:8080::8080
- endif
- endif
- ifeq ($(vga),no)
- QEMUFLAGS+=-nographic -vga none
- endif
- #,int,pcall
- #-device intel-iommu
+# Disk images
+include mk/disk.mk
- UNAME := $(shell uname)
- ifeq ($(UNAME),Darwin)
- export CC=$(ARCH)-elf-gcc
- export CXX=$(ARCH)-elf-g++
- ECHO=/bin/echo
- FUMOUNT=sudo umount
- export LD=$(ARCH)-elf-ld
- export LDFLAGS=--gc-sections
- VB_AUDIO=coreaudio
- VBM="/Applications/VirtualBox.app/Contents/MacOS/VBoxManage"
- else
- export CC=gcc
- export CXX=g++
- ECHO=echo
- FUMOUNT=fusermount -u
- export LD=ld
- export LDFLAGS=--gc-sections
- ifneq ($(kvm),no)
- QEMUFLAGS+=-enable-kvm -cpu host
- endif
- VB_AUDIO="pulse"
- VBM=VBoxManage
- endif
+# Travis target
+travis: FORCE
+ INSTALLER_FLAGS= make build/harddrive.bin.gz build/livedisk.iso
+ rm -rf build/travis
+ mkdir build/travis
+ mv build/harddrive.bin.gz build/travis/redox_$(TRAVIS_TAG).bin.gz
+ mv build/livedisk.iso build/travis/redox_$(TRAVIS_TAG).iso
+ cd build/travis && sha256sum -b redox_$(TRAVIS_TAG).bin.gz redox_$(TRAVIS_TAG).iso > SHA256SUM
- KRUSTCFLAGS+=-C linker=$(CC)
- KCARGOFLAGS+=-C linker=$(CC)
- RUSTCFLAGS+=-C linker=$(CC)
- CARGOFLAGS+=-C linker=$(CC)
+# An empty target
+FORCE:
+# A method of creating a listing for any binary
%.list: %
objdump -C -M intel -D $< > $@
-build/harddrive.bin: $(KBUILD)/kernel bootloader/$(ARCH)/** build/filesystem.bin
- nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/$(ARCH)/ bootloader/$(ARCH)/harddrive.asm
-
-build/livedisk.bin: $(KBUILD)/kernel_live bootloader/$(ARCH)/**
- nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/$(ARCH)/ bootloader/$(ARCH)/livedisk.asm
-
-build/%.bin.gz: build/%.bin
- gzip -k -f $<
-
-build/livedisk.iso: build/livedisk.bin.gz
- rm -rf build/iso/
- mkdir -p build/iso/
- cp -RL isolinux build/iso/
- cp $< build/iso/livedisk.gz
- genisoimage -o $@ -b isolinux/isolinux.bin -c isolinux/boot.cat \
- -no-emul-boot -boot-load-size 4 -boot-info-table \
- build/iso/
- isohybrid $@
-
-qemu: build/harddrive.bin
- $(QEMU) $(QEMUFLAGS) -drive file=$<,format=raw
-
-qemu_extra: build/harddrive.bin
- if [ ! -e build/extra.bin ]; then dd if=/dev/zero of=build/extra.bin bs=1M count=1024; fi
- $(QEMU) $(QEMUFLAGS) -drive file=$<,format=raw -drive file=build/extra.bin,format=raw
-
-qemu_no_build:
- $(QEMU) $(QEMUFLAGS) -drive file=build/harddrive.bin,format=raw
-
-qemu_live: build/livedisk.bin
- $(QEMU) $(QEMUFLAGS) -device usb-ehci,id=flash_bus -drive id=flash_drive,file=$<,format=raw,if=none -device usb-storage,drive=flash_drive,bus=flash_bus.0
-
-qemu_live_no_build:
- $(QEMU) $(QEMUFLAGS) -device usb-ehci,id=flash_bus -drive id=flash_drive,file=build/livedisk.bin,format=raw,if=none -device usb-storage,drive=flash_drive,bus=flash_bus.0
-
-qemu_iso: build/livedisk.iso
- $(QEMU) $(QEMUFLAGS) -boot d -cdrom $<
-
-qemu_iso_no_build:
- $(QEMU) $(QEMUFLAGS) -boot d -cdrom build/livedisk.iso
-
-endif
-
-bochs: build/harddrive.bin
- bochs -f bochs.$(ARCH)
-
-virtualbox: build/harddrive.bin
- echo "Delete VM"
- -$(VBM) unregistervm Redox --delete; \
- if [ $$? -ne 0 ]; \
- then \
- if [ -d "$$HOME/VirtualBox VMs/Redox" ]; \
- then \
- echo "Redox directory exists, deleting..."; \
- $(RM) -rf "$$HOME/VirtualBox VMs/Redox"; \
- fi \
- fi
- echo "Delete Disk"
- -$(RM) harddrive.vdi
- echo "Create VM"
- $(VBM) createvm --name Redox --register
- echo "Set Configuration"
- $(VBM) modifyvm Redox --memory 1024
- $(VBM) modifyvm Redox --vram 16
- if [ "$(net)" != "no" ]; \
- then \
- $(VBM) modifyvm Redox --nic1 nat; \
- $(VBM) modifyvm Redox --nictype1 82540EM; \
- $(VBM) modifyvm Redox --cableconnected1 on; \
- $(VBM) modifyvm Redox --nictrace1 on; \
- $(VBM) modifyvm Redox --nictracefile1 build/network.pcap; \
- fi
- $(VBM) modifyvm Redox --uart1 0x3F8 4
- $(VBM) modifyvm Redox --uartmode1 file build/serial.log
- $(VBM) modifyvm Redox --usb off # on
- $(VBM) modifyvm Redox --keyboard ps2
- $(VBM) modifyvm Redox --mouse ps2
- $(VBM) modifyvm Redox --audio $(VB_AUDIO)
- $(VBM) modifyvm Redox --audiocontroller ac97
- $(VBM) modifyvm Redox --nestedpaging off
- echo "Create Disk"
- $(VBM) convertfromraw $< build/harddrive.vdi
- echo "Attach Disk"
- $(VBM) storagectl Redox --name ATA --add sata --controller IntelAHCI --bootable on --portcount 1
- $(VBM) storageattach Redox --storagectl ATA --port 0 --device 0 --type hdd --medium build/harddrive.vdi
- echo "Run VM"
- $(VBM) startvm Redox
-
-# Kernel recipes
-$(KBUILD)/libcore.rlib: rust/src/libcore/lib.rs
- mkdir -p $(KBUILD)
- $(KRUSTC) $(KRUSTCFLAGS) -o $@ $<
-
-$(KBUILD)/librand.rlib: rust/src/librand/lib.rs $(KBUILD)/libcore.rlib
- $(KRUSTC) $(KRUSTCFLAGS) -o $@ $<
-
-$(KBUILD)/liballoc.rlib: rust/src/liballoc/lib.rs $(KBUILD)/libcore.rlib
- $(KRUSTC) $(KRUSTCFLAGS) -o $@ $<
-
-$(KBUILD)/libstd_unicode.rlib: rust/src/libstd_unicode/lib.rs $(KBUILD)/libcore.rlib
- $(KRUSTC) $(KRUSTCFLAGS) -o $@ $<
-
-$(KBUILD)/libcollections.rlib: rust/src/libcollections/lib.rs $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/libstd_unicode.rlib
- $(KRUSTC) $(KRUSTCFLAGS) -o $@ $<
-
-$(KBUILD)/libkernel.a: kernel/** $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/libcollections.rlib $(BUILD)/initfs.rs
- $(KCARGO) rustc $(KCARGOFLAGS) -C lto -o $@
-
-$(KBUILD)/libkernel_live.a: kernel/** $(KBUILD)/libcore.rlib $(KBUILD)/liballoc.rlib $(KBUILD)/libcollections.rlib $(BUILD)/initfs.rs build/filesystem.bin
- $(KCARGO) rustc --lib $(KCARGOFLAGS) --cfg 'feature="live"' -C lto --emit obj=$@
-
-$(KBUILD)/kernel: $(KBUILD)/libkernel.a
- $(LD) $(LDFLAGS) -z max-page-size=0x1000 -T arch/$(ARCH)/src/linker.ld -o $@ $<
-
-$(KBUILD)/kernel_live: $(KBUILD)/libkernel_live.a
- $(LD) $(LDFLAGS) -z max-page-size=0x1000 -T arch/$(ARCH)/src/linker.ld -o $@ $<
-
-# Userspace recipes
-$(BUILD)/libstd.rlib: rust/src/libstd/Cargo.toml rust/src/libstd/**
- mkdir -p $(BUILD)
- $(CARGO) rustc --verbose --manifest-path $< $(CARGOFLAGS) -L native=libc-artifacts/lib -o $@
- cp rust/src/target/$(TARGET)/release/deps/*.rlib $(BUILD)
-
-initfs/bin/%: drivers/%/Cargo.toml drivers/%/src/** $(BUILD)/libstd.rlib
- mkdir -p initfs/bin
- $(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@
- strip $@
-
-initfs/bin/%: programs/%/Cargo.toml programs/%/src/** $(BUILD)/libstd.rlib
- mkdir -p initfs/bin
- $(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@
- #strip $@
-
-initfs/bin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib
- mkdir -p initfs/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-$(BUILD)/initfs.rs: \
- initfs/bin/init \
- initfs/bin/ahcid \
- initfs/bin/bgad \
- initfs/bin/pcid \
- initfs/bin/ps2d \
- initfs/bin/redoxfs \
- initfs/bin/vesad \
- initfs/etc/**
- echo 'use collections::BTreeMap;' > $@
- echo 'pub fn gen() -> BTreeMap<&'"'"'static [u8], (&'"'"'static [u8], bool)> {' >> $@
- echo ' let mut files: BTreeMap<&'"'"'static [u8], (&'"'"'static [u8], bool)> = BTreeMap::new();' >> $@
- for folder in `find initfs -type d | sort`; do \
- name=$$(echo $$folder | sed 's/initfs//' | cut -d '/' -f2-) ; \
- $(ECHO) -n ' files.insert(b"'$$name'", (b"' >> $@ ; \
- ls -1 $$folder | sort | awk 'NR > 1 {printf("\\n")} {printf("%s", $$0)}' >> $@ ; \
- echo '", true));' >> $@ ; \
- done
- find initfs -type f -o -type l | cut -d '/' -f2- | sort | awk '{printf(" files.insert(b\"%s\", (include_bytes!(\"../../initfs/%s\"), false));\n", $$0, $$0)}' >> $@
- echo ' files' >> $@
- echo '}' >> $@
-
-filesystem/sbin/%: drivers/%/Cargo.toml drivers/%/src/** $(BUILD)/libstd.rlib
- mkdir -p filesystem/sbin
- $(CARGO) rustc --manifest-path $< $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/%: programs/%/Cargo.toml programs/%/src/** $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/sh: filesystem/bin/ion
- cp $< $@
-
-filesystem/bin/%: programs/binutils/Cargo.toml programs/binutils/src/bin/%.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/%: programs/coreutils/Cargo.toml programs/coreutils/src/bin/%.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/%: programs/extrautils/Cargo.toml programs/extrautils/src/bin/%.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/%: programs/games/Cargo.toml programs/games/src/%/**.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/%: programs/netutils/Cargo.toml programs/netutils/src/%/**.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/ui/bin/%: programs/orbutils/Cargo.toml programs/orbutils/src/%/**.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/ui/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/%: programs/pkgutils/Cargo.toml programs/pkgutils/src/%/**.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/bin/%: programs/userutils/Cargo.toml programs/userutils/src/bin/%.rs $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/sbin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib
- mkdir -p filesystem/sbin
- $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@
- strip $@
-
-filesystem/sbin/redoxfs-mkfs: schemes/redoxfs/Cargo.toml schemes/redoxfs/src/** $(BUILD)/libstd.rlib
- mkdir -p filesystem/bin
- $(CARGO) rustc --manifest-path $< --bin redoxfs-mkfs $(CARGOFLAGS) -o $@
- strip $@
-
-drivers: \
- filesystem/sbin/pcid \
- filesystem/sbin/e1000d \
- filesystem/sbin/rtl8168d
-
-binutils: \
- filesystem/bin/hex \
- filesystem/bin/hexdump \
- filesystem/bin/strings
-
-coreutils: \
- filesystem/bin/basename \
- filesystem/bin/cat \
- filesystem/bin/chmod \
- filesystem/bin/clear \
- filesystem/bin/cp \
- filesystem/bin/cut \
- filesystem/bin/date \
- filesystem/bin/dd \
- filesystem/bin/df \
- filesystem/bin/du \
- filesystem/bin/echo \
- filesystem/bin/env \
- filesystem/bin/false \
- filesystem/bin/free \
- filesystem/bin/head \
- filesystem/bin/kill \
- filesystem/bin/ls \
- filesystem/bin/mkdir \
- filesystem/bin/mv \
- filesystem/bin/printenv \
- filesystem/bin/ps \
- filesystem/bin/pwd \
- filesystem/bin/realpath \
- filesystem/bin/reset \
- filesystem/bin/rmdir \
- filesystem/bin/rm \
- filesystem/bin/seq \
- filesystem/bin/sleep \
- filesystem/bin/sort \
- filesystem/bin/tail \
- filesystem/bin/tee \
- filesystem/bin/time \
- filesystem/bin/touch \
- filesystem/bin/true \
- filesystem/bin/wc \
- filesystem/bin/yes
- #filesystem/bin/shutdown filesystem/bin/test
-
-extrautils: \
- filesystem/bin/calc \
- filesystem/bin/cksum \
- filesystem/bin/cur \
- filesystem/bin/grep \
- filesystem/bin/less \
- filesystem/bin/man \
- filesystem/bin/mdless \
- filesystem/bin/mtxt \
- filesystem/bin/rem \
- #filesystem/bin/dmesg filesystem/bin/info filesystem/bin/watch
-
-games: \
- filesystem/bin/ice \
- filesystem/bin/minesweeper \
- filesystem/bin/reblox \
- filesystem/bin/rusthello \
- filesystem/bin/snake
-
-netutils: \
- filesystem/bin/dhcpd \
- filesystem/bin/dns \
- filesystem/bin/httpd \
- filesystem/bin/irc \
- filesystem/bin/nc \
- filesystem/bin/ntp \
- filesystem/bin/wget
-
-orbutils: \
- filesystem/ui/bin/browser \
- filesystem/ui/bin/calculator \
- filesystem/ui/bin/character_map \
- filesystem/ui/bin/editor \
- filesystem/ui/bin/file_manager \
- filesystem/ui/bin/launcher \
- filesystem/ui/bin/orblogin \
- filesystem/ui/bin/terminal \
- filesystem/ui/bin/viewer
-
-pkgutils: \
- filesystem/bin/pkg
-
-userutils: \
- filesystem/bin/getty \
- filesystem/bin/id \
- filesystem/bin/login \
- filesystem/bin/passwd \
- filesystem/bin/su \
- filesystem/bin/sudo
-
-schemes: \
- filesystem/sbin/ethernetd \
- filesystem/sbin/ipd \
- filesystem/sbin/orbital \
- filesystem/sbin/ptyd \
- filesystem/sbin/randd \
- filesystem/sbin/redoxfs \
- filesystem/sbin/redoxfs-mkfs \
- filesystem/sbin/tcpd \
- filesystem/sbin/udpd
-
-build/filesystem.bin: \
- drivers \
- coreutils \
- extrautils \
- games \
- netutils \
- orbutils \
- pkgutils \
- userutils \
- schemes \
- filesystem/bin/acid \
- filesystem/bin/contain \
- filesystem/bin/ion \
- filesystem/bin/sh \
- filesystem/bin/smith \
- filesystem/bin/tar
- -$(FUMOUNT) build/filesystem/
- rm -rf $@ build/filesystem/
- dd if=/dev/zero of=$@ bs=1M count=128
- cargo run --manifest-path schemes/redoxfs/Cargo.toml --release --bin redoxfs-mkfs $@
- mkdir -p build/filesystem/
- cargo build --manifest-path schemes/redoxfs/Cargo.toml --release --bin redoxfs
- schemes/redoxfs/target/release/redoxfs $@ build/filesystem/
- sleep 2
- pgrep redoxfs
- cp -RL filesystem/* build/filesystem/
- chown -R 0:0 build/filesystem
- chown -R 1000:1000 build/filesystem/home/user
- chmod -R uog+rX build/filesystem
- chmod -R u+w build/filesystem
- chmod -R og-w build/filesystem
- chmod -R 755 build/filesystem/bin
- chmod -R u+rwX build/filesystem/root
- chmod -R og-rwx build/filesystem/root
- chmod -R u+rwX build/filesystem/home/user
- chmod -R og-rwx build/filesystem/home/user
- chmod +s build/filesystem/bin/passwd
- chmod +s build/filesystem/bin/su
- chmod +s build/filesystem/bin/sudo
- mkdir build/filesystem/tmp
- chmod 1777 build/filesystem/tmp
- sync
- -$(FUMOUNT) build/filesystem/
- rm -rf build/filesystem/
-
-mount: FORCE
- mkdir -p build/filesystem/
- cargo build --manifest-path schemes/redoxfs/Cargo.toml --release --bin redoxfs
- schemes/redoxfs/target/release/redoxfs build/harddrive.bin build/filesystem/
- sleep 2
- pgrep redoxfs
-
-unmount: FORCE
- sync
- -$(FUMOUNT) build/filesystem/
- rm -rf build/filesystem/
-
+# Wireshark
wireshark: FORCE
wireshark build/network.pcap
diff --git a/README.md b/README.md
index 82c53ca..8c0b53f 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,40 @@
-
+
**Redox** is an operating system written in Rust, a language with focus on safety and high performance. Redox, following the microkernel design, aims to be secure, usable, and free. Redox is inspired by previous kernels and operating systems, such as SeL4, Minix, Plan 9, and BSD.
-Redox _is not_ just a kernel, it's a full-featured Operating System, providing packages (memory allocator, file system, display manager, core utilities, etc.) that together makes up a functional and convenient operating system. You can loosly think of it as the GNU or BSD ecosystem, but in a memory safe language and with modern technology. See [this list](#ecosystem) for overview of the ecosystem.
+Redox _is not_ just a kernel, it's a **full-featured Operating System**, providing packages (memory allocator, file system, display manager, core utilities, etc.) that together make up a functional and convenient operating system. You can loosely think of it as the GNU or BSD ecosystem, but in a memory safe language and with modern technology. See [this list](#ecosystem) for overview of the ecosystem.
The website can be found at https://www.redox-os.org.
Please make sure you use the **latest nightly** of `rustc` before building (for more troubleshooting, see ["Help! Redox won't compile!"](#compile-help)).
[](https://travis-ci.org/redox-os/redox)
+[](https://github.com/redox-os/redox/releases)
[](./LICENSE.md)
--lightgrey.svg)
+
## Contents
-* [What it looks like](#what-it-looks-like)
+* [What it looks like](#screenshots)
* [Ecosystem](#ecosystem)
* [Help! Redox won't compile](#compile-help)
* [Contributing to Redox](#contributing)
* [Cloning, Building and running](#cloning-building-running)
* [Quick Setup](#quick-setup)
* [Manual Setup](#manual-setup)
+ * [Setup Using Docker](#setup-using-docker)
-## What it looks like
+## What it looks like
-
-
+
+
-
+
## Ecosystem
@@ -40,48 +42,49 @@ The ecosystem and software Redox OS provides is listed below.
| Name (lexicographic order) | Maintainer
|-----------------------------------------------------------------------------|---------------------------
-| [Ion (shell)](https://github.com/redox-os/ion) | [**@skylerberg**](https://github.com/skylerberg) & [**@jackpot51**](https://github.com/jackpot51)
-| [RANSID](https://github.com/redox-os/ransid) | [**@jackpot51**](https://github.com/jackpot51)
-| [Sodium (editor)](https://github.com/redox-os/sodium) | [**@ticki**](https://github.com/ticki)
-| [Standard library](https://github.com/redox-os/libstd) | [**@jackpot51**](https://github.com/jackpot51)
-| [TFS (filesystem)](https://github.com/ticki/tfs) | [**@ticki**](https://github.com/ticki)
-| [The Redox book](https://github.com/redox-os/book) | [**@ticki**](https://github.com/ticki)
-| [The old kernel](https://github.com/redox-os/old) | abandoned
-| [ZFS](https://github.com/redox-os/zfs) | abandoned, superseded by TFS
-| [acid tests](https://github.com/redox-os/acid) | [**@jackpot51**](https://github.com/jackpot51) (co.: [**@ticki**](https://github.com/ticki), [**@nilset](https://github.com/nilset))
+| [acid (kernel integration tests)](https://github.com/redox-os/acid) | [**@jackpot51**](https://github.com/jackpot51) (co.: [**@ticki**](https://github.com/ticki), [**@nilset](https://github.com/nilset))
| [binutils](https://github.com/redox-os/binutils) | [**@ticki**](https://github.com/ticki)
-| [bots (other internal bots)](https://github.com/redox-os/bots) | [**@ticki**](https://github.com/ticki)
+| [bots (custom Mattermost bots)](https://github.com/redox-os/bots) | [**@ticki**](https://github.com/ticki)
| [cookbook](https://github.com/redox-os/cookbook) | [**@jackpot51**](https://github.com/jackpot51)
| [coreutils](https://github.com/redox-os/coreutils) | [**@ticki**](https://github.com/ticki) (co.: [**@stratact**](https://github.com/stratact))
| [extrautils](https://github.com/redox-os/extrautils) | [**@ticki**](https://github.com/ticki)
| [games](https://github.com/redox-os/games) | [**@ticki**](https://github.com/ticki)
+| [Ion (shell)](https://github.com/redox-os/ion) | [**@skylerberg**](https://github.com/skylerberg) & [**@jackpot51**](https://github.com/jackpot51)
| [kernel](https://github.com/redox-os/kernel) | [**@jackpot51**](https://github.com/jackpot51)
| [libextra](https://github.com/redox-os/libextra) | [**@ticki**](https://github.com/ticki)
| [libpager](https://github.com/redox-os/libpager) | [**@ticki**](https://github.com/ticki)
-| [magnet (future package manager)](https://github.com/redox-os/magnet) | [**@ticki**](https://github.com/ticki)
+| [libstd (Redox standard library)](https://github.com/redox-os/libstd) | [**@jackpot51**](https://github.com/jackpot51)
| [netutils](https://github.com/redox-os/netutils) | [**@jackpot51**](https://github.com/jackpot51)
-| [orbclient](https://github.com/redox-os/orbclient) | [**@jackpot51**](https://github.com/jackpot51)
+| [orbclient (Orbital client)](https://github.com/redox-os/orbclient) | [**@jackpot51**](https://github.com/jackpot51)
| [orbdata](https://github.com/redox-os/orbdata) | [**@jackpot51**](https://github.com/jackpot51)
-| [orbital](https://github.com/redox-os/orbital) | [**@jackpot51**](https://github.com/jackpot51)
-| [orbtk](https://github.com/redox-os/orbtk) | [**@stratact**](https://github.com/stratact)
-| [orbutils](https://github.com/redox-os/orbutils) | [**@jackpot51**](https://github.com/jackpot51)
+| [Orbital (windowing and compositing system)](https://github.com/redox-os/orbital) | [**@jackpot51**](https://github.com/jackpot51)
+| [orbtk (Orbital toolkit)](https://github.com/redox-os/orbtk) | [**@stratact**](https://github.com/stratact)
+| [orbutils (Orbital utilities)](https://github.com/redox-os/orbutils) | [**@jackpot51**](https://github.com/jackpot51)
| [pkgutils (current package manager)](https://github.com/redox-os/pkgutils) | [**@jackpot51**](https://github.com/jackpot51)
| [playbot (internal REPL bot)](https://github.com/redox-os/playbot) | [**@ticki**](https://github.com/ticki)
| [ralloc](https://github.com/redox-os/ralloc) | [**@ticki**](https://github.com/ticki)
+| [RANSID (Rust ANSI driver)](https://github.com/redox-os/ransid) | [**@jackpot51**](https://github.com/jackpot51)
| [redoxfs (old filesystem)](https://github.com/redox-os/redoxfs) | [**@jackpot51**](https://github.com/jackpot51)
| [syscall](https://github.com/redox-os/syscall) | [**@jackpot51**](https://github.com/jackpot51)
+| [Sodium (Vim-inspired text editor)](https://github.com/redox-os/sodium) | [**@ticki**](https://github.com/ticki)
| [userutils](https://github.com/redox-os/userutils) | [**@jackpot51**](https://github.com/jackpot51)
+| [TFS (ticki filesystem)](https://github.com/ticki/tfs) | [**@ticki**](https://github.com/ticki)
+| [The Redox book](https://github.com/redox-os/book) | [**@ticki**](https://github.com/ticki)
+| [The old kernel](https://github.com/redox-os/old) | **abandoned**
+| [ZFS](https://github.com/redox-os/zfs) | **abandoned, superseded by [TFS](https://github.com/ticki/tfs)**
## Help! Redox won't compile!
Sometimes things go wrong when compiling. Try the following before opening an issue:
-1. Run `make clean`.
-2. Run `git clean -X -f -d`.
-3. Make sure you have **the latest version of Rust nightly!** ([rustup.rs](https://www.rustup.rs) is recommended for managing Rust versions).
-4. Update **GNU Make**, **NASM** and **QEMU/VirtualBox**.
-5. Pull the upstream master branch (`git remote add upstream git@github.com:redox-os/redox.git; git pull upstream master`).
-6. Update submodules (`git submodule update --recursive --init`).
+1. Make sure you have a redox toolchain (`x86_64-unknown-redox-gcc`).
+ * You can install from .deb packages(`https://static.redox-os.org/toolchain/apt/`) or build [redox-os/libc](https://github.com/redox-os/libc) manually.
+1. Run `rustup update`
+1. Run `make clean pull`.
+1. Make sure you have **the latest version of Rust nightly!** ([rustup.rs](https://www.rustup.rs) is recommended for managing Rust versions. If you already have it, run `rustup`).
+1. Update **GNU Make**, **NASM** and **QEMU/VirtualBox**.
+1. Pull the upstream master branch (`git remote add upstream git@github.com:redox-os/redox.git; git pull upstream master`).
+1. Update submodules (`git submodule update --recursive --init`).
and then rebuild!
@@ -89,9 +92,9 @@ and then rebuild!
If you're interested in this project, and you'd like to help us out, [here](CONTRIBUTING.md) is a list of ways you can do just that.
-## Cloning, Building, and Running
+## Cloning, Building and Running
-Redox is big (even compressed)! So cloning Redox takes a lot of bandwidth, and (depending on your data plan) can be costly, so clone at your own risk!
+Redox is big, even compressed. Downloading the full history may take a lot of bandwidth, and can even be costly on some data plans. Clone at your own risk!
### Quick Setup
@@ -101,6 +104,9 @@ $ cd path/to/your/projects/folder/
# Run bootstrap setup
$ curl -sf https://raw.githubusercontent.com/redox-os/redox/master/bootstrap.sh -o bootstrap.sh && bash -e bootstrap.sh
+#Change to project directory
+$ cd redox
+
# Build Redox
$ make all
@@ -112,11 +118,11 @@ $ make qemu kvm=no
#### QEMU with KVM
-To use QEMU with KVM (kernel-based virtual Machine), which is faster than without KVM, you need a CPU with Intel® Virtualization Technology (Intel® VT) or AMD Virtualization™ (AMD-V™) support. Most systems have this disabled in the BIOS by default, so you may need to reboot and enable the feature in the BIOS.
+To use QEMU with KVM (kernel-based virtual Machine), which is faster than without KVM, you need a CPU with Intel® Virtualization Technology (Intel® VT) or AMD Virtualization™ (AMD-V™) support. Most systems have this disabled by default, so you may need to reboot, go into the BIOS, and enable it.
### Manual Setup
-To manually clone, build and run Redox using a Linux host, run the following commands (with exceptions, be sure to read the comments):
+To manually clone, build and run Redox using a Unix-based host, run the following commands (with exceptions, be sure to read the comments):
```bash
$ cd path/to/your/projects/folder/
@@ -128,7 +134,7 @@ $ git clone git@github.com:redox-os/redox.git --origin upstream --recursive
$ cd redox/
# Install/update dependencies
-$ bash bootstrap.sh -d
+$ ./bootstrap.sh -d
# Install rustup.rs
$ curl https://sh.rustup.rs -sSf | sh
@@ -146,6 +152,22 @@ $ make all
# Launch using QEMU
$ make qemu
+
# Launch using QEMU without using KVM (Kernel Virtual Machine). Try if QEMU gives an error.
$ make qemu kvm=no
+
+# Launch using QEMU without using KVM (Kernel Virtual Machine) nor Graphics
+make qemu kvm=no vga=no
```
+
+### Setup using Docker
+We also provide docker image. After cloning this repository, please follow README under the `docker` directory.
+
+### Updating the codebase using the Makefile
+To update the codebase run:
+
+```
+make pull; make fetch
+```
+
+`make pull` pulls and updates the submodules, and `make fetch` updates the sources for cookbook recipes.
diff --git a/arch/arm/Cargo.toml b/arch/arm/Cargo.toml
deleted file mode 100644
index deadc75..0000000
--- a/arch/arm/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "arch_arm"
-version = "0.1.0"
-
-[dependencies]
-bitflags = "*"
-hole_list_allocator = { path = "../../crates/hole_list_allocator"}
-spin = "*"
diff --git a/arch/arm/src/context.rs b/arch/arm/src/context.rs
deleted file mode 100644
index db711c3..0000000
--- a/arch/arm/src/context.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#[derive(Debug)]
-pub struct Context;
-
-impl Context {
- pub fn new() -> Self {
- Context
- }
-}
-
diff --git a/arch/arm/src/externs.rs b/arch/arm/src/externs.rs
deleted file mode 100644
index 3b87427..0000000
--- a/arch/arm/src/externs.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-/// Memcpy
-///
-/// Copy N bytes of memory from one location to another.
-#[no_mangle]
-pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
- n: usize) -> *mut u8 {
- let mut i = 0;
- while i < n {
- *dest.offset(i as isize) = *src.offset(i as isize);
- i += 1;
- }
-
- dest
-}
-
-/// Memmove
-///
-/// Copy N bytes of memory from src to dest. The memory areas may overlap.
-#[no_mangle]
-pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
- n: usize) -> *mut u8 {
- if src < dest as *const u8 {
- let mut i = n;
- while i != 0 {
- i -= 1;
- *dest.offset(i as isize) = *src.offset(i as isize);
- }
- } else {
- let mut i = 0;
- while i < n {
- *dest.offset(i as isize) = *src.offset(i as isize);
- i += 1;
- }
- }
-
- dest
-}
-
-/// Memset
-///
-/// Fill a block of memory with a specified value.
-#[no_mangle]
-pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
- let mut i = 0;
- while i < n {
- *s.offset(i as isize) = c as u8;
- i += 1;
- }
-
- s
-}
-
-/// Memcmp
-///
-/// Compare two blocks of memory.
-#[no_mangle]
-pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
- let mut i = 0;
-
- while i < n {
- let a = *s1.offset(i as isize);
- let b = *s2.offset(i as isize);
- if a != b {
- return a as i32 - b as i32
- }
- i += 1;
- }
-
- 0
-}
diff --git a/arch/arm/src/interrupt.rs b/arch/arm/src/interrupt.rs
deleted file mode 100644
index 6d7d460..0000000
--- a/arch/arm/src/interrupt.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//! Interrupt instructions
-
-/// Clear interrupts
-#[inline(always)]
-pub unsafe fn disable() {
-}
-
-/// Set interrupts
-#[inline(always)]
-pub unsafe fn enable() {
-}
-
-/// Set interrupts and halt
-#[inline(always)]
-pub unsafe fn enable_and_halt() {
- halt();
-}
-
-/// Halt instruction
-#[inline(always)]
-pub unsafe fn halt() {
- //asm!("wfi" : : : : "volatile");
- asm!("nop" : : : : "volatile");
-}
-
-/// Get a stack trace
-//TODO: Check for stack being mapped before dereferencing
-#[inline(never)]
-pub unsafe fn stack_trace() {
-}
diff --git a/arch/arm/src/lib.rs b/arch/arm/src/lib.rs
deleted file mode 100644
index 77b0e9c..0000000
--- a/arch/arm/src/lib.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-//! Architecture support for ARM
-
-#![feature(asm)]
-#![feature(lang_items)]
-#![feature(naked_functions)]
-#![no_std]
-
-extern crate hole_list_allocator as allocator;
-#[macro_use]
-extern crate bitflags;
-extern crate spin;
-
-/// Print to console
-#[macro_export]
-macro_rules! print {
- ($($arg:tt)*) => ({});
-}
-
-/// Print with new line to console
-#[macro_export]
-macro_rules! println {
- ($fmt:expr) => (print!(concat!($fmt, "\n")));
- ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
-}
-
-/// Context switching
-pub mod context;
-
-/// Memset, memcpy, etc.
-pub mod externs;
-
-/// Interrupt handling
-pub mod interrupt;
-
-/// Panic support
-pub mod panic;
-
-/// Initialization function
-pub mod start;
diff --git a/arch/arm/src/linker.ld b/arch/arm/src/linker.ld
deleted file mode 100644
index 71fd23e..0000000
--- a/arch/arm/src/linker.ld
+++ /dev/null
@@ -1,60 +0,0 @@
-ENTRY(kstart)
-OUTPUT_ARCH(arm)
-OUTPUT_FORMAT(elf32-littlearm)
-
-KERNEL_OFFSET = 0;
-
-SECTIONS {
- . = KERNEL_OFFSET;
-
- .text : AT(ADDR(.text) - KERNEL_OFFSET) {
- __text_start = .;
- *(.text*)
- . = ALIGN(4096);
- __text_end = .;
- }
-
- .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
- __rodata_start = .;
- *(.rodata*)
- . = ALIGN(4096);
- __rodata_end = .;
- }
-
- .data : AT(ADDR(.data) - KERNEL_OFFSET) {
- __data_start = .;
- *(.data*)
- . = ALIGN(4096);
- __data_end = .;
- }
-
- .tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
- __tdata_start = .;
- *(.tdata*)
- . = ALIGN(4096);
- __tdata_end = .;
- __tbss_start = .;
- *(.tbss*)
- . += 8;
- . = ALIGN(4096);
- __tbss_end = .;
- }
-
- .bss : AT(ADDR(.bss) - KERNEL_OFFSET) {
- __bss_start = .;
- *(.bss*)
- . = ALIGN(4096);
- __bss_end = .;
- }
-
- __end = .;
-
- /DISCARD/ : {
- *(.comment*)
- *(.debug*)
- *(.eh_frame*)
- *(.gcc_except_table*)
- *(.note*)
- *(.rel.eh_frame*)
- }
-}
diff --git a/arch/arm/src/panic.rs b/arch/arm/src/panic.rs
deleted file mode 100644
index 2acb38e..0000000
--- a/arch/arm/src/panic.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-//! Intrinsics for panic handling
-
-use interrupt;
-
-#[cfg(not(test))]
-#[lang = "eh_personality"]
-extern "C" fn eh_personality() {}
-
-#[cfg(not(test))]
-/// Required to handle panics
-#[lang = "panic_fmt"]
-extern "C" fn panic_fmt(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
- println!("PANIC: {}", fmt);
- println!("FILE: {}", file);
- println!("LINE: {}", line);
-
- unsafe { interrupt::stack_trace(); }
-
- println!("HALT");
- loop {
- unsafe { interrupt::halt(); }
- }
-}
-
-#[allow(non_snake_case)]
-#[no_mangle]
-/// Required to handle panics
-pub extern "C" fn _Unwind_Resume() -> ! {
- loop {
- unsafe { interrupt::halt(); }
- }
-}
-
-/// Required for linker
-#[no_mangle]
-pub extern "C" fn __aeabi_unwind_cpp_pr0() {
- loop {}
-}
diff --git a/arch/arm/src/start.rs b/arch/arm/src/start.rs
deleted file mode 100644
index b9abbe6..0000000
--- a/arch/arm/src/start.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-const SERIAL_BASE: *mut u8 = 0x16000000 as *mut u8;
-const SERIAL_FLAG_REGISTER: *const u8 = 0x16000018 as *const u8;
-const SERIAL_BUFFER_FULL: u8 = (1 << 5);
-
-unsafe fn putc (c: u8)
-{
- /* Wait until the serial buffer is empty */
- while *SERIAL_FLAG_REGISTER & SERIAL_BUFFER_FULL == SERIAL_BUFFER_FULL {}
-
- /* Put our character, c, into the serial buffer */
- *SERIAL_BASE = c;
-}
-
-unsafe fn puts(string: &str)
-{
- for b in string.bytes() {
- putc(b);
- }
-}
-
-#[no_mangle]
-#[naked]
-pub unsafe extern fn kstart() -> ! {
- asm!("mov sp, 0x18000" : : : : "volatile");
- puts("TEST\r\n");
- loop {}
-}
diff --git a/arch/test/Cargo.toml b/arch/test/Cargo.toml
deleted file mode 100644
index 1900c7d..0000000
--- a/arch/test/Cargo.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[package]
-name = "arch_test"
-version = "0.1.0"
diff --git a/arch/test/src/interrupt.rs b/arch/test/src/interrupt.rs
deleted file mode 100644
index 9e49020..0000000
--- a/arch/test/src/interrupt.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-//! Interrupt instructions
-
-static mut INTERRUPTS_ENABLED: bool = false;
-
-/// Clear interrupts
-#[inline(always)]
-pub unsafe fn disable() {
- println!("CLEAR INTERRUPTS");
- INTERRUPTS_ENABLED = false;
-}
-
-/// Set interrupts
-#[inline(always)]
-pub unsafe fn enable() {
- println!("SET INTERRUPTS");
- INTERRUPTS_ENABLED = true;
-}
-
-/// Halt instruction
-#[inline(always)]
-pub unsafe fn halt() {
- assert!(INTERRUPTS_ENABLED);
- ::std::thread::yield_now();
-}
-
-/// Pause instruction
-#[inline(always)]
-pub unsafe fn pause() {
-
-}
-
-/// Set interrupts and nop
-#[inline(always)]
-pub unsafe fn enable_and_nop() {
- enable();
-}
-
-/// Set interrupts and halt
-#[inline(always)]
-pub unsafe fn enable_and_halt() {
- enable();
- halt();
-}
diff --git a/arch/test/src/lib.rs b/arch/test/src/lib.rs
deleted file mode 100644
index 8a155cd..0000000
--- a/arch/test/src/lib.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-//! Architecture support for testing
-
-pub use std::io;
-
-/// Print to console
-#[macro_export]
-macro_rules! print {
- ($($arg:tt)*) => ({
- use $crate::io::Write;
- let _ = write!($crate::io::stdout(), $($arg)*);
- });
-}
-
-/// Print with new line to console
-#[macro_export]
-macro_rules! println {
- ($fmt:expr) => (print!(concat!($fmt, "\n")));
- ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
-}
-
-/// Create an interrupt function that can safely run rust code
-#[macro_export]
-macro_rules! interrupt {
- ($name:ident, $func:block) => {
- pub unsafe extern fn $name () {
- unsafe fn inner() {
- $func
- }
-
- // Call inner rust function
- inner();
- }
- };
-}
-
-/// Interrupt instructions
-pub mod interrupt;
-
-/// Initialization and main function
-pub mod main;
-
-/// Time functions
-pub mod time;
diff --git a/arch/test/src/main.rs b/arch/test/src/main.rs
deleted file mode 100644
index 3f93ffb..0000000
--- a/arch/test/src/main.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-/// This function is where the kernel sets up IRQ handlers
-/// It is increcibly unsafe, and should be minimal in nature
-
-extern {
- fn kmain() -> !;
-}
-
-#[no_mangle]
-pub unsafe extern fn kstart() -> ! {
- kmain();
-}
diff --git a/arch/test/src/time.rs b/arch/test/src/time.rs
deleted file mode 100644
index 6f7889d..0000000
--- a/arch/test/src/time.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-pub fn monotonic() -> (u64, u64) {
- (0, 0)
-}
-
-pub fn realtime() -> (u64, u64) {
- (0, 0)
-}
diff --git a/arch/x86_64/Cargo.toml b/arch/x86_64/Cargo.toml
deleted file mode 100644
index 695a907..0000000
--- a/arch/x86_64/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "arch_x86_64"
-version = "0.1.0"
-
-[dependencies]
-bitflags = "*"
-hole_list_allocator = { path = "../../crates/hole_list_allocator/" }
-io = { path = "../../crates/io/" }
-raw-cpuid = { git = "https://github.com/gz/rust-cpuid" }
-spin = "*"
-redox_syscall = { path = "../../syscall/" }
-
-[dependencies.x86]
-version = "0.7"
-default-features = false
diff --git a/arch/x86_64/src/acpi/dmar/drhd.rs b/arch/x86_64/src/acpi/dmar/drhd.rs
deleted file mode 100644
index 494917e..0000000
--- a/arch/x86_64/src/acpi/dmar/drhd.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-#[repr(packed)]
-pub struct DrhdFault {
- pub sts: u32,
- pub ctrl: u32,
- pub data: u32,
- pub addr: [u32; 2],
- _rsv: [u64; 2],
- pub log: u64,
-}
-
-#[repr(packed)]
-pub struct DrhdProtectedMemory {
- pub en: u32,
- pub low_base: u32,
- pub low_limit: u32,
- pub high_base: u64,
- pub high_limit: u64,
-}
-
-#[repr(packed)]
-pub struct DrhdInvalidation {
- pub queue_head: u64,
- pub queue_tail: u64,
- pub queue_addr: u64,
- _rsv: u32,
- pub cmpl_sts: u32,
- pub cmpl_ctrl: u32,
- pub cmpl_data: u32,
- pub cmpl_addr: [u32; 2],
-}
-
-#[repr(packed)]
-pub struct DrhdPageRequest {
- pub queue_head: u64,
- pub queue_tail: u64,
- pub queue_addr: u64,
- _rsv: u32,
- pub sts: u32,
- pub ctrl: u32,
- pub data: u32,
- pub addr: [u32; 2],
-}
-
-#[repr(packed)]
-pub struct DrhdMtrrVariable {
- pub base: u64,
- pub mask: u64,
-}
-
-#[repr(packed)]
-pub struct DrhdMtrr {
- pub cap: u64,
- pub def_type: u64,
- pub fixed: [u64; 11],
- pub variable: [DrhdMtrrVariable; 10],
-}
-
-#[repr(packed)]
-pub struct Drhd {
- pub version: u32,
- _rsv: u32,
- pub cap: u64,
- pub ext_cap: u64,
- pub gl_cmd: u32,
- pub gl_sts: u32,
- pub root_table: u64,
- pub ctx_cmd: u64,
- _rsv1: u32,
- pub fault: DrhdFault,
- _rsv2: u32,
- pub pm: DrhdProtectedMemory,
- pub invl: DrhdInvalidation,
- _rsv3: u64,
- pub intr_table: u64,
- pub page_req: DrhdPageRequest,
- pub mtrr: DrhdMtrr,
-}
diff --git a/arch/x86_64/src/acpi/dmar/mod.rs b/arch/x86_64/src/acpi/dmar/mod.rs
deleted file mode 100644
index d13184f..0000000
--- a/arch/x86_64/src/acpi/dmar/mod.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-use core::mem;
-
-use super::sdt::Sdt;
-use self::drhd::Drhd;
-use memory::Frame;
-use paging::{entry, ActivePageTable, PhysicalAddress};
-
-pub mod drhd;
-
-/// The DMA Remapping Table
-#[derive(Debug)]
-pub struct Dmar {
- sdt: &'static Sdt,
- pub addr_width: u8,
- pub flags: u8,
- _rsv: [u8; 10],
-}
-
-impl Dmar {
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"DMAR" && sdt.data_len() >= 12 { //Not valid if no local address and flags
- let addr_width = unsafe { *(sdt.data_address() as *const u8) };
- let flags = unsafe { *(sdt.data_address() as *const u8).offset(1) };
- let rsv: [u8; 10] = unsafe { *((sdt.data_address() as *const u8).offset(2) as *const [u8; 10]) };
-
- Some(Dmar {
- sdt: sdt,
- addr_width: addr_width,
- flags: flags,
- _rsv: rsv,
- })
- } else {
- None
- }
- }
-
- pub fn iter(&self) -> DmarIter {
- DmarIter {
- sdt: self.sdt,
- i: 12 // Skip address width and flags
- }
- }
-}
-
-///
-
-/// DMAR DMA Remapping Hardware Unit Definition
-// TODO: Implement iterator on DmarDrhd scope
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarDrhd {
- kind: u16,
- length: u16,
- flags: u8,
- _rsv: u8,
- segment: u16,
- base: u64,
-}
-
-impl DmarDrhd {
- pub fn get(&self, active_table: &mut ActivePageTable) -> &'static mut Drhd {
- active_table.identity_map(Frame::containing_address(PhysicalAddress::new(self.base as usize)), entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
- unsafe { &mut *(self.base as *mut Drhd) }
- }
-}
-
-/// DMAR Reserved Memory Region Reporting
-// TODO: Implement iterator on DmarRmrr scope
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarRmrr {
- kind: u16,
- length: u16,
- _rsv: u16,
- segment: u16,
- base: u64,
- limit: u64,
-}
-
-/// DMAR Root Port ATS Capability Reporting
-// TODO: Implement iterator on DmarAtsr scope
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarAtsr {
- kind: u16,
- length: u16,
- flags: u8,
- _rsv: u8,
- segment: u16,
-}
-
-/// DMAR Remapping Hardware Static Affinity
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarRhsa {
- kind: u16,
- length: u16,
- _rsv: u32,
- base: u64,
- domain: u32,
-}
-
-/// DMAR ACPI Name-space Device Declaration
-// TODO: Implement iterator on DmarAndd object name
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarAndd {
- kind: u16,
- length: u16,
- _rsv: [u8; 3],
- acpi_dev: u8,
-}
-
-/// DMAR Entries
-#[derive(Debug)]
-pub enum DmarEntry {
- Drhd(&'static DmarDrhd),
- InvalidDrhd(usize),
- Rmrr(&'static DmarRmrr),
- InvalidRmrr(usize),
- Atsr(&'static DmarAtsr),
- InvalidAtsr(usize),
- Rhsa(&'static DmarRhsa),
- InvalidRhsa(usize),
- Andd(&'static DmarAndd),
- InvalidAndd(usize),
- Unknown(u16)
-}
-
-pub struct DmarIter {
- sdt: &'static Sdt,
- i: usize
-}
-
-impl Iterator for DmarIter {
- type Item = DmarEntry;
- fn next(&mut self) -> Option {
- if self.i + 4 <= self.sdt.data_len() {
- let entry_type = unsafe { *((self.sdt.data_address() as *const u8).offset(self.i as isize) as *const u16) };
- let entry_len = unsafe { *((self.sdt.data_address() as *const u8).offset(self.i as isize + 2) as *const u16) } as usize;
-
- if self.i + entry_len <= self.sdt.data_len() {
- let item = match entry_type {
- 0 => if entry_len >= mem::size_of::() {
- DmarEntry::Drhd(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarDrhd) })
- } else {
- DmarEntry::InvalidDrhd(entry_len)
- },
- 1 => if entry_len >= mem::size_of::() {
- DmarEntry::Rmrr(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarRmrr) })
- } else {
- DmarEntry::InvalidRmrr(entry_len)
- },
- 2 => if entry_len >= mem::size_of::() {
- DmarEntry::Atsr(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarAtsr) })
- } else {
- DmarEntry::InvalidAtsr(entry_len)
- },
- 3 => if entry_len == mem::size_of::() {
- DmarEntry::Rhsa(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarRhsa) })
- } else {
- DmarEntry::InvalidRhsa(entry_len)
- },
- 4 => if entry_len >= mem::size_of::() {
- DmarEntry::Andd(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarAndd) })
- } else {
- DmarEntry::InvalidAndd(entry_len)
- },
- _ => DmarEntry::Unknown(entry_type)
- };
-
- self.i += entry_len;
-
- Some(item)
- } else {
- None
- }
- } else {
- None
- }
- }
-}
diff --git a/arch/x86_64/src/acpi/fadt.rs b/arch/x86_64/src/acpi/fadt.rs
deleted file mode 100644
index d40d5a1..0000000
--- a/arch/x86_64/src/acpi/fadt.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-use core::{mem, ptr};
-
-use super::sdt::Sdt;
-
-#[repr(packed)]
-#[derive(Debug)]
-pub struct Fadt {
- pub header: Sdt,
- pub firmware_ctrl: u32,
- pub dsdt: u32,
-
- // field used in ACPI 1.0; no longer in use, for compatibility only
- reserved: u8,
-
- pub preferred_power_managament: u8,
- pub sci_interrupt: u16,
- pub smi_command_port: u32,
- pub acpi_enable: u8,
- pub acpi_disable: u8,
- pub s4_bios_req: u8,
- pub pstate_control: u8,
- pub pm1a_event_block: u32,
- pub pm1b_event_block: u32,
- pub pm1a_control_block: u32,
- pub pm1b_control_block: u32,
- pub pm2_control_block: u32,
- pub pm_timer_block: u32,
- pub gpe0_block: u32,
- pub gpe1_block: u32,
- pub pm1_event_length: u8,
- pub pm1_control_length: u8,
- pub pm2_control_length: u8,
- pub pm_timer_length: u8,
- pub gpe0_ength: u8,
- pub gpe1_length: u8,
- pub gpe1_base: u8,
- pub c_state_control: u8,
- pub worst_c2_latency: u16,
- pub worst_c3_latency: u16,
- pub flush_size: u16,
- pub flush_stride: u16,
- pub duty_offset: u8,
- pub duty_width: u8,
- pub day_alarm: u8,
- pub month_alarm: u8,
- pub century: u8,
-
- // reserved in ACPI 1.0; used since ACPI 2.0+
- pub boot_architecture_flags: u16,
-
- reserved2: u8,
- pub flags: u32,
-}
-
-/* ACPI 2 structure
-#[repr(packed)]
-#[derive(Clone, Copy, Debug, Default)]
-pub struct GenericAddressStructure {
- address_space: u8,
- bit_width: u8,
- bit_offset: u8,
- access_size: u8,
- address: u64,
-}
-
-{
- // 12 byte structure; see below for details
- pub reset_reg: GenericAddressStructure,
-
- pub reset_value: u8,
- reserved3: [u8; 3],
-
- // 64bit pointers - Available on ACPI 2.0+
- pub x_firmware_control: u64,
- pub x_dsdt: u64,
-
- pub x_pm1a_event_block: GenericAddressStructure,
- pub x_pm1b_event_block: GenericAddressStructure,
- pub x_pm1a_control_block: GenericAddressStructure,
- pub x_pm1b_control_block: GenericAddressStructure,
- pub x_pm2_control_block: GenericAddressStructure,
- pub x_pm_timer_block: GenericAddressStructure,
- pub x_gpe0_block: GenericAddressStructure,
- pub x_gpe1_block: GenericAddressStructure,
-}
-*/
-
-impl Fadt {
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"FACP" && sdt.length as usize >= mem::size_of::() {
- Some(unsafe { ptr::read((sdt as *const Sdt) as *const Fadt) })
- } else {
- None
- }
- }
-}
diff --git a/arch/x86_64/src/acpi/madt.rs b/arch/x86_64/src/acpi/madt.rs
deleted file mode 100644
index dac16dc..0000000
--- a/arch/x86_64/src/acpi/madt.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use core::mem;
-
-use super::sdt::Sdt;
-
-/// The Multiple APIC Descriptor Table
-#[derive(Debug)]
-pub struct Madt {
- sdt: &'static Sdt,
- pub local_address: u32,
- pub flags: u32
-}
-
-impl Madt {
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"APIC" && sdt.data_len() >= 8 { //Not valid if no local address and flags
- let local_address = unsafe { *(sdt.data_address() as *const u32) };
- let flags = unsafe { *(sdt.data_address() as *const u32).offset(1) };
-
- Some(Madt {
- sdt: sdt,
- local_address: local_address,
- flags: flags
- })
- } else {
- None
- }
- }
-
- pub fn iter(&self) -> MadtIter {
- MadtIter {
- sdt: self.sdt,
- i: 8 // Skip local controller address and flags
- }
- }
-}
-
-///
-
-/// MADT Local APIC
-#[derive(Debug)]
-#[repr(packed)]
-pub struct MadtLocalApic {
- /// Processor ID
- pub processor: u8,
- /// Local APIC ID
- pub id: u8,
- /// Flags. 1 means that the processor is enabled
- pub flags: u32
-}
-
-/// MADT I/O APIC
-#[derive(Debug)]
-#[repr(packed)]
-pub struct MadtIoApic {
- /// I/O APIC ID
- pub id: u8,
- /// reserved
- reserved: u8,
- /// I/O APIC address
- pub address: u32,
- /// Global system interrupt base
- pub gsi_base: u32
-}
-
-/// MADT Interrupt Source Override
-#[derive(Debug)]
-#[repr(packed)]
-pub struct MadtIntSrcOverride {
- /// Bus Source
- pub bus_source: u8,
- /// IRQ Source
- pub irq_source: u8,
- /// Global system interrupt base
- pub gsi_base: u32,
- /// Flags
- pub flags: u16
-}
-
-/// MADT Entries
-#[derive(Debug)]
-pub enum MadtEntry {
- LocalApic(&'static MadtLocalApic),
- InvalidLocalApic(usize),
- IoApic(&'static MadtIoApic),
- InvalidIoApic(usize),
- IntSrcOverride(&'static MadtIntSrcOverride),
- InvalidIntSrcOverride(usize),
- Unknown(u8)
-}
-
-pub struct MadtIter {
- sdt: &'static Sdt,
- i: usize
-}
-
-impl Iterator for MadtIter {
- type Item = MadtEntry;
- fn next(&mut self) -> Option {
- if self.i + 1 < self.sdt.data_len() {
- let entry_type = unsafe { *(self.sdt.data_address() as *const u8).offset(self.i as isize) };
- let entry_len = unsafe { *(self.sdt.data_address() as *const u8).offset(self.i as isize + 1) } as usize;
-
- if self.i + entry_len <= self.sdt.data_len() {
- let item = match entry_type {
- 0 => if entry_len == mem::size_of::() + 2 {
- MadtEntry::LocalApic(unsafe { &*((self.sdt.data_address() + self.i + 2) as *const MadtLocalApic) })
- } else {
- MadtEntry::InvalidLocalApic(entry_len)
- },
- 1 => if entry_len == mem::size_of::() + 2 {
- MadtEntry::IoApic(unsafe { &*((self.sdt.data_address() + self.i + 2) as *const MadtIoApic) })
- } else {
- MadtEntry::InvalidIoApic(entry_len)
- },
- 2 => if entry_len == mem::size_of::() + 2 {
- MadtEntry::IntSrcOverride(unsafe { &*((self.sdt.data_address() + self.i + 2) as *const MadtIntSrcOverride) })
- } else {
- MadtEntry::InvalidIntSrcOverride(entry_len)
- },
- _ => MadtEntry::Unknown(entry_type)
- };
-
- self.i += entry_len;
-
- Some(item)
- } else {
- None
- }
- } else {
- None
- }
- }
-}
diff --git a/arch/x86_64/src/acpi/mod.rs b/arch/x86_64/src/acpi/mod.rs
deleted file mode 100644
index 87f4416..0000000
--- a/arch/x86_64/src/acpi/mod.rs
+++ /dev/null
@@ -1,284 +0,0 @@
-//! # ACPI
-//! Code to parse the ACPI tables
-
-use core::intrinsics::{atomic_load, atomic_store};
-use core::sync::atomic::Ordering;
-
-use device::local_apic::LOCAL_APIC;
-use interrupt;
-use memory::{allocate_frames, Frame};
-use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
-use start::{kstart_ap, CPU_COUNT, AP_READY};
-
-use self::dmar::{Dmar, DmarEntry};
-use self::fadt::Fadt;
-use self::madt::{Madt, MadtEntry};
-use self::rsdt::Rsdt;
-use self::sdt::Sdt;
-use self::xsdt::Xsdt;
-
-pub mod dmar;
-pub mod fadt;
-pub mod madt;
-pub mod rsdt;
-pub mod sdt;
-pub mod xsdt;
-
-const TRAMPOLINE: usize = 0x7E00;
-const AP_STARTUP: usize = TRAMPOLINE + 512;
-
-pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
- print!(" ");
- for &c in sdt.signature.iter() {
- print!("{}", c as char);
- }
-
- if let Some(fadt) = Fadt::new(sdt) {
- println!(": {:#?}", fadt);
- } else if let Some(madt) = Madt::new(sdt) {
- println!(": {:>08X}: {}", madt.local_address, madt.flags);
-
- let mut local_apic = unsafe { &mut LOCAL_APIC };
-
- let me = local_apic.id() as u8;
-
- if local_apic.x2 {
- println!(" X2APIC {}", me);
- } else {
- println!(" XAPIC {}: {:>08X}", me, local_apic.address);
- }
-
- let trampoline_frame = Frame::containing_address(PhysicalAddress::new(TRAMPOLINE));
- let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
-
- // Map trampoline
- active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
- active_table.flush(trampoline_page);
-
- for madt_entry in madt.iter() {
- println!(" {:?}", madt_entry);
- match madt_entry {
- MadtEntry::LocalApic(ap_local_apic) => if ap_local_apic.id == me {
- println!(" This is my local APIC");
- } else {
- if ap_local_apic.flags & 1 == 1 {
- // Increase CPU ID
- CPU_COUNT.fetch_add(1, Ordering::SeqCst);
-
- // Allocate a stack
- let stack_start = allocate_frames(64).expect("no more frames in acpi stack_start").start_address().get() + ::KERNEL_OFFSET;
- let stack_end = stack_start + 64 * 4096;
-
- let ap_ready = TRAMPOLINE as *mut u64;
- let ap_cpu_id = unsafe { ap_ready.offset(1) };
- let ap_page_table = unsafe { ap_ready.offset(2) };
- let ap_stack_start = unsafe { ap_ready.offset(3) };
- let ap_stack_end = unsafe { ap_ready.offset(4) };
- let ap_code = unsafe { ap_ready.offset(5) };
-
- // Set the ap_ready to 0, volatile
- unsafe { atomic_store(ap_ready, 0) };
- unsafe { atomic_store(ap_cpu_id, ap_local_apic.id as u64) };
- unsafe { atomic_store(ap_page_table, active_table.address() as u64) };
- unsafe { atomic_store(ap_stack_start, stack_start as u64) };
- unsafe { atomic_store(ap_stack_end, stack_end as u64) };
- unsafe { atomic_store(ap_code, kstart_ap as u64) };
- AP_READY.store(false, Ordering::SeqCst);
-
- print!(" AP {}:", ap_local_apic.id);
-
- // Send INIT IPI
- {
- let mut icr = 0x4500;
- if local_apic.x2 {
- icr |= (ap_local_apic.id as u64) << 32;
- } else {
- icr |= (ap_local_apic.id as u64) << 56;
- }
- print!(" IPI...");
- local_apic.set_icr(icr);
- }
-
- // Send START IPI
- {
- //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
- let ap_segment = (AP_STARTUP >> 12) & 0xFF;
- let mut icr = 0x4600 | ap_segment as u64;
-
- if local_apic.x2 {
- icr |= (ap_local_apic.id as u64) << 32;
- } else {
- icr |= (ap_local_apic.id as u64) << 56;
- }
-
- print!(" SIPI...");
- local_apic.set_icr(icr);
- }
-
- // Wait for trampoline ready
- print!(" Wait...");
- while unsafe { atomic_load(ap_ready) } == 0 {
- interrupt::pause();
- }
- print!(" Trampoline...");
- while ! AP_READY.load(Ordering::SeqCst) {
- interrupt::pause();
- }
- println!(" Ready");
-
- active_table.flush_all();
- } else {
- println!(" CPU Disabled");
- }
- },
- _ => ()
- }
- }
-
- // Unmap trampoline
- active_table.unmap(trampoline_page);
- active_table.flush(trampoline_page);
- } else if let Some(dmar) = Dmar::new(sdt) {
- println!(": {}: {}", dmar.addr_width, dmar.flags);
-
- for dmar_entry in dmar.iter() {
- println!(" {:?}", dmar_entry);
- match dmar_entry {
- DmarEntry::Drhd(dmar_drhd) => {
- let drhd = dmar_drhd.get(active_table);
-
- println!("VER: {:X}", drhd.version);
- println!("CAP: {:X}", drhd.cap);
- println!("EXT_CAP: {:X}", drhd.ext_cap);
- println!("GCMD: {:X}", drhd.gl_cmd);
- println!("GSTS: {:X}", drhd.gl_sts);
- println!("RT: {:X}", drhd.root_table);
- },
- _ => ()
- }
- }
- } else {
- println!(": Unknown");
- }
-}
-
-/// Parse the ACPI tables to gather CPU, interrupt, and timer information
-pub unsafe fn init(active_table: &mut ActivePageTable) -> Option {
- let start_addr = 0xE0000;
- let end_addr = 0xFFFFF;
-
- // Map all of the ACPI RSDP space
- {
- let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
- let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
- for frame in Frame::range_inclusive(start_frame, end_frame) {
- let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
- active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
- active_table.flush(page);
- }
- }
-
- // Search for RSDP
- if let Some(rsdp) = RSDP::search(start_addr, end_addr) {
- let get_sdt = |sdt_address: usize, active_table: &mut ActivePageTable| -> (&'static Sdt, bool) {
- let mapped = if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() {
- let sdt_frame = Frame::containing_address(PhysicalAddress::new(sdt_address));
- let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
- active_table.map_to(sdt_page, sdt_frame, entry::PRESENT | entry::NO_EXECUTE);
- active_table.flush(sdt_page);
- true
- } else {
- false
- };
- (&*(sdt_address as *const Sdt), mapped)
- };
-
- let drop_sdt = |sdt: &'static Sdt, mapped: bool, active_table: &mut ActivePageTable| {
- let sdt_address = sdt as *const Sdt as usize;
- drop(sdt);
- if mapped {
- let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
- active_table.unmap(sdt_page);
- active_table.flush(sdt_page);
- }
- };
-
- let (rxsdt, rxmapped) = get_sdt(rsdp.sdt_address(), active_table);
-
- for &c in rxsdt.signature.iter() {
- print!("{}", c as char);
- }
- println!(":");
- if let Some(rsdt) = Rsdt::new(rxsdt) {
- for sdt_address in rsdt.iter() {
- let (sdt, mapped) = get_sdt(sdt_address, active_table);
- init_sdt(sdt, active_table);
- drop_sdt(sdt, mapped, active_table);
- }
- } else if let Some(xsdt) = Xsdt::new(rxsdt) {
- for sdt_address in xsdt.iter() {
- let (sdt, mapped) = get_sdt(sdt_address, active_table);
- init_sdt(sdt, active_table);
- drop_sdt(sdt, mapped, active_table);
- }
- } else {
- println!("UNKNOWN RSDT OR XSDT SIGNATURE");
- }
-
- drop_sdt(rxsdt, rxmapped, active_table);
- } else {
- println!("NO RSDP FOUND");
- }
-
- // Unmap all of the ACPI RSDP space
- {
- let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
- let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
- for frame in Frame::range_inclusive(start_frame, end_frame) {
- let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
- active_table.unmap(page);
- active_table.flush(page);
- }
- }
-
- None
-}
-
-pub struct Acpi;
-
-/// RSDP
-#[derive(Copy, Clone, Debug)]
-#[repr(packed)]
-pub struct RSDP {
- signature: [u8; 8],
- checksum: u8,
- oemid: [u8; 6],
- revision: u8,
- rsdt_address: u32,
- length: u32,
- xsdt_address: u64,
- extended_checksum: u8,
- reserved: [u8; 3]
-}
-
-impl RSDP {
- /// Search for the RSDP
- pub fn search(start_addr: usize, end_addr: usize) -> Option {
- for i in 0 .. (end_addr + 1 - start_addr)/16 {
- let rsdp = unsafe { &*((start_addr + i * 16) as *const RSDP) };
- if &rsdp.signature == b"RSD PTR " {
- return Some(*rsdp);
- }
- }
- None
- }
-
- /// Get the RSDT or XSDT address
- pub fn sdt_address(&self) -> usize {
- if self.revision >= 2 {
- self.xsdt_address as usize
- } else {
- self.rsdt_address as usize
- }
- }
-}
diff --git a/arch/x86_64/src/acpi/rsdt.rs b/arch/x86_64/src/acpi/rsdt.rs
deleted file mode 100644
index fa391c0..0000000
--- a/arch/x86_64/src/acpi/rsdt.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use core::mem;
-
-use super::sdt::Sdt;
-
-#[derive(Debug)]
-pub struct Rsdt(&'static Sdt);
-
-impl Rsdt {
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"RSDT" {
- Some(Rsdt(sdt))
- } else {
- None
- }
- }
-
- pub fn iter(&self) -> RsdtIter {
- RsdtIter {
- sdt: self.0,
- i: 0
- }
- }
-}
-
-pub struct RsdtIter {
- sdt: &'static Sdt,
- i: usize
-}
-
-impl Iterator for RsdtIter {
- type Item = usize;
- fn next(&mut self) -> Option {
- if self.i < self.sdt.data_len()/mem::size_of::() {
- let item = unsafe { *(self.sdt.data_address() as *const u32).offset(self.i as isize) };
- self.i += 1;
- Some(item as usize)
- } else {
- None
- }
- }
-}
diff --git a/arch/x86_64/src/acpi/sdt.rs b/arch/x86_64/src/acpi/sdt.rs
deleted file mode 100644
index 0d8cedd..0000000
--- a/arch/x86_64/src/acpi/sdt.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-use core::mem;
-
-#[derive(Copy, Clone, Debug)]
-#[repr(packed)]
-pub struct Sdt {
- pub signature: [u8; 4],
- pub length: u32,
- pub revision: u8,
- pub checksum: u8,
- pub oem_id: [u8; 6],
- pub oem_table_id: [u8; 8],
- pub oem_revision: u32,
- pub creator_id: u32,
- pub creator_revision: u32
-}
-
-impl Sdt {
- /// Get the address of this tables data
- pub fn data_address(&'static self) -> usize {
- self as *const _ as usize + mem::size_of::()
- }
-
- /// Get the length of this tables data
- pub fn data_len(&'static self) -> usize {
- let total_size = self.length as usize;
- let header_size = mem::size_of::();
- if total_size >= header_size {
- total_size - header_size
- } else {
- 0
- }
- }
-}
diff --git a/arch/x86_64/src/acpi/xsdt.rs b/arch/x86_64/src/acpi/xsdt.rs
deleted file mode 100644
index 5ec6036..0000000
--- a/arch/x86_64/src/acpi/xsdt.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use core::mem;
-
-use super::sdt::Sdt;
-
-#[derive(Debug)]
-pub struct Xsdt(&'static Sdt);
-
-impl Xsdt {
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"XSDT" {
- Some(Xsdt(sdt))
- } else {
- None
- }
- }
-
- pub fn iter(&self) -> XsdtIter {
- XsdtIter {
- sdt: self.0,
- i: 0
- }
- }
-}
-
-pub struct XsdtIter {
- sdt: &'static Sdt,
- i: usize
-}
-
-impl Iterator for XsdtIter {
- type Item = usize;
- fn next(&mut self) -> Option {
- if self.i < self.sdt.data_len()/mem::size_of::() {
- let item = unsafe { *(self.sdt.data_address() as *const u64).offset(self.i as isize) };
- self.i += 1;
- Some(item as usize)
- } else {
- None
- }
- }
-}
diff --git a/arch/x86_64/src/console.rs b/arch/x86_64/src/console.rs
deleted file mode 100644
index 92f28d8..0000000
--- a/arch/x86_64/src/console.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use core::fmt::{self, Write};
-use spin::Mutex;
-
-use device::serial::COM1;
-
-pub static CONSOLE: Mutex = Mutex::new(Console);
-
-pub struct Console;
-
-impl Write for Console {
- fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
- COM1.lock().write_str(s)
- }
-}
diff --git a/arch/x86_64/src/context.rs b/arch/x86_64/src/context.rs
deleted file mode 100644
index 2a8242d..0000000
--- a/arch/x86_64/src/context.rs
+++ /dev/null
@@ -1,184 +0,0 @@
-use core::mem;
-use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
-
-/// This must be used by the kernel to ensure that context switches are done atomically
-/// Compare and exchange this to true when beginning a context switch on any CPU
-/// The Context::switch_to function will set it back to false, allowing other CPU's to switch
-/// This must be done, as no locks can be held on the stack during switch
-pub static CONTEXT_SWITCH_LOCK: AtomicBool = ATOMIC_BOOL_INIT;
-
-#[derive(Clone, Debug)]
-pub struct Context {
- /// FX valid?
- loadable: bool,
- /// FX location
- fx: usize,
- /// Page table pointer
- cr3: usize,
- /// RFLAGS register
- rflags: usize,
- /// RBX register
- rbx: usize,
- /// R12 register
- r12: usize,
- /// R13 register
- r13: usize,
- /// R14 register
- r14: usize,
- /// R15 register
- r15: usize,
- /// Base pointer
- rbp: usize,
- /// Stack pointer
- rsp: usize
-}
-
-impl Context {
- pub fn new() -> Context {
- Context {
- loadable: false,
- fx: 0,
- cr3: 0,
- rflags: 0,
- rbx: 0,
- r12: 0,
- r13: 0,
- r14: 0,
- r15: 0,
- rbp: 0,
- rsp: 0
- }
- }
-
- pub fn get_page_table(&self) -> usize {
- self.cr3
- }
-
- pub fn set_fx(&mut self, address: usize) {
- self.fx = address;
- }
-
- pub fn set_page_table(&mut self, address: usize) {
- self.cr3 = address;
- }
-
- pub fn set_stack(&mut self, address: usize) {
- self.rsp = address;
- }
-
- pub unsafe fn signal_stack(&mut self, handler: extern fn(usize), sig: u8) {
- self.push_stack(sig as usize);
- self.push_stack(handler as usize);
- self.push_stack(signal_handler_wrapper as usize);
- }
-
- pub unsafe fn push_stack(&mut self, value: usize) {
- self.rsp -= mem::size_of::();
- *(self.rsp as *mut usize) = value;
- }
-
- pub unsafe fn pop_stack(&mut self) -> usize {
- let value = *(self.rsp as *const usize);
- self.rsp += mem::size_of::();
- value
- }
-
- /// Switch to the next context by restoring its stack and registers
- #[cold]
- #[inline(never)]
- #[naked]
- pub unsafe fn switch_to(&mut self, next: &mut Context) {
- asm!("fxsave [$0]" : : "r"(self.fx) : "memory" : "intel", "volatile");
- self.loadable = true;
- if next.loadable {
- asm!("fxrstor [$0]" : : "r"(next.fx) : "memory" : "intel", "volatile");
- }else{
- asm!("fninit" : : : "memory" : "intel", "volatile");
- }
-
- asm!("mov $0, cr3" : "=r"(self.cr3) : : "memory" : "intel", "volatile");
- if next.cr3 != self.cr3 {
- asm!("mov cr3, $0" : : "r"(next.cr3) : "memory" : "intel", "volatile");
- }
-
- asm!("pushfq ; pop $0" : "=r"(self.rflags) : : "memory" : "intel", "volatile");
- asm!("push $0 ; popfq" : : "r"(next.rflags) : "memory" : "intel", "volatile");
-
- asm!("mov $0, rbx" : "=r"(self.rbx) : : "memory" : "intel", "volatile");
- asm!("mov rbx, $0" : : "r"(next.rbx) : "memory" : "intel", "volatile");
-
- asm!("mov $0, r12" : "=r"(self.r12) : : "memory" : "intel", "volatile");
- asm!("mov r12, $0" : : "r"(next.r12) : "memory" : "intel", "volatile");
-
- asm!("mov $0, r13" : "=r"(self.r13) : : "memory" : "intel", "volatile");
- asm!("mov r13, $0" : : "r"(next.r13) : "memory" : "intel", "volatile");
-
- asm!("mov $0, r14" : "=r"(self.r14) : : "memory" : "intel", "volatile");
- asm!("mov r14, $0" : : "r"(next.r14) : "memory" : "intel", "volatile");
-
- asm!("mov $0, r15" : "=r"(self.r15) : : "memory" : "intel", "volatile");
- asm!("mov r15, $0" : : "r"(next.r15) : "memory" : "intel", "volatile");
-
- asm!("mov $0, rsp" : "=r"(self.rsp) : : "memory" : "intel", "volatile");
- asm!("mov rsp, $0" : : "r"(next.rsp) : "memory" : "intel", "volatile");
-
- asm!("mov $0, rbp" : "=r"(self.rbp) : : "memory" : "intel", "volatile");
- asm!("mov rbp, $0" : : "r"(next.rbp) : "memory" : "intel", "volatile");
- }
-}
-
-#[repr(packed)]
-pub struct SignalHandlerStack {
- r11: usize,
- r10: usize,
- r9: usize,
- r8: usize,
- rsi: usize,
- rdi: usize,
- rdx: usize,
- rcx: usize,
- rax: usize,
- handler: extern fn(usize),
- sig: usize,
- rip: usize,
-}
-
-#[naked]
-unsafe extern fn signal_handler_wrapper() {
- #[inline(never)]
- unsafe fn inner(stack: &SignalHandlerStack) {
- (stack.handler)(stack.sig);
- }
-
- // Push scratch registers
- asm!("push rax
- push rcx
- push rdx
- push rdi
- push rsi
- push r8
- push r9
- push r10
- push r11"
- : : : : "intel", "volatile");
-
- // Get reference to stack variables
- let rsp: usize;
- asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
-
- // Call inner rust function
- inner(&*(rsp as *const SignalHandlerStack));
-
- // Pop scratch registers, error code, and return
- asm!("pop r11
- pop r10
- pop r9
- pop r8
- pop rsi
- pop rdi
- pop rdx
- pop rcx
- pop rax
- add rsp, 16"
- : : : : "intel", "volatile");
-}
diff --git a/arch/x86_64/src/device/cpu.rs b/arch/x86_64/src/device/cpu.rs
deleted file mode 100644
index e48547b..0000000
--- a/arch/x86_64/src/device/cpu.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-extern crate raw_cpuid;
-
-use core::fmt::{Result, Write};
-
-use self::raw_cpuid::CpuId;
-
-pub fn cpu_info(w: &mut W) -> Result {
- let cpuid = CpuId::new();
-
- if let Some(info) = cpuid.get_vendor_info() {
- write!(w, "Vendor: {}\n", info.as_string())?;
- }
-
- if let Some(info) = cpuid.get_extended_function_info() {
- if let Some(brand) = info.processor_brand_string() {
- write!(w, "Model: {}\n", brand)?;
- }
- }
-
- if let Some(info) = cpuid.get_processor_frequency_info() {
- write!(w, "CPU Base MHz: {}\n", info.processor_base_frequency())?;
- write!(w, "CPU Max MHz: {}\n", info.processor_max_frequency())?;
- write!(w, "Bus MHz: {}\n", info.bus_frequency())?;
- }
-
- write!(w, "Features:")?;
-
- if let Some(info) = cpuid.get_feature_info() {
- if info.has_fpu() { write!(w, " fpu")? };
- if info.has_vme() { write!(w, " vme")? };
- if info.has_de() { write!(w, " de")? };
- if info.has_pse() { write!(w, " pse")? };
- if info.has_tsc() { write!(w, " tsc")? };
- if info.has_msr() { write!(w, " msr")? };
- if info.has_pae() { write!(w, " pae")? };
- if info.has_mce() { write!(w, " mce")? };
-
- if info.has_cmpxchg8b() { write!(w, " cx8")? };
- if info.has_apic() { write!(w, " apic")? };
- if info.has_sysenter_sysexit() { write!(w, " sep")? };
- if info.has_mtrr() { write!(w, " mtrr")? };
- if info.has_pge() { write!(w, " pge")? };
- if info.has_mca() { write!(w, " mca")? };
- if info.has_cmov() { write!(w, " cmov")? };
- if info.has_pat() { write!(w, " pat")? };
-
- if info.has_pse36() { write!(w, " pse36")? };
- if info.has_psn() { write!(w, " psn")? };
- if info.has_clflush() { write!(w, " clflush")? };
- if info.has_ds() { write!(w, " ds")? };
- if info.has_acpi() { write!(w, " acpi")? };
- if info.has_mmx() { write!(w, " mmx")? };
- if info.has_fxsave_fxstor() { write!(w, " fxsr")? };
- if info.has_sse() { write!(w, " sse")? };
-
- if info.has_sse2() { write!(w, " sse2")? };
- if info.has_ss() { write!(w, " ss")? };
- if info.has_htt() { write!(w, " ht")? };
- if info.has_tm() { write!(w, " tm")? };
- if info.has_pbe() { write!(w, " pbe")? };
-
- if info.has_sse3() { write!(w, " sse3")? };
- if info.has_pclmulqdq() { write!(w, " pclmulqdq")? };
- if info.has_ds_area() { write!(w, " dtes64")? };
- if info.has_monitor_mwait() { write!(w, " monitor")? };
- if info.has_cpl() { write!(w, " ds_cpl")? };
- if info.has_vmx() { write!(w, " vmx")? };
- if info.has_smx() { write!(w, " smx")? };
- if info.has_eist() { write!(w, " est")? };
-
- if info.has_tm2() { write!(w, " tm2")? };
- if info.has_ssse3() { write!(w, " ssse3")? };
- if info.has_cnxtid() { write!(w, " cnxtid")? };
- if info.has_fma() { write!(w, " fma")? };
- if info.has_cmpxchg16b() { write!(w, " cx16")? };
- if info.has_pdcm() { write!(w, " pdcm")? };
- if info.has_pcid() { write!(w, " pcid")? };
- if info.has_dca() { write!(w, " dca")? };
-
- if info.has_sse41() { write!(w, " sse4_1")? };
- if info.has_sse42() { write!(w, " sse4_2")? };
- if info.has_x2apic() { write!(w, " x2apic")? };
- if info.has_movbe() { write!(w, " movbe")? };
- if info.has_popcnt() { write!(w, " popcnt")? };
- if info.has_tsc_deadline() { write!(w, " tsc_deadline_timer")? };
- if info.has_aesni() { write!(w, " aes")? };
- if info.has_xsave() { write!(w, " xsave")? };
-
- if info.has_oxsave() { write!(w, " xsaveopt")? };
- if info.has_avx() { write!(w, " avx")? };
- if info.has_f16c() { write!(w, " f16c")? };
- if info.has_rdrand() { write!(w, " rdrand")? };
- }
-
- if let Some(info) = cpuid.get_extended_function_info() {
- if info.has_64bit_mode() { write!(w, " lm")? };
- if info.has_rdtscp() { write!(w, " rdtscp")? };
- if info.has_1gib_pages() { write!(w, " pdpe1gb")? };
- if info.has_execute_disable() { write!(w, " nx")? };
- if info.has_syscall_sysret() { write!(w, " syscall")? };
- if info.has_prefetchw() { write!(w, " prefetchw")? };
- if info.has_lzcnt() { write!(w, " lzcnt")? };
- if info.has_lahf_sahf() { write!(w, " lahf_lm")? };
- if info.has_invariant_tsc() { write!(w, " constant_tsc")? };
- }
-
- if let Some(info) = cpuid.get_extended_feature_info() {
- if info.has_fsgsbase() { write!(w, " fsgsbase")? };
- if info.has_tsc_adjust_msr() { write!(w, " tsc_adjust")? };
- if info.has_bmi1() { write!(w, " bmi1")? };
- if info.has_hle() { write!(w, " hle")? };
- if info.has_avx2() { write!(w, " avx2")? };
- if info.has_smep() { write!(w, " smep")? };
- if info.has_bmi2() { write!(w, " bmi2")? };
- if info.has_rep_movsb_stosb() { write!(w, " erms")? };
- if info.has_invpcid() { write!(w, " invpcid")? };
- if info.has_rtm() { write!(w, " rtm")? };
- if info.has_qm() { write!(w, " qm")? };
- if info.has_fpu_cs_ds_deprecated() { write!(w, " fpu_seg")? };
- if info.has_mpx() { write!(w, " mpx")? };
- }
-
- write!(w, "\n")?;
-
- Ok(())
-}
diff --git a/arch/x86_64/src/device/local_apic.rs b/arch/x86_64/src/device/local_apic.rs
deleted file mode 100644
index d352c2c..0000000
--- a/arch/x86_64/src/device/local_apic.rs
+++ /dev/null
@@ -1,114 +0,0 @@
-use core::intrinsics::{volatile_load, volatile_store};
-use x86::cpuid::CpuId;
-use x86::msr::*;
-
-use memory::Frame;
-use paging::{entry, ActivePageTable, PhysicalAddress, Page, VirtualAddress};
-
-pub static mut LOCAL_APIC: LocalApic = LocalApic {
- address: 0,
- x2: false
-};
-
-pub unsafe fn init(active_table: &mut ActivePageTable) {
- LOCAL_APIC.init(active_table);
-}
-
-pub unsafe fn init_ap() {
- LOCAL_APIC.init_ap();
-}
-
-/// Local APIC
-pub struct LocalApic {
- pub address: usize,
- pub x2: bool
-}
-
-impl LocalApic {
- unsafe fn init(&mut self, active_table: &mut ActivePageTable) {
- self.address = (rdmsr(IA32_APIC_BASE) as usize & 0xFFFF0000) + ::KERNEL_OFFSET;
- self.x2 = CpuId::new().get_feature_info().unwrap().has_x2apic();
-
- if ! self.x2 {
- let page = Page::containing_address(VirtualAddress::new(self.address));
- let frame = Frame::containing_address(PhysicalAddress::new(self.address - ::KERNEL_OFFSET));
- active_table.map_to(page, frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
- }
-
- self.init_ap();
- }
-
- unsafe fn init_ap(&mut self) {
- if self.x2 {
- wrmsr(IA32_APIC_BASE, rdmsr(IA32_APIC_BASE) | 1 << 10);
- wrmsr(IA32_X2APIC_SIVR, 0x100);
- } else {
- self.write(0xF0, 0x100);
- }
- }
-
- unsafe fn read(&self, reg: u32) -> u32 {
- volatile_load((self.address + reg as usize) as *const u32)
- }
-
- unsafe fn write(&mut self, reg: u32, value: u32) {
- volatile_store((self.address + reg as usize) as *mut u32, value);
- }
-
- pub fn id(&self) -> u32 {
- if self.x2 {
- unsafe { rdmsr(IA32_X2APIC_APICID) as u32 }
- } else {
- unsafe { self.read(0x20) }
- }
- }
-
- pub fn version(&self) -> u32 {
- if self.x2 {
- unsafe { rdmsr(IA32_X2APIC_VERSION) as u32 }
- } else {
- unsafe { self.read(0x30) }
- }
- }
-
- pub fn icr(&self) -> u64 {
- if self.x2 {
- unsafe { rdmsr(IA32_X2APIC_ICR) }
- } else {
- unsafe {
- (self.read(0x310) as u64) << 32 | self.read(0x300) as u64
- }
- }
- }
-
- pub fn set_icr(&mut self, value: u64) {
- if self.x2 {
- unsafe { wrmsr(IA32_X2APIC_ICR, value); }
- } else {
- unsafe {
- while self.read(0x300) & 1 << 12 == 1 << 12 {}
- self.write(0x310, (value >> 32) as u32);
- self.write(0x300, value as u32);
- while self.read(0x300) & 1 << 12 == 1 << 12 {}
- }
- }
- }
-
- pub fn ipi(&mut self, apic_id: usize) {
- let mut icr = 0x4040;
- if self.x2 {
- icr |= (apic_id as u64) << 32;
- } else {
- icr |= (apic_id as u64) << 56;
- }
- self.set_icr(icr);
- }
-
- pub unsafe fn eoi(&mut self) {
- if self.x2 {
- wrmsr(IA32_X2APIC_EOI, 0);
- } else {
- self.write(0xB0, 0);
- }
- }
-}
diff --git a/arch/x86_64/src/device/mod.rs b/arch/x86_64/src/device/mod.rs
deleted file mode 100644
index d4d56e6..0000000
--- a/arch/x86_64/src/device/mod.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-use paging::ActivePageTable;
-
-pub mod cpu;
-pub mod local_apic;
-pub mod rtc;
-pub mod serial;
-
-pub unsafe fn init(active_table: &mut ActivePageTable){
- local_apic::init(active_table);
- rtc::init();
- serial::init();
-}
-
-pub unsafe fn init_ap() {
- local_apic::init_ap();
-}
diff --git a/arch/x86_64/src/device/rtc.rs b/arch/x86_64/src/device/rtc.rs
deleted file mode 100644
index ef6de05..0000000
--- a/arch/x86_64/src/device/rtc.rs
+++ /dev/null
@@ -1,109 +0,0 @@
-use io::{Io, Pio};
-use time;
-
-pub fn init() {
- let mut rtc = Rtc::new();
- time::START.lock().0 = rtc.time();
-}
-
-fn cvt_bcd(value: usize) -> usize {
- (value & 0xF) + ((value / 16) * 10)
-}
-
-/// RTC
-pub struct Rtc {
- addr: Pio,
- data: Pio,
-}
-
-impl Rtc {
- /// Create new empty RTC
- pub fn new() -> Self {
- return Rtc {
- addr: Pio::::new(0x70),
- data: Pio::::new(0x71),
- };
- }
-
- /// Read
- unsafe fn read(&mut self, reg: u8) -> u8 {
- self.addr.write(reg);
- return self.data.read();
- }
-
- /// Wait
- unsafe fn wait(&mut self) {
- while self.read(0xA) & 0x80 != 0x80 {}
- while self.read(0xA) & 0x80 == 0x80 {}
- }
-
- /// Get time
- pub fn time(&mut self) -> u64 {
- let mut second;
- let mut minute;
- let mut hour;
- let mut day;
- let mut month;
- let mut year;
- let register_b;
- unsafe {
- self.wait();
- second = self.read(0) as usize;
- minute = self.read(2) as usize;
- hour = self.read(4) as usize;
- day = self.read(7) as usize;
- month = self.read(8) as usize;
- year = self.read(9) as usize;
- register_b = self.read(0xB);
- }
-
- if register_b & 4 != 4 {
- second = cvt_bcd(second);
- minute = cvt_bcd(minute);
- hour = cvt_bcd(hour & 0x7F) | (hour & 0x80);
- day = cvt_bcd(day);
- month = cvt_bcd(month);
- year = cvt_bcd(year);
- }
-
- if register_b & 2 != 2 || hour & 0x80 == 0x80 {
- hour = ((hour & 0x7F) + 12) % 24;
- }
-
- // TODO: Century Register
- year += 2000;
-
- // Unix time from clock
- let mut secs: u64 = (year as u64 - 1970) * 31536000;
-
- let mut leap_days = (year as u64 - 1972) / 4 + 1;
- if year % 4 == 0 {
- if month <= 2 {
- leap_days -= 1;
- }
- }
- secs += leap_days * 86400;
-
- match month {
- 2 => secs += 2678400,
- 3 => secs += 5097600,
- 4 => secs += 7776000,
- 5 => secs += 10368000,
- 6 => secs += 13046400,
- 7 => secs += 15638400,
- 8 => secs += 18316800,
- 9 => secs += 20995200,
- 10 => secs += 23587200,
- 11 => secs += 26265600,
- 12 => secs += 28857600,
- _ => (),
- }
-
- secs += (day as u64 - 1) * 86400;
- secs += hour as u64 * 3600;
- secs += minute as u64 * 60;
- secs += second as u64;
-
- secs
- }
-}
diff --git a/arch/x86_64/src/device/serial.rs b/arch/x86_64/src/device/serial.rs
deleted file mode 100644
index 521c04e..0000000
--- a/arch/x86_64/src/device/serial.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use core::fmt::{self, Write};
-use spin::Mutex;
-
-use io::{Io, Pio, ReadOnly};
-
-pub static COM1: Mutex = Mutex::new(SerialPort::new(0x3F8));
-pub static COM2: Mutex = Mutex::new(SerialPort::new(0x2F8));
-
-pub unsafe fn init() {
- COM1.lock().init();
- COM2.lock().init();
-}
-
-bitflags! {
- /// Interrupt enable flags
- flags IntEnFlags: u8 {
- const RECEIVED = 1,
- const SENT = 1 << 1,
- const ERRORED = 1 << 2,
- const STATUS_CHANGE = 1 << 3,
- // 4 to 7 are unused
- }
-}
-
-bitflags! {
- /// Line status flags
- flags LineStsFlags: u8 {
- const INPUT_FULL = 1,
- // 1 to 4 unknown
- const OUTPUT_EMPTY = 1 << 5,
- // 6 and 7 unknown
- }
-}
-
-#[allow(dead_code)]
-pub struct SerialPort {
- /// Data register, read to receive, write to send
- data: Pio,
- /// Interrupt enable
- int_en: Pio,
- /// FIFO control
- fifo_ctrl: Pio,
- /// Line control
- line_ctrl: Pio,
- /// Modem control
- modem_ctrl: Pio,
- /// Line status
- line_sts: ReadOnly>,
- /// Modem status
- modem_sts: ReadOnly>,
-}
-
-impl SerialPort {
- const fn new(base: u16) -> SerialPort {
- SerialPort {
- data: Pio::new(base),
- int_en: Pio::new(base + 1),
- fifo_ctrl: Pio::new(base + 2),
- line_ctrl: Pio::new(base + 3),
- modem_ctrl: Pio::new(base + 4),
- line_sts: ReadOnly::new(Pio::new(base + 5)),
- modem_sts: ReadOnly::new(Pio::new(base + 6))
- }
- }
-
- fn line_sts(&self) -> LineStsFlags {
- LineStsFlags::from_bits_truncate(self.line_sts.read())
- }
-
- fn write(&mut self, data: u8) {
- while ! self.line_sts().contains(OUTPUT_EMPTY) {}
- self.data.write(data)
- }
-
- fn init(&mut self) {
- //TODO: Cleanup
- self.int_en.write(0x00);
- self.line_ctrl.write(0x80);
- self.data.write(0x03);
- self.int_en.write(0x00);
- self.line_ctrl.write(0x03);
- self.fifo_ctrl.write(0xC7);
- self.modem_ctrl.write(0x0B);
- self.int_en.write(0x01);
- }
-
- pub fn on_receive(&mut self) {
- let data = self.data.read();
-
- extern {
- fn debug_input(byte: u8);
- }
-
- unsafe { debug_input(data) };
- }
-}
-
-impl Write for SerialPort {
- fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
- for byte in s.bytes() {
- match byte {
- 8 | 0x7F => {
- self.write(8);
- self.write(b' ');
- self.write(8);
- },
- _ => {
- self.write(byte);
- }
- }
- }
-
- Ok(())
- }
-}
diff --git a/arch/x86_64/src/externs.rs b/arch/x86_64/src/externs.rs
deleted file mode 100644
index d92f8c4..0000000
--- a/arch/x86_64/src/externs.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-/// Memcpy
-///
-/// Copy N bytes of memory from one location to another.
-#[no_mangle]
-pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
- n: usize) -> *mut u8 {
- let mut i = 0;
- while i < n {
- *((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
- i += 1;
- }
-
- dest
-}
-
-/// Memmove
-///
-/// Copy N bytes of memory from src to dest. The memory areas may overlap.
-#[no_mangle]
-pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
- n: usize) -> *mut u8 {
- if src < dest as *const u8 {
- let mut i = n;
- while i != 0 {
- i -= 1;
- *((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
- }
- } else {
- let mut i = 0;
- while i < n {
- *((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
- i += 1;
- }
- }
-
- dest
-}
-
-/// Memset
-///
-/// Fill a block of memory with a specified value.
-#[no_mangle]
-pub unsafe extern fn memset(dest: *mut u8, c: i32, n: usize) -> *mut u8 {
- let mut i = 0;
- while i < n {
- *((dest as usize + i) as *mut u8) = c as u8;
- i += 1;
- }
-
- dest
-}
-
-/// Memcmp
-///
-/// Compare two blocks of memory.
-#[no_mangle]
-pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
- let mut i = 0;
-
- while i < n {
- let a = *((s1 as usize + i) as *const u8);
- let b = *((s2 as usize + i) as *const u8);
- if a != b {
- return a as i32 - b as i32
- }
- i += 1;
- }
-
- 0
-}
diff --git a/arch/x86_64/src/gdt.rs b/arch/x86_64/src/gdt.rs
deleted file mode 100644
index 96e1b99..0000000
--- a/arch/x86_64/src/gdt.rs
+++ /dev/null
@@ -1,177 +0,0 @@
-//! Global descriptor table
-
-use core::mem;
-use x86::dtables::{self, DescriptorTablePointer};
-use x86::segmentation::{self, SegmentSelector};
-use x86::task::{self, TaskStateSegment};
-
-pub const GDT_NULL: usize = 0;
-pub const GDT_KERNEL_CODE: usize = 1;
-pub const GDT_KERNEL_DATA: usize = 2;
-pub const GDT_KERNEL_TLS: usize = 3;
-pub const GDT_USER_CODE: usize = 4;
-pub const GDT_USER_DATA: usize = 5;
-pub const GDT_USER_TLS: usize = 6;
-pub const GDT_TSS: usize = 7;
-pub const GDT_TSS_HIGH: usize = 8;
-
-pub const GDT_A_PRESENT: u8 = 1 << 7;
-pub const GDT_A_RING_0: u8 = 0 << 5;
-pub const GDT_A_RING_1: u8 = 1 << 5;
-pub const GDT_A_RING_2: u8 = 2 << 5;
-pub const GDT_A_RING_3: u8 = 3 << 5;
-pub const GDT_A_SYSTEM: u8 = 1 << 4;
-pub const GDT_A_EXECUTABLE: u8 = 1 << 3;
-pub const GDT_A_CONFORMING: u8 = 1 << 2;
-pub const GDT_A_PRIVILEGE: u8 = 1 << 1;
-pub const GDT_A_DIRTY: u8 = 1;
-
-pub const GDT_A_TSS_AVAIL: u8 = 0x9;
-pub const GDT_A_TSS_BUSY: u8 = 0xB;
-
-pub const GDT_F_PAGE_SIZE: u8 = 1 << 7;
-pub const GDT_F_PROTECTED_MODE: u8 = 1 << 6;
-pub const GDT_F_LONG_MODE: u8 = 1 << 5;
-
-static mut INIT_GDTR: DescriptorTablePointer = DescriptorTablePointer {
- limit: 0,
- base: 0
-};
-
-static mut INIT_GDT: [GdtEntry; 4] = [
- // Null
- GdtEntry::new(0, 0, 0, 0),
- // Kernel code
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_0 | GDT_A_SYSTEM | GDT_A_EXECUTABLE | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // Kernel data
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_0 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // Kernel TLS
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE)
-];
-
-#[thread_local]
-pub static mut GDTR: DescriptorTablePointer = DescriptorTablePointer {
- limit: 0,
- base: 0
-};
-
-#[thread_local]
-pub static mut GDT: [GdtEntry; 9] = [
- // Null
- GdtEntry::new(0, 0, 0, 0),
- // Kernel code
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_0 | GDT_A_SYSTEM | GDT_A_EXECUTABLE | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // Kernel data
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_0 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // Kernel TLS
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_0 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // User code
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_EXECUTABLE | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // User data
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // User TLS
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_SYSTEM | GDT_A_PRIVILEGE, GDT_F_LONG_MODE),
- // TSS
- GdtEntry::new(0, 0, GDT_A_PRESENT | GDT_A_RING_3 | GDT_A_TSS_AVAIL, 0),
- // TSS must be 16 bytes long, twice the normal size
- GdtEntry::new(0, 0, 0, 0),
-];
-
-#[thread_local]
-pub static mut TSS: TaskStateSegment = TaskStateSegment {
- reserved: 0,
- rsp: [0; 3],
- reserved2: 0,
- ist: [0; 7],
- reserved3: 0,
- reserved4: 0,
- iomap_base: 0xFFFF
-};
-
-/// Initialize GDT
-pub unsafe fn init(tcb_offset: usize, stack_offset: usize) {
- // Setup the initial GDT with TLS, so we can setup the TLS GDT (a little confusing)
- // This means that each CPU will have its own GDT, but we only need to define it once as a thread local
- INIT_GDTR.limit = (INIT_GDT.len() * mem::size_of::() - 1) as u16;
- INIT_GDTR.base = INIT_GDT.as_ptr() as u64;
-
- // Set the TLS segment to the offset of the Thread Control Block
- INIT_GDT[GDT_KERNEL_TLS].set_offset(tcb_offset as u32);
-
- // Load the initial GDT, before we have access to thread locals
- dtables::lgdt(&INIT_GDTR);
-
- // Load the segment descriptors
- segmentation::load_cs(SegmentSelector::new(GDT_KERNEL_CODE as u16));
- segmentation::load_ds(SegmentSelector::new(GDT_KERNEL_DATA as u16));
- segmentation::load_es(SegmentSelector::new(GDT_KERNEL_DATA as u16));
- segmentation::load_fs(SegmentSelector::new(GDT_KERNEL_TLS as u16));
- segmentation::load_gs(SegmentSelector::new(GDT_KERNEL_DATA as u16));
- segmentation::load_ss(SegmentSelector::new(GDT_KERNEL_DATA as u16));
-
- // Now that we have access to thread locals, setup the AP's individual GDT
- GDTR.limit = (GDT.len() * mem::size_of::() - 1) as u16;
- GDTR.base = GDT.as_ptr() as u64;
-
- // Set the TLS segment to the offset of the Thread Control Block
- GDT[GDT_KERNEL_TLS].set_offset(tcb_offset as u32);
-
- // Set the User TLS segment to the offset of the user TCB
- GDT[GDT_USER_TLS].set_offset(::USER_TCB_OFFSET as u32);
-
- // We can now access our TSS, which is a thread local
- GDT[GDT_TSS].set_offset(&TSS as *const _ as u32);
- GDT[GDT_TSS].set_limit(mem::size_of::() as u32);
-
- // Set the stack pointer when coming back from userspace
- TSS.rsp[0] = stack_offset as u64;
-
- // Load the new GDT, which is correctly located in thread local storage
- dtables::lgdt(&GDTR);
-
- // Reload the segment descriptors
- segmentation::load_cs(SegmentSelector::new(GDT_KERNEL_CODE as u16));
- segmentation::load_ds(SegmentSelector::new(GDT_KERNEL_DATA as u16));
- segmentation::load_es(SegmentSelector::new(GDT_KERNEL_DATA as u16));
- segmentation::load_fs(SegmentSelector::new(GDT_KERNEL_TLS as u16));
- segmentation::load_gs(SegmentSelector::new(GDT_KERNEL_DATA as u16));
- segmentation::load_ss(SegmentSelector::new(GDT_KERNEL_DATA as u16));
-
- // Load the task register
- task::load_ltr(SegmentSelector::new(GDT_TSS as u16));
-}
-
-#[derive(Copy, Clone, Debug)]
-#[repr(packed)]
-pub struct GdtEntry {
- pub limitl: u16,
- pub offsetl: u16,
- pub offsetm: u8,
- pub access: u8,
- pub flags_limith: u8,
- pub offseth: u8
-}
-
-impl GdtEntry {
- pub const fn new(offset: u32, limit: u32, access: u8, flags: u8) -> Self {
- GdtEntry {
- limitl: limit as u16,
- offsetl: offset as u16,
- offsetm: (offset >> 16) as u8,
- access: access,
- flags_limith: flags & 0xF0 | ((limit >> 16) as u8) & 0x0F,
- offseth: (offset >> 24) as u8
- }
- }
-
- pub fn set_offset(&mut self, offset: u32) {
- self.offsetl = offset as u16;
- self.offsetm = (offset >> 16) as u8;
- self.offseth = (offset >> 24) as u8;
- }
-
- pub fn set_limit(&mut self, limit: u32) {
- self.limitl = limit as u16;
- self.flags_limith = self.flags_limith & 0xF0 | ((limit >> 16) as u8) & 0x0F;
- }
-}
diff --git a/arch/x86_64/src/idt.rs b/arch/x86_64/src/idt.rs
deleted file mode 100644
index 0d0d95e..0000000
--- a/arch/x86_64/src/idt.rs
+++ /dev/null
@@ -1,142 +0,0 @@
-use core::mem;
-use x86::dtables::{self, DescriptorTablePointer};
-
-use interrupt::*;
-
-pub static mut IDTR: DescriptorTablePointer = DescriptorTablePointer {
- limit: 0,
- base: 0
-};
-
-pub static mut IDT: [IdtEntry; 256] = [IdtEntry::new(); 256];
-
-pub unsafe fn init() {
- IDTR.limit = (IDT.len() * mem::size_of::() - 1) as u16;
- IDTR.base = IDT.as_ptr() as u64;
-
- // Set up exceptions
- IDT[0].set_func(exception::divide_by_zero);
- IDT[1].set_func(exception::debug);
- IDT[2].set_func(exception::non_maskable);
- IDT[3].set_func(exception::breakpoint);
- IDT[4].set_func(exception::overflow);
- IDT[5].set_func(exception::bound_range);
- IDT[6].set_func(exception::invalid_opcode);
- IDT[7].set_func(exception::device_not_available);
- IDT[8].set_func(exception::double_fault);
- // 9 no longer available
- IDT[10].set_func(exception::invalid_tss);
- IDT[11].set_func(exception::segment_not_present);
- IDT[12].set_func(exception::stack_segment);
- IDT[13].set_func(exception::protection);
- IDT[14].set_func(exception::page);
- // 15 reserved
- IDT[16].set_func(exception::fpu);
- IDT[17].set_func(exception::alignment_check);
- IDT[18].set_func(exception::machine_check);
- IDT[19].set_func(exception::simd);
- IDT[20].set_func(exception::virtualization);
- // 21 through 29 reserved
- IDT[30].set_func(exception::security);
- // 31 reserved
-
- // Set up IRQs
- IDT[32].set_func(irq::pit);
- IDT[33].set_func(irq::keyboard);
- IDT[34].set_func(irq::cascade);
- IDT[35].set_func(irq::com2);
- IDT[36].set_func(irq::com1);
- IDT[37].set_func(irq::lpt2);
- IDT[38].set_func(irq::floppy);
- IDT[39].set_func(irq::lpt1);
- IDT[40].set_func(irq::rtc);
- IDT[41].set_func(irq::pci1);
- IDT[42].set_func(irq::pci2);
- IDT[43].set_func(irq::pci3);
- IDT[44].set_func(irq::mouse);
- IDT[45].set_func(irq::fpu);
- IDT[46].set_func(irq::ata1);
- IDT[47].set_func(irq::ata2);
-
- // Set IPI handler (null)
- IDT[0x40].set_func(ipi::ipi);
-
- // Set syscall function
- IDT[0x80].set_func(syscall::syscall);
- IDT[0x80].set_flags(IDT_PRESENT | IDT_RING_3 | IDT_INTERRUPT);
-
- dtables::lidt(&IDTR);
-}
-
-bitflags! {
- pub flags IdtFlags: u8 {
- const IDT_PRESENT = 1 << 7,
- const IDT_RING_0 = 0 << 5,
- const IDT_RING_1 = 1 << 5,
- const IDT_RING_2 = 2 << 5,
- const IDT_RING_3 = 3 << 5,
- const IDT_SS = 1 << 4,
- const IDT_INTERRUPT = 0xE,
- const IDT_TRAP = 0xF,
- }
-}
-
-#[repr(packed)]
-pub struct IdtDescriptor {
- size: u16,
- offset: u64
-}
-
-impl IdtDescriptor {
- pub fn set_slice(&mut self, slice: &'static [IdtEntry]) {
- self.size = (slice.len() * mem::size_of::() - 1) as u16;
- self.offset = slice.as_ptr() as u64;
- }
-
- pub unsafe fn load(&self) {
- asm!("lidt [rax]" : : "{rax}"(self as *const _ as usize) : : "intel", "volatile");
- }
-}
-
-#[derive(Copy, Clone, Debug)]
-#[repr(packed)]
-pub struct IdtEntry {
- offsetl: u16,
- selector: u16,
- zero: u8,
- attribute: u8,
- offsetm: u16,
- offseth: u32,
- zero2: u32
-}
-
-impl IdtEntry {
- pub const fn new() -> IdtEntry {
- IdtEntry {
- offsetl: 0,
- selector: 0,
- zero: 0,
- attribute: 0,
- offsetm: 0,
- offseth: 0,
- zero2: 0
- }
- }
-
- pub fn set_flags(&mut self, flags: IdtFlags) {
- self.attribute = flags.bits;
- }
-
- pub fn set_offset(&mut self, selector: u16, base: usize) {
- self.selector = selector;
- self.offsetl = base as u16;
- self.offsetm = (base >> 16) as u16;
- self.offseth = (base >> 32) as u32;
- }
-
- // A function to set the offset more easily
- pub fn set_func(&mut self, func: unsafe extern fn()) {
- self.set_flags(IDT_PRESENT | IDT_RING_0 | IDT_INTERRUPT);
- self.set_offset(8, func as usize);
- }
-}
diff --git a/arch/x86_64/src/interrupt/exception.rs b/arch/x86_64/src/interrupt/exception.rs
deleted file mode 100644
index 3822779..0000000
--- a/arch/x86_64/src/interrupt/exception.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-use interrupt::stack_trace;
-use syscall::flag::*;
-
-extern {
- fn ksignal(signal: usize);
-}
-
-interrupt_stack!(divide_by_zero, stack, {
- println!("Divide by zero fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGFPE);
-});
-
-interrupt_stack!(debug, stack, {
- println!("Debug trap at {:>02X}:{:>016X}", stack.cs, stack.rip);
- ksignal(SIGTRAP);
-});
-
-interrupt_stack!(non_maskable, stack, {
- println!("Non-maskable interrupt at {:>02X}:{:>016X}", stack.cs, stack.rip);
-});
-
-interrupt_stack!(breakpoint, stack, {
- println!("Breakpoint trap at {:>02X}:{:>016X}", stack.cs, stack.rip);
- ksignal(SIGTRAP);
-});
-
-interrupt_stack!(overflow, stack, {
- println!("Overflow trap at {:>02X}:{:>016X}", stack.cs, stack.rip);
- ksignal(SIGFPE);
-});
-
-interrupt_stack!(bound_range, stack, {
- println!("Bound range exceeded fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGSEGV);
-});
-
-interrupt_stack!(invalid_opcode, stack, {
- println!("Invalid opcode fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGILL);
-});
-
-interrupt_stack!(device_not_available, stack, {
- println!("Device not available fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGILL);
-});
-
-interrupt_error!(double_fault, stack, {
- println!("Double fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGSEGV);
-});
-
-interrupt_error!(invalid_tss, stack, {
- println!("Invalid TSS fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGSEGV);
-});
-
-interrupt_error!(segment_not_present, stack, {
- println!("Segment not present fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGSEGV);
-});
-
-interrupt_error!(stack_segment, stack, {
- println!("Stack segment fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGSEGV);
-});
-
-interrupt_error!(protection, stack, {
- println!("Protection fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGSEGV);
-});
-
-interrupt_error!(page, stack, {
- let cr2: usize;
- asm!("mov rax, cr2" : "={rax}"(cr2) : : : "intel", "volatile");
- println!("Page fault: {:>02X}:{:>016X} at {:>02X}:{:>016X}", stack.code, cr2, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGSEGV);
-});
-
-interrupt_stack!(fpu, stack, {
- println!("FPU floating point fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGFPE);
-});
-
-interrupt_error!(alignment_check, stack, {
- println!("Alignment check fault: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGBUS);
-});
-
-interrupt_stack!(machine_check, stack, {
- println!("Machine check fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGBUS);
-});
-
-interrupt_stack!(simd, stack, {
- println!("SIMD floating point fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGFPE);
-});
-
-interrupt_stack!(virtualization, stack, {
- println!("Virtualization fault at {:>02X}:{:>016X}", stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGBUS);
-});
-
-interrupt_error!(security, stack, {
- println!("Security exception: {:X} at {:>02X}:{:>016X}", stack.code, stack.cs, stack.rip);
- stack_trace();
- ksignal(SIGBUS);
-});
diff --git a/arch/x86_64/src/interrupt/ipi.rs b/arch/x86_64/src/interrupt/ipi.rs
deleted file mode 100644
index 325d9d8..0000000
--- a/arch/x86_64/src/interrupt/ipi.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use device::local_apic::LOCAL_APIC;
-
-interrupt!(ipi, {
- LOCAL_APIC.eoi();
-});
diff --git a/arch/x86_64/src/interrupt/irq.rs b/arch/x86_64/src/interrupt/irq.rs
deleted file mode 100644
index c6a8733..0000000
--- a/arch/x86_64/src/interrupt/irq.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use x86::io;
-
-use device::serial::{COM1, COM2};
-use time;
-
-extern {
- fn irq_trigger(irq: u8);
-}
-
-#[inline(always)]
-unsafe fn master_ack() {
- io::outb(0x20, 0x20);
-}
-
-#[inline(always)]
-unsafe fn slave_ack() {
- io::outb(0xA0, 0x20);
- master_ack();
-}
-
-pub unsafe fn acknowledge(irq: usize) {
- if irq >= 8 {
- slave_ack();
- } else {
- master_ack();
- }
-}
-
-interrupt!(pit, {
- // Saves CPU time by not sending IRQ event irq_trigger(0);
-
- {
- const PIT_RATE: u64 = 2250286;
-
- let mut offset = time::OFFSET.lock();
- let sum = offset.1 + PIT_RATE;
- offset.1 = sum % 1000000000;
- offset.0 += sum / 1000000000;
- }
-
- master_ack();
-});
-
-interrupt!(keyboard, {
- irq_trigger(1);
-});
-
-interrupt!(cascade, {
- irq_trigger(2);
- master_ack();
-});
-
-interrupt!(com2, {
- irq_trigger(3);
- COM2.lock().on_receive();
- master_ack();
-});
-
-interrupt!(com1, {
- irq_trigger(4);
- COM1.lock().on_receive();
- master_ack();
-});
-
-interrupt!(lpt2, {
- irq_trigger(5);
- master_ack();
-});
-
-interrupt!(floppy, {
- irq_trigger(6);
- master_ack();
-});
-
-interrupt!(lpt1, {
- irq_trigger(7);
- master_ack();
-});
-
-interrupt!(rtc, {
- irq_trigger(8);
- slave_ack();
-});
-
-interrupt!(pci1, {
- irq_trigger(9);
- slave_ack();
-});
-
-interrupt!(pci2, {
- irq_trigger(10);
-});
-
-interrupt!(pci3, {
- irq_trigger(11);
-});
-
-interrupt!(mouse, {
- irq_trigger(12);
-});
-
-interrupt!(fpu, {
- irq_trigger(13);
- slave_ack();
-});
-
-interrupt!(ata1, {
- irq_trigger(14);
- slave_ack();
-});
-
-interrupt!(ata2, {
- irq_trigger(15);
- slave_ack();
-});
diff --git a/arch/x86_64/src/interrupt/mod.rs b/arch/x86_64/src/interrupt/mod.rs
deleted file mode 100644
index 3cc5caa..0000000
--- a/arch/x86_64/src/interrupt/mod.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-//! Interrupt instructions
-
-use core::mem;
-
-use paging::{ActivePageTable, VirtualAddress};
-
-pub mod exception;
-pub mod ipi;
-pub mod irq;
-pub mod syscall;
-
-/// Clear interrupts
-#[inline(always)]
-pub unsafe fn disable() {
- asm!("cli" : : : : "intel", "volatile");
-}
-
-/// Set interrupts
-#[inline(always)]
-pub unsafe fn enable() {
- asm!("sti" : : : : "intel", "volatile");
-}
-
-/// Set interrupts and halt
-/// This will atomically wait for the next interrupt
-/// Performing enable followed by halt is not guaranteed to be atomic, use this instead!
-#[inline(always)]
-pub unsafe fn enable_and_halt() {
- asm!("sti
- hlt"
- : : : : "intel", "volatile");
-}
-
-/// Set interrupts and nop
-/// This will enable interrupts and allow the IF flag to be processed
-/// Simply enabling interrupts does not gurantee that they will trigger, use this instead!
-#[inline(always)]
-pub unsafe fn enable_and_nop() {
- asm!("sti
- nop"
- : : : : "intel", "volatile");
-}
-
-/// Halt instruction
-#[inline(always)]
-pub unsafe fn halt() {
- asm!("hlt" : : : : "intel", "volatile");
-}
-
-/// Pause instruction
-/// Safe because it is similar to a NOP, and has no memory effects
-#[inline(always)]
-pub fn pause() {
- unsafe { asm!("pause" : : : : "intel", "volatile"); }
-}
-
-/// Get a stack trace
-//TODO: Check for stack being mapped before dereferencing
-#[inline(never)]
-pub unsafe fn stack_trace() {
- let mut rbp: usize;
- asm!("" : "={rbp}"(rbp) : : : "intel", "volatile");
-
- println!("TRACE: {:>016X}", rbp);
- //Maximum 64 frames
- let active_table = ActivePageTable::new();
- for _frame in 0..64 {
- if let Some(rip_rbp) = rbp.checked_add(mem::size_of::()) {
- if active_table.translate(VirtualAddress::new(rbp)).is_some() && active_table.translate(VirtualAddress::new(rip_rbp)).is_some() {
- let rip = *(rip_rbp as *const usize);
- if rip == 0 {
- println!(" {:>016X}: EMPTY RETURN", rbp);
- break;
- }
- println!(" {:>016X}: {:>016X}", rbp, rip);
- rbp = *(rbp as *const usize);
- } else {
- println!(" {:>016X}: GUARD PAGE", rbp);
- break;
- }
- } else {
- println!(" {:>016X}: RBP OVERFLOW", rbp);
- }
- }
-}
diff --git a/arch/x86_64/src/interrupt/syscall.rs b/arch/x86_64/src/interrupt/syscall.rs
deleted file mode 100644
index d1527da..0000000
--- a/arch/x86_64/src/interrupt/syscall.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-#[naked]
-pub unsafe extern fn syscall() {
- #[inline(never)]
- unsafe fn inner() {
- extern {
- fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> usize;
- }
-
- let mut a;
- {
- let b;
- let c;
- let d;
- let e;
- let f;
- let stack;
- asm!("" : "={rax}"(a), "={rbx}"(b), "={rcx}"(c), "={rdx}"(d), "={rsi}"(e), "={rdi}"(f), "={rbp}"(stack)
- : : : "intel", "volatile");
-
- a = syscall(a, b, c, d, e, f, stack);
- }
-
- asm!("" : : "{rax}"(a) : : "intel", "volatile");
- }
-
- // Push scratch registers, minus rax for the return value
- asm!("push rcx
- push rdx
- push rdi
- push rsi
- push r8
- push r9
- push r10
- push r11
- push fs
- mov r11, 0x18
- mov fs, r11"
- : : : : "intel", "volatile");
-
- inner();
-
- // Interrupt return
- asm!("pop fs
- pop r11
- pop r10
- pop r9
- pop r8
- pop rsi
- pop rdi
- pop rdx
- pop rcx
- iretq"
- : : : : "intel", "volatile");
-}
-
-#[naked]
-pub unsafe extern fn clone_ret() -> usize {
- asm!("pop rbp"
- : : : : "intel", "volatile");
- 0
-}
diff --git a/arch/x86_64/src/lib.rs b/arch/x86_64/src/lib.rs
deleted file mode 100644
index dc30d69..0000000
--- a/arch/x86_64/src/lib.rs
+++ /dev/null
@@ -1,323 +0,0 @@
-//! Architecture support for x86_64
-
-#![feature(asm)]
-#![feature(concat_idents)]
-#![feature(const_fn)]
-#![feature(core_intrinsics)]
-#![feature(drop_types_in_const)]
-#![feature(lang_items)]
-#![feature(naked_functions)]
-#![feature(thread_local)]
-#![feature(unique)]
-#![no_std]
-
-extern crate hole_list_allocator as allocator;
-
-#[macro_use]
-extern crate bitflags;
-extern crate io;
-extern crate spin;
-extern crate syscall;
-pub extern crate x86;
-
-// Because the memory map is so important to not be aliased, it is defined here, in one place
-// The lower 256 PML4 entries are reserved for userspace
-// Each PML4 entry references up to 512 GB of memory
-// The top (511) PML4 is reserved for recursive mapping
-// The second from the top (510) PML4 is reserved for the kernel
- /// The size of a single PML4
- pub const PML4_SIZE: usize = 0x0000_0080_0000_0000;
-
- /// Offset of recursive paging
- pub const RECURSIVE_PAGE_OFFSET: usize = (-(PML4_SIZE as isize)) as usize;
-
- /// Offset of kernel
- pub const KERNEL_OFFSET: usize = RECURSIVE_PAGE_OFFSET - PML4_SIZE;
-
- /// Offset to kernel heap
- pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET + PML4_SIZE/2;
- /// Size of kernel heap
- pub const KERNEL_HEAP_SIZE: usize = 256 * 1024 * 1024; // 256 MB
-
- /// Offset to kernel percpu variables
- //TODO: Use 64-bit fs offset to enable this pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_HEAP_OFFSET - PML4_SIZE;
- pub const KERNEL_PERCPU_OFFSET: usize = 0xC000_0000;
- /// Size of kernel percpu variables
- pub const KERNEL_PERCPU_SIZE: usize = 64 * 1024; // 64 KB
-
- /// Offset to user image
- pub const USER_OFFSET: usize = 0;
-
- /// Offset to user TCB
- pub const USER_TCB_OFFSET: usize = 0xB000_0000;
-
- /// Offset to user arguments
- pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE/2;
-
- /// Offset to user heap
- pub const USER_HEAP_OFFSET: usize = USER_OFFSET + PML4_SIZE;
-
- /// Offset to user grants
- pub const USER_GRANT_OFFSET: usize = USER_HEAP_OFFSET + PML4_SIZE;
-
- /// Offset to user stack
- pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE;
- /// Size of user stack
- pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB
-
- /// Offset to user TLS
- pub const USER_TLS_OFFSET: usize = USER_STACK_OFFSET + PML4_SIZE;
-
- /// Offset to user temporary image (used when cloning)
- pub const USER_TMP_OFFSET: usize = USER_TLS_OFFSET + PML4_SIZE;
-
- /// Offset to user temporary heap (used when cloning)
- pub const USER_TMP_HEAP_OFFSET: usize = USER_TMP_OFFSET + PML4_SIZE;
-
- /// Offset to user temporary page for grants
- pub const USER_TMP_GRANT_OFFSET: usize = USER_TMP_HEAP_OFFSET + PML4_SIZE;
-
- /// Offset to user temporary stack (used when cloning)
- pub const USER_TMP_STACK_OFFSET: usize = USER_TMP_GRANT_OFFSET + PML4_SIZE;
-
- /// Offset to user temporary tls (used when cloning)
- pub const USER_TMP_TLS_OFFSET: usize = USER_TMP_STACK_OFFSET + PML4_SIZE;
-
-
-/// Print to console
-#[macro_export]
-macro_rules! print {
- ($($arg:tt)*) => ({
- use core::fmt::Write;
- let _ = write!($crate::console::CONSOLE.lock(), $($arg)*);
- });
-}
-
-/// Print with new line to console
-#[macro_export]
-macro_rules! println {
- ($fmt:expr) => (print!(concat!($fmt, "\n")));
- ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
-}
-
-/// Create an interrupt function that can safely run rust code
-#[macro_export]
-macro_rules! interrupt {
- ($name:ident, $func:block) => {
- #[naked]
- pub unsafe extern fn $name () {
- #[inline(never)]
- unsafe fn inner() {
- $func
- }
-
- // Push scratch registers
- asm!("push rax
- push rcx
- push rdx
- push rdi
- push rsi
- push r8
- push r9
- push r10
- push r11
- push fs
- mov rax, 0x18
- mov fs, ax"
- : : : : "intel", "volatile");
-
- // Call inner rust function
- inner();
-
- // Pop scratch registers and return
- asm!("pop fs
- pop r11
- pop r10
- pop r9
- pop r8
- pop rsi
- pop rdi
- pop rdx
- pop rcx
- pop rax
- iretq"
- : : : : "intel", "volatile");
- }
- };
-}
-
-#[repr(packed)]
-pub struct InterruptStack {
- fs: usize,
- r11: usize,
- r10: usize,
- r9: usize,
- r8: usize,
- rsi: usize,
- rdi: usize,
- rdx: usize,
- rcx: usize,
- rax: usize,
- rip: usize,
- cs: usize,
- rflags: usize,
-}
-
-#[macro_export]
-macro_rules! interrupt_stack {
- ($name:ident, $stack: ident, $func:block) => {
- #[naked]
- pub unsafe extern fn $name () {
- #[inline(never)]
- unsafe fn inner($stack: &$crate::InterruptStack) {
- $func
- }
-
- // Push scratch registers
- asm!("push rax
- push rcx
- push rdx
- push rdi
- push rsi
- push r8
- push r9
- push r10
- push r11
- push fs
- mov rax, 0x18
- mov fs, ax"
- : : : : "intel", "volatile");
-
- // Get reference to stack variables
- let rsp: usize;
- asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
-
- // Call inner rust function
- inner(&*(rsp as *const $crate::InterruptStack));
-
- // Pop scratch registers and return
- asm!("pop fs
- pop r11
- pop r10
- pop r9
- pop r8
- pop rsi
- pop rdi
- pop rdx
- pop rcx
- pop rax
- iretq"
- : : : : "intel", "volatile");
- }
- };
-}
-
-#[repr(packed)]
-pub struct InterruptErrorStack {
- fs: usize,
- r11: usize,
- r10: usize,
- r9: usize,
- r8: usize,
- rsi: usize,
- rdi: usize,
- rdx: usize,
- rcx: usize,
- rax: usize,
- code: usize,
- rip: usize,
- cs: usize,
- rflags: usize,
-}
-
-#[macro_export]
-macro_rules! interrupt_error {
- ($name:ident, $stack:ident, $func:block) => {
- #[naked]
- pub unsafe extern fn $name () {
- #[inline(never)]
- unsafe fn inner($stack: &$crate::InterruptErrorStack) {
- $func
- }
-
- // Push scratch registers
- asm!("push rax
- push rcx
- push rdx
- push rdi
- push rsi
- push r8
- push r9
- push r10
- push r11
- push fs
- mov rax, 0x18
- mov fs, ax"
- : : : : "intel", "volatile");
-
- // Get reference to stack variables
- let rsp: usize;
- asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
-
- // Call inner rust function
- inner(&*(rsp as *const $crate::InterruptErrorStack));
-
- // Pop scratch registers, error code, and return
- asm!("pop fs
- pop r11
- pop r10
- pop r9
- pop r8
- pop rsi
- pop rdi
- pop rdx
- pop rcx
- pop rax
- add rsp, 8
- iretq"
- : : : : "intel", "volatile");
- }
- };
-}
-
-/// ACPI table parsing
-pub mod acpi;
-
-/// Console handling
-pub mod console;
-
-/// Context switching
-pub mod context;
-
-/// Devices
-pub mod device;
-
-/// Memcpy, memmove, etc.
-pub mod externs;
-
-/// Global descriptor table
-pub mod gdt;
-
-/// Interrupt descriptor table
-pub mod idt;
-
-/// Interrupt instructions
-pub mod interrupt;
-
-/// Memory management
-pub mod memory;
-
-/// Paging
-pub mod paging;
-
-/// Panic
-pub mod panic;
-
-/// Initialization and start function
-pub mod start;
-
-/// Shutdown function
-pub mod stop;
-
-/// Time
-pub mod time;
diff --git a/arch/x86_64/src/linker.ld b/arch/x86_64/src/linker.ld
deleted file mode 100644
index 546adaa..0000000
--- a/arch/x86_64/src/linker.ld
+++ /dev/null
@@ -1,63 +0,0 @@
-ENTRY(kstart)
-OUTPUT_FORMAT(elf64-x86-64)
-
-KERNEL_OFFSET = 0xffffff0000100000;
-/* KERNEL_OFFSET = 0x100000; */
-
-SECTIONS {
- . = KERNEL_OFFSET;
-
- . += SIZEOF_HEADERS;
- . = ALIGN(4096);
-
- .text : AT(ADDR(.text) - KERNEL_OFFSET) {
- __text_start = .;
- *(.text*)
- . = ALIGN(4096);
- __text_end = .;
- }
-
- .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
- __rodata_start = .;
- *(.rodata*)
- . = ALIGN(4096);
- __rodata_end = .;
- }
-
- .data : AT(ADDR(.data) - KERNEL_OFFSET) {
- __data_start = .;
- *(.data*)
- . = ALIGN(4096);
- __data_end = .;
- }
-
- .tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
- __tdata_start = .;
- *(.tdata*)
- . = ALIGN(4096);
- __tdata_end = .;
- __tbss_start = .;
- *(.tbss*)
- . += 8;
- . = ALIGN(4096);
- __tbss_end = .;
- }
-
- .bss : AT(ADDR(.bss) - KERNEL_OFFSET) {
- __bss_start = .;
- *(.bss*)
- . = ALIGN(4096);
- __bss_end = .;
- }
-
- __end = .;
-
- /DISCARD/ : {
- *(.comment*)
- *(.debug*)
- *(.eh_frame*)
- *(.gcc_except_table*)
- *(.note*)
- *(.rel.eh_frame*)
- }
-}
diff --git a/arch/x86_64/src/memory/area_frame_allocator.rs b/arch/x86_64/src/memory/area_frame_allocator.rs
deleted file mode 100644
index e25f22a..0000000
--- a/arch/x86_64/src/memory/area_frame_allocator.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-//! # Area frame allocator
-//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/allocating-frames.html)
-
-use paging::PhysicalAddress;
-
-use super::{Frame, FrameAllocator, MemoryArea, MemoryAreaIter};
-
-
-pub struct AreaFrameAllocator {
- next_free_frame: Frame,
- current_area: Option<&'static MemoryArea>,
- areas: MemoryAreaIter,
- kernel_start: Frame,
- kernel_end: Frame
-}
-
-impl AreaFrameAllocator {
- pub fn new(kernel_start: usize, kernel_end: usize, memory_areas: MemoryAreaIter) -> AreaFrameAllocator {
- let mut allocator = AreaFrameAllocator {
- next_free_frame: Frame::containing_address(PhysicalAddress::new(0)),
- current_area: None,
- areas: memory_areas,
- kernel_start: Frame::containing_address(PhysicalAddress::new(kernel_start)),
- kernel_end: Frame::containing_address(PhysicalAddress::new(kernel_end))
- };
- allocator.choose_next_area();
- allocator
- }
-
- fn choose_next_area(&mut self) {
- self.current_area = self.areas.clone().filter(|area| {
- let address = area.base_addr + area.length - 1;
- Frame::containing_address(PhysicalAddress::new(address as usize)) >= self.next_free_frame
- }).min_by_key(|area| area.base_addr);
-
- if let Some(area) = self.current_area {
- let start_frame = Frame::containing_address(PhysicalAddress::new(area.base_addr as usize));
- if self.next_free_frame < start_frame {
- self.next_free_frame = start_frame;
- }
- }
- }
-}
-
-impl FrameAllocator for AreaFrameAllocator {
- fn free_frames(&self) -> usize {
- let mut count = 0;
-
- for area in self.areas.clone() {
- let start_frame = Frame::containing_address(PhysicalAddress::new(area.base_addr as usize));
- let end_frame = Frame::containing_address(PhysicalAddress::new((area.base_addr + area.length - 1) as usize));
- for frame in Frame::range_inclusive(start_frame, end_frame) {
- if frame >= self.kernel_start && frame <= self.kernel_end {
- // Inside of kernel range
- } else if frame >= self.next_free_frame {
- // Frame is in free range
- count += 1;
- } else {
- // Inside of used range
- }
- }
- }
-
- count
- }
-
- fn used_frames(&self) -> usize {
- let mut count = 0;
-
- for area in self.areas.clone() {
- let start_frame = Frame::containing_address(PhysicalAddress::new(area.base_addr as usize));
- let end_frame = Frame::containing_address(PhysicalAddress::new((area.base_addr + area.length - 1) as usize));
- for frame in Frame::range_inclusive(start_frame, end_frame) {
- if frame >= self.kernel_start && frame <= self.kernel_end {
- // Inside of kernel range
- count += 1
- } else if frame >= self.next_free_frame {
- // Frame is in free range
- } else {
- count += 1;
- }
- }
- }
-
- count
- }
-
- fn allocate_frames(&mut self, count: usize) -> Option {
- if count == 0 {
- None
- } else if let Some(area) = self.current_area {
- // "Clone" the frame to return it if it's free. Frame doesn't
- // implement Clone, but we can construct an identical frame.
- let start_frame = Frame{ number: self.next_free_frame.number };
- let end_frame = Frame { number: self.next_free_frame.number + (count - 1) };
-
- // the last frame of the current area
- let current_area_last_frame = {
- let address = area.base_addr + area.length - 1;
- Frame::containing_address(PhysicalAddress::new(address as usize))
- };
-
- if end_frame > current_area_last_frame {
- // all frames of current area are used, switch to next area
- self.choose_next_area();
- } else if (start_frame >= self.kernel_start && start_frame <= self.kernel_end)
- || (end_frame >= self.kernel_start && end_frame <= self.kernel_end) {
- // `frame` is used by the kernel
- self.next_free_frame = Frame {
- number: self.kernel_end.number + 1
- };
- } else {
- // frame is unused, increment `next_free_frame` and return it
- self.next_free_frame.number += count;
- return Some(start_frame);
- }
- // `frame` was not valid, try it again with the updated `next_free_frame`
- self.allocate_frames(count)
- } else {
- None // no free frames left
- }
- }
-
- fn deallocate_frames(&mut self, frame: Frame, count: usize) {
- //panic!("AreaFrameAllocator::deallocate_frame: not supported: {:?}", frame);
- }
-}
diff --git a/arch/x86_64/src/memory/mod.rs b/arch/x86_64/src/memory/mod.rs
deleted file mode 100644
index 17b2200..0000000
--- a/arch/x86_64/src/memory/mod.rs
+++ /dev/null
@@ -1,189 +0,0 @@
-//! # Memory management
-//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/allocating-frames.html)
-
-pub use paging::{PAGE_SIZE, PhysicalAddress};
-
-use self::area_frame_allocator::AreaFrameAllocator;
-
-use spin::Mutex;
-
-pub mod area_frame_allocator;
-
-/// The current memory map. It's size is maxed out to 512 entries, due to it being
-/// from 0x500 to 0x5000 (800 is the absolute total)
-static mut MEMORY_MAP: [MemoryArea; 512] = [MemoryArea { base_addr: 0, length: 0, _type: 0, acpi: 0 }; 512];
-
-/// Memory does not exist
-pub const MEMORY_AREA_NULL: u32 = 0;
-
-/// Memory is free to use
-pub const MEMORY_AREA_FREE: u32 = 1;
-
-/// Memory is reserved
-pub const MEMORY_AREA_RESERVED: u32 = 2;
-
-/// Memory is used by ACPI, and can be reclaimed
-pub const MEMORY_AREA_ACPI: u32 = 3;
-
-/// A memory map area
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(packed)]
-pub struct MemoryArea {
- pub base_addr: u64,
- pub length: u64,
- pub _type: u32,
- pub acpi: u32
-}
-
-#[derive(Clone)]
-pub struct MemoryAreaIter {
- _type: u32,
- i: usize
-}
-
-impl MemoryAreaIter {
- fn new(_type: u32) -> Self {
- MemoryAreaIter {
- _type: _type,
- i: 0
- }
- }
-}
-
-impl Iterator for MemoryAreaIter {
- type Item = &'static MemoryArea;
- fn next(&mut self) -> Option {
- while self.i < unsafe { MEMORY_MAP.len() } {
- let entry = unsafe { &MEMORY_MAP[self.i] };
- self.i += 1;
- if entry._type == self._type {
- return Some(entry);
- }
- }
- None
- }
-}
-
-static ALLOCATOR: Mutex