diff --git a/Cargo.lock b/Cargo.lock index 34decae3..c0052c6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arrayvec" @@ -39,7 +45,7 @@ dependencies = [ "log", "parking", "polling", - "rustix", + "rustix 0.37.26", "slab", "socket2", "waker-fn", @@ -67,9 +73,9 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix", + "rustix 0.37.26", "signal-hook", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -99,6 +105,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bincode" version = "1.3.3" @@ -122,9 +134,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -138,6 +150,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "blocking" version = "1.3.1" @@ -148,7 +169,7 @@ dependencies = [ "async-lock", "async-task", "atomic-waker", - "fastrand", + "fastrand 1.9.0", "futures-lite", "log", ] @@ -271,8 +292,12 @@ name = "bootloader_test_runner" version = "0.1.0" dependencies = [ "bootloader", - "ovmf-prebuilt", + "lzma-rs", + "sha2", "strip-ansi-escapes", + "tar", + "tempfile", + "ureq", ] [[package]] @@ -283,9 +308,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.79" +version = "1.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -317,6 +345,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e763eef8846b13b380f37dfecda401770b0ca4e56e95170237bd7c25c7db3582" +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.0.1" @@ -332,6 +369,15 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "critical-section" version = "1.1.1" @@ -348,24 +394,33 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", + "generic-array", + "typenum", ] [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -383,6 +438,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + [[package]] name = "fatfs" version = "0.3.6" @@ -394,6 +455,37 @@ dependencies = [ "log", ] +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "flate2" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "funty" version = "2.0.0" @@ -465,7 +557,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -515,6 +607,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -532,7 +634,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8283e7331b8c93b9756e0cfdbcfb90312852f953c6faf9bf741e684cc3b6ad69" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.6.0", "crc", "log", "uuid", @@ -566,6 +668,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "instant" version = "0.1.12" @@ -583,7 +695,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -594,9 +706,20 @@ checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall", +] [[package]] name = "linux-raw-sys" @@ -604,6 +727,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "llvm-tools" version = "0.1.1" @@ -626,6 +755,16 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + [[package]] name = "mbr-nostd" version = "0.1.0" @@ -654,6 +793,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "noto-sans-mono-bitmap" version = "0.1.6" @@ -667,10 +815,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a27daf9557165efe1d09b52f97393bf6283cadb0a76fbe64a1061e15553a994a" [[package]] -name = "ovmf-prebuilt" -version = "0.1.0-alpha.1" +name = "once_cell" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa50141d081512ab30fd9e7e7692476866df5098b028536ad6680212e717fa8d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parking" @@ -678,6 +826,12 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project" version = "1.1.2" @@ -723,7 +877,7 @@ dependencies = [ "libc", "log", "pin-project-lite", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -826,11 +980,26 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", ] [[package]] @@ -861,8 +1030,53 @@ dependencies = [ "errno", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -940,6 +1154,23 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.15" @@ -1011,6 +1242,12 @@ dependencies = [ "vte", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -1039,18 +1276,28 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tar" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "tempfile" -version = "3.6.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ - "autocfg", "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys", + "fastrand 2.1.1", + "once_cell", + "rustix 0.38.37", + "windows-sys 0.59.0", ] [[package]] @@ -1163,6 +1410,27 @@ dependencies = [ "syn 2.0.23", ] +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "uart_16550" version = "0.2.18" @@ -1176,43 +1444,111 @@ dependencies = [ [[package]] name = "ucs2" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad643914094137d475641b6bab89462505316ec2ce70907ad20102d28a79ab8" +checksum = "df79298e11f316400c57ec268f3c2c29ac3c4d4777687955cd3d4f3a35ce7eba" dependencies = [ "bit_field", ] [[package]] name = "uefi" -version = "0.20.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab39d5e7740f21ed4c46d6659f31038bbe3fe7a8be1f702d8a984348837c43b1" +checksum = "91f17ea8502a6bd414acb2bf5194f90ca4c48e33a2d18cb57eab3294d2050d99" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", + "cfg-if", "log", "ptr_meta", "ucs2", "uefi-macros", + "uefi-raw", + "uguid", ] [[package]] name = "uefi-macros" -version = "0.11.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0caeb0e7b31b9f1f347e541106be10aa8c66c76fa722a3298a4cd21433fabd4" +checksum = "c19ee3a01d435eda42cb9931269b349d28a1762f91ddf01c68d276f74b957cc3" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", ] +[[package]] +name = "uefi-raw" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b463030b802e1265a3800fab24df95d3229c202c2e408832a206f05b4d1496ca" +dependencies = [ + "bitflags 2.6.0", + "ptr_meta", + "uguid", +] + +[[package]] +name = "uguid" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + [[package]] name = "unicode-ident" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" +dependencies = [ + "base64", + "flate2", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "url", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "usize_conversions" version = "0.2.0" @@ -1234,6 +1570,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "volatile" version = "0.4.6" @@ -1273,6 +1615,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "webpki-roots" +version = "0.26.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1301,7 +1652,25 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1310,13 +1679,29 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -1325,42 +1710,90 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "wyz" version = "0.5.1" @@ -1382,6 +1815,17 @@ dependencies = [ "volatile", ] +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys 0.4.14", + "rustix 0.38.37", +] + [[package]] name = "xmas-elf" version = "0.8.0" @@ -1396,3 +1840,9 @@ name = "zero" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fe21bcc34ca7fe6dd56cc2cb1261ea59d6b93620215aefb5ea6032265527784" + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/tests/runner/Cargo.toml b/tests/runner/Cargo.toml index 796ffb01..233a8263 100644 --- a/tests/runner/Cargo.toml +++ b/tests/runner/Cargo.toml @@ -9,9 +9,13 @@ edition = "2021" [features] default = ["bios", "uefi"] bios = ["bootloader/bios"] -uefi = ["bootloader/uefi", "dep:ovmf-prebuilt"] +uefi = ["bootloader/uefi"] [dependencies] bootloader = { path = "../..", default-features = false } strip-ansi-escapes = "0.1.1" -ovmf-prebuilt = { version = "0.1.0-alpha.1", optional = true } +ureq = "2.10.1" +sha2 = "0.10.8" +tar = "0.4.41" +lzma-rs = "0.3.0" +tempfile = "3.12.0" diff --git a/tests/runner/src/lib.rs b/tests/runner/src/lib.rs index 3edb4d94..f34d9baa 100644 --- a/tests/runner/src/lib.rs +++ b/tests/runner/src/lib.rs @@ -2,6 +2,11 @@ use bootloader::BootConfig; use bootloader::DiskImageBuilder; use std::path::Path; +#[cfg(feature = "uefi")] +mod omvf; +#[cfg(feature = "uefi")] +use crate::omvf::OvmfPaths; + pub fn run_test_kernel(kernel_binary_path: &str) { run_test_kernel_internal(kernel_binary_path, None, None) } @@ -31,12 +36,15 @@ pub fn run_test_kernel_internal( #[cfg(feature = "uefi")] { + let mut ovmf_paths = OvmfPaths::find(); + ovmf_paths.with_temp_vars(); + let gpt_path = kernel_path.with_extension("gpt"); let tftp_path = kernel_path.with_extension("tftp"); image_builder.create_uefi_image(&gpt_path).unwrap(); image_builder.create_uefi_tftp_folder(&tftp_path).unwrap(); - run_test_kernel_on_uefi(&gpt_path); - run_test_kernel_on_uefi_pxe(&tftp_path); + run_test_kernel_on_uefi(&gpt_path, &ovmf_paths); + run_test_kernel_on_uefi_pxe(&tftp_path, &ovmf_paths); } #[cfg(feature = "bios")] @@ -50,11 +58,18 @@ pub fn run_test_kernel_internal( } #[cfg(feature = "uefi")] -pub fn run_test_kernel_on_uefi(out_gpt_path: &Path) { - let ovmf_pure_efi = ovmf_prebuilt::ovmf_pure_efi(); +pub fn run_test_kernel_on_uefi(out_gpt_path: &Path, ovmf_paths: &OvmfPaths) { let args = [ - "-bios", - ovmf_pure_efi.to_str().unwrap(), + "-drive", + &format!( + "if=pflash,format=raw,readonly=on,file={}", + ovmf_paths.code().display() + ), + "-drive", + &format!( + "if=pflash,format=raw,readonly=off,file={}", + ovmf_paths.vars().display() + ), "-drive", &format!("format=raw,file={}", out_gpt_path.display()), ]; @@ -71,8 +86,7 @@ pub fn run_test_kernel_on_bios(out_mbr_path: &Path) { } #[cfg(feature = "uefi")] -pub fn run_test_kernel_on_uefi_pxe(out_tftp_path: &Path) { - let ovmf_pure_efi = ovmf_prebuilt::ovmf_pure_efi(); +pub fn run_test_kernel_on_uefi_pxe(out_tftp_path: &Path, ovmf_paths: &OvmfPaths) { let args = [ "-netdev", &format!( @@ -81,8 +95,16 @@ pub fn run_test_kernel_on_uefi_pxe(out_tftp_path: &Path) { ), "-device", "virtio-net-pci,netdev=net0", - "-bios", - ovmf_pure_efi.to_str().unwrap(), + "-drive", + &format!( + "if=pflash,format=raw,readonly=on,file={}", + ovmf_paths.code().display() + ), + "-drive", + &format!( + "if=pflash,format=raw,readonly=off,file={}", + ovmf_paths.vars().display() + ), ]; run_qemu(args); } @@ -105,6 +127,8 @@ where "-display", "none", "--no-reboot", + "-smp", + "4", ]; const SEPARATOR: &str = "\n____________________________________\n"; @@ -138,10 +162,9 @@ where ) }); - let exit_status = child.wait().unwrap(); - match exit_status.code() { - Some(33) => {} // success - Some(35) => panic!("Test failed"), // success + match child.wait().unwrap().code() { + Some(33) => {} // success + Some(35) => panic!("Test failed"), other => panic!("Test failed with unexpected exit code `{other:?}`"), } diff --git a/tests/runner/src/omvf.rs b/tests/runner/src/omvf.rs new file mode 100644 index 00000000..e00c87e0 --- /dev/null +++ b/tests/runner/src/omvf.rs @@ -0,0 +1,262 @@ +use sha2::{Digest, Sha256}; +use std::{ + env, + fs::{copy, create_dir_all, read_to_string, remove_dir_all, rename, set_permissions, write}, + io::{Cursor, Read}, + path::{Path, PathBuf}, +}; +use tar::Archive; +use tempfile::TempDir; +use ureq::Agent; +#[cfg(target_os = "linux")] +use {std::fs::Permissions, std::os::unix::fs::PermissionsExt}; + +/// Name of the ovmf-prebuilt release tag. +const OVMF_PREBUILT_TAG: &str = "edk2-stable202311-r2"; + +/// SHA-256 hash of the release tarball. +const OVMF_PREBUILT_HASH: &str = "4a7d01b7dc6b0fdbf3a0e17dacd364b772fb5b712aaf64ecf328273584185ca0"; + +/// Directory into which the prebuilts will be download (relative to the repo root). +const OVMF_PREBUILT_DIR: &str = "target/ovmf"; + +/// Environment variable for overriding the path of the OVMF code file. +pub const ENV_VAR_OVMF_CODE: &str = "OVMF_CODE"; + +/// Environment variable for overriding the path of the OVMF vars file. +pub const ENV_VAR_OVMF_VARS: &str = "OVMF_VARS"; + +/// Environment variable for overriding the path of the OVMF shell file. +pub const ENV_VAR_OVMF_SHELL: &str = "OVMF_SHELL"; + +#[derive(Clone, Copy, Debug)] +pub enum OvmfFileType { + Code, + Vars, + Shell, +} + +impl OvmfFileType { + fn as_str(&self) -> &'static str { + match self { + Self::Code => "code", + Self::Vars => "vars", + Self::Shell => "shell", + } + } + + fn extension(&self) -> &'static str { + match self { + Self::Code | Self::Vars => "fd", + Self::Shell => "efi", + } + } + + /// Get a user-provided path for the given OVMF file type. + /// + /// This uses an environment variable. If not present, returns `None`. + pub fn get_user_provided_path(self) -> Option { + let var_name = match self { + Self::Code => ENV_VAR_OVMF_CODE, + Self::Vars => ENV_VAR_OVMF_VARS, + Self::Shell => ENV_VAR_OVMF_SHELL, + }; + env::var_os(var_name).map(PathBuf::from) + } +} + +pub struct OvmfPaths { + code: PathBuf, + vars: PathBuf, + shell: PathBuf, + temp_dir: Option, + temp_vars: Option, +} + +impl OvmfPaths { + pub fn code(&self) -> &PathBuf { + &self.code + } + + pub fn vars(&self) -> &PathBuf { + self.temp_vars.as_ref().unwrap_or(&self.vars) + } + + pub fn shell(&self) -> &PathBuf { + &self.shell + } + + /// Search for an OVMF file (either code or vars). + /// + /// There are multiple locations where a file is searched at in the following + /// priority: + /// 1. Command-line arg + /// 2. Environment variable + /// 3. Prebuilt file (automatically downloaded) + pub fn find_ovmf_file(file_type: OvmfFileType) -> PathBuf { + if let Some(path) = file_type.get_user_provided_path() { + // The user provided an exact path to use; verify that it + // exists. + if path.exists() { + path + } else { + panic!( + "ovmf {} file does not exist: {}", + file_type.as_str(), + path.display() + ); + } + } else { + let prebuilt_dir = update_prebuilt(); + + prebuilt_dir.join(format!( + "x86_64/{}.{}", + file_type.as_str(), + file_type.extension() + )) + } + } + + /// Find path to OVMF files by the strategy documented for + /// [`Self::find_ovmf_file`]. + pub fn find() -> Self { + let code = Self::find_ovmf_file(OvmfFileType::Code); + let vars = Self::find_ovmf_file(OvmfFileType::Vars); + let shell = Self::find_ovmf_file(OvmfFileType::Shell); + + Self { + code, + vars, + shell, + temp_dir: None, + temp_vars: None, + } + } + + /// Creates a copy with a writable, temp copy + pub fn with_temp_vars(&mut self) { + let temp_dir = TempDir::new().expect("Failed to create temp directory"); + let temp_path = temp_dir.path(); + + // Make a copy of the OVMF vars file so that it can be used + // read+write without modifying the original. Under AArch64, some + // versions of OVMF won't boot if the vars file isn't writeable. + let ovmf_vars = temp_path.join("ovmf_vars"); + copy(&self.vars, &ovmf_vars).expect("Failed to copy vars file to a temp location"); + // Necessary, as for example on NixOS, the files are read-only inside + // the Nix store. + #[cfg(target_os = "linux")] + set_permissions(&ovmf_vars, Permissions::from_mode(0o666)) + .expect("Failed to set permissions on temp vars file"); + + self.temp_vars = Some(ovmf_vars); + self.temp_dir = Some(temp_dir); + } +} + +/// Update the local copy of the prebuilt OVMF files. Does nothing if the local +/// copy is already up to date. +fn update_prebuilt() -> PathBuf { + let prebuilt_dir = Path::new(OVMF_PREBUILT_DIR); + let hash_path = prebuilt_dir.join("sha256"); + + // Check if the hash file already has the expected hash in it. If so, assume + // that we've already got the correct prebuilt downloaded and unpacked. + if let Ok(current_hash) = read_to_string(&hash_path) { + if current_hash == OVMF_PREBUILT_HASH { + return prebuilt_dir.to_path_buf(); + } + } + + let base_url = "https://github.com/rust-osdev/ovmf-prebuilt/releases/download"; + let url = format!( + "{base_url}/{release}/{release}-bin.tar.xz", + release = OVMF_PREBUILT_TAG + ); + + let data = download_url(&url); + + // Validate the hash. + let actual_hash = format!("{:x}", Sha256::digest(&data)); + if actual_hash != OVMF_PREBUILT_HASH { + panic!( + "file hash {actual_hash} does not match {}", + OVMF_PREBUILT_HASH + ); + } + + // Unpack the tarball. + println!("decompressing tarball"); + let mut decompressed = Vec::new(); + let mut compressed = Cursor::new(data); + lzma_rs::xz_decompress(&mut compressed, &mut decompressed) + .expect("Failed to decompress tarball"); + + // Clear out the existing prebuilt dir, if present. + let _ = remove_dir_all(prebuilt_dir); + + // Extract the files. + extract_prebuilt(&decompressed, prebuilt_dir); + + // Rename the x64 directory to x86_64, to match `Arch::as_str`. + rename(prebuilt_dir.join("x64"), prebuilt_dir.join("x86_64")) + .expect("Failed to rename x64 artefacts"); + + // Write out the hash file. When we upgrade to a new release of + // ovmf-prebuilt, the hash will no longer match, triggering a fresh + // download. + write(&hash_path, actual_hash).expect("Failed to save calculated hash"); + + prebuilt_dir.to_path_buf() +} + +/// Download `url` and return the raw data. +fn download_url(url: &str) -> Vec { + let agent: Agent = ureq::AgentBuilder::new() + .user_agent("uefi-rs-ovmf-downloader") + .build(); + + // Limit the size of the download. + let max_size_in_bytes = 5 * 1024 * 1024; + + // Download the file. + println!("downloading {url}"); + let resp = agent.get(url).call().unwrap(); + let mut data = Vec::with_capacity(max_size_in_bytes); + resp.into_reader() + .take(max_size_in_bytes.try_into().unwrap()) + .read_to_end(&mut data) + .unwrap(); + println!("received {} bytes", data.len()); + + data +} + +// Extract the tarball's files into `prebuilt_dir`. +// +// `tarball_data` is raw decompressed tar data. +fn extract_prebuilt(tarball_data: &[u8], prebuilt_dir: &Path) { + let cursor = Cursor::new(tarball_data); + let mut archive = Archive::new(cursor); + + // Extract each file entry. + for entry in archive.entries().unwrap() { + let mut entry = entry.unwrap(); + + // Skip directories. + if entry.size() == 0 { + continue; + } + + let path = entry.path().unwrap(); + // Strip the leading directory, which is the release name. + let path: PathBuf = path.components().skip(1).collect(); + + let dir = path.parent().unwrap(); + let dst_dir = prebuilt_dir.join(dir); + let dst_path = prebuilt_dir.join(path); + println!("unpacking to {}", dst_path.display()); + create_dir_all(dst_dir).unwrap(); + entry.unpack(dst_path).unwrap(); + } +} diff --git a/uefi/Cargo.toml b/uefi/Cargo.toml index 80168be5..c457e17e 100644 --- a/uefi/Cargo.toml +++ b/uefi/Cargo.toml @@ -15,4 +15,5 @@ bootloader-boot-config = { workspace = true } log = "0.4.14" x86_64 = "0.14.8" serde-json-core = "0.5.0" -uefi = "0.20.0" +uefi = "0.32.0" + diff --git a/uefi/src/main.rs b/uefi/src/main.rs index 93dfb6c7..67dec389 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -9,12 +9,17 @@ use bootloader_x86_64_common::{ legacy_memory_region::LegacyFrameAllocator, Kernel, RawFrameBufferInfo, SystemInfo, }; use core::{ - cell::UnsafeCell, ops::{Deref, DerefMut}, ptr, slice, + sync::atomic::AtomicBool, }; use uefi::{ - prelude::{entry, Boot, Handle, Status, SystemTable}, + boot::{ + allocate_pages, exit_boot_services, get_handle_for_protocol, image_handle, + locate_device_path, open_protocol, ScopedProtocol, + }, + mem::memory_map::{MemoryMap, MemoryMapMut}, + prelude::{entry, Handle, Status}, proto::{ console::gop::{GraphicsOutput, PixelFormat}, device_path::DevicePath, @@ -29,9 +34,8 @@ use uefi::{ }, ProtocolPointer, }, - table::boot::{ - AllocateType, MemoryType, OpenProtocolAttributes, OpenProtocolParams, ScopedProtocol, - }, + system::with_config_table, + table::boot::{AllocateType, MemoryType, OpenProtocolAttributes, OpenProtocolParams}, CStr16, CStr8, }; use x86_64::{ @@ -41,48 +45,26 @@ use x86_64::{ mod memory_descriptor; -static SYSTEM_TABLE: RacyCell>> = RacyCell::new(None); - -struct RacyCell(UnsafeCell); - -impl RacyCell { - const fn new(v: T) -> Self { - Self(UnsafeCell::new(v)) - } -} - -unsafe impl Sync for RacyCell {} - -impl core::ops::Deref for RacyCell { - type Target = UnsafeCell; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} +static SYSTEM_SERVICE_AVAILABLE: AtomicBool = AtomicBool::new(true); #[entry] -fn efi_main(image: Handle, st: SystemTable) -> Status { - main_inner(image, st) +fn efi_main() -> Status { + main_inner() } -fn main_inner(image: Handle, mut st: SystemTable) -> Status { - // temporarily clone the y table for printing panics - unsafe { - *SYSTEM_TABLE.get() = Some(st.unsafe_clone()); - } - +fn main_inner() -> Status { let mut boot_mode = BootMode::Disk; + let image = image_handle(); - let mut kernel = load_kernel(image, &mut st, boot_mode); + let mut kernel = load_kernel(image, boot_mode); if kernel.is_none() { // Try TFTP boot boot_mode = BootMode::Tftp; - kernel = load_kernel(image, &mut st, boot_mode); + kernel = load_kernel(image, boot_mode); } let kernel = kernel.expect("Failed to load kernel"); - let config_file = load_config_file(image, &mut st, boot_mode); + let config_file = load_config_file(image, boot_mode); let mut error_loading_config: Option = None; let mut config: BootConfig = match config_file .as_deref() @@ -96,22 +78,17 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { } }; - #[allow(deprecated)] + #[allow(deprecated)] // allow writing the kernel config framebuffer if config.frame_buffer.minimum_framebuffer_height.is_none() { config.frame_buffer.minimum_framebuffer_height = kernel.config.frame_buffer.minimum_framebuffer_height; } - #[allow(deprecated)] + #[allow(deprecated)] // allow writing the kernel config framebuffer if config.frame_buffer.minimum_framebuffer_width.is_none() { config.frame_buffer.minimum_framebuffer_width = kernel.config.frame_buffer.minimum_framebuffer_width; } - let framebuffer = init_logger(image, &st, &config); - - unsafe { - *SYSTEM_TABLE.get() = None; - } - + let framebuffer = init_logger(image, &config); log::info!("UEFI bootloader started"); if let Some(framebuffer) = framebuffer { @@ -126,7 +103,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { log::info!("Trying to load ramdisk via {:?}", boot_mode); // Ramdisk must load from same source, or not at all. - let ramdisk = load_ramdisk(image, &mut st, boot_mode); + let ramdisk = load_ramdisk(image, boot_mode); log::info!( "{}", @@ -137,7 +114,9 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { ); log::trace!("exiting boot services"); - let (system_table, mut memory_map) = st.exit_boot_services(); + SYSTEM_SERVICE_AVAILABLE.store(false, core::sync::atomic::Ordering::SeqCst); + let mut memory_map = unsafe { exit_boot_services(MemoryType::LOADER_DATA) }; + log::trace!("exit boot service done"); memory_map.sort(); @@ -156,13 +135,15 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { framebuffer, rsdp_addr: { use uefi::table::cfg; - let mut config_entries = system_table.config_table().iter(); - // look for an ACPI2 RSDP first - let acpi2_rsdp = config_entries.find(|entry| matches!(entry.guid, cfg::ACPI2_GUID)); - // if no ACPI2 RSDP is found, look for a ACPI1 RSDP - let rsdp = acpi2_rsdp - .or_else(|| config_entries.find(|entry| matches!(entry.guid, cfg::ACPI_GUID))); - rsdp.map(|entry| PhysAddr::new(entry.address as u64)) + with_config_table(|config_table| { + let mut config_entries = config_table.iter(); + // look for an ACPI2 RSDP first + let acpi2_rsdp = config_entries.find(|entry| matches!(entry.guid, cfg::ACPI2_GUID)); + // if no ACPI2 RSDP is found, look for a ACPI1 RSDP + let rsdp = acpi2_rsdp + .or_else(|| config_entries.find(|entry| matches!(entry.guid, cfg::ACPI_GUID))); + rsdp.map(|entry| PhysAddr::new(entry.address as u64)) + }) }, ramdisk_addr, ramdisk_len, @@ -183,50 +164,33 @@ pub enum BootMode { Tftp, } -fn load_ramdisk( - image: Handle, - st: &mut SystemTable, - boot_mode: BootMode, -) -> Option<&'static mut [u8]> { - load_file_from_boot_method(image, st, "ramdisk\0", boot_mode) +fn load_ramdisk(image: Handle, boot_mode: BootMode) -> Option<&'static mut [u8]> { + load_file_from_boot_method(image, "ramdisk\0", boot_mode) } -fn load_config_file( - image: Handle, - st: &mut SystemTable, - boot_mode: BootMode, -) -> Option<&'static mut [u8]> { - load_file_from_boot_method(image, st, "boot.json\0", boot_mode) +fn load_config_file(image: Handle, boot_mode: BootMode) -> Option<&'static mut [u8]> { + load_file_from_boot_method(image, "boot.json\0", boot_mode) } -fn load_kernel( - image: Handle, - st: &mut SystemTable, - boot_mode: BootMode, -) -> Option> { - let kernel_slice = load_file_from_boot_method(image, st, "kernel-x86_64\0", boot_mode)?; +fn load_kernel(image: Handle, boot_mode: BootMode) -> Option> { + let kernel_slice = load_file_from_boot_method(image, "kernel-x86_64\0", boot_mode)?; Some(Kernel::parse(kernel_slice)) } fn load_file_from_boot_method( image: Handle, - st: &mut SystemTable, filename: &str, boot_mode: BootMode, ) -> Option<&'static mut [u8]> { match boot_mode { - BootMode::Disk => load_file_from_disk(filename, image, st), - BootMode::Tftp => load_file_from_tftp_boot_server(filename, image, st), + BootMode::Disk => load_file_from_disk(filename, image), + BootMode::Tftp => load_file_from_tftp_boot_server(filename, image), } } -fn open_device_path_protocol( - image: Handle, - st: &SystemTable, -) -> Option> { - let this = st.boot_services(); +fn open_device_path_protocol(image: Handle) -> Option> { let loaded_image = unsafe { - this.open_protocol::( + open_protocol::( OpenProtocolParams { handle: image, agent: image, @@ -243,10 +207,10 @@ fn open_device_path_protocol( let loaded_image = loaded_image.unwrap(); let loaded_image = loaded_image.deref(); - let device_handle = loaded_image.device(); + let device_handle = loaded_image.device()?; let device_path = unsafe { - this.open_protocol::( + open_protocol::( OpenProtocolParams { handle: device_handle, agent: image, @@ -262,15 +226,11 @@ fn open_device_path_protocol( Some(device_path.unwrap()) } -fn locate_and_open_protocol( - image: Handle, - st: &SystemTable, -) -> Option> { - let this = st.boot_services(); - let device_path = open_device_path_protocol(image, st)?; +fn locate_and_open_protocol(image: Handle) -> Option> { + let device_path = open_device_path_protocol(image)?; let mut device_path = device_path.deref(); - let fs_handle = this.locate_device_path::

(&mut device_path); + let fs_handle = locate_device_path::

(&mut device_path); if fs_handle.is_err() { log::error!("Failed to open device path"); return None; @@ -279,7 +239,7 @@ fn locate_and_open_protocol( let fs_handle = fs_handle.unwrap(); let opened_handle = unsafe { - this.open_protocol::

( + open_protocol::

( OpenProtocolParams { handle: fs_handle, agent: image, @@ -296,12 +256,8 @@ fn locate_and_open_protocol( Some(opened_handle.unwrap()) } -fn load_file_from_disk( - name: &str, - image: Handle, - st: &SystemTable, -) -> Option<&'static mut [u8]> { - let mut file_system_raw = locate_and_open_protocol::(image, st)?; +fn load_file_from_disk(name: &str, image: Handle) -> Option<&'static mut [u8]> { + let mut file_system_raw = locate_and_open_protocol::(image)?; let file_system = file_system_raw.deref_mut(); let mut root = file_system.open_volume().unwrap(); @@ -326,14 +282,13 @@ fn load_file_from_disk( let file_info: &mut FileInfo = file.get_info(&mut buf).unwrap(); let file_size = usize::try_from(file_info.file_size()).unwrap(); - let file_ptr = st - .boot_services() - .allocate_pages( - AllocateType::AnyPages, - MemoryType::LOADER_DATA, - ((file_size - 1) / 4096) + 1, - ) - .unwrap() as *mut u8; + let file_ptr = allocate_pages( + AllocateType::AnyPages, + MemoryType::LOADER_DATA, + ((file_size - 1) / 4096) + 1, + ) + .unwrap() + .as_ptr(); unsafe { ptr::write_bytes(file_ptr, 0, file_size) }; let file_slice = unsafe { slice::from_raw_parts_mut(file_ptr, file_size) }; file.read(file_slice).unwrap(); @@ -342,12 +297,8 @@ fn load_file_from_disk( } /// Try to load a kernel from a TFTP boot server. -fn load_file_from_tftp_boot_server( - name: &str, - image: Handle, - st: &SystemTable, -) -> Option<&'static mut [u8]> { - let mut base_code_raw = locate_and_open_protocol::(image, st)?; +fn load_file_from_tftp_boot_server(name: &str, image: Handle) -> Option<&'static mut [u8]> { + let mut base_code_raw = locate_and_open_protocol::(image)?; let base_code = base_code_raw.deref_mut(); // Find the TFTP boot server. @@ -364,14 +315,13 @@ fn load_file_from_tftp_boot_server( let kernel_size = usize::try_from(file_size).expect("The file size should fit into usize"); // Allocate some memory for the kernel file. - let ptr = st - .boot_services() - .allocate_pages( - AllocateType::AnyPages, - MemoryType::LOADER_DATA, - ((kernel_size - 1) / 4096) + 1, - ) - .expect("Failed to allocate memory for the file") as *mut u8; + let ptr = allocate_pages( + AllocateType::AnyPages, + MemoryType::LOADER_DATA, + ((kernel_size - 1) / 4096) + 1, + ) + .expect("Failed to allocate memory for the file") + .as_ptr(); let slice = unsafe { slice::from_raw_parts_mut(ptr, kernel_size) }; // Load the kernel file. @@ -448,26 +398,18 @@ fn create_page_tables( } } -fn init_logger( - image_handle: Handle, - st: &SystemTable, - config: &BootConfig, -) -> Option { - let gop_handle = st - .boot_services() - .get_handle_for_protocol::() - .ok()?; +fn init_logger(image_handle: Handle, config: &BootConfig) -> Option { + let gop_handle = get_handle_for_protocol::().ok()?; let mut gop = unsafe { - st.boot_services() - .open_protocol::( - OpenProtocolParams { - handle: gop_handle, - agent: image_handle, - controller: None, - }, - OpenProtocolAttributes::Exclusive, - ) - .ok()? + open_protocol::( + OpenProtocolParams { + handle: gop_handle, + agent: image_handle, + controller: None, + }, + OpenProtocolAttributes::Exclusive, + ) + .ok()? }; let mode = { @@ -537,10 +479,14 @@ fn init_logger( fn panic(info: &core::panic::PanicInfo) -> ! { use core::arch::asm; use core::fmt::Write; - - if let Some(st) = unsafe { &mut *SYSTEM_TABLE.get() } { - let _ = st.stdout().clear(); - let _ = writeln!(st.stdout(), "{}", info); + use uefi::system::with_stdout; + + if SYSTEM_SERVICE_AVAILABLE.load(core::sync::atomic::Ordering::SeqCst) { + // this panics after the exit_boot_services call + with_stdout(|stdout| { + let _ = stdout.clear(); + let _ = writeln!(stdout, "{}", info); + }); } unsafe {