Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • redox-os/bootloader
  • microcolonel/bootloader
  • noam93k/bootloader
  • carrot93/bootloader
  • tcrawford/bootloader
  • potatogim/bootloader
  • 4lDO2/bootloader
  • Ivan/bootloader
  • uuuvn/bootloader
  • lewiszlw/bootloader
  • andar1an/bootloader
  • BjornTheProgrammer/bootloader
  • CodingRays/bootloader
  • ybalrid/bootloader
  • rus/bootloader
  • saraelsa/bootloader
  • willnode/bootloader
  • bjorn3/bootloader
  • jensliu29/bootloader
  • xTibor/bootloader
  • enygmator/bootloader
  • crclark96/bootloader
22 results
Show changes
Commits on Source (46)
Showing with 778 additions and 201 deletions
[editor]
auto-format = false
[[language]]
name = "rust"
# TODO: Add more targets (BIOS, x86_32)
# Uncomment this line and set cargo.target to your target to get accurate completions
# config = { cargo.target = "aarch64-unknown-uefi", check.targets = ["x86_64-unknown-uefi", "aarch64-unknown-uefi"] }
...@@ -26,21 +26,21 @@ dependencies = [ ...@@ -26,21 +26,21 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]] [[package]]
name = "base64ct" name = "base64ct"
version = "1.1.1" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]] [[package]]
name = "bit_field" name = "bit_field"
version = "0.10.1" version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
...@@ -48,24 +48,36 @@ version = "1.3.2" ...@@ -48,24 +48,36 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]] [[package]]
name = "blake2" name = "blake2"
version = "0.10.4" version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [ dependencies = [
"digest", "digest",
] ]
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.10.2" version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
...@@ -83,9 +95,9 @@ dependencies = [ ...@@ -83,9 +95,9 @@ dependencies = [
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.4" version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [ dependencies = [
"libc", "libc",
] ]
...@@ -102,20 +114,41 @@ dependencies = [ ...@@ -102,20 +114,41 @@ dependencies = [
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.3" version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [ dependencies = [
"block-buffer", "block-buffer",
"crypto-common", "crypto-common",
"subtle", "subtle",
] ]
[[package]]
name = "dmidecode"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25f44cd5ffdff729d49b8e8fbef8e18fbc0291b5cb7b5926b4410da39fbafb95"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "endian-num"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad847bb2094f110bbdd6fa564894ca4556fd978958e93985420d680d3cb6d14"
[[package]]
name = "fdt"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67"
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.6" version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [ dependencies = [
"typenum", "typenum",
"version_check", "version_check",
...@@ -123,24 +156,24 @@ dependencies = [ ...@@ -123,24 +156,24 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.132" version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]] [[package]]
name = "linked_list_allocator" name = "linked_list_allocator"
version = "0.9.1" version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "549ce1740e46b291953c4340adcd74c59bcf4308f4cac050fd33ba91b7168f4a" checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
dependencies = [ dependencies = [
"spinning_top", "spinning_top",
] ]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.7" version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
...@@ -148,33 +181,39 @@ dependencies = [ ...@@ -148,33 +181,39 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
version = "0.3.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]] [[package]]
name = "raw-cpuid" name = "raw-cpuid"
version = "10.5.0" version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aa2540135b6a94f74c7bc90ad4b794f822026a894f3d7bcd185c100d13d4ad6" checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.3.2",
] ]
[[package]]
name = "redox-path"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
[[package]] [[package]]
name = "redox_bootloader" name = "redox_bootloader"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.3.2",
"byteorder",
"dmidecode",
"fdt",
"linked_list_allocator", "linked_list_allocator",
"log", "log",
"redox_syscall", "redox_syscall",
...@@ -185,41 +224,32 @@ dependencies = [ ...@@ -185,41 +224,32 @@ dependencies = [
"x86", "x86",
] ]
[[package]]
name = "redox_simple_endian"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4e4404b4e54e59e7bb5f5236b61d8e822c2a77b2e955be8072002ff7ff8d69c"
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.5.0",
] ]
[[package]] [[package]]
name = "redox_uefi" name = "redox_uefi"
version = "0.1.5" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://gitlab.redox-os.org/redox-os/uefi.git#8e25274441fc590b870053479467b337cebeac60"
checksum = "0c483e82899e79d50a4ad1a5eb8f3fc918e9b37b0387d85510fa4cf21d2e3dda"
[[package]] [[package]]
name = "redox_uefi_alloc" name = "redox_uefi_alloc"
version = "0.1.4" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://gitlab.redox-os.org/redox-os/uefi.git#8e25274441fc590b870053479467b337cebeac60"
checksum = "09eebe4aab0f8207676234160ffd94cb6c8660694079449ded0eea6a4e27ede1"
dependencies = [ dependencies = [
"redox_uefi", "redox_uefi",
] ]
[[package]] [[package]]
name = "redox_uefi_std" name = "redox_uefi_std"
version = "0.1.7" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://gitlab.redox-os.org/redox-os/uefi.git#8e25274441fc590b870053479467b337cebeac60"
checksum = "5ecc253339d4dc0606421b6118458ef45c184d76ccdc8e20296cdaddf2e401ae"
dependencies = [ dependencies = [
"redox_uefi", "redox_uefi",
"redox_uefi_alloc", "redox_uefi_alloc",
...@@ -227,15 +257,17 @@ dependencies = [ ...@@ -227,15 +257,17 @@ dependencies = [
[[package]] [[package]]
name = "redoxfs" name = "redoxfs"
version = "0.5.0" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd98e5e165138cdf4effae3a3be28a81931b013bc3758e33fccfcb37a4737652" checksum = "45ebd559766fa473d5324f662e23841e32534fd3cabab409e377e59c2e00e82b"
dependencies = [ dependencies = [
"aes", "aes",
"argon2", "argon2",
"base64ct", "base64ct",
"endian-num",
"libc",
"log", "log",
"redox_simple_endian", "redox-path",
"redox_syscall", "redox_syscall",
"seahash", "seahash",
"uuid", "uuid",
...@@ -243,9 +275,9 @@ dependencies = [ ...@@ -243,9 +275,9 @@ dependencies = [
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "seahash" name = "seahash"
...@@ -255,39 +287,39 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" ...@@ -255,39 +287,39 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]] [[package]]
name = "spin" name = "spin"
version = "0.9.4" version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [ dependencies = [
"lock_api", "lock_api",
] ]
[[package]] [[package]]
name = "spinning_top" name = "spinning_top"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75adad84ee84b521fb2cca2d4fd0f1dab1d8d026bda3c5bea4ca63b5f9f9293c" checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
dependencies = [ dependencies = [
"lock_api", "lock_api",
] ]
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.4.1" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.15.0" version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "0.5.1" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
[[package]] [[package]]
name = "version_check" name = "version_check"
...@@ -297,11 +329,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" ...@@ -297,11 +329,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "x86" name = "x86"
version = "0.47.0" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55b5be8cc34d017d8aabec95bc45a43d0f20e8b2a31a453cabc804fe996f8dca" checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
dependencies = [ dependencies = [
"bit_field", "bit_field",
"bitflags", "bitflags 1.3.2",
"raw-cpuid", "raw-cpuid",
] ]
...@@ -16,24 +16,30 @@ crate-type = ["staticlib"] ...@@ -16,24 +16,30 @@ crate-type = ["staticlib"]
[dependencies] [dependencies]
bitflags = "1.3.2" bitflags = "1.3.2"
linked_list_allocator = "0.9.1" linked_list_allocator = "0.10.5"
log = "0.4.14" log = "0.4.17"
redox_syscall = "0.2.16" redox_syscall = "0.5"
spin = "0.9.2" spin = "0.9.5"
[dependencies.redoxfs] [dependencies.redoxfs]
version = "0.5.0" version = "0.6.0"
default-features = false default-features = false
features = ["force-soft"] features = ["force-soft", "log"]
[target.'cfg(target_os = "uefi")'.dependencies] [target.'cfg(target_os = "uefi")'.dependencies]
redox_uefi = "0.1.5" redox_uefi = { git = "https://gitlab.redox-os.org/redox-os/uefi.git" }
redox_uefi_std = "0.1.7" redox_uefi_std = { git = "https://gitlab.redox-os.org/redox-os/uefi.git" }
[target."aarch64-unknown-uefi".dependencies]
byteorder = { version = "1", default-features = false }
dmidecode = "0.8.0"
fdt = "0.1.5"
[target."x86_64-unknown-uefi".dependencies] [target."x86_64-unknown-uefi".dependencies]
x86 = "0.47.0" x86 = "0.52.0"
[features] [features]
default = [] default = []
live = [] live = []
serial_debug = [] serial_debug = []
...@@ -17,6 +17,6 @@ $(BUILD)/filesystem: ...@@ -17,6 +17,6 @@ $(BUILD)/filesystem:
$(BUILD)/filesystem.bin: $(BUILD)/filesystem $(BUILD)/filesystem.bin: $(BUILD)/filesystem
mkdir -p $(BUILD) mkdir -p $(BUILD)
rm -f $@.partial rm -f $@.partial
fallocate -l 255MiB $@.partial fallocate -l 254MiB $@.partial
redoxfs-ar $@.partial $< redoxfs-ar $@.partial $<
mv $@.partial $@ mv $@.partial $@
...@@ -2,7 +2,7 @@ SECTION .text ...@@ -2,7 +2,7 @@ SECTION .text
USE16 USE16
cpuid_required_features: cpuid_required_features:
.edx equ cpuid_edx.fpu | cpuid_edx.pae | cpuid_edx.pse | cpuid_edx.pge | cpuid_edx.fxsr .edx equ cpuid_edx.fpu | cpuid_edx.pse | cpuid_edx.pge | cpuid_edx.fxsr
.ecx equ 0 .ecx equ 0
cpuid_check: cpuid_check:
......
...@@ -55,10 +55,10 @@ $(BUILD)/harddrive.bin: $(BUILD)/bootloader.bin $(BUILD)/filesystem.bin ...@@ -55,10 +55,10 @@ $(BUILD)/harddrive.bin: $(BUILD)/bootloader.bin $(BUILD)/filesystem.bin
rm -f $@.partial rm -f $@.partial
fallocate -l 256MiB $@.partial fallocate -l 256MiB $@.partial
$(PARTED) -s -a minimal $@.partial mklabel msdos $(PARTED) -s -a minimal $@.partial mklabel msdos
$(PARTED) -s -a minimal $@.partial mkpart primary 1MiB 100% $(PARTED) -s -a minimal $@.partial mkpart primary 2MiB 100%
dd if=$< of=$@.partial bs=1 count=446 conv=notrunc dd if=$< of=$@.partial bs=1 count=446 conv=notrunc
dd if=$< of=$@.partial bs=512 skip=1 seek=1 conv=notrunc dd if=$< of=$@.partial bs=512 skip=1 seek=1 conv=notrunc
dd if=$(BUILD)/filesystem.bin of=$@.partial bs=1MiB seek=1 conv=notrunc dd if=$(BUILD)/filesystem.bin of=$@.partial bs=1MiB seek=2 conv=notrunc
mv $@.partial $@ mv $@.partial $@
qemu: $(BUILD)/harddrive.bin qemu: $(BUILD)/harddrive.bin
......
...@@ -31,8 +31,8 @@ $(BUILD)/bootloader-live.efi: Cargo.lock Cargo.toml $(shell find src -type f) ...@@ -31,8 +31,8 @@ $(BUILD)/bootloader-live.efi: Cargo.lock Cargo.toml $(shell find src -type f)
$(BUILD)/esp.bin: $(BUILD)/bootloader.efi $(BUILD)/esp.bin: $(BUILD)/bootloader.efi
mkdir -p $(BUILD) mkdir -p $(BUILD)
rm -f $@.partial rm -f $@.partial
fallocate -l 64MiB $@.partial fallocate -l 1MiB $@.partial
mkfs.vfat -F 32 $@.partial mkfs.vfat $@.partial
mmd -i $@.partial efi mmd -i $@.partial efi
mmd -i $@.partial efi/boot mmd -i $@.partial efi/boot
mcopy -i $@.partial $< ::efi/boot/bootx64.efi mcopy -i $@.partial $< ::efi/boot/bootx64.efi
...@@ -43,11 +43,11 @@ $(BUILD)/harddrive.bin: $(BUILD)/esp.bin $(BUILD)/filesystem.bin ...@@ -43,11 +43,11 @@ $(BUILD)/harddrive.bin: $(BUILD)/esp.bin $(BUILD)/filesystem.bin
rm -f $@.partial rm -f $@.partial
fallocate -l 320MiB $@.partial fallocate -l 320MiB $@.partial
$(PARTED) -s -a minimal $@.partial mklabel gpt $(PARTED) -s -a minimal $@.partial mklabel gpt
$(PARTED) -s -a minimal $@.partial mkpart ESP FAT32 1MiB 65MiB $(PARTED) -s -a minimal $@.partial mkpart ESP FAT32 1MiB 2MiB
$(PARTED) -s -a minimal $@.partial mkpart REDOXFS 65MiB 100% $(PARTED) -s -a minimal $@.partial mkpart REDOXFS 2MiB 100%
$(PARTED) -s -a minimal $@.partial toggle 1 boot $(PARTED) -s -a minimal $@.partial toggle 1 boot
dd if=$(BUILD)/esp.bin of=$@.partial bs=1MiB seek=1 conv=notrunc dd if=$(BUILD)/esp.bin of=$@.partial bs=1MiB seek=1 conv=notrunc
dd if=$(BUILD)/filesystem.bin of=$@.partial bs=1MiB seek=65 conv=notrunc dd if=$(BUILD)/filesystem.bin of=$@.partial bs=1MiB seek=2 conv=notrunc
mv $@.partial $@ mv $@.partial $@
$(BUILD)/firmware.rom: $(BUILD)/firmware.rom:
......
[toolchain] [toolchain]
channel = "nightly-2022-03-18" channel = "nightly-2024-05-11"
components = ["rust-src"] components = ["rust-src"]
use core::slice; use core::slice;
use redoxfs::Disk; use redoxfs::Disk;
use crate::os::{Os, OsVideoMode}; use crate::os::{Os, OsVideoMode, dtb::is_in_dev_mem_region};
const ENTRY_ADDRESS_MASK: u64 = 0x000F_FFFF_FFFF_F000; const ENTRY_ADDRESS_MASK: u64 = 0x000F_FFFF_FFFF_F000;
const PAGE_ENTRIES: usize = 512; const PAGE_ENTRIES: usize = 512;
...@@ -39,6 +39,7 @@ pub unsafe fn paging_create< ...@@ -39,6 +39,7 @@ pub unsafe fn paging_create<
l0[256] = l1.as_ptr() as u64 | 1 << 10 | 1 << 1 | 1; l0[256] = l1.as_ptr() as u64 | 1 << 10 | 1 << 1 | 1;
// Identity map 8 GiB using 2 MiB pages // Identity map 8 GiB using 2 MiB pages
let mut cur_addr: usize = 0;
for l1_i in 0..8 { for l1_i in 0..8 {
let l2 = paging_allocate(os)?; let l2 = paging_allocate(os)?;
l1[l1_i] = l2.as_ptr() as u64 | 1 << 10 | 1 << 1 | 1; l1[l1_i] = l2.as_ptr() as u64 | 1 << 10 | 1 << 1 | 1;
...@@ -47,6 +48,10 @@ pub unsafe fn paging_create< ...@@ -47,6 +48,10 @@ pub unsafe fn paging_create<
l1_i as u64 * 0x4000_0000 + l1_i as u64 * 0x4000_0000 +
l2_i as u64 * 0x20_0000; l2_i as u64 * 0x20_0000;
l2[l2_i] = addr | 1 << 10 | 1; l2[l2_i] = addr | 1 << 10 | 1;
if is_in_dev_mem_region(cur_addr) {
l2[l2_i] |= (2 << 2);
}
cur_addr += 0x20_0000;
} }
} }
} }
......
...@@ -23,6 +23,10 @@ unsafe fn paging_allocate< ...@@ -23,6 +23,10 @@ unsafe fn paging_allocate<
} }
} }
const PRESENT: u64 = 1;
const WRITABLE: u64 = 1 << 1;
const LARGE: u64 = 1 << 7;
pub unsafe fn paging_create< pub unsafe fn paging_create<
D: Disk, D: Disk,
V: Iterator<Item=OsVideoMode> V: Iterator<Item=OsVideoMode>
...@@ -35,50 +39,52 @@ pub unsafe fn paging_create< ...@@ -35,50 +39,52 @@ pub unsafe fn paging_create<
let pdp = paging_allocate(os)?; let pdp = paging_allocate(os)?;
// Link first user and first kernel PML4 entry to PDP // Link first user and first kernel PML4 entry to PDP
pml4[0] = pdp.as_ptr() as u64 | 1 << 1 | 1; pml4[0] = pdp.as_ptr() as u64 | WRITABLE | PRESENT;
pml4[256] = pdp.as_ptr() as u64 | 1 << 1 | 1; pml4[256] = pdp.as_ptr() as u64 | WRITABLE | PRESENT;
// Identity map 8 GiB using 2 MiB pages // Identity map 8 GiB using 2 MiB pages
for pdp_i in 0..8 { for pdp_i in 0..8 {
let pd = paging_allocate(os)?; let pd = paging_allocate(os)?;
pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1; pdp[pdp_i] = pd.as_ptr() as u64 | WRITABLE | PRESENT;
for pd_i in 0..pd.len() { for pd_i in 0..pd.len() {
let addr = let addr =
pdp_i as u64 * 0x4000_0000 + pdp_i as u64 * 0x4000_0000 +
pd_i as u64 * 0x20_0000; pd_i as u64 * 0x20_0000;
pd[pd_i] = addr | 1 << 7 | 1 << 1 | 1; pd[pd_i] = addr | LARGE | WRITABLE | PRESENT;
} }
} }
} }
{ {
// Create PDP for kernel mapping // Create PDP (spanning 512 GiB) for kernel mapping
let pdp = paging_allocate(os)?; let pdp = paging_allocate(os)?;
// Link second to last PML4 entry to PDP // Link last PML4 entry to PDP
pml4[510] = pdp.as_ptr() as u64 | 1 << 1 | 1; pml4[511] = pdp.as_ptr() as u64 | WRITABLE | PRESENT;
// Create PD (spanning 1 GiB) for kernel mapping.
let pd = paging_allocate(os)?;
// The kernel is mapped at -2^31, i.e. 0xFFFF_FFFF_8000_0000. Since a PD is 1 GiB, link
// the second last PDP entry to PD.
pdp[510] = pd.as_ptr() as u64 | WRITABLE | PRESENT;
// Map kernel_size bytes to kernel offset, i.e. to the start of the PD.
// Map kernel_size at kernel offset
let mut kernel_mapped = 0; let mut kernel_mapped = 0;
let mut pdp_i = 0;
while kernel_mapped < kernel_size && pdp_i < pdp.len() { let mut pd_idx = 0;
let pd = paging_allocate(os)?; while kernel_mapped < kernel_size && pd_idx < pd.len(){
pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1; let pt = paging_allocate(os)?;
pdp_i += 1; pd[pd_idx] = pt.as_ptr() as u64 | WRITABLE | PRESENT;
pd_idx += 1;
let mut pd_i = 0;
while kernel_mapped < kernel_size && pd_i < pd.len(){ let mut pt_idx = 0;
let pt = paging_allocate(os)?; while kernel_mapped < kernel_size && pt_idx < pt.len() {
pd[pd_i] = pt.as_ptr() as u64 | 1 << 1 | 1; let addr = kernel_phys + kernel_mapped;
pd_i += 1; pt[pt_idx] = addr | WRITABLE | PRESENT;
pt_idx += 1;
let mut pt_i = 0; kernel_mapped += PAGE_SIZE as u64;
while kernel_mapped < kernel_size && pt_i < pt.len() {
let addr = kernel_phys + kernel_mapped;
pt[pt_i] = addr | 1 << 1 | 1;
pt_i += 1;
kernel_mapped += PAGE_SIZE as u64;
}
} }
} }
assert!(kernel_mapped >= kernel_size); assert!(kernel_mapped >= kernel_size);
......
#![no_std] #![no_std]
#![feature(alloc_error_handler)]
#![feature(int_roundings)]
#![feature(lang_items)] #![feature(lang_items)]
#![cfg_attr( #![cfg_attr(
target_os = "uefi", target_os = "uefi",
...@@ -81,23 +83,20 @@ pub struct KernelArgs { ...@@ -81,23 +83,20 @@ pub struct KernelArgs {
env_base: u64, env_base: u64,
env_size: u64, env_size: u64,
/// The base 64-bit pointer to an array of saved RSDPs. It's up to the kernel (and possibly /// The base pointer to the saved RSDP.
/// userspace), to decide which RSDP to use. The buffer will be a linked list containing a
/// 32-bit relative (to this field) next, and the actual struct afterwards.
/// ///
/// This field can be NULL, and if so, the system has not booted with UEFI or in some other way /// This field can be NULL, and if so, the system has not booted with UEFI or in some other way
/// retrieved the RSDPs. The kernel or a userspace driver will thus try searching the BIOS /// retrieved the RSDPs. The kernel or a userspace driver will thus try searching the BIOS
/// memory instead. On UEFI systems, searching is not guaranteed to actually work though. /// memory instead. On UEFI systems, searching is not guaranteed to actually work though.
acpi_rsdps_base: u64, acpi_rsdp_base: u64,
/// The size of the RSDPs region. /// The size of the RSDP region.
acpi_rsdps_size: u64, acpi_rsdp_size: u64,
areas_base: u64, areas_base: u64,
areas_size: u64, areas_size: u64,
bootstrap_base: u64, bootstrap_base: u64,
bootstrap_size: u64, bootstrap_size: u64,
bootstrap_entry: u64,
} }
fn select_mode< fn select_mode<
...@@ -300,7 +299,7 @@ fn redoxfs< ...@@ -300,7 +299,7 @@ fn redoxfs<
#[derive(PartialEq)] #[derive(PartialEq)]
enum Filetype { enum Filetype {
Elf, Elf,
Other, Initfs,
} }
fn load_to_memory<D: Disk>(os: &mut dyn Os<D, impl Iterator<Item=OsVideoMode>>, fs: &mut redoxfs::FileSystem<D>, dirname: &str, filename: &str, filetype: Filetype) -> &'static mut [u8] { fn load_to_memory<D: Disk>(os: &mut dyn Os<D, impl Iterator<Item=OsVideoMode>>, fs: &mut redoxfs::FileSystem<D>, dirname: &str, filename: &str, filetype: Filetype) -> &'static mut [u8] {
fs.tx(|tx| { fs.tx(|tx| {
...@@ -336,6 +335,11 @@ fn load_to_memory<D: Disk>(os: &mut dyn Os<D, impl Iterator<Item=OsVideoMode>>, ...@@ -336,6 +335,11 @@ fn load_to_memory<D: Disk>(os: &mut dyn Os<D, impl Iterator<Item=OsVideoMode>>,
if magic != b"\x7FELF" { if magic != b"\x7FELF" {
panic!("{} has invalid magic number {:#X?}", filename, magic); panic!("{} has invalid magic number {:#X?}", filename, magic);
} }
} else if filetype == Filetype::Initfs {
let magic = &slice[..8];
if magic != b"RedoxFtw" {
panic!("{} has invalid magic number {:#X?}", filename, magic);
}
} }
Ok(slice) Ok(slice)
...@@ -448,25 +452,18 @@ fn main< ...@@ -448,25 +452,18 @@ fn main<
(kernel, kernel_entry) (kernel, kernel_entry)
}; };
let (bootstrap_size, bootstrap_base, bootstrap_entry, initfs_offset, initfs_len) = { let (bootstrap_size, bootstrap_base) = {
let bootstrap_slice = load_to_memory(os, &mut fs, "boot", "bootstrap", Filetype::Elf); let initfs_slice = load_to_memory(os, &mut fs, "boot", "initfs", Filetype::Initfs);
let bootstrap_len = (bootstrap_slice.len()+4095)/4096*4096;
let (bootstrap_entry, bootstrap_64bit) = elf_entry(bootstrap_slice);
unsafe { assert_eq!(KERNEL_64BIT, bootstrap_64bit); }
let initfs_slice = load_to_memory(os, &mut fs, "boot", "initfs", Filetype::Other);
let initfs_len = (initfs_slice.len()+4095)/4096*4096;
let memory = unsafe { let memory = unsafe {
let total_size = initfs_len + bootstrap_len; let total_size = initfs_slice.len().next_multiple_of(4096);
let ptr = os.alloc_zeroed_page_aligned(total_size); let ptr = os.alloc_zeroed_page_aligned(total_size);
assert!(!ptr.is_null(), "failed to allocate bootstrap+initfs memory"); assert!(!ptr.is_null(), "failed to allocate bootstrap+initfs memory");
core::slice::from_raw_parts_mut(ptr, total_size) core::slice::from_raw_parts_mut(ptr, total_size)
}; };
memory[..bootstrap_slice.len()].copy_from_slice(bootstrap_slice); memory[..initfs_slice.len()].copy_from_slice(initfs_slice);
memory[bootstrap_len..bootstrap_len + initfs_slice.len()].copy_from_slice(initfs_slice);
(memory.len() as u64, memory.as_mut_ptr() as u64, bootstrap_entry, bootstrap_len, initfs_len) (memory.len() as u64, memory.as_mut_ptr() as u64)
}; };
let page_phys = unsafe { let page_phys = unsafe {
...@@ -541,8 +538,6 @@ fn main< ...@@ -541,8 +538,6 @@ fn main<
} }
} }
} }
writeln!(w, "INITFS_OFFSET={:016x}", initfs_offset).unwrap();
writeln!(w, "INITFS_LENGTH={:016x}", initfs_len).unwrap();
env_size = w.i; env_size = w.i;
} }
...@@ -557,8 +552,8 @@ fn main< ...@@ -557,8 +552,8 @@ fn main<
stack_size: stack_size as u64, stack_size: stack_size as u64,
env_base: env_base as u64, env_base: env_base as u64,
env_size: env_size as u64, env_size: env_size as u64,
acpi_rsdps_base: 0, acpi_rsdp_base: 0,
acpi_rsdps_size: 0, acpi_rsdp_size: 0,
areas_base: unsafe { areas_base: unsafe {
AREAS.as_ptr() as u64 AREAS.as_ptr() as u64
}, },
...@@ -567,7 +562,6 @@ fn main< ...@@ -567,7 +562,6 @@ fn main<
}, },
bootstrap_base, bootstrap_base,
bootstrap_size, bootstrap_size,
bootstrap_entry,
} }
) )
} }
...@@ -233,7 +233,7 @@ pub unsafe extern "C" fn start( ...@@ -233,7 +233,7 @@ pub unsafe extern "C" fn start(
let (heap_start, heap_size) = memory_map(os.thunk15) let (heap_start, heap_size) = memory_map(os.thunk15)
.expect("No memory for heap"); .expect("No memory for heap");
ALLOCATOR.lock().init(heap_start, heap_size); ALLOCATOR.lock().init(heap_start as *mut u8, heap_size);
let (page_phys, func, args) = crate::main(&mut os); let (page_phys, func, args) = crate::main(&mut os);
......
...@@ -11,7 +11,7 @@ pub extern "C" fn rust_eh_personality() {} ...@@ -11,7 +11,7 @@ pub extern "C" fn rust_eh_personality() {}
/// Required to handle panics /// Required to handle panics
#[panic_handler] #[panic_handler]
#[no_mangle] #[no_mangle]
pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! { pub fn rust_begin_unwind(info: &PanicInfo) -> ! {
unsafe { unsafe {
println!("BOOTLOADER PANIC:\n{}", info); println!("BOOTLOADER PANIC:\n{}", info);
loop { loop {
...@@ -20,7 +20,7 @@ pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! { ...@@ -20,7 +20,7 @@ pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! {
} }
} }
#[lang = "oom"] #[alloc_error_handler]
#[no_mangle] #[no_mangle]
#[allow(improper_ctypes_definitions)] // Layout is not repr(C) #[allow(improper_ctypes_definitions)] // Layout is not repr(C)
pub extern fn rust_oom(_layout: Layout) -> ! { pub extern fn rust_oom(_layout: Layout) -> ! {
......
...@@ -3,8 +3,8 @@ use uefi::guid::GuidKind; ...@@ -3,8 +3,8 @@ use uefi::guid::GuidKind;
use crate::{Disk, Os, OsVideoMode}; use crate::{Disk, Os, OsVideoMode};
pub(crate) static mut RSDPS_AREA_BASE: *mut u8 = 0 as *mut u8; pub(crate) static mut RSDP_AREA_BASE: *mut u8 = 0 as *mut u8;
pub(crate) static mut RSDPS_AREA_SIZE: usize = 0; pub(crate) static mut RSDP_AREA_SIZE: usize = 0;
struct Invalid; struct Invalid;
...@@ -60,40 +60,38 @@ pub(crate) fn find_acpi_table_pointers< ...@@ -60,40 +60,38 @@ pub(crate) fn find_acpi_table_pointers<
D: Disk, D: Disk,
V: Iterator<Item=OsVideoMode> V: Iterator<Item=OsVideoMode>
>(os: &mut dyn Os<D, V>) { >(os: &mut dyn Os<D, V>) {
let mut rsdps_area = Vec::new();
let cfg_tables = std::system_table().config_tables(); let cfg_tables = std::system_table().config_tables();
let mut acpi = None;
for (address, v2) in cfg_tables.iter().find_map(|cfg_table| { let mut acpi2 = None;
for cfg_table in cfg_tables.iter() {
if cfg_table.VendorGuid.kind() == GuidKind::Acpi { if cfg_table.VendorGuid.kind() == GuidKind::Acpi {
Some((cfg_table.VendorTable, false)) match validate_rsdp(cfg_table.VendorTable, false) {
Ok(length) => {
acpi = Some(unsafe { core::slice::from_raw_parts(cfg_table.VendorTable as *const u8, length) });
}
Err(_) => log::warn!("Found RSDP that was not valid at {:p}", cfg_table.VendorTable as *const u8),
}
} else if cfg_table.VendorGuid.kind() == GuidKind::Acpi2 { } else if cfg_table.VendorGuid.kind() == GuidKind::Acpi2 {
Some((cfg_table.VendorTable, true)) match validate_rsdp(cfg_table.VendorTable, true) {
} else { Ok(length) => {
None acpi2 = Some(unsafe { core::slice::from_raw_parts(cfg_table.VendorTable as *const u8, length) });
} }
}) { Err(_) => log::warn!("Found RSDP that was not valid at {:p}", cfg_table.VendorTable as *const u8),
match validate_rsdp(address, v2) {
Ok(length) => {
let align = 8;
rsdps_area.extend(&u32::to_ne_bytes(length as u32));
rsdps_area.extend(unsafe { core::slice::from_raw_parts(address as *const u8, length) });
rsdps_area.resize(((rsdps_area.len() + (align - 1)) / align) * align, 0u8);
} }
Err(_) => log::warn!("Found RSDP that was not valid at {:p}", address as *const u8),
} }
} }
if ! rsdps_area.is_empty() { let rsdp_area = acpi2.or(acpi).unwrap_or(&[]);
if !rsdp_area.is_empty() {
unsafe { unsafe {
// Copy to page aligned area // Copy to page aligned area
RSDPS_AREA_SIZE = rsdps_area.len(); RSDP_AREA_SIZE = rsdp_area.len();
RSDPS_AREA_BASE = os.alloc_zeroed_page_aligned(RSDPS_AREA_SIZE); RSDP_AREA_BASE = os.alloc_zeroed_page_aligned(RSDP_AREA_SIZE);
slice::from_raw_parts_mut( slice::from_raw_parts_mut(
RSDPS_AREA_BASE, RSDP_AREA_BASE,
RSDPS_AREA_SIZE RSDP_AREA_SIZE
).copy_from_slice(&rsdps_area); ).copy_from_slice(&rsdp_area);
} }
} }
} }
...@@ -9,19 +9,14 @@ use crate::{ ...@@ -9,19 +9,14 @@ use crate::{
use super::super::{ use super::super::{
OsEfi, OsEfi,
acpi::{ dtb::{
RSDPS_AREA_BASE, RSDP_AREA_BASE,
RSDPS_AREA_SIZE, RSDP_AREA_SIZE,
find_acpi_table_pointers, find_dtb,
}, },
memory_map::memory_map, memory_map::memory_map,
}; };
#[no_mangle]
pub extern "C" fn __chkstk() {
//TODO
}
unsafe extern "C" fn kernel_entry( unsafe extern "C" fn kernel_entry(
page_phys: usize, page_phys: usize,
stack: u64, stack: u64,
...@@ -35,7 +30,6 @@ unsafe extern "C" fn kernel_entry( ...@@ -35,7 +30,6 @@ unsafe extern "C" fn kernel_entry(
memory_iter.set_virtual_address_map(PHYS_OFFSET); memory_iter.set_virtual_address_map(PHYS_OFFSET);
mem::forget(memory_iter); mem::forget(memory_iter);
} }
// Disable interrupts // Disable interrupts
asm!("msr daifset, #2"); asm!("msr daifset, #2");
...@@ -52,15 +46,24 @@ unsafe extern "C" fn kernel_entry( ...@@ -52,15 +46,24 @@ unsafe extern "C" fn kernel_entry(
asm!( asm!(
"dsb sy", // Data sync barrier "dsb sy", // Data sync barrier
"msr ttbr1_el1, {0}", // Set higher half page table "msr ttbr1_el1, {0}", // Set higher half page table
"msr ttbr0_el1, {0}", // Set lower half page table
"isb", // Instruction sync barrier "isb", // Instruction sync barrier
"tlbi vmalle1is", // Invalidate TLB "tlbi vmalle1is", // Invalidate TLB
in(reg) page_phys, in(reg) page_phys,
); );
// Set MAIR // Set MAIR
// You can think about MAIRs as of an array with 8 elements each of 8 bits long.
// You can store inside MAIRs up to 8 attributes sets and reffer them by the index 0..7 stored in INDX (AttrIndx) field of the table descriptor.
// https://lowenware.com/blog/aarch64-mmu-programming/
// https://developer.arm.com/documentation/102376/0200/Describing-memory-in-AArch64
// https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/MAIR-EL1--Memory-Attribute-Indirection-Register--EL1-
// Attribute 0 (0xFF) - normal memory, caches are enabled
// Attribute 1 (0x44) - normal memory, caches are disabled. Atomics wouldn't work here if memory doesn't support exclusive access (most real hardware don't)
// Attribute 2 (0x00) - nGnRnE device memory, caches are disabled, gathering, re-ordering, and early write acknowledgement aren't allowed.
asm!( asm!(
"msr mair_el1, {0}", "msr mair_el1, {0}",
in(reg) 0xff4400, // MAIR: Arrange for Device, Normal Non-Cache, Normal Write-Back access types in(reg) 0x00000000000044FF as u64, // MAIR: Arrange for Device, Normal Non-Cache, Normal Write-Back access types
); );
// Set TCR // Set TCR
...@@ -104,13 +107,13 @@ pub fn main() -> Result<()> { ...@@ -104,13 +107,13 @@ pub fn main() -> Result<()> {
// Disable cursor // Disable cursor
let _ = (os.st.ConsoleOut.EnableCursor)(os.st.ConsoleOut, false); let _ = (os.st.ConsoleOut.EnableCursor)(os.st.ConsoleOut, false);
find_acpi_table_pointers(&mut os); find_dtb(&mut os);
let (page_phys, func, mut args) = crate::main(&mut os); let (page_phys, func, mut args) = crate::main(&mut os);
unsafe { unsafe {
args.acpi_rsdps_base = RSDPS_AREA_BASE as u64; args.acpi_rsdp_base = RSDP_AREA_BASE as u64;
args.acpi_rsdps_size = RSDPS_AREA_SIZE as u64; args.acpi_rsdp_size = RSDP_AREA_SIZE as u64;
kernel_entry( kernel_entry(
page_phys, page_phys,
......
...@@ -14,8 +14,8 @@ use crate::{ ...@@ -14,8 +14,8 @@ use crate::{
use super::super::{ use super::super::{
OsEfi, OsEfi,
acpi::{ acpi::{
RSDPS_AREA_BASE, RSDP_AREA_BASE,
RSDPS_AREA_SIZE, RSDP_AREA_SIZE,
find_acpi_table_pointers, find_acpi_table_pointers,
}, },
memory_map::memory_map, memory_map::memory_map,
...@@ -86,8 +86,8 @@ pub fn main() -> Result<()> { ...@@ -86,8 +86,8 @@ pub fn main() -> Result<()> {
let (page_phys, func, mut args) = crate::main(&mut os); let (page_phys, func, mut args) = crate::main(&mut os);
unsafe { unsafe {
args.acpi_rsdps_base = RSDPS_AREA_BASE as u64; args.acpi_rsdp_base = RSDP_AREA_BASE as u64;
args.acpi_rsdps_size = RSDPS_AREA_SIZE as u64; args.acpi_rsdp_size = RSDP_AREA_SIZE as u64;
kernel_entry( kernel_entry(
page_phys, page_phys,
......
use alloc::{
string::String,
vec::Vec,
};
use core::{
fmt::Write,
mem,
ptr,
slice,
};
use uefi::{
Handle,
device::{
DevicePath,
DevicePathType,
DevicePathHardwareType,
DevicePathAcpiType,
DevicePathMessagingType,
DevicePathMediaType,
DevicePathBbsType,
DevicePathEndType,
},
guid::Guid,
};
use uefi_std::{
loaded_image::LoadedImage,
proto::Protocol,
};
use super::disk::DiskEfi;
#[derive(Debug)]
enum DevicePathRelation {
This,
Parent(usize),
Child(usize),
None,
}
fn device_path_relation(a_path: &DevicePath, b_path: &DevicePath) -> DevicePathRelation {
let mut a_iter = DevicePathIter::new(a_path);
let mut b_iter = DevicePathIter::new(b_path);
loop {
match (a_iter.next(), b_iter.next()) {
(None, None) => return DevicePathRelation::This,
(None, Some(_)) => return DevicePathRelation::Parent(b_iter.count()),
(Some(_), None) => return DevicePathRelation::Child(a_iter.count()),
(Some((a_node, a_data)), Some((b_node, b_data))) => {
if a_node.Type != b_node.Type {
return DevicePathRelation::None;
}
if a_node.SubType != b_node.SubType {
return DevicePathRelation::None;
}
if a_data != b_data {
return DevicePathRelation::None;
}
}
}
}
}
pub struct DiskDevice {
pub handle: Handle,
pub disk: DiskEfi,
pub device_path: DevicePathProtocol,
}
pub fn disk_device_priority() -> Vec<DiskDevice> {
// Get the handle of the partition this program was loaded from, which should be the ESP
let esp_handle = match LoadedImage::handle_protocol(std::handle()) {
Ok(loaded_image) => loaded_image.0.DeviceHandle,
Err(err) => {
log::warn!("Failed to find LoadedImage protocol: {:?}", err);
return Vec::new();
}
};
// Get the device path of the ESP
let esp_device_path = match DevicePathProtocol::handle_protocol(esp_handle) {
Ok(ok) => ok,
Err(err) => {
log::warn!("Failed to find device path protocol on {:?}: {:?}", esp_handle, err);
return Vec::new();
}
};
// Get all block I/O handles along with their block I/O implementations and device paths
let handles = match DiskEfi::locate_handle() {
Ok(ok) => ok,
Err(err) => {
log::warn!("Failed to find block I/O handles: {:?}", err);
Vec::new()
}
};
let mut devices = Vec::with_capacity(handles.len());
for handle in handles {
let disk = match DiskEfi::handle_protocol(handle) {
Ok(ok) => ok,
Err(err) => {
log::warn!("Failed to find block I/O protocol on {:?}: {:?}", handle, err);
continue;
}
};
let device_path = match DevicePathProtocol::handle_protocol(handle) {
Ok(ok) => ok,
Err(err) => {
log::warn!("Failed to find device path protocol on {:?}: {:?}", handle, err);
continue;
}
};
devices.push(DiskDevice {
handle,
disk,
device_path,
});
}
// Find possible boot disks
let mut boot_disks = Vec::with_capacity(1);
{
let mut i = 0;
while i < devices.len() {
match device_path_relation(devices[i].device_path.0, esp_device_path.0) {
DevicePathRelation::Parent(0) => {
boot_disks.push(devices.remove(i));
continue;
},
_ => (),
}
i += 1;
}
}
// Find all children of possible boot devices
let mut priority = Vec::with_capacity(devices.capacity());
for boot_disk in boot_disks {
let mut i = 0;
while i < devices.len() {
// Only prioritize non-ESP devices
if devices[i].handle != esp_handle {
match device_path_relation(devices[i].device_path.0, boot_disk.device_path.0) {
DevicePathRelation::Child(0) => {
priority.push(devices.remove(i));
continue;
},
_ => (),
}
}
i += 1;
}
priority.push(boot_disk);
}
// Add any remaining devices
priority.extend(devices);
priority
}
#[repr(packed)]
#[allow(dead_code)]
struct DevicePathHarddrive {
partition_number: u32,
partition_start: u64,
partition_size: u64,
partition_signature: [u8; 16],
partition_format: u8,
signature_type: u8,
}
pub fn device_path_to_string(device_path: &DevicePath) -> String {
let mut s = String::new();
for (node, node_data) in DevicePathIter::new(device_path) {
let read_u16 = |i: usize| -> u16 {
(node_data[i] as u16) |
(node_data[i + 1] as u16) << 8
};
let read_u32 = |i: usize| -> u32 {
(node_data[i] as u32) |
(node_data[i + 1] as u32) << 8 |
(node_data[i + 2] as u32) << 16 |
(node_data[i + 3] as u32) << 24
};
if ! s.is_empty() {
s.push('/');
}
let write_result = match DevicePathType::try_from(node.Type) {
Ok(path_type) => match path_type {
DevicePathType::Hardware => match DevicePathHardwareType::try_from(node.SubType) {
Ok(sub_type) => match sub_type {
DevicePathHardwareType::Pci if node_data.len() == 2 => {
let func = node_data[0];
let dev = node_data[1];
write!(s, "Pci(0x{:X},0x{:X})", dev, func)
},
_ => write!(s, "{:?} {:?} {:X?}", path_type, sub_type, node_data),
}
Err(()) => write!(s, "{:?} 0x{:02X} {:X?}", path_type, node.SubType, node_data),
},
DevicePathType::Acpi => match DevicePathAcpiType::try_from(node.SubType) {
Ok(sub_type) => match sub_type {
DevicePathAcpiType::Acpi if node_data.len() == 8 => {
let hid = read_u32(0);
let uid = read_u32(4);
if hid & 0xFFFF == 0x41D0 {
write!(s, "Acpi(PNP{:04X},0x{:X})", hid >> 16, uid)
} else {
write!(s, "Acpi(0x{:08X},0x{:X})", hid, uid)
}
},
_ => write!(s, "{:?} {:?} {:X?}", path_type, sub_type, node_data),
}
Err(()) => write!(s, "{:?} 0x{:02X} {:X?}", path_type, node.SubType, node_data),
},
DevicePathType::Messaging => match DevicePathMessagingType::try_from(node.SubType) {
Ok(sub_type) => match sub_type {
DevicePathMessagingType::Sata if node_data.len() == 6 => {
let hba_port = read_u16(0);
let multiplier_port = read_u16(2);
let logical_unit = read_u16(4);
if multiplier_port & (1 << 15) != 0 {
write!(s, "Sata(0x{:X},0x{:X})", hba_port, logical_unit)
} else {
write!(s, "Sata(0x{:X},0x{:X},0x{:X})", hba_port, multiplier_port, logical_unit)
}
},
DevicePathMessagingType::Usb if node_data.len() == 2 => {
let port = node_data[0];
let iface = node_data[1];
write!(s, "Usb(0x{:X},0x{:X})", port, iface)
},
DevicePathMessagingType::Nvme if node_data.len() == 12 => {
let nsid = read_u32(0);
let eui = &node_data[4..];
if eui == &[0, 0, 0, 0, 0, 0, 0, 0] {
write!(s, "NVMe(0x{:X})", nsid)
} else {
write!(
s,
"NVMe(0x{:X},{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X})",
nsid,
eui[0],
eui[1],
eui[2],
eui[3],
eui[4],
eui[5],
eui[6],
eui[7],
)
}
},
_ => write!(s, "{:?} {:?} {:X?}", path_type, sub_type, node_data),
}
Err(()) => write!(s, "{:?} 0x{:02X} {:X?}", path_type, node.SubType, node_data),
},
DevicePathType::Media => match DevicePathMediaType::try_from(node.SubType) {
Ok(sub_type) => match sub_type {
DevicePathMediaType::Harddrive if node_data.len() == mem::size_of::<DevicePathHarddrive>() => {
let harddrive = unsafe { ptr::read(node_data.as_ptr() as *const DevicePathHarddrive) };
let partition_number = unsafe { ptr::read_unaligned(ptr::addr_of!(harddrive.partition_number)) };
match harddrive.signature_type {
1 => {
let id = unsafe { ptr::read(harddrive.partition_signature.as_ptr() as *const u32) };
write!(s, "HD(0x{:X},MBR,0x{:X})", partition_number, id)
},
2 => {
let guid = unsafe { ptr::read(harddrive.partition_signature.as_ptr() as *const Guid) };
write!(
s,
"HD(0x{:X},GPT,{:08X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X})",
partition_number,
guid.0,
guid.1,
guid.2,
guid.3[0],
guid.3[1],
guid.3[2],
guid.3[3],
guid.3[4],
guid.3[5],
guid.3[6],
guid.3[7],
)
},
_ => {
write!(s, "HD(0x{:X},0x{:X},{:X?})", partition_number, harddrive.signature_type, harddrive.partition_signature)
}
}
},
DevicePathMediaType::Filepath => {
for chunk in node_data.chunks_exact(2) {
let data = (chunk[0] as u16) | (chunk[1] as u16) << 8;
match unsafe { char::from_u32_unchecked(data as u32) } {
'\\' => s.push('/'),
c => s.push(c),
}
}
Ok(())
},
_ => write!(s, "{:?} {:?} {:X?}", path_type, sub_type, node_data),
}
Err(()) => write!(s, "{:?} 0x{:02X} {:X?}", path_type, node.SubType, node_data),
},
DevicePathType::Bbs => match DevicePathBbsType::try_from(node.SubType) {
Ok(sub_type) => match sub_type {
_ => write!(s, "{:?} {:?} {:X?}", path_type, sub_type, node_data),
}
Err(()) => write!(s, "{:?} 0x{:02X} {:X?}", path_type, node.SubType, node_data),
},
DevicePathType::End => match DevicePathEndType::try_from(node.SubType) {
Ok(sub_type) => match sub_type {
_ => write!(s, "{:?} {:?} {:X?}", path_type, sub_type, node_data),
}
Err(()) => write!(s, "{:?} 0x{:02X} {:X?}", path_type, node.SubType, node_data),
},
},
Err(()) => {
write!(s, "0x{:02X} 0x{:02X} {:X?}", node.Type, node.SubType, node_data)
},
};
}
s
}
pub struct DevicePathProtocol(pub &'static mut DevicePath);
impl Protocol<DevicePath> for DevicePathProtocol {
fn guid() -> Guid {
uefi::guid::DEVICE_PATH_GUID
}
fn new(inner: &'static mut DevicePath) -> Self {
Self(inner)
}
}
pub struct LoadedImageDevicePathProtocol(pub &'static mut DevicePath);
impl Protocol<DevicePath> for LoadedImageDevicePathProtocol {
fn guid() -> Guid {
uefi::guid::LOADED_IMAGE_DEVICE_PATH_GUID
}
fn new(inner: &'static mut DevicePath) -> Self {
Self(inner)
}
}
pub struct DevicePathIter<'a> {
device_path: &'a DevicePath,
node_ptr: *const DevicePath,
}
impl<'a> DevicePathIter<'a> {
pub fn new(device_path: &'a DevicePath) -> Self {
Self {
device_path,
node_ptr: device_path as *const DevicePath,
}
}
}
impl<'a> Iterator for DevicePathIter<'a> {
type Item = (&'a DevicePath, &'a [u8]);
fn next(&mut self) -> Option<Self::Item> {
let node = unsafe { &*self.node_ptr };
if node.Type == DevicePathType::End as u8 {
return None;
}
let node_data = unsafe {
slice::from_raw_parts(
self.node_ptr.add(1) as *mut u8,
node.Length.saturating_sub(4) as usize,
)
};
self.node_ptr = (self.node_ptr as usize + node.Length as usize) as *const DevicePath;
Some((node, node_data))
}
}
use core::ops::{ControlFlow, Try}; use core::ops::{ControlFlow, Try};
use core::slice; use core::slice;
use redoxfs::{BLOCK_SIZE, Disk}; use redoxfs::{BLOCK_SIZE, RECORD_SIZE, Disk};
use syscall::{EIO, Error, Result}; use syscall::{EIO, EINVAL, Error, Result};
use std::proto::Protocol; use std::proto::Protocol;
use uefi::guid::{Guid, BLOCK_IO_GUID}; use uefi::guid::{Guid, BLOCK_IO_GUID};
use uefi::block_io::BlockIo as UefiBlockIo; use uefi::block_io::BlockIo as UefiBlockIo;
...@@ -16,10 +16,10 @@ impl Protocol<UefiBlockIo> for DiskEfi { ...@@ -16,10 +16,10 @@ impl Protocol<UefiBlockIo> for DiskEfi {
fn new(inner: &'static mut UefiBlockIo) -> Self { fn new(inner: &'static mut UefiBlockIo) -> Self {
// Hack to get aligned buffer // Hack to get aligned buffer
let block = unsafe { let block = unsafe {
let ptr = super::alloc_zeroed_page_aligned(BLOCK_SIZE as usize); let ptr = super::alloc_zeroed_page_aligned(RECORD_SIZE as usize);
slice::from_raw_parts_mut( slice::from_raw_parts_mut(
ptr, ptr,
BLOCK_SIZE as usize, RECORD_SIZE as usize,
) )
}; };
...@@ -45,8 +45,12 @@ impl Disk for DiskEfi { ...@@ -45,8 +45,12 @@ impl Disk for DiskEfi {
let mut ptr = buffer.as_mut_ptr(); let mut ptr = buffer.as_mut_ptr();
if self.0.Media.IoAlign != 0 { if self.0.Media.IoAlign != 0 {
if (ptr as usize) % (self.0.Media.IoAlign as usize) != 0 { if (ptr as usize) % (self.0.Media.IoAlign as usize) != 0 {
if buffer.len() == self.1.len() { if buffer.len() <= self.1.len() {
ptr = self.1.as_mut_ptr(); ptr = self.1.as_mut_ptr();
} else {
println!("DiskEfi::read_at 0x{:X} requires alignment, ptr = 0x{:p}, len = 0x{:x}",
block, ptr, buffer.len());
return Err(Error::new(EINVAL));
} }
} }
} }
...@@ -58,7 +62,8 @@ impl Disk for DiskEfi { ...@@ -58,7 +62,8 @@ impl Disk for DiskEfi {
ControlFlow::Continue(_) => { ControlFlow::Continue(_) => {
// Copy to original buffer if using aligned buffer // Copy to original buffer if using aligned buffer
if ptr != buffer.as_mut_ptr() { if ptr != buffer.as_mut_ptr() {
buffer.copy_from_slice(&self.1); let (left, _) = self.1.split_at(buffer.len());
buffer.copy_from_slice(left);
} }
Ok(buffer.len()) Ok(buffer.len())
}, },
......
use uefi::guid::Guid; use byteorder::ByteOrder;
use byteorder::BE;
use fdt;
use std::{slice, vec::Vec};
use uefi::guid::GuidKind;
use uefi::status::{Error, Result}; use uefi::status::{Error, Result};
static DTB_GUID: Guid = Guid(0xb1b621d5, 0xf19c, 0x41a5, [0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0]); use crate::{Disk, Os, OsVideoMode};
pub(crate) fn find_dtb() -> Result<u64> { pub(crate) static mut RSDP_AREA_BASE: *mut u8 = 0 as *mut u8;
pub(crate) static mut RSDP_AREA_SIZE: usize = 0;
pub static mut DEV_MEM_AREA: Vec<(usize, usize)> = Vec::new();
pub unsafe fn is_in_dev_mem_region(addr: usize) -> bool {
if DEV_MEM_AREA.is_empty() {
return false;
}
for item in &DEV_MEM_AREA {
if (addr >= item.0) && (addr < item.0 + item.1) {
return true;
}
}
return false;
}
unsafe fn get_dev_mem_region(fdt: &fdt::Fdt) {
let soc = fdt.find_node("/soc");
let cell_sizes = fdt.root().cell_sizes();
let chunk_size = (cell_sizes.address_cells * 2 + cell_sizes.size_cells) * 4;
if let Some(soc) = soc {
if let Some(ranges) = soc.property("ranges") {
for chunk in ranges.value.chunks(chunk_size) {
let child_bus_addr = {
if cell_sizes.address_cells == 1 {
BE::read_u32(&chunk[0..4]) as u64
} else if cell_sizes.address_cells == 2 {
BE::read_u32(&chunk[0..8]) as u64
} else {
DEV_MEM_AREA.clear();
return;
}
};
let parent_bus_addr = {
if cell_sizes.address_cells == 1 {
BE::read_u32(&chunk[4..8]) as u64
} else if cell_sizes.address_cells == 2 {
BE::read_u32(&chunk[8..16]) as u64
} else {
DEV_MEM_AREA.clear();
return;
}
};
let addr_size = {
if cell_sizes.address_cells == 1 {
BE::read_u32(&chunk[8..12]) as u64
} else if cell_sizes.address_cells == 2 {
BE::read_u32(&chunk[16..24]) as u64
} else {
DEV_MEM_AREA.clear();
return;
}
};
println!(
"dev mem 0x{:08x} 0x{:08x} 0x{:08x}",
child_bus_addr, parent_bus_addr, addr_size
);
DEV_MEM_AREA.push((parent_bus_addr as usize, addr_size as usize));
}
}
}
}
fn parse_dtb<D: Disk, V: Iterator<Item = OsVideoMode>>(os: &mut dyn Os<D, V>, address: *const u8) {
unsafe {
if let Ok(fdt) = fdt::Fdt::from_ptr(address) {
let mut rsdps_area = Vec::new();
//println!("DTB model = {}", fdt.root().model());
get_dev_mem_region(&fdt);
let length = fdt.total_size();
let align = 8;
rsdps_area.extend(core::slice::from_raw_parts(address, length));
rsdps_area.resize(((rsdps_area.len() + (align - 1)) / align) * align, 0u8);
RSDP_AREA_SIZE = rsdps_area.len();
RSDP_AREA_BASE = os.alloc_zeroed_page_aligned(RSDP_AREA_SIZE);
slice::from_raw_parts_mut(RSDP_AREA_BASE, RSDP_AREA_SIZE)
.copy_from_slice(&rsdps_area);
} else {
println!("Failed to parse DTB");
}
}
}
fn find_smbios3_system(address: *const u8) -> Result<dmidecode::System<'static>> {
unsafe {
let smb = core::slice::from_raw_parts(address, 24);
if let Ok(smbios) = dmidecode::EntryPoint::search(smb) {
let smb_structure_data = core::slice::from_raw_parts(
smbios.smbios_address() as *const u8,
smbios.smbios_len() as usize,
);
for structure in smbios.structures(smb_structure_data) {
if let Ok(sval) = structure {
//println!("SMBIOS: {:#?}", sval);
if let dmidecode::Structure::System(buf) = sval {
return Ok(buf);
}
}
}
}
}
Err(Error::NotFound)
}
pub(crate) fn find_dtb<D: Disk, V: Iterator<Item = OsVideoMode>>(os: &mut dyn Os<D, V>) {
let cfg_tables = std::system_table().config_tables(); let cfg_tables = std::system_table().config_tables();
for cfg_table in cfg_tables.iter() { for cfg_table in cfg_tables.iter() {
if cfg_table.VendorGuid == DTB_GUID { if cfg_table.VendorGuid.kind() == GuidKind::DeviceTree {
let addr = cfg_table.VendorTable as u64; let addr = cfg_table.VendorTable;
println!("DTB: {:X}", addr); println!("DTB: {:X}", addr);
return Ok(addr); parse_dtb(os, addr as *const u8);
return;
}
}
for cfg_table in cfg_tables.iter() {
if cfg_table.VendorGuid.kind() == GuidKind::Smbios3 {
let addr = cfg_table.VendorTable;
if let Ok(sys) = find_smbios3_system(addr as *const u8) {
let get_dtb_addr = match (sys.manufacturer, sys.version) {
("QEMU", version) if version.starts_with("virt") => Some(0x4000_0000 as usize),
_ => None,
};
if let Some(dtb_addr) = get_dtb_addr {
println!("Fallback DTB: {:X}", dtb_addr);
parse_dtb(os, dtb_addr as *const u8);
}
};
return;
} }
} }
println!("Failed to find DTB"); println!("Failed to find DTB");
Err(Error::NotFound)
} }