├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── docs ├── design.md ├── images │ ├── 2020demo.gif │ ├── Untitled Diagram.drawio │ └── demo3.gif ├── linux-image-setup-64.md └── specifications.md ├── resources ├── .config └── eg-kernel │ ├── .cargo │ └── config.toml │ ├── Cargo.toml │ ├── example.ld │ ├── i586-example_os.json │ ├── rust-toolchain │ ├── src │ └── main.rs │ └── x64-example_os.json ├── rust-toolchain └── src ├── bios ├── plankton │ ├── Cargo.toml │ └── src │ │ ├── con.rs │ │ ├── dev.rs │ │ ├── ios.rs │ │ ├── layout.rs │ │ ├── lib.rs │ │ └── mem.rs ├── stage_1st │ ├── Cargo.toml │ ├── i586-stage_1st.json │ ├── src │ │ ├── lib.rs │ │ └── main.rs │ └── stage_1st.ld ├── stage_2nd │ ├── Cargo.toml │ ├── i586-stage_2nd.json │ ├── src │ │ ├── lib.rs │ │ └── main.rs │ └── stage_2nd.ld ├── stage_3rd │ ├── Cargo.toml │ ├── i586-stage_3rd.json │ ├── src │ │ ├── init.rs │ │ ├── init │ │ │ ├── a20.rs │ │ │ ├── cur.rs │ │ │ ├── ist.rs │ │ │ ├── kbd.rs │ │ │ ├── msz.rs │ │ │ ├── vid.rs │ │ │ ├── vrs.rs │ │ │ └── zero.rs │ │ ├── lib.rs │ │ ├── main.rs │ │ ├── mpm.rs │ │ └── rfn.rs │ └── stage_3rd.ld └── stage_4th │ ├── Cargo.toml │ ├── i586-stage_4th.json │ ├── src │ ├── fs │ │ ├── blkdev.rs │ │ ├── fat32.rs │ │ ├── fat32 │ │ │ ├── dir.rs │ │ │ └── file.rs │ │ ├── gpt.rs │ │ └── mod.rs │ ├── lib.rs │ ├── loader.rs │ ├── loader │ │ ├── config.rs │ │ └── elf.rs │ ├── main.rs │ ├── svm │ │ ├── lm.rs │ │ ├── mod.rs │ │ ├── pm.rs │ │ └── rm.rs │ └── text.rs │ └── stage_4th.ld └── main.rs /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: ellbrid 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *target 2 | *test.img 3 | Cargo.lock 4 | bochsrc 5 | settings.json 6 | disk*.img -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at ell@exoskeleton.dev. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributions Welcome 2 | Thank you for your interest in contributing to this project. Any bug reports, new features, correction, or additional documentation are welcome. 3 | 4 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary information to effectively respond to your bug report or contribution. 5 | 6 | ## Contribution Workflow 7 | Krabs uses the “fork-and-pull” development model. Follow these steps if you want to merge your changes to Krabs: 8 | 9 | 1. Within your fork of Krabs, create a branch for your contribution. Use a meaningful name. 10 | 2. Create a pull request against the master branch of the repository. 11 | 3. Once the pull request is approved, Krabs will merge it. 12 | 13 | ## Reporting Bugs/Feature Requests 14 | Krabs welcome you to use the GitHub issue tracker to report bugs or suggest features. 15 | 16 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 17 | 18 | * A reproducible test case or series of steps 19 | * The version of our code being used 20 | * Any modifications you've made relevant to the bug 21 | * Anything unusual about your environment or deployment 22 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "krabs" 3 | version = "0.1.0" 4 | authors = ["Hayato Ohhashi "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | structopt = "0.3.15" 11 | gpt = "1.0.0" 12 | 13 | [build-dependencies] 14 | llvm-tools = "0.1.1" 15 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 Hayato Ohhashi 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Hayato Ohhashi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KRaBs: Kernel Reader and Booters 2 | KRaBs is an x86/x86_64 chain loader written in pure Rust. 3 | 4 | ## What is KRaBs? 5 | KRaBs is working on booting vmlinux and other kernels formatted in ELF on 32-bit/64-bit PCs and is under the development. Krabs also aims to support only the minimal Linux x86/x86_64 boot protocol. This allows you to use the kernel command line and initrd/initramfs. 6 | 7 | Other features: 8 | * Supports GPT and FAT32 File System on EFI System Partition(ESP). 9 | * You can configure KRaBs's boot option in CONFIG.TXT on FAT32 ESP. 10 | * CONFIG.TXT is a simple matrix-oriented text file. See [CONFIG.TXT formats](#configtxt-format). 11 | 12 | ## News 13 | * 2020/08: **Currently, KRaBs can boot kernel-5.8.3! initrd and kernel command line also work fine!!**. see [details](docs/linux-image-setup-64.md) 14 | ``` 15 | cargo run -- -we disk.img 16 | ``` 17 | 18 | ![sample](./docs/images/demo3.gif) 19 | 20 | ## Getting Started 21 | To get started with KRaBs, build it from source. 22 | 23 | ### Requirements 24 | 1. `rust-src` and `llvm-tools-preview` 25 | 2. GPTed disk image that has BIOS Boot Partition and EFI System Partition. 26 | 3. CONFIG.TXT, kernel image and initrd on FAT32 FileSystem on EFI System Partition. 27 | 4. (option) qemu-system-x86 28 | 29 | #### Prepare `rust-src` and `llvm-tools-preview` 30 | ```shell 31 | $ cd /path/to/krabs 32 | $ rustup component add rust-src 33 | $ rustup component add llvm-tools-preview 34 | ``` 35 | 36 | #### Example of GPT disk image: 37 | ```shell 38 | $ gdisk -l disk.img 39 | ... 40 | Found valid GPT with protective MBR; using GPT. 41 | Disk disk2.img: 204800 sectors, 100.0 MiB 42 | Sector size (logical): 512 bytes 43 | Disk identifier (GUID): 2A1F86BB-74EA-47C5-923A-7A3BAF83B5DF 44 | Partition table holds up to 128 entries 45 | Main partition table begins at sector 2 and ends at sector 33 46 | First usable sector is 34, last usable sector is 204766 47 | Partitions will be aligned on 2048-sector boundaries 48 | Total free space is 2014 sectors (1007.0 KiB) 49 | 50 | Number Start (sector) End (sector) Size Code Name 51 | 1 2048 4095 1024.0 KiB EF02 BIOS boot partition 52 | 2 4096 106495 50.0 MiB EF00 EFI system partition 53 | 3 106496 204766 48.0 MiB 8300 Linux filesystem 54 | $ sudo kpartx -av disk.img 55 | $ sudo mkfs.fat -F 32 /dev/mapper/loop0p2 56 | $ sudo mkfs.ext4 /dev/mapper/loop0p3 57 | ``` 58 | 59 | #### Prepare CONFIG.TXT, kernel, initrd: 60 | ```shell 61 | $ sudo mount /dev/mapper/loop0p2 /mnt 62 | $ ls /mnt 63 | CONFIG.TXT initramfs.cpio.gz vmlinux-5.8.3 64 | ``` 65 | 66 | #### CONFIG.TXT format 67 | simple matrix-oriented text file 68 | ```shell 69 | main.kernel vmlinux-5.8.3 70 | main.initrd initramfs.cpio.gz 71 | main.cmdlin clocksource=tsc net.ifnames=0 72 | ``` 73 | 74 | ### Build 75 | ```shell 76 | cargo build 77 | ``` 78 | 79 | ### Burn 80 | ```shell 81 | cargo run -- -w disk.img 82 | ``` 83 | 84 | ### Test 85 | ```shell 86 | cargo run -- -e disk.img 87 | ``` 88 | 89 | ## Examples 90 | Examples for x86-64 Linux is described in 91 | [the docs of 'Creating Custom Linux Images and Booting'](docs/linux-image-setup-64.md). 92 | 93 | ## Contributing 94 | KRaBs welcomes all contributions. 95 | To contribute to KRaBs, check out the [getting started guide](#getting-started) 96 | and then the KRaBs [contribution guidelines](CONTRIBUTING.md). 97 | 98 | ## Design 99 | KRaBs's overall architecture is described in 100 | [the design document](docs/design.md) and 101 | [the specification document](docs/specifications.md). 102 | 103 | ## Features 104 | 1. Supports legacy BIOS. 105 | 2. Supported media are HDD and SSD which have GPT. 106 | 3. Supports 32bit protected mode and 64bit long mode. 107 | 4. Supports OS kernel formatted in ELF32/ELF64. 108 | 5. Supports minimal 109 | [x86/x86_64 linux boot protocol](https://www.kernel.org/doc/html/latest/x86/boot.html). 110 | 6. KRaBs interprets the FAT32 file system. 111 | 7. KRaBs's boot optuon is configureset by CONFIG.TXT on the FAT32 file system. 112 | 7. KRaBs can load modules such as initramsfs/initrd according to linux boot protocol. 113 | 8. KRaBs can transmit kernel command line to the kernel according to linux boot protocol. 114 | 115 | ## ToDO 116 | 1. support gziped kernel. 117 | 2. support recovery mode. 118 | 119 | ## License 120 | This project is licensed under either of 121 | 122 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or 123 | http://www.apache.org/licenses/LICENSE-2.0) 124 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or 125 | http://opensource.org/licenses/MIT) 126 | 127 | at your option. 128 | 129 | Unless you explicitly state otherwise, any contribution intentionally submitted 130 | for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be 131 | dual licensed as above, without any additional terms or conditions. 132 | 133 | ## Contact 134 | You can get in touch with me in the following ways: 135 | 136 | * Contact me on my [twitter](https://twitter.com/o8_vm). 137 | * Open a GitHub issue in this repository. 138 | * Email me at [o8@vmm.dev](mailto:o8@vmm.dev). 139 | 140 | _Note: I'm on a Japan time zone._ 141 | 142 | When communicating within the Krabs community, please mind our 143 | [code of conduct](CODE_OF_CONDUCT.md). 144 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use llvm_tools::{exe, LlvmTools}; 2 | use std::env; 3 | use std::path::Path; 4 | use std::process::Command; 5 | 6 | fn main() { 7 | let cargo_path = env::var("CARGO").expect("Missing CARGO environment variable"); 8 | let cargo = Path::new(&cargo_path); 9 | let llvm_tools = LlvmTools::new().expect("LLVM tools not found"); 10 | let objcopy = llvm_tools 11 | .tool(&exe("llvm-objcopy")) 12 | .expect("llvm-objcopy not found"); 13 | 14 | let manifest_dir_path = 15 | env::var("CARGO_MANIFEST_DIR").expect("Missing CARGO_MANIFEST_DIR environment variable"); 16 | let manifest_dir = Path::new(&manifest_dir_path); 17 | let current_dir = env::current_dir().expect("Couldn't get current directory"); 18 | let target_dir_rel = manifest_dir.join("target"); 19 | let target_dir = current_dir.join(target_dir_rel); 20 | 21 | // build stage 1st 22 | let stage_1st_dir = manifest_dir.join("src/bios/stage_1st"); 23 | let stage_1st_triple = stage_1st_dir.join("i586-stage_1st.json"); 24 | build_subproject( 25 | &stage_1st_dir, 26 | &stage_1st_triple, 27 | &target_dir, 28 | &objcopy, 29 | &cargo, 30 | ); 31 | 32 | // build stage_2nd 33 | let stage_2nd_dir = manifest_dir.join("src/bios/stage_2nd"); 34 | let stage_2nd_triple = stage_2nd_dir.join("i586-stage_2nd.json"); 35 | build_subproject( 36 | &stage_2nd_dir, 37 | &stage_2nd_triple, 38 | &target_dir, 39 | &objcopy, 40 | &cargo, 41 | ); 42 | 43 | // build stage_3rd 44 | let stage_3rd_dir = manifest_dir.join("src/bios/stage_3rd"); 45 | let stage_3rd_triple = stage_3rd_dir.join("i586-stage_3rd.json"); 46 | build_subproject( 47 | &stage_3rd_dir, 48 | &stage_3rd_triple, 49 | &target_dir, 50 | &objcopy, 51 | &cargo, 52 | ); 53 | 54 | // build stage_4th 55 | let stage_4th_dir = manifest_dir.join("src/bios/stage_4th"); 56 | let stage_4th_triple = stage_4th_dir.join("i586-stage_4th.json"); 57 | build_subproject( 58 | &stage_4th_dir, 59 | &stage_4th_triple, 60 | &target_dir, 61 | &objcopy, 62 | &cargo, 63 | ); 64 | } 65 | 66 | fn build_subproject( 67 | subproject_dir: &Path, 68 | target_triple: &Path, 69 | root_target_dir: &Path, 70 | objcopy: &Path, 71 | cargo: &Path, 72 | ) { 73 | println!("cargo:rerun-if-changed={}", &target_triple.display()); 74 | println!("cargo:rerun-if-changed={}", &subproject_dir.display()); 75 | // build 76 | let subproject_name = subproject_dir 77 | .file_stem() 78 | .expect("Couldn't get subproject name") 79 | .to_str() 80 | .expect("Subproject Name is not valid UTF-8"); 81 | let target_file = Path::new(&target_triple) 82 | .file_stem() 83 | .expect("Couldn't get target file stem"); 84 | let target_dir = root_target_dir.join(&subproject_name); 85 | 86 | let mut build_cmd = Command::new(cargo); 87 | build_cmd.current_dir(&subproject_dir); 88 | build_cmd.arg("build").arg("--release"); 89 | build_cmd.arg("-Zbuild-std=core,alloc"); 90 | build_cmd.arg(format!("--target-dir={}", &target_dir.display())); 91 | build_cmd.arg("--target").arg(target_triple); 92 | let build_status = build_cmd.status().expect("Subcrate build failed!"); 93 | assert!(build_status.success(), "Subcrate build failed!"); 94 | 95 | // llvm-objcopy 96 | let object_dir = target_dir.join(&target_file).join("release"); 97 | let object_path = object_dir.join(&subproject_name); 98 | let binary_path = object_dir.join(subproject_name.to_string() + ".bin"); 99 | let mut objcopy_cmd = Command::new(objcopy); 100 | objcopy_cmd 101 | .arg("-I") 102 | .arg("elf32-i386") 103 | .arg("-O") 104 | .arg("binary"); 105 | objcopy_cmd.arg(object_path); 106 | objcopy_cmd.arg(binary_path); 107 | let objcopy_status = objcopy_cmd.status().expect("Objcopy failed!"); 108 | assert!(objcopy_status.success(), "Objcopy failed!"); 109 | } 110 | -------------------------------------------------------------------------------- /docs/design.md: -------------------------------------------------------------------------------- 1 | # KRaBs Design 2 | 3 | ## Scope 4 | 5 | ### What is KRaBs 6 | KRaBs is working on booting vmlinux and other kernels formatted in ELF on 7 | 32-bit/64-bit PCs and is under the development. Krabs also aims to support only the minimal Linux x86/x86_64 boot protocol. 8 | This allows you to specify the kernel command line and initrd/initramfs. 9 | 10 | ### Features 11 | 1. Supports legacy BIOS. 12 | 2. Supported media are HDD and SSD which have GPT. 13 | 3. GPT must have BIOS Boot Partition and EFI System Partition. 14 | 4. Supports 32bit protected mode and 64bit long mode. 15 | 5. Supports OS kernel formatted in ELF32/ELF64. 16 | 6. Supports minimal 17 | [x86/x86_64 linux boot protocol](https://www.kernel.org/doc/html/latest/x86/boot.html). 18 | 7. KRaBs interprets the FAT32 file system and is set by CONFIG.TXT on the that file system. 19 | 8. KRaBs can load modules such as initramsfs/initrd according to linux boot protocol. 20 | 9. KRaBs can transmit kernel command line to the kernel according to linux boot protocol. 21 | 22 | ### Specifications 23 | KRaBs's technical specifications are available in 24 | [the Specifications document](specifications.md). 25 | KRaBs supports only the minimal 26 | [x86 Linux boot protocol](https://www.kernel.org/doc/html/latest/x86/boot.html). 27 | So your OS needs to use this as well. 28 | Read more about it in [the Specification document](specifications.md). 29 | 30 | ### CONFIG.TXT formats 31 | simple matrix-oriented text file like this: 32 | ``` 33 | main.kernel sample-kernel 34 | main.initrd sample-initrd 35 | main.cmdlin sample command line clocksource=tsc net.ifnames=0 36 | ``` 37 | 38 | ## How KRaBs works 39 | The minimum requirement for booting an ELF-formatted kernel is that the kernel 40 | image must be parsed and loaded to the address specified in the program header. 41 | In this project, the following four types of initialization processing are 42 | performed. 43 | 44 | **Hardware initialization:** 45 | * Setting the keyboard repeat rate. 46 | * Disable interrupts and mask all interrupt levels. 47 | * Setting Interrupt descriptor (IDT) and segment descriptor (GDT). As a result, 48 | all selectors (CS, DS, ES, FS, GS) refer to the 4 Gbyte flat linear address 49 | space. 50 | * Change the address bus to 32 bits (Enable A20 line). 51 | * Transition to protected mode. 52 | * If the target is ELF64, set the 4G boot pagetable and transition to long mode. 53 | 54 | **Software initialization:** 55 | * Get system memory by BIOS call. 56 | 57 | **Information transmission to the kernel:** 58 | * KRaBs mount the FAT32 EFI System Partition and Reading the CONFIG.TXT. 59 | * Setting [Zero Page](https://www.kernel.org/doc/html/latest/x86/zero-page.html) 60 | of kernel parameters and transmit it to the OS. 61 | 62 | **Load items and Relocate the kernel:** 63 | * Load kernel, initrd and command line according to CONFIG.TXT. 64 | * The target is an ELF file, KRaBs do the ELF relocation. 65 | 66 | ## Structure and Overview 67 | 1. stage1 68 | A 446 byte program written to the boot sector. The segment registers(CS, DS, ES, SS) are set to `0x07C0`, and the stack pointer (ESP) is initialized to `0xFFF0`. After that, stage2 is loaded to address `0x07C0:0x0200`, and jumps to address `0x07C0:0x0206`. In the latter half of stage1, there is an area for storing the sector position and length (in units of 512 bytes) of the stage2 program. 69 | 2. stage2 70 | Load stage3 and stage4, then jump to stage3. The stage3 program is loaded at address `0x07C0:0x6000`, the stage4 is loaded at address `0x0003_0000` in the extended memory area. The file is read from the disk using a 2K byte track buffer from address `0x07C0:0xEE00`, and further transferred to an appropriate address using `INT 15h` BIOS Function `0x87h`. A mechanism similar to this function is used in stage 4. When the loading of stage3 and stage4 is completed, jump to address `0x07C0:0x6000`. 71 | 3. stage3 72 | Do hardware and software initialization which need BIOS calls. After a series of initialization, empty_zero_page information is prepared in `0x07C0:0x0000` to `0x07C0:0x0FFF`. Enable the A20 line, change the address bus to 32 bits, and shift to the protect mode. Then, jump to the Stage4. 73 | 4. stage4 74 | Mount the FAT32 EFI System Partition. Then, read and parse the CONFIG.TXT on that partition. Load ELF kernel image, initrd, and kernel command line according to CONFIG.TXT. Drop to real mode when executing I/O. Set Command line and image informations in empty_zero_page. ELF kernel image is stored to the extended memory address `0x100000` or later, and then the ELF32/ELF64 file is parsed and loaded. If the target is ELF64, set the 4G boot pagetable and transition to long mode. Finally, jump to the entry point to launch the kernel. At this time, put the physical address (`0x00007C00`) of the empty_zero_page information prepared in the low-order memory into the `ESI` or `RSI` register. 75 | 76 | 5. plankton🦠 77 | library common to stage1 ~ stage4. -------------------------------------------------------------------------------- /docs/images/2020demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/o8vm/krabs/4cb5edc8e55a11ef4c54e6b0d22aad225d92b911/docs/images/2020demo.gif -------------------------------------------------------------------------------- /docs/images/Untitled Diagram.drawio: -------------------------------------------------------------------------------- 1 | UzV2zq1wL0osyPDNT0nNUTV2VTV2LsrPL4GwciucU3NyVI0MMlNUjV1UjYwMgFjVyA2HrCFY1qAgsSg1rwSLBiADYTaQg2Y1AA== -------------------------------------------------------------------------------- /docs/images/demo3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/o8vm/krabs/4cb5edc8e55a11ef4c54e6b0d22aad225d92b911/docs/images/demo3.gif -------------------------------------------------------------------------------- /docs/linux-image-setup-64.md: -------------------------------------------------------------------------------- 1 | # Creating Custom Linux Images and Booting 2 | Create custom Linux images and boot it with KRaBs. 3 | This example needs to be run on Linux. 4 | 5 | 1. Build a vmlinux 6 | 3. Create a initramfs 7 | 2. Create a Disk Image 8 | 4. Boot the custom linux image with KRaBs 9 | 10 | ## Build a minimal vmlinux 11 | 1. Get the Linux source code: 12 | ```shell 13 | wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.8.3.tar.xz 14 | tar xf linux-5.8.3.tar.xz 15 | cd linux-5.8.3 16 | ``` 17 | 2. Configure your Linux build according the following: 18 | ```shell 19 | make allnoconfig 20 | make menuconfig 21 | ``` 22 | ``` 23 | 64-bit kernel ---> yes 24 | General setup ---> Initial RAM filesystem and RAM disk (initramfs/initrd) support ---> yes 25 | General setup ---> Configure standard kernel features ---> Enable support for printk ---> yes 26 | Executable file formats / Emulations ---> Kernel support for ELF binaries ---> yes 27 | Executable file formats / Emulations ---> Kernel support for scripts starting with #! ---> yes 28 | Enable the block layer ---> yes 29 | Device Drivers ---> Generic Driver Options ---> Maintain a devtmpfs filesystem to mount at /dev ---> yes 30 | Device Drivers ---> Generic Driver Options ---> Automount devtmpfs at /dev, after the kernel mounted the rootfs ---> yes 31 | Device Drivers ---> Character devices ---> Enable TTY ---> yes 32 | Device Drivers ---> Character devices ---> Serial drivers ---> 8250/16550 and compatible serial support ---> yes 33 | Device Drivers ---> Character devices ---> Serial drivers ---> Console on 8250/16550 and compatible serial port ---> yes 34 | Device Drivers ---> Block devices ---> yes 35 | Device Drivers ---> PCI Support --> yes 36 | Device Drivers ---> Serial ATA and Parallel ATA drivers (libata) ---> yes 37 | Device Drivers ---> Serial ATA and Parallel ATA drivers (libata) ---> Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support ---> yes 38 | Device Drivers ---> Serial ATA and Parallel ATA drivers (libata) ---> Generic ATA support ---> yes 39 | Device Drivers ---> SCSI device support ---> SCSI disk support 40 | File systems ---> The Extended 4 (ext4) filesystem ---> yes 41 | File systems ---> Pseudo filesystems ---> /proc file system support ---> yes 42 | File systems ---> Pseudo filesystems ---> sysfs file system support ---> yes 43 | File systems ---> DOS/FAT/EXFAT/NT Filesystems ---> VFAT (Windows-95) fs support ---> yes 44 | File systems ---> DOS/FAT/EXFAT/NT Filesystems ---> Enable FAT UTF-8 option by default ---> yes 45 | File systems ---> Native language support ---> Codepage 437 (United States, Canada) ---> yes 46 | File systems ---> Native language support ---> Codepage 437 (United States, Canada) ---> yes 47 | File systems ---> Native language support ---> ASCII (United States) ---> yes 48 | File systems ---> Native language support ---> NLS ISO 8859-1 (Latin 1; Western European Languages) ---> yes 49 | File systems ---> Native language support ---> NLS UTF-8 ---> yes 50 | File systems ---> UTF-8 normalization and casefolding support --- yes 51 | ``` 52 | Or Copy the [my recommended config](../resources/.config) to `.config`, then 53 | do the menuconfig for adjustments: 54 | ```shell 55 | wget https://raw.githubusercontent.com/ellbrid/krabs/master/resources/.config -O .config 56 | make menuconfig 57 | ``` 58 | 3. Build the vmlinux: 59 | ```shell 60 | make vmlinux 61 | cp vmlinux vmlinux-5.8.3 62 | ``` 63 | 4. You can find vmlinux under current directry as `./vmlinux-5.8.3`. 64 | 65 | ## Create a initramfs 66 | 1. Start off by creating basic `./src/initramfs` directory: 67 | ```shell 68 | cd .. 69 | mkdir --parents src/initramfs/{bin,dev,etc,lib,lib64,mnt/root,proc,root,sbin,sys} 70 | ``` 71 | 2. Copy basic device nodes(null, console, tty, sda1, sda2 ...) from the root 72 | filesystem to the initramfs example location: 73 | ```shell 74 | sudo cp --archive /dev/{null,console,tty,tty[0-4],sda,sda[1-8],mem,kmsg,random,urandom,zero} src/initramfs/dev/ 75 | ``` 76 | 3. Instead of using some core tools like sh and mount, we can get them from 77 | busybox: 78 | ```shell 79 | curl -L 'https://www.busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64' > src/initramfs/bin/busybox 80 | sudo chmod +x src/initramfs/bin/busybox 81 | ./src/initramfs/bin/busybox --list | sed 's:^:src/initramfs/bin/:' | xargs -n 1 ln -s busybox 82 | ``` 83 | 4. We'll also need an init script. example: 84 | ```shell 85 | cat >> src/initramfs/init << EOF 86 | #!/bin/sh 87 | 88 | mount -t devtmpfs devtmpfs /dev 89 | mount -t proc proc /proc 90 | mount -t sysfs sysfs /sys 91 | sleep 2 92 | cat < ../../initramfs.cpio.gz 119 | ``` 120 | 121 | ## Create a Disk Image 122 | 1. Create an image file with qemu: 123 | ```shell 124 | qemu-img create disk.img 512M 125 | ``` 126 | 2. Partition with fdisk: 127 | ```shell 128 | gdisk disk.img 129 | ... 130 | Creating new GPT entries in memory. 131 | 132 | Command (? for help): n 133 | Partition number (1-128, default 1): 134 | First sector (34-1048542, default = 2048) or {+-}size{KMGTP}: 135 | Last sector (2048-1048542, default = 1048542) or {+-}size{KMGTP}: +1M 136 | Current type is 8300 (Linux filesystem) 137 | Hex code or GUID (L to show codes, Enter = 8300): EF02 138 | Changed type of partition to 'BIOS boot partition' 139 | 140 | Command (? for help): n 141 | Partition number (2-128, default 2): 142 | First sector (34-1048542, default = 4096) or {+-}size{KMGTP}: 143 | Last sector (4096-1048542, default = 1048542) or {+-}size{KMGTP}: +50M 144 | Current type is 8300 (Linux filesystem) 145 | Hex code or GUID (L to show codes, Enter = 8300): EF00 146 | Changed type of partition to 'EFI system partition' 147 | 148 | Command (? for help): n 149 | Partition number (3-128, default 3): 150 | First sector (34-1048542, default = 106496) or {+-}size{KMGTP}: 151 | Last sector (106496-1048542, default = 1048542) or {+-}size{KMGTP}: 152 | Current type is 8300 (Linux filesystem) 153 | Hex code or GUID (L to show codes, Enter = 8300): 154 | Changed type of partition to 'Linux filesystem' 155 | 156 | Command (? for help): w 157 | ``` 158 | 3. Create FAT32 on the second partition, ext4 on the 3rd partition. 159 | ```shell 160 | sudo kpartx -av disk.img 161 | sudo mkfs.fat -F 32 /dev/mapper/loop0p2 162 | sudo mkfs.ext4 /dev/mapper/loop0p3 163 | ``` 164 | 165 | ## Set FAT32 EFI System Partition 166 | 1. Copy vmlinux and initrd into EFI System Partition 167 | ```shell 168 | $ sudo mount /dev/mapper/loop0p2 /mnt 169 | $ sudo cp path/to/vmlinux-5.8.3 /mnt/ 170 | $ sudo cp path/to/initramfs.cpio.gz /mnt/ 171 | ``` 172 | 2. Set the CONFIG.TXT. it is a simple matrix-oriented text file. It is described as follows: 173 | ```shell 174 | $ sudo vi /mnt/CONFIG.txt 175 | main.kernel vmlinux-5.8.3 176 | main.initrd initramfs.cpio.gz 177 | main.cmdlin clocksource=tsc 178 | ``` 179 | 3. umount 180 | ``` 181 | sudo umount /mnt 182 | sudo kpartx -d disk.img 183 | ``` 184 | 185 | ## Boot the custom linux image with KRaBs 186 | Just run cargo; the -w option writes to disk and the -e option launches QEMU after the write. 187 | ```shell 188 | $ pwd 189 | path/to/krabs 190 | $ cargo build 191 | $ cargo run -- -w disk.img -e 192 | ``` 193 | 194 | ## Working Example 195 | 196 | ![bootlin](images/2020demo.gif) 197 | 198 | ## DiskSpace layout 199 | ``` 200 | $ gdisk -l disk.img 201 | GPT fdisk (gdisk) version 1.0.5 202 | 203 | Partition table scan: 204 | MBR: protective 205 | BSD: not present 206 | APM: not present 207 | GPT: present 208 | 209 | Found valid GPT with protective MBR; using GPT. 210 | Disk disk.img: 1048576 sectors, 512.0 MiB 211 | Sector size (logical): 512 bytes 212 | Disk identifier (GUID): D35B348E-F03D-4B3C-B934-BD9FA055B967 213 | Partition table holds up to 128 entries 214 | Main partition table begins at sector 2 and ends at sector 33 215 | First usable sector is 34, last usable sector is 1048542 216 | Partitions will be aligned on 2048-sector boundaries 217 | Total free space is 2014 sectors (1007.0 KiB) 218 | 219 | Number Start (sector) End (sector) Size Code Name 220 | 1 2048 4095 1024.0 KiB EF02 BIOS boot partition 221 | 2 4096 106495 50.0 MiB EF00 EFI system partition 222 | 3 106496 1048542 460.0 MiB 8300 Linux filesystem 223 | ``` 224 | 225 | -------------------------------------------------------------------------------- /docs/specifications.md: -------------------------------------------------------------------------------- 1 | # Specifications 2 | KRaBs supports only the minimal 3 | [x86 Linux boot protocol](https://www.kernel.org/doc/html/latest/x86/boot.html). 4 | Before attempting to use KRaBs for loading and booting your OS, take action as 5 | needed to meet the following requirements: 6 | 7 | ## 32bit boot protocol 8 | * At entry, the CPU is in 32-bit protected mode with paging disabled. 9 | * A GDT is loaded with the descriptors for selectors `__BOOT_CS(0x10)` and 10 | `__BOOT_DS(0x18)`. Both descriptors is 4G flat segment. `__BOOT_CS` has 11 | execute/read permission, and `__BOOT_DS` has read/write permission. 12 | * `CS` is `__BOOT_CS` and `DS`, `ES`, `SS` is `__BOOT_DS`. 13 | * Interrupt is disabled. 14 | * `%ebp`, `%edi` and `%ebx` is zero. 15 | * `%esi` holds the base physical address(`0x7C00`) of the 16 | [struct boot_params](https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/bootparam.h#L175). 17 | 18 | ## 64bit boot protocol 19 | * At entry, the CPU is in 64-bit mode with paging enabled. 20 | * A GDT is loaded with the descriptors for selectors `__BOOT_CS(0x10)` and 21 | `__BOOT_DS(0x18)`. Both descriptors is 4G flat segment. `__BOOT_CS` has 22 | execute/read permission, and `__BOOT_DS` has read/write permission. 23 | * `CS` is `__BOOT_CS` and `DS`, `ES`, `SS` is `__BOOT_DS`. 24 | * Interrupt is disabled. 25 | * `%rsi` holds the base physical address(`0x7C00`) of the 26 | [struct boot_params](https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/bootparam.h#L175). 27 | -------------------------------------------------------------------------------- /resources/.config: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated file; DO NOT EDIT. 3 | # Linux/x86 5.8.3 Kernel Configuration 4 | # 5 | CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0" 6 | CONFIG_CC_IS_GCC=y 7 | CONFIG_GCC_VERSION=90300 8 | CONFIG_LD_VERSION=234000000 9 | CONFIG_CLANG_VERSION=0 10 | CONFIG_CC_CAN_LINK=y 11 | CONFIG_CC_CAN_LINK_STATIC=y 12 | CONFIG_CC_HAS_ASM_GOTO=y 13 | CONFIG_CC_HAS_ASM_INLINE=y 14 | CONFIG_IRQ_WORK=y 15 | CONFIG_BUILDTIME_TABLE_SORT=y 16 | CONFIG_THREAD_INFO_IN_TASK=y 17 | 18 | # 19 | # General setup 20 | # 21 | CONFIG_BROKEN_ON_SMP=y 22 | CONFIG_INIT_ENV_ARG_LIMIT=32 23 | # CONFIG_COMPILE_TEST is not set 24 | CONFIG_LOCALVERSION="" 25 | # CONFIG_LOCALVERSION_AUTO is not set 26 | CONFIG_BUILD_SALT="" 27 | CONFIG_HAVE_KERNEL_GZIP=y 28 | CONFIG_HAVE_KERNEL_BZIP2=y 29 | CONFIG_HAVE_KERNEL_LZMA=y 30 | CONFIG_HAVE_KERNEL_XZ=y 31 | CONFIG_HAVE_KERNEL_LZO=y 32 | CONFIG_HAVE_KERNEL_LZ4=y 33 | CONFIG_KERNEL_GZIP=y 34 | # CONFIG_KERNEL_BZIP2 is not set 35 | # CONFIG_KERNEL_LZMA is not set 36 | # CONFIG_KERNEL_XZ is not set 37 | # CONFIG_KERNEL_LZO is not set 38 | # CONFIG_KERNEL_LZ4 is not set 39 | CONFIG_DEFAULT_INIT="" 40 | CONFIG_DEFAULT_HOSTNAME="(none)" 41 | CONFIG_SWAP=y 42 | # CONFIG_SYSVIPC is not set 43 | # CONFIG_WATCH_QUEUE is not set 44 | # CONFIG_CROSS_MEMORY_ATTACH is not set 45 | # CONFIG_USELIB is not set 46 | CONFIG_HAVE_ARCH_AUDITSYSCALL=y 47 | 48 | # 49 | # IRQ subsystem 50 | # 51 | CONFIG_GENERIC_IRQ_PROBE=y 52 | CONFIG_GENERIC_IRQ_SHOW=y 53 | CONFIG_HARDIRQS_SW_RESEND=y 54 | CONFIG_IRQ_DOMAIN=y 55 | CONFIG_IRQ_DOMAIN_HIERARCHY=y 56 | CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y 57 | CONFIG_GENERIC_IRQ_RESERVATION_MODE=y 58 | CONFIG_IRQ_FORCED_THREADING=y 59 | CONFIG_SPARSE_IRQ=y 60 | # end of IRQ subsystem 61 | 62 | CONFIG_CLOCKSOURCE_WATCHDOG=y 63 | CONFIG_ARCH_CLOCKSOURCE_INIT=y 64 | CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y 65 | CONFIG_GENERIC_TIME_VSYSCALL=y 66 | CONFIG_GENERIC_CLOCKEVENTS=y 67 | CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y 68 | CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y 69 | CONFIG_GENERIC_CMOS_UPDATE=y 70 | 71 | # 72 | # Timers subsystem 73 | # 74 | CONFIG_HZ_PERIODIC=y 75 | # CONFIG_NO_HZ_IDLE is not set 76 | # CONFIG_NO_HZ is not set 77 | # CONFIG_HIGH_RES_TIMERS is not set 78 | # end of Timers subsystem 79 | 80 | CONFIG_PREEMPT_NONE=y 81 | # CONFIG_PREEMPT_VOLUNTARY is not set 82 | # CONFIG_PREEMPT is not set 83 | 84 | # 85 | # CPU/Task time and stats accounting 86 | # 87 | CONFIG_TICK_CPU_ACCOUNTING=y 88 | # CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set 89 | # CONFIG_IRQ_TIME_ACCOUNTING is not set 90 | # CONFIG_PSI is not set 91 | # end of CPU/Task time and stats accounting 92 | 93 | # 94 | # RCU Subsystem 95 | # 96 | CONFIG_TINY_RCU=y 97 | # CONFIG_RCU_EXPERT is not set 98 | CONFIG_SRCU=y 99 | CONFIG_TINY_SRCU=y 100 | # end of RCU Subsystem 101 | 102 | # CONFIG_IKCONFIG is not set 103 | # CONFIG_IKHEADERS is not set 104 | CONFIG_LOG_BUF_SHIFT=17 105 | CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 106 | CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y 107 | 108 | # 109 | # Scheduler features 110 | # 111 | # end of Scheduler features 112 | 113 | CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y 114 | CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y 115 | CONFIG_CC_HAS_INT128=y 116 | CONFIG_ARCH_SUPPORTS_INT128=y 117 | # CONFIG_CGROUPS is not set 118 | # CONFIG_CHECKPOINT_RESTORE is not set 119 | # CONFIG_SCHED_AUTOGROUP is not set 120 | # CONFIG_SYSFS_DEPRECATED is not set 121 | # CONFIG_RELAY is not set 122 | CONFIG_BLK_DEV_INITRD=y 123 | CONFIG_INITRAMFS_SOURCE="" 124 | CONFIG_RD_GZIP=y 125 | # CONFIG_RD_BZIP2 is not set 126 | # CONFIG_RD_LZMA is not set 127 | # CONFIG_RD_XZ is not set 128 | # CONFIG_RD_LZO is not set 129 | # CONFIG_RD_LZ4 is not set 130 | # CONFIG_BOOT_CONFIG is not set 131 | CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y 132 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 133 | CONFIG_SYSCTL=y 134 | CONFIG_SYSCTL_EXCEPTION_TRACE=y 135 | CONFIG_HAVE_PCSPKR_PLATFORM=y 136 | CONFIG_EXPERT=y 137 | # CONFIG_MULTIUSER is not set 138 | # CONFIG_SGETMASK_SYSCALL is not set 139 | # CONFIG_SYSFS_SYSCALL is not set 140 | # CONFIG_FHANDLE is not set 141 | # CONFIG_POSIX_TIMERS is not set 142 | CONFIG_PRINTK=y 143 | CONFIG_PRINTK_NMI=y 144 | # CONFIG_BUG is not set 145 | # CONFIG_PCSPKR_PLATFORM is not set 146 | # CONFIG_BASE_FULL is not set 147 | # CONFIG_FUTEX is not set 148 | # CONFIG_EPOLL is not set 149 | # CONFIG_SIGNALFD is not set 150 | # CONFIG_TIMERFD is not set 151 | # CONFIG_EVENTFD is not set 152 | # CONFIG_SHMEM is not set 153 | # CONFIG_AIO is not set 154 | # CONFIG_IO_URING is not set 155 | # CONFIG_ADVISE_SYSCALLS is not set 156 | # CONFIG_MEMBARRIER is not set 157 | # CONFIG_KALLSYMS is not set 158 | # CONFIG_BPF_SYSCALL is not set 159 | CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y 160 | # CONFIG_USERFAULTFD is not set 161 | CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y 162 | # CONFIG_RSEQ is not set 163 | CONFIG_EMBEDDED=y 164 | CONFIG_HAVE_PERF_EVENTS=y 165 | # CONFIG_PC104 is not set 166 | 167 | # 168 | # Kernel Performance Events And Counters 169 | # 170 | CONFIG_PERF_EVENTS=y 171 | # CONFIG_DEBUG_PERF_USE_VMALLOC is not set 172 | # end of Kernel Performance Events And Counters 173 | 174 | # CONFIG_VM_EVENT_COUNTERS is not set 175 | CONFIG_SLUB_DEBUG=y 176 | # CONFIG_COMPAT_BRK is not set 177 | # CONFIG_SLAB is not set 178 | CONFIG_SLUB=y 179 | # CONFIG_SLOB is not set 180 | # CONFIG_SLAB_MERGE_DEFAULT is not set 181 | # CONFIG_SLAB_FREELIST_RANDOM is not set 182 | # CONFIG_SLAB_FREELIST_HARDENED is not set 183 | # CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set 184 | # CONFIG_PROFILING is not set 185 | # end of General setup 186 | 187 | CONFIG_64BIT=y 188 | CONFIG_X86_64=y 189 | CONFIG_X86=y 190 | CONFIG_INSTRUCTION_DECODER=y 191 | CONFIG_OUTPUT_FORMAT="elf64-x86-64" 192 | CONFIG_LOCKDEP_SUPPORT=y 193 | CONFIG_STACKTRACE_SUPPORT=y 194 | CONFIG_MMU=y 195 | CONFIG_ARCH_MMAP_RND_BITS_MIN=28 196 | CONFIG_ARCH_MMAP_RND_BITS_MAX=32 197 | CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 198 | CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 199 | CONFIG_GENERIC_ISA_DMA=y 200 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y 201 | CONFIG_GENERIC_CALIBRATE_DELAY=y 202 | CONFIG_ARCH_HAS_CPU_RELAX=y 203 | CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y 204 | CONFIG_ARCH_HAS_FILTER_PGPROT=y 205 | CONFIG_HAVE_SETUP_PER_CPU_AREA=y 206 | CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y 207 | CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y 208 | CONFIG_ARCH_HIBERNATION_POSSIBLE=y 209 | CONFIG_ARCH_SUSPEND_POSSIBLE=y 210 | CONFIG_ARCH_WANT_GENERAL_HUGETLB=y 211 | CONFIG_ZONE_DMA32=y 212 | CONFIG_AUDIT_ARCH=y 213 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y 214 | CONFIG_ARCH_SUPPORTS_UPROBES=y 215 | CONFIG_FIX_EARLYCON_MEM=y 216 | CONFIG_PGTABLE_LEVELS=5 217 | CONFIG_CC_HAS_SANE_STACKPROTECTOR=y 218 | 219 | # 220 | # Processor type and features 221 | # 222 | # CONFIG_ZONE_DMA is not set 223 | # CONFIG_SMP is not set 224 | CONFIG_X86_FEATURE_NAMES=y 225 | CONFIG_X86_MPPARSE=y 226 | # CONFIG_GOLDFISH is not set 227 | # CONFIG_RETPOLINE is not set 228 | # CONFIG_X86_CPU_RESCTRL is not set 229 | # CONFIG_X86_EXTENDED_PLATFORM is not set 230 | # CONFIG_IOSF_MBI is not set 231 | # CONFIG_SCHED_OMIT_FRAME_POINTER is not set 232 | # CONFIG_HYPERVISOR_GUEST is not set 233 | # CONFIG_MK8 is not set 234 | # CONFIG_MPSC is not set 235 | # CONFIG_MCORE2 is not set 236 | # CONFIG_MATOM is not set 237 | CONFIG_GENERIC_CPU=y 238 | CONFIG_X86_INTERNODE_CACHE_SHIFT=6 239 | CONFIG_X86_L1_CACHE_SHIFT=6 240 | CONFIG_X86_TSC=y 241 | CONFIG_X86_CMPXCHG64=y 242 | CONFIG_X86_CMOV=y 243 | CONFIG_X86_MINIMUM_CPU_FAMILY=64 244 | CONFIG_X86_DEBUGCTLMSR=y 245 | CONFIG_IA32_FEAT_CTL=y 246 | CONFIG_X86_VMX_FEATURE_NAMES=y 247 | # CONFIG_PROCESSOR_SELECT is not set 248 | CONFIG_CPU_SUP_INTEL=y 249 | CONFIG_CPU_SUP_AMD=y 250 | CONFIG_CPU_SUP_HYGON=y 251 | CONFIG_CPU_SUP_CENTAUR=y 252 | CONFIG_CPU_SUP_ZHAOXIN=y 253 | CONFIG_HPET_TIMER=y 254 | # CONFIG_DMI is not set 255 | # CONFIG_GART_IOMMU is not set 256 | CONFIG_NR_CPUS_RANGE_BEGIN=1 257 | CONFIG_NR_CPUS_RANGE_END=1 258 | CONFIG_NR_CPUS_DEFAULT=1 259 | CONFIG_NR_CPUS=1 260 | CONFIG_UP_LATE_INIT=y 261 | CONFIG_X86_LOCAL_APIC=y 262 | CONFIG_X86_IO_APIC=y 263 | # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set 264 | # CONFIG_X86_MCE is not set 265 | 266 | # 267 | # Performance monitoring 268 | # 269 | CONFIG_PERF_EVENTS_INTEL_UNCORE=y 270 | CONFIG_PERF_EVENTS_INTEL_RAPL=y 271 | CONFIG_PERF_EVENTS_INTEL_CSTATE=y 272 | # CONFIG_PERF_EVENTS_AMD_POWER is not set 273 | # end of Performance monitoring 274 | 275 | CONFIG_X86_VSYSCALL_EMULATION=y 276 | # CONFIG_X86_IOPL_IOPERM is not set 277 | # CONFIG_I8K is not set 278 | # CONFIG_MICROCODE is not set 279 | # CONFIG_X86_MSR is not set 280 | # CONFIG_X86_CPUID is not set 281 | CONFIG_X86_5LEVEL=y 282 | CONFIG_X86_DIRECT_GBPAGES=y 283 | # CONFIG_AMD_MEM_ENCRYPT is not set 284 | CONFIG_ARCH_SPARSEMEM_ENABLE=y 285 | CONFIG_ARCH_SPARSEMEM_DEFAULT=y 286 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y 287 | CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 288 | # CONFIG_X86_PMEM_LEGACY is not set 289 | # CONFIG_X86_CHECK_BIOS_CORRUPTION is not set 290 | CONFIG_X86_RESERVE_LOW=64 291 | # CONFIG_MTRR is not set 292 | # CONFIG_ARCH_RANDOM is not set 293 | # CONFIG_X86_SMAP is not set 294 | # CONFIG_X86_UMIP is not set 295 | CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y 296 | CONFIG_X86_INTEL_TSX_MODE_OFF=y 297 | # CONFIG_X86_INTEL_TSX_MODE_ON is not set 298 | # CONFIG_X86_INTEL_TSX_MODE_AUTO is not set 299 | # CONFIG_SECCOMP is not set 300 | # CONFIG_HZ_100 is not set 301 | CONFIG_HZ_250=y 302 | # CONFIG_HZ_300 is not set 303 | # CONFIG_HZ_1000 is not set 304 | CONFIG_HZ=250 305 | # CONFIG_KEXEC is not set 306 | # CONFIG_CRASH_DUMP is not set 307 | CONFIG_PHYSICAL_START=0x1000000 308 | # CONFIG_RELOCATABLE is not set 309 | CONFIG_PHYSICAL_ALIGN=0x200000 310 | CONFIG_DYNAMIC_MEMORY_LAYOUT=y 311 | # CONFIG_LEGACY_VSYSCALL_EMULATE is not set 312 | CONFIG_LEGACY_VSYSCALL_XONLY=y 313 | # CONFIG_LEGACY_VSYSCALL_NONE is not set 314 | # CONFIG_CMDLINE_BOOL is not set 315 | # CONFIG_MODIFY_LDT_SYSCALL is not set 316 | CONFIG_HAVE_LIVEPATCH=y 317 | # end of Processor type and features 318 | 319 | CONFIG_ARCH_HAS_ADD_PAGES=y 320 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y 321 | CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y 322 | 323 | # 324 | # Power management and ACPI options 325 | # 326 | # CONFIG_SUSPEND is not set 327 | # CONFIG_HIBERNATION is not set 328 | # CONFIG_PM is not set 329 | CONFIG_ARCH_SUPPORTS_ACPI=y 330 | # CONFIG_ACPI is not set 331 | # CONFIG_SFI is not set 332 | 333 | # 334 | # CPU Frequency scaling 335 | # 336 | # CONFIG_CPU_FREQ is not set 337 | # end of CPU Frequency scaling 338 | 339 | # 340 | # CPU Idle 341 | # 342 | # CONFIG_CPU_IDLE is not set 343 | # end of CPU Idle 344 | # end of Power management and ACPI options 345 | 346 | # 347 | # Bus options (PCI etc.) 348 | # 349 | CONFIG_PCI_DIRECT=y 350 | # CONFIG_PCI_CNB20LE_QUIRK is not set 351 | # CONFIG_ISA_BUS is not set 352 | CONFIG_ISA_DMA_API=y 353 | CONFIG_AMD_NB=y 354 | # CONFIG_X86_SYSFB is not set 355 | # end of Bus options (PCI etc.) 356 | 357 | # 358 | # Binary Emulations 359 | # 360 | # CONFIG_IA32_EMULATION is not set 361 | # CONFIG_X86_X32 is not set 362 | # end of Binary Emulations 363 | 364 | # 365 | # Firmware Drivers 366 | # 367 | # CONFIG_EDD is not set 368 | # CONFIG_FIRMWARE_MEMMAP is not set 369 | # CONFIG_FW_CFG_SYSFS is not set 370 | # CONFIG_GOOGLE_FIRMWARE is not set 371 | CONFIG_EFI_EARLYCON=y 372 | 373 | # 374 | # Tegra firmware driver 375 | # 376 | # end of Tegra firmware driver 377 | # end of Firmware Drivers 378 | 379 | CONFIG_HAVE_KVM=y 380 | # CONFIG_VIRTUALIZATION is not set 381 | CONFIG_AS_AVX512=y 382 | CONFIG_AS_SHA1_NI=y 383 | CONFIG_AS_SHA256_NI=y 384 | CONFIG_AS_TPAUSE=y 385 | 386 | # 387 | # General architecture-dependent options 388 | # 389 | CONFIG_HAVE_OPROFILE=y 390 | CONFIG_OPROFILE_NMI_TIMER=y 391 | # CONFIG_JUMP_LABEL is not set 392 | CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y 393 | CONFIG_ARCH_USE_BUILTIN_BSWAP=y 394 | CONFIG_HAVE_IOREMAP_PROT=y 395 | CONFIG_HAVE_KPROBES=y 396 | CONFIG_HAVE_KRETPROBES=y 397 | CONFIG_HAVE_OPTPROBES=y 398 | CONFIG_HAVE_KPROBES_ON_FTRACE=y 399 | CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y 400 | CONFIG_HAVE_NMI=y 401 | CONFIG_HAVE_ARCH_TRACEHOOK=y 402 | CONFIG_HAVE_DMA_CONTIGUOUS=y 403 | CONFIG_GENERIC_SMP_IDLE_THREAD=y 404 | CONFIG_ARCH_HAS_FORTIFY_SOURCE=y 405 | CONFIG_ARCH_HAS_SET_MEMORY=y 406 | CONFIG_ARCH_HAS_SET_DIRECT_MAP=y 407 | CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y 408 | CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y 409 | CONFIG_HAVE_ASM_MODVERSIONS=y 410 | CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y 411 | CONFIG_HAVE_RSEQ=y 412 | CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y 413 | CONFIG_HAVE_HW_BREAKPOINT=y 414 | CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y 415 | CONFIG_HAVE_USER_RETURN_NOTIFIER=y 416 | CONFIG_HAVE_PERF_EVENTS_NMI=y 417 | CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y 418 | CONFIG_HAVE_PERF_REGS=y 419 | CONFIG_HAVE_PERF_USER_STACK_DUMP=y 420 | CONFIG_HAVE_ARCH_JUMP_LABEL=y 421 | CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y 422 | CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y 423 | CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y 424 | CONFIG_HAVE_CMPXCHG_LOCAL=y 425 | CONFIG_HAVE_CMPXCHG_DOUBLE=y 426 | CONFIG_HAVE_ARCH_SECCOMP_FILTER=y 427 | CONFIG_HAVE_ARCH_STACKLEAK=y 428 | CONFIG_HAVE_STACKPROTECTOR=y 429 | CONFIG_CC_HAS_STACKPROTECTOR_NONE=y 430 | # CONFIG_STACKPROTECTOR is not set 431 | CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y 432 | CONFIG_HAVE_CONTEXT_TRACKING=y 433 | CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y 434 | CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y 435 | CONFIG_HAVE_MOVE_PMD=y 436 | CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y 437 | CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y 438 | CONFIG_HAVE_ARCH_HUGE_VMAP=y 439 | CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y 440 | CONFIG_HAVE_ARCH_SOFT_DIRTY=y 441 | CONFIG_HAVE_MOD_ARCH_SPECIFIC=y 442 | CONFIG_MODULES_USE_ELF_RELA=y 443 | CONFIG_ARCH_HAS_ELF_RANDOMIZE=y 444 | CONFIG_HAVE_ARCH_MMAP_RND_BITS=y 445 | CONFIG_HAVE_EXIT_THREAD=y 446 | CONFIG_ARCH_MMAP_RND_BITS=28 447 | CONFIG_HAVE_COPY_THREAD_TLS=y 448 | CONFIG_HAVE_STACK_VALIDATION=y 449 | # CONFIG_COMPAT_32BIT_TIME is not set 450 | CONFIG_HAVE_ARCH_VMAP_STACK=y 451 | CONFIG_VMAP_STACK=y 452 | CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y 453 | CONFIG_STRICT_KERNEL_RWX=y 454 | CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y 455 | CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y 456 | CONFIG_ARCH_USE_MEMREMAP_PROT=y 457 | CONFIG_ARCH_HAS_MEM_ENCRYPT=y 458 | 459 | # 460 | # GCOV-based kernel profiling 461 | # 462 | CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y 463 | # end of GCOV-based kernel profiling 464 | 465 | CONFIG_HAVE_GCC_PLUGINS=y 466 | # end of General architecture-dependent options 467 | 468 | CONFIG_BASE_SMALL=1 469 | # CONFIG_MODULES is not set 470 | CONFIG_MODULES_TREE_LOOKUP=y 471 | CONFIG_BLOCK=y 472 | CONFIG_BLK_SCSI_REQUEST=y 473 | CONFIG_BLK_DEV_BSG=y 474 | # CONFIG_BLK_DEV_BSGLIB is not set 475 | # CONFIG_BLK_DEV_INTEGRITY is not set 476 | # CONFIG_BLK_DEV_ZONED is not set 477 | # CONFIG_BLK_CMDLINE_PARSER is not set 478 | # CONFIG_BLK_WBT is not set 479 | # CONFIG_BLK_SED_OPAL is not set 480 | # CONFIG_BLK_INLINE_ENCRYPTION is not set 481 | 482 | # 483 | # Partition Types 484 | # 485 | # CONFIG_PARTITION_ADVANCED is not set 486 | CONFIG_MSDOS_PARTITION=y 487 | CONFIG_EFI_PARTITION=y 488 | # end of Partition Types 489 | 490 | CONFIG_BLK_MQ_PCI=y 491 | 492 | # 493 | # IO Schedulers 494 | # 495 | CONFIG_MQ_IOSCHED_DEADLINE=y 496 | CONFIG_MQ_IOSCHED_KYBER=y 497 | # CONFIG_IOSCHED_BFQ is not set 498 | # end of IO Schedulers 499 | 500 | CONFIG_INLINE_SPIN_UNLOCK_IRQ=y 501 | CONFIG_INLINE_READ_UNLOCK=y 502 | CONFIG_INLINE_READ_UNLOCK_IRQ=y 503 | CONFIG_INLINE_WRITE_UNLOCK=y 504 | CONFIG_INLINE_WRITE_UNLOCK_IRQ=y 505 | CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y 506 | CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y 507 | CONFIG_ARCH_USE_QUEUED_RWLOCKS=y 508 | CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y 509 | CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y 510 | CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y 511 | 512 | # 513 | # Executable file formats 514 | # 515 | CONFIG_BINFMT_ELF=y 516 | CONFIG_ELFCORE=y 517 | CONFIG_BINFMT_SCRIPT=y 518 | # CONFIG_BINFMT_MISC is not set 519 | # CONFIG_COREDUMP is not set 520 | # end of Executable file formats 521 | 522 | # 523 | # Memory Management options 524 | # 525 | CONFIG_SELECT_MEMORY_MODEL=y 526 | CONFIG_SPARSEMEM_MANUAL=y 527 | CONFIG_SPARSEMEM=y 528 | CONFIG_HAVE_MEMORY_PRESENT=y 529 | CONFIG_SPARSEMEM_EXTREME=y 530 | CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y 531 | CONFIG_SPARSEMEM_VMEMMAP=y 532 | CONFIG_HAVE_FAST_GUP=y 533 | # CONFIG_MEMORY_HOTPLUG is not set 534 | CONFIG_SPLIT_PTLOCK_CPUS=4 535 | # CONFIG_COMPACTION is not set 536 | # CONFIG_PAGE_REPORTING is not set 537 | CONFIG_PHYS_ADDR_T_64BIT=y 538 | CONFIG_VIRT_TO_BUS=y 539 | # CONFIG_KSM is not set 540 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 541 | # CONFIG_TRANSPARENT_HUGEPAGE is not set 542 | CONFIG_ARCH_WANTS_THP_SWAP=y 543 | CONFIG_NEED_PER_CPU_KM=y 544 | # CONFIG_CLEANCACHE is not set 545 | # CONFIG_FRONTSWAP is not set 546 | # CONFIG_CMA is not set 547 | # CONFIG_ZPOOL is not set 548 | # CONFIG_ZBUD is not set 549 | # CONFIG_ZSMALLOC is not set 550 | CONFIG_GENERIC_EARLY_IOREMAP=y 551 | # CONFIG_IDLE_PAGE_TRACKING is not set 552 | CONFIG_ARCH_HAS_PTE_DEVMAP=y 553 | CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y 554 | CONFIG_ARCH_HAS_PKEYS=y 555 | # CONFIG_PERCPU_STATS is not set 556 | # CONFIG_GUP_BENCHMARK is not set 557 | CONFIG_ARCH_HAS_PTE_SPECIAL=y 558 | # end of Memory Management options 559 | 560 | # CONFIG_NET is not set 561 | CONFIG_HAVE_EBPF_JIT=y 562 | 563 | # 564 | # Device Drivers 565 | # 566 | CONFIG_HAVE_EISA=y 567 | # CONFIG_EISA is not set 568 | CONFIG_HAVE_PCI=y 569 | CONFIG_PCI=y 570 | CONFIG_PCI_DOMAINS=y 571 | # CONFIG_PCIEPORTBUS is not set 572 | CONFIG_PCIEASPM=y 573 | CONFIG_PCIEASPM_DEFAULT=y 574 | # CONFIG_PCIEASPM_POWERSAVE is not set 575 | # CONFIG_PCIEASPM_POWER_SUPERSAVE is not set 576 | # CONFIG_PCIEASPM_PERFORMANCE is not set 577 | # CONFIG_PCIE_PTM is not set 578 | # CONFIG_PCI_MSI is not set 579 | CONFIG_PCI_QUIRKS=y 580 | # CONFIG_PCI_DEBUG is not set 581 | # CONFIG_PCI_STUB is not set 582 | CONFIG_PCI_LOCKLESS_CONFIG=y 583 | # CONFIG_PCI_IOV is not set 584 | # CONFIG_PCI_PRI is not set 585 | # CONFIG_PCI_PASID is not set 586 | # CONFIG_HOTPLUG_PCI is not set 587 | 588 | # 589 | # PCI controller drivers 590 | # 591 | 592 | # 593 | # DesignWare PCI Core Support 594 | # 595 | # end of DesignWare PCI Core Support 596 | 597 | # 598 | # Mobiveil PCIe Core Support 599 | # 600 | # end of Mobiveil PCIe Core Support 601 | 602 | # 603 | # Cadence PCIe controllers support 604 | # 605 | # end of Cadence PCIe controllers support 606 | # end of PCI controller drivers 607 | 608 | # 609 | # PCI Endpoint 610 | # 611 | # CONFIG_PCI_ENDPOINT is not set 612 | # end of PCI Endpoint 613 | 614 | # 615 | # PCI switch controller drivers 616 | # 617 | # CONFIG_PCI_SW_SWITCHTEC is not set 618 | # end of PCI switch controller drivers 619 | 620 | # CONFIG_PCCARD is not set 621 | # CONFIG_RAPIDIO is not set 622 | 623 | # 624 | # Generic Driver Options 625 | # 626 | # CONFIG_UEVENT_HELPER is not set 627 | CONFIG_DEVTMPFS=y 628 | CONFIG_DEVTMPFS_MOUNT=y 629 | # CONFIG_STANDALONE is not set 630 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set 631 | 632 | # 633 | # Firmware loader 634 | # 635 | # CONFIG_FW_LOADER is not set 636 | # end of Firmware loader 637 | 638 | # CONFIG_ALLOW_DEV_COREDUMP is not set 639 | # CONFIG_DEBUG_DRIVER is not set 640 | # CONFIG_DEBUG_DEVRES is not set 641 | # CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set 642 | CONFIG_GENERIC_CPU_AUTOPROBE=y 643 | CONFIG_GENERIC_CPU_VULNERABILITIES=y 644 | # end of Generic Driver Options 645 | 646 | # 647 | # Bus devices 648 | # 649 | # CONFIG_MHI_BUS is not set 650 | # end of Bus devices 651 | 652 | # CONFIG_GNSS is not set 653 | # CONFIG_MTD is not set 654 | # CONFIG_OF is not set 655 | CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y 656 | # CONFIG_PARPORT is not set 657 | CONFIG_BLK_DEV=y 658 | # CONFIG_BLK_DEV_NULL_BLK is not set 659 | # CONFIG_BLK_DEV_FD is not set 660 | # CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set 661 | # CONFIG_BLK_DEV_UMEM is not set 662 | # CONFIG_BLK_DEV_LOOP is not set 663 | 664 | # 665 | # DRBD disabled because PROC_FS or INET not selected 666 | # 667 | # CONFIG_BLK_DEV_SKD is not set 668 | # CONFIG_BLK_DEV_SX8 is not set 669 | # CONFIG_BLK_DEV_RAM is not set 670 | # CONFIG_CDROM_PKTCDVD is not set 671 | # CONFIG_BLK_DEV_RSXX is not set 672 | 673 | # 674 | # NVME Support 675 | # 676 | # CONFIG_BLK_DEV_NVME is not set 677 | # CONFIG_NVME_FC is not set 678 | # end of NVME Support 679 | 680 | # 681 | # Misc devices 682 | # 683 | # CONFIG_DUMMY_IRQ is not set 684 | # CONFIG_IBM_ASM is not set 685 | # CONFIG_PHANTOM is not set 686 | # CONFIG_TIFM_CORE is not set 687 | # CONFIG_ENCLOSURE_SERVICES is not set 688 | # CONFIG_HP_ILO is not set 689 | # CONFIG_SRAM is not set 690 | # CONFIG_PCI_ENDPOINT_TEST is not set 691 | # CONFIG_XILINX_SDFEC is not set 692 | # CONFIG_C2PORT is not set 693 | 694 | # 695 | # EEPROM support 696 | # 697 | # CONFIG_EEPROM_93CX6 is not set 698 | # end of EEPROM support 699 | 700 | # CONFIG_CB710_CORE is not set 701 | 702 | # 703 | # Texas Instruments shared transport line discipline 704 | # 705 | # end of Texas Instruments shared transport line discipline 706 | 707 | # 708 | # Altera FPGA firmware download module (requires I2C) 709 | # 710 | # CONFIG_INTEL_MEI is not set 711 | # CONFIG_INTEL_MEI_ME is not set 712 | # CONFIG_INTEL_MEI_TXE is not set 713 | # CONFIG_VMWARE_VMCI is not set 714 | 715 | # 716 | # Intel MIC & related support 717 | # 718 | # CONFIG_INTEL_MIC_BUS is not set 719 | # CONFIG_SCIF_BUS is not set 720 | # CONFIG_VOP_BUS is not set 721 | # end of Intel MIC & related support 722 | 723 | # CONFIG_GENWQE is not set 724 | # CONFIG_ECHO is not set 725 | # CONFIG_MISC_ALCOR_PCI is not set 726 | # CONFIG_MISC_RTSX_PCI is not set 727 | # CONFIG_HABANA_AI is not set 728 | # end of Misc devices 729 | 730 | CONFIG_HAVE_IDE=y 731 | # CONFIG_IDE is not set 732 | 733 | # 734 | # SCSI device support 735 | # 736 | CONFIG_SCSI_MOD=y 737 | # CONFIG_RAID_ATTRS is not set 738 | CONFIG_SCSI=y 739 | CONFIG_SCSI_DMA=y 740 | CONFIG_SCSI_PROC_FS=y 741 | 742 | # 743 | # SCSI support type (disk, tape, CD-ROM) 744 | # 745 | CONFIG_BLK_DEV_SD=y 746 | # CONFIG_CHR_DEV_ST is not set 747 | # CONFIG_BLK_DEV_SR is not set 748 | # CONFIG_CHR_DEV_SG is not set 749 | # CONFIG_CHR_DEV_SCH is not set 750 | # CONFIG_SCSI_CONSTANTS is not set 751 | # CONFIG_SCSI_LOGGING is not set 752 | # CONFIG_SCSI_SCAN_ASYNC is not set 753 | 754 | # 755 | # SCSI Transports 756 | # 757 | # CONFIG_SCSI_SPI_ATTRS is not set 758 | # CONFIG_SCSI_SAS_ATTRS is not set 759 | # CONFIG_SCSI_SAS_LIBSAS is not set 760 | # CONFIG_SCSI_SRP_ATTRS is not set 761 | # end of SCSI Transports 762 | 763 | CONFIG_SCSI_LOWLEVEL=y 764 | # CONFIG_ISCSI_BOOT_SYSFS is not set 765 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set 766 | # CONFIG_SCSI_HPSA is not set 767 | # CONFIG_SCSI_3W_9XXX is not set 768 | # CONFIG_SCSI_3W_SAS is not set 769 | # CONFIG_SCSI_ACARD is not set 770 | # CONFIG_SCSI_AACRAID is not set 771 | # CONFIG_SCSI_AIC7XXX is not set 772 | # CONFIG_SCSI_AIC79XX is not set 773 | # CONFIG_SCSI_AIC94XX is not set 774 | # CONFIG_SCSI_MVSAS is not set 775 | # CONFIG_SCSI_MVUMI is not set 776 | # CONFIG_SCSI_DPT_I2O is not set 777 | # CONFIG_SCSI_ADVANSYS is not set 778 | # CONFIG_SCSI_ARCMSR is not set 779 | # CONFIG_SCSI_ESAS2R is not set 780 | # CONFIG_MEGARAID_NEWGEN is not set 781 | # CONFIG_MEGARAID_LEGACY is not set 782 | # CONFIG_MEGARAID_SAS is not set 783 | # CONFIG_SCSI_MPT3SAS is not set 784 | # CONFIG_SCSI_MPT2SAS is not set 785 | # CONFIG_SCSI_SMARTPQI is not set 786 | # CONFIG_SCSI_UFSHCD is not set 787 | # CONFIG_SCSI_HPTIOP is not set 788 | # CONFIG_SCSI_BUSLOGIC is not set 789 | # CONFIG_SCSI_MYRB is not set 790 | # CONFIG_SCSI_MYRS is not set 791 | # CONFIG_VMWARE_PVSCSI is not set 792 | # CONFIG_SCSI_SNIC is not set 793 | # CONFIG_SCSI_DMX3191D is not set 794 | # CONFIG_SCSI_FDOMAIN_PCI is not set 795 | # CONFIG_SCSI_GDTH is not set 796 | # CONFIG_SCSI_ISCI is not set 797 | # CONFIG_SCSI_IPS is not set 798 | # CONFIG_SCSI_INITIO is not set 799 | # CONFIG_SCSI_INIA100 is not set 800 | # CONFIG_SCSI_STEX is not set 801 | # CONFIG_SCSI_SYM53C8XX_2 is not set 802 | # CONFIG_SCSI_IPR is not set 803 | # CONFIG_SCSI_QLOGIC_1280 is not set 804 | # CONFIG_SCSI_DC395x is not set 805 | # CONFIG_SCSI_AM53C974 is not set 806 | # CONFIG_SCSI_WD719X is not set 807 | # CONFIG_SCSI_DEBUG is not set 808 | # CONFIG_SCSI_PM8001 is not set 809 | # CONFIG_SCSI_DH is not set 810 | # end of SCSI device support 811 | 812 | CONFIG_ATA=y 813 | CONFIG_SATA_HOST=y 814 | CONFIG_ATA_VERBOSE_ERROR=y 815 | CONFIG_ATA_FORCE=y 816 | CONFIG_SATA_PMP=y 817 | 818 | # 819 | # Controllers with non-SFF native interface 820 | # 821 | # CONFIG_SATA_AHCI is not set 822 | # CONFIG_SATA_AHCI_PLATFORM is not set 823 | # CONFIG_SATA_INIC162X is not set 824 | # CONFIG_SATA_ACARD_AHCI is not set 825 | # CONFIG_SATA_SIL24 is not set 826 | CONFIG_ATA_SFF=y 827 | 828 | # 829 | # SFF controllers with custom DMA interface 830 | # 831 | # CONFIG_PDC_ADMA is not set 832 | # CONFIG_SATA_QSTOR is not set 833 | # CONFIG_SATA_SX4 is not set 834 | CONFIG_ATA_BMDMA=y 835 | 836 | # 837 | # SATA SFF controllers with BMDMA 838 | # 839 | CONFIG_ATA_PIIX=y 840 | # CONFIG_SATA_MV is not set 841 | # CONFIG_SATA_NV is not set 842 | # CONFIG_SATA_PROMISE is not set 843 | # CONFIG_SATA_SIL is not set 844 | # CONFIG_SATA_SIS is not set 845 | # CONFIG_SATA_SVW is not set 846 | # CONFIG_SATA_ULI is not set 847 | # CONFIG_SATA_VIA is not set 848 | # CONFIG_SATA_VITESSE is not set 849 | 850 | # 851 | # PATA SFF controllers with BMDMA 852 | # 853 | # CONFIG_PATA_ALI is not set 854 | # CONFIG_PATA_AMD is not set 855 | # CONFIG_PATA_ARTOP is not set 856 | # CONFIG_PATA_ATIIXP is not set 857 | # CONFIG_PATA_ATP867X is not set 858 | # CONFIG_PATA_CMD64X is not set 859 | # CONFIG_PATA_CYPRESS is not set 860 | # CONFIG_PATA_EFAR is not set 861 | # CONFIG_PATA_HPT366 is not set 862 | # CONFIG_PATA_HPT37X is not set 863 | # CONFIG_PATA_HPT3X2N is not set 864 | # CONFIG_PATA_HPT3X3 is not set 865 | # CONFIG_PATA_IT8213 is not set 866 | # CONFIG_PATA_IT821X is not set 867 | # CONFIG_PATA_JMICRON is not set 868 | # CONFIG_PATA_MARVELL is not set 869 | # CONFIG_PATA_NETCELL is not set 870 | # CONFIG_PATA_NINJA32 is not set 871 | # CONFIG_PATA_NS87415 is not set 872 | # CONFIG_PATA_OLDPIIX is not set 873 | # CONFIG_PATA_OPTIDMA is not set 874 | # CONFIG_PATA_PDC2027X is not set 875 | # CONFIG_PATA_PDC_OLD is not set 876 | # CONFIG_PATA_RADISYS is not set 877 | # CONFIG_PATA_RDC is not set 878 | # CONFIG_PATA_SCH is not set 879 | # CONFIG_PATA_SERVERWORKS is not set 880 | # CONFIG_PATA_SIL680 is not set 881 | # CONFIG_PATA_SIS is not set 882 | # CONFIG_PATA_TOSHIBA is not set 883 | # CONFIG_PATA_TRIFLEX is not set 884 | # CONFIG_PATA_VIA is not set 885 | # CONFIG_PATA_WINBOND is not set 886 | 887 | # 888 | # PIO-only SFF controllers 889 | # 890 | # CONFIG_PATA_CMD640_PCI is not set 891 | # CONFIG_PATA_MPIIX is not set 892 | # CONFIG_PATA_NS87410 is not set 893 | # CONFIG_PATA_OPTI is not set 894 | # CONFIG_PATA_PLATFORM is not set 895 | # CONFIG_PATA_RZ1000 is not set 896 | 897 | # 898 | # Generic fallback / legacy drivers 899 | # 900 | CONFIG_ATA_GENERIC=y 901 | # CONFIG_PATA_LEGACY is not set 902 | # CONFIG_MD is not set 903 | # CONFIG_TARGET_CORE is not set 904 | # CONFIG_FUSION is not set 905 | 906 | # 907 | # IEEE 1394 (FireWire) support 908 | # 909 | # CONFIG_FIREWIRE is not set 910 | # CONFIG_FIREWIRE_NOSY is not set 911 | # end of IEEE 1394 (FireWire) support 912 | 913 | # CONFIG_MACINTOSH_DRIVERS is not set 914 | # CONFIG_NVM is not set 915 | 916 | # 917 | # Input device support 918 | # 919 | CONFIG_INPUT=y 920 | # CONFIG_INPUT_FF_MEMLESS is not set 921 | # CONFIG_INPUT_POLLDEV is not set 922 | # CONFIG_INPUT_SPARSEKMAP is not set 923 | # CONFIG_INPUT_MATRIXKMAP is not set 924 | 925 | # 926 | # Userland interfaces 927 | # 928 | # CONFIG_INPUT_MOUSEDEV is not set 929 | # CONFIG_INPUT_JOYDEV is not set 930 | # CONFIG_INPUT_EVDEV is not set 931 | # CONFIG_INPUT_EVBUG is not set 932 | 933 | # 934 | # Input Device Drivers 935 | # 936 | CONFIG_INPUT_KEYBOARD=y 937 | CONFIG_KEYBOARD_ATKBD=y 938 | # CONFIG_KEYBOARD_LKKBD is not set 939 | # CONFIG_KEYBOARD_NEWTON is not set 940 | # CONFIG_KEYBOARD_OPENCORES is not set 941 | # CONFIG_KEYBOARD_SAMSUNG is not set 942 | # CONFIG_KEYBOARD_STOWAWAY is not set 943 | # CONFIG_KEYBOARD_SUNKBD is not set 944 | # CONFIG_KEYBOARD_XTKBD is not set 945 | CONFIG_INPUT_MOUSE=y 946 | CONFIG_MOUSE_PS2=y 947 | CONFIG_MOUSE_PS2_ALPS=y 948 | CONFIG_MOUSE_PS2_BYD=y 949 | CONFIG_MOUSE_PS2_LOGIPS2PP=y 950 | CONFIG_MOUSE_PS2_SYNAPTICS=y 951 | CONFIG_MOUSE_PS2_CYPRESS=y 952 | CONFIG_MOUSE_PS2_TRACKPOINT=y 953 | # CONFIG_MOUSE_PS2_ELANTECH is not set 954 | # CONFIG_MOUSE_PS2_SENTELIC is not set 955 | # CONFIG_MOUSE_PS2_TOUCHKIT is not set 956 | CONFIG_MOUSE_PS2_FOCALTECH=y 957 | # CONFIG_MOUSE_SERIAL is not set 958 | # CONFIG_MOUSE_VSXXXAA is not set 959 | # CONFIG_INPUT_JOYSTICK is not set 960 | # CONFIG_INPUT_TABLET is not set 961 | # CONFIG_INPUT_TOUCHSCREEN is not set 962 | # CONFIG_INPUT_MISC is not set 963 | # CONFIG_RMI4_CORE is not set 964 | 965 | # 966 | # Hardware I/O ports 967 | # 968 | CONFIG_SERIO=y 969 | CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y 970 | CONFIG_SERIO_I8042=y 971 | CONFIG_SERIO_SERPORT=y 972 | # CONFIG_SERIO_CT82C710 is not set 973 | # CONFIG_SERIO_PCIPS2 is not set 974 | CONFIG_SERIO_LIBPS2=y 975 | # CONFIG_SERIO_RAW is not set 976 | # CONFIG_SERIO_ALTERA_PS2 is not set 977 | # CONFIG_SERIO_PS2MULT is not set 978 | # CONFIG_SERIO_ARC_PS2 is not set 979 | # CONFIG_USERIO is not set 980 | # CONFIG_GAMEPORT is not set 981 | # end of Hardware I/O ports 982 | # end of Input device support 983 | 984 | # 985 | # Character devices 986 | # 987 | CONFIG_TTY=y 988 | CONFIG_VT=y 989 | CONFIG_CONSOLE_TRANSLATIONS=y 990 | CONFIG_VT_CONSOLE=y 991 | CONFIG_HW_CONSOLE=y 992 | # CONFIG_VT_HW_CONSOLE_BINDING is not set 993 | CONFIG_UNIX98_PTYS=y 994 | CONFIG_LEGACY_PTYS=y 995 | CONFIG_LEGACY_PTY_COUNT=256 996 | CONFIG_LDISC_AUTOLOAD=y 997 | 998 | # 999 | # Serial drivers 1000 | # 1001 | CONFIG_SERIAL_EARLYCON=y 1002 | CONFIG_SERIAL_8250=y 1003 | CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y 1004 | # CONFIG_SERIAL_8250_16550A_VARIANTS is not set 1005 | # CONFIG_SERIAL_8250_FINTEK is not set 1006 | CONFIG_SERIAL_8250_CONSOLE=y 1007 | CONFIG_SERIAL_8250_PCI=y 1008 | CONFIG_SERIAL_8250_EXAR=y 1009 | CONFIG_SERIAL_8250_NR_UARTS=4 1010 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 1011 | # CONFIG_SERIAL_8250_EXTENDED is not set 1012 | CONFIG_SERIAL_8250_DWLIB=y 1013 | # CONFIG_SERIAL_8250_DW is not set 1014 | # CONFIG_SERIAL_8250_RT288X is not set 1015 | CONFIG_SERIAL_8250_LPSS=y 1016 | CONFIG_SERIAL_8250_MID=y 1017 | 1018 | # 1019 | # Non-8250 serial port support 1020 | # 1021 | # CONFIG_SERIAL_UARTLITE is not set 1022 | CONFIG_SERIAL_CORE=y 1023 | CONFIG_SERIAL_CORE_CONSOLE=y 1024 | # CONFIG_SERIAL_JSM is not set 1025 | # CONFIG_SERIAL_LANTIQ is not set 1026 | # CONFIG_SERIAL_SCCNXP is not set 1027 | # CONFIG_SERIAL_ALTERA_JTAGUART is not set 1028 | # CONFIG_SERIAL_ALTERA_UART is not set 1029 | # CONFIG_SERIAL_ARC is not set 1030 | # CONFIG_SERIAL_RP2 is not set 1031 | # CONFIG_SERIAL_FSL_LPUART is not set 1032 | # CONFIG_SERIAL_FSL_LINFLEXUART is not set 1033 | # CONFIG_SERIAL_SPRD is not set 1034 | # end of Serial drivers 1035 | 1036 | # CONFIG_SERIAL_NONSTANDARD is not set 1037 | # CONFIG_NOZOMI is not set 1038 | # CONFIG_NULL_TTY is not set 1039 | # CONFIG_TRACE_SINK is not set 1040 | # CONFIG_SERIAL_DEV_BUS is not set 1041 | # CONFIG_TTY_PRINTK is not set 1042 | # CONFIG_IPMI_HANDLER is not set 1043 | # CONFIG_HW_RANDOM is not set 1044 | # CONFIG_APPLICOM is not set 1045 | # CONFIG_MWAVE is not set 1046 | # CONFIG_DEVMEM is not set 1047 | # CONFIG_DEVKMEM is not set 1048 | # CONFIG_NVRAM is not set 1049 | # CONFIG_RAW_DRIVER is not set 1050 | CONFIG_DEVPORT=y 1051 | # CONFIG_HANGCHECK_TIMER is not set 1052 | # CONFIG_TCG_TPM is not set 1053 | # CONFIG_TELCLOCK is not set 1054 | # CONFIG_XILLYBUS is not set 1055 | # end of Character devices 1056 | 1057 | # CONFIG_RANDOM_TRUST_BOOTLOADER is not set 1058 | 1059 | # 1060 | # I2C support 1061 | # 1062 | # CONFIG_I2C is not set 1063 | # end of I2C support 1064 | 1065 | # CONFIG_I3C is not set 1066 | # CONFIG_SPI is not set 1067 | # CONFIG_SPMI is not set 1068 | # CONFIG_HSI is not set 1069 | # CONFIG_PPS is not set 1070 | 1071 | # 1072 | # PTP clock support 1073 | # 1074 | 1075 | # 1076 | # Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. 1077 | # 1078 | # end of PTP clock support 1079 | 1080 | # CONFIG_PINCTRL is not set 1081 | # CONFIG_GPIOLIB is not set 1082 | # CONFIG_W1 is not set 1083 | # CONFIG_POWER_AVS is not set 1084 | # CONFIG_POWER_RESET is not set 1085 | # CONFIG_POWER_SUPPLY is not set 1086 | # CONFIG_HWMON is not set 1087 | # CONFIG_THERMAL is not set 1088 | # CONFIG_WATCHDOG is not set 1089 | CONFIG_SSB_POSSIBLE=y 1090 | # CONFIG_SSB is not set 1091 | CONFIG_BCMA_POSSIBLE=y 1092 | # CONFIG_BCMA is not set 1093 | 1094 | # 1095 | # Multifunction device drivers 1096 | # 1097 | # CONFIG_MFD_MADERA is not set 1098 | # CONFIG_HTC_PASIC3 is not set 1099 | # CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set 1100 | # CONFIG_LPC_ICH is not set 1101 | # CONFIG_LPC_SCH is not set 1102 | # CONFIG_MFD_INTEL_LPSS_PCI is not set 1103 | # CONFIG_MFD_JANZ_CMODIO is not set 1104 | # CONFIG_MFD_KEMPLD is not set 1105 | # CONFIG_MFD_MT6397 is not set 1106 | # CONFIG_MFD_RDC321X is not set 1107 | # CONFIG_MFD_SM501 is not set 1108 | # CONFIG_ABX500_CORE is not set 1109 | # CONFIG_MFD_SYSCON is not set 1110 | # CONFIG_MFD_TI_AM335X_TSCADC is not set 1111 | # CONFIG_MFD_TQMX86 is not set 1112 | # CONFIG_MFD_VX855 is not set 1113 | # end of Multifunction device drivers 1114 | 1115 | # CONFIG_REGULATOR is not set 1116 | # CONFIG_RC_CORE is not set 1117 | # CONFIG_MEDIA_CEC_SUPPORT is not set 1118 | # CONFIG_MEDIA_SUPPORT is not set 1119 | 1120 | # 1121 | # Graphics support 1122 | # 1123 | # CONFIG_AGP is not set 1124 | CONFIG_VGA_ARB=y 1125 | CONFIG_VGA_ARB_MAX_GPUS=16 1126 | # CONFIG_DRM is not set 1127 | 1128 | # 1129 | # ARM devices 1130 | # 1131 | # end of ARM devices 1132 | 1133 | # 1134 | # Frame buffer Devices 1135 | # 1136 | # CONFIG_FB is not set 1137 | # end of Frame buffer Devices 1138 | 1139 | # 1140 | # Backlight & LCD device support 1141 | # 1142 | # CONFIG_LCD_CLASS_DEVICE is not set 1143 | # CONFIG_BACKLIGHT_CLASS_DEVICE is not set 1144 | # end of Backlight & LCD device support 1145 | 1146 | # 1147 | # Console display driver support 1148 | # 1149 | CONFIG_VGA_CONSOLE=y 1150 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set 1151 | CONFIG_DUMMY_CONSOLE=y 1152 | CONFIG_DUMMY_CONSOLE_COLUMNS=80 1153 | CONFIG_DUMMY_CONSOLE_ROWS=25 1154 | # end of Console display driver support 1155 | # end of Graphics support 1156 | 1157 | # CONFIG_SOUND is not set 1158 | 1159 | # 1160 | # HID support 1161 | # 1162 | CONFIG_HID=y 1163 | # CONFIG_HID_BATTERY_STRENGTH is not set 1164 | # CONFIG_HIDRAW is not set 1165 | # CONFIG_UHID is not set 1166 | CONFIG_HID_GENERIC=y 1167 | 1168 | # 1169 | # Special HID drivers 1170 | # 1171 | # CONFIG_HID_A4TECH is not set 1172 | # CONFIG_HID_ACRUX is not set 1173 | # CONFIG_HID_APPLE is not set 1174 | # CONFIG_HID_AUREAL is not set 1175 | # CONFIG_HID_BELKIN is not set 1176 | # CONFIG_HID_CHERRY is not set 1177 | # CONFIG_HID_CHICONY is not set 1178 | # CONFIG_HID_COUGAR is not set 1179 | # CONFIG_HID_MACALLY is not set 1180 | # CONFIG_HID_CMEDIA is not set 1181 | # CONFIG_HID_CYPRESS is not set 1182 | # CONFIG_HID_DRAGONRISE is not set 1183 | # CONFIG_HID_EMS_FF is not set 1184 | # CONFIG_HID_ELECOM is not set 1185 | # CONFIG_HID_EZKEY is not set 1186 | # CONFIG_HID_GEMBIRD is not set 1187 | # CONFIG_HID_GFRM is not set 1188 | # CONFIG_HID_GLORIOUS is not set 1189 | # CONFIG_HID_KEYTOUCH is not set 1190 | # CONFIG_HID_KYE is not set 1191 | # CONFIG_HID_WALTOP is not set 1192 | # CONFIG_HID_VIEWSONIC is not set 1193 | # CONFIG_HID_GYRATION is not set 1194 | # CONFIG_HID_ICADE is not set 1195 | # CONFIG_HID_ITE is not set 1196 | # CONFIG_HID_JABRA is not set 1197 | # CONFIG_HID_TWINHAN is not set 1198 | # CONFIG_HID_KENSINGTON is not set 1199 | # CONFIG_HID_LCPOWER is not set 1200 | # CONFIG_HID_LENOVO is not set 1201 | # CONFIG_HID_MAGICMOUSE is not set 1202 | # CONFIG_HID_MALTRON is not set 1203 | # CONFIG_HID_MAYFLASH is not set 1204 | # CONFIG_HID_REDRAGON is not set 1205 | # CONFIG_HID_MICROSOFT is not set 1206 | # CONFIG_HID_MONTEREY is not set 1207 | # CONFIG_HID_MULTITOUCH is not set 1208 | # CONFIG_HID_NTI is not set 1209 | # CONFIG_HID_ORTEK is not set 1210 | # CONFIG_HID_PANTHERLORD is not set 1211 | # CONFIG_HID_PETALYNX is not set 1212 | # CONFIG_HID_PICOLCD is not set 1213 | # CONFIG_HID_PLANTRONICS is not set 1214 | # CONFIG_HID_PRIMAX is not set 1215 | # CONFIG_HID_SAITEK is not set 1216 | # CONFIG_HID_SAMSUNG is not set 1217 | # CONFIG_HID_SPEEDLINK is not set 1218 | # CONFIG_HID_STEAM is not set 1219 | # CONFIG_HID_STEELSERIES is not set 1220 | # CONFIG_HID_SUNPLUS is not set 1221 | # CONFIG_HID_RMI is not set 1222 | # CONFIG_HID_GREENASIA is not set 1223 | # CONFIG_HID_SMARTJOYPLUS is not set 1224 | # CONFIG_HID_TIVO is not set 1225 | # CONFIG_HID_TOPSEED is not set 1226 | # CONFIG_HID_THRUSTMASTER is not set 1227 | # CONFIG_HID_UDRAW_PS3 is not set 1228 | # CONFIG_HID_XINMO is not set 1229 | # CONFIG_HID_ZEROPLUS is not set 1230 | # CONFIG_HID_ZYDACRON is not set 1231 | # CONFIG_HID_SENSOR_HUB is not set 1232 | # CONFIG_HID_ALPS is not set 1233 | # end of Special HID drivers 1234 | 1235 | # 1236 | # Intel ISH HID support 1237 | # 1238 | # CONFIG_INTEL_ISH_HID is not set 1239 | # end of Intel ISH HID support 1240 | # end of HID support 1241 | 1242 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y 1243 | # CONFIG_USB_SUPPORT is not set 1244 | # CONFIG_MMC is not set 1245 | # CONFIG_MEMSTICK is not set 1246 | # CONFIG_NEW_LEDS is not set 1247 | # CONFIG_ACCESSIBILITY is not set 1248 | CONFIG_EDAC_ATOMIC_SCRUB=y 1249 | CONFIG_EDAC_SUPPORT=y 1250 | CONFIG_RTC_LIB=y 1251 | CONFIG_RTC_MC146818_LIB=y 1252 | # CONFIG_RTC_CLASS is not set 1253 | # CONFIG_DMADEVICES is not set 1254 | 1255 | # 1256 | # DMABUF options 1257 | # 1258 | # CONFIG_SYNC_FILE is not set 1259 | # CONFIG_DMABUF_MOVE_NOTIFY is not set 1260 | # CONFIG_DMABUF_HEAPS is not set 1261 | # end of DMABUF options 1262 | 1263 | # CONFIG_AUXDISPLAY is not set 1264 | # CONFIG_UIO is not set 1265 | # CONFIG_VIRT_DRIVERS is not set 1266 | # CONFIG_VIRTIO_MENU is not set 1267 | # CONFIG_VDPA is not set 1268 | CONFIG_VHOST_MENU=y 1269 | # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set 1270 | 1271 | # 1272 | # Microsoft Hyper-V guest support 1273 | # 1274 | # end of Microsoft Hyper-V guest support 1275 | 1276 | # CONFIG_GREYBUS is not set 1277 | # CONFIG_STAGING is not set 1278 | # CONFIG_X86_PLATFORM_DEVICES is not set 1279 | CONFIG_PMC_ATOM=y 1280 | # CONFIG_MFD_CROS_EC is not set 1281 | # CONFIG_CHROME_PLATFORMS is not set 1282 | # CONFIG_MELLANOX_PLATFORM is not set 1283 | CONFIG_HAVE_CLK=y 1284 | CONFIG_CLKDEV_LOOKUP=y 1285 | CONFIG_HAVE_CLK_PREPARE=y 1286 | CONFIG_COMMON_CLK=y 1287 | # CONFIG_HWSPINLOCK is not set 1288 | 1289 | # 1290 | # Clock Source drivers 1291 | # 1292 | CONFIG_CLKEVT_I8253=y 1293 | CONFIG_CLKBLD_I8253=y 1294 | # end of Clock Source drivers 1295 | 1296 | # CONFIG_MAILBOX is not set 1297 | # CONFIG_IOMMU_SUPPORT is not set 1298 | 1299 | # 1300 | # Remoteproc drivers 1301 | # 1302 | # CONFIG_REMOTEPROC is not set 1303 | # end of Remoteproc drivers 1304 | 1305 | # 1306 | # Rpmsg drivers 1307 | # 1308 | # CONFIG_RPMSG_VIRTIO is not set 1309 | # end of Rpmsg drivers 1310 | 1311 | # 1312 | # SOC (System On Chip) specific Drivers 1313 | # 1314 | 1315 | # 1316 | # Amlogic SoC drivers 1317 | # 1318 | # end of Amlogic SoC drivers 1319 | 1320 | # 1321 | # Aspeed SoC drivers 1322 | # 1323 | # end of Aspeed SoC drivers 1324 | 1325 | # 1326 | # Broadcom SoC drivers 1327 | # 1328 | # end of Broadcom SoC drivers 1329 | 1330 | # 1331 | # NXP/Freescale QorIQ SoC drivers 1332 | # 1333 | # end of NXP/Freescale QorIQ SoC drivers 1334 | 1335 | # 1336 | # i.MX SoC drivers 1337 | # 1338 | # end of i.MX SoC drivers 1339 | 1340 | # 1341 | # Qualcomm SoC drivers 1342 | # 1343 | # end of Qualcomm SoC drivers 1344 | 1345 | # CONFIG_SOC_TI is not set 1346 | 1347 | # 1348 | # Xilinx SoC drivers 1349 | # 1350 | # CONFIG_XILINX_VCU is not set 1351 | # end of Xilinx SoC drivers 1352 | # end of SOC (System On Chip) specific Drivers 1353 | 1354 | # CONFIG_PM_DEVFREQ is not set 1355 | # CONFIG_EXTCON is not set 1356 | # CONFIG_MEMORY is not set 1357 | # CONFIG_IIO is not set 1358 | # CONFIG_NTB is not set 1359 | # CONFIG_VME_BUS is not set 1360 | # CONFIG_PWM is not set 1361 | 1362 | # 1363 | # IRQ chip support 1364 | # 1365 | # end of IRQ chip support 1366 | 1367 | # CONFIG_IPACK_BUS is not set 1368 | # CONFIG_RESET_CONTROLLER is not set 1369 | 1370 | # 1371 | # PHY Subsystem 1372 | # 1373 | # CONFIG_GENERIC_PHY is not set 1374 | # CONFIG_BCM_KONA_USB2_PHY is not set 1375 | # CONFIG_PHY_PXA_28NM_HSIC is not set 1376 | # CONFIG_PHY_PXA_28NM_USB2 is not set 1377 | # CONFIG_PHY_INTEL_EMMC is not set 1378 | # end of PHY Subsystem 1379 | 1380 | # CONFIG_POWERCAP is not set 1381 | # CONFIG_MCB is not set 1382 | 1383 | # 1384 | # Performance monitor support 1385 | # 1386 | # end of Performance monitor support 1387 | 1388 | # CONFIG_RAS is not set 1389 | # CONFIG_USB4 is not set 1390 | 1391 | # 1392 | # Android 1393 | # 1394 | # CONFIG_ANDROID is not set 1395 | # end of Android 1396 | 1397 | # CONFIG_LIBNVDIMM is not set 1398 | # CONFIG_DAX is not set 1399 | # CONFIG_NVMEM is not set 1400 | 1401 | # 1402 | # HW tracing support 1403 | # 1404 | # CONFIG_STM is not set 1405 | # CONFIG_INTEL_TH is not set 1406 | # end of HW tracing support 1407 | 1408 | # CONFIG_FPGA is not set 1409 | # CONFIG_TEE is not set 1410 | # CONFIG_SIOX is not set 1411 | # CONFIG_SLIMBUS is not set 1412 | # CONFIG_INTERCONNECT is not set 1413 | # CONFIG_COUNTER is not set 1414 | # end of Device Drivers 1415 | 1416 | # 1417 | # File systems 1418 | # 1419 | CONFIG_DCACHE_WORD_ACCESS=y 1420 | # CONFIG_VALIDATE_FS_PARSER is not set 1421 | CONFIG_FS_IOMAP=y 1422 | # CONFIG_EXT2_FS is not set 1423 | # CONFIG_EXT3_FS is not set 1424 | CONFIG_EXT4_FS=y 1425 | CONFIG_EXT4_USE_FOR_EXT2=y 1426 | # CONFIG_EXT4_FS_POSIX_ACL is not set 1427 | # CONFIG_EXT4_FS_SECURITY is not set 1428 | # CONFIG_EXT4_DEBUG is not set 1429 | CONFIG_JBD2=y 1430 | # CONFIG_JBD2_DEBUG is not set 1431 | CONFIG_FS_MBCACHE=y 1432 | # CONFIG_REISERFS_FS is not set 1433 | # CONFIG_JFS_FS is not set 1434 | # CONFIG_XFS_FS is not set 1435 | # CONFIG_GFS2_FS is not set 1436 | # CONFIG_BTRFS_FS is not set 1437 | # CONFIG_NILFS2_FS is not set 1438 | # CONFIG_F2FS_FS is not set 1439 | # CONFIG_FS_DAX is not set 1440 | # CONFIG_EXPORTFS_BLOCK_OPS is not set 1441 | # CONFIG_FILE_LOCKING is not set 1442 | # CONFIG_FS_ENCRYPTION is not set 1443 | # CONFIG_FS_VERITY is not set 1444 | # CONFIG_DNOTIFY is not set 1445 | # CONFIG_INOTIFY_USER is not set 1446 | # CONFIG_FANOTIFY is not set 1447 | # CONFIG_QUOTA is not set 1448 | # CONFIG_AUTOFS4_FS is not set 1449 | # CONFIG_AUTOFS_FS is not set 1450 | # CONFIG_FUSE_FS is not set 1451 | # CONFIG_OVERLAY_FS is not set 1452 | 1453 | # 1454 | # Caches 1455 | # 1456 | # CONFIG_FSCACHE is not set 1457 | # end of Caches 1458 | 1459 | # 1460 | # CD-ROM/DVD Filesystems 1461 | # 1462 | # CONFIG_ISO9660_FS is not set 1463 | # CONFIG_UDF_FS is not set 1464 | # end of CD-ROM/DVD Filesystems 1465 | 1466 | # 1467 | # DOS/FAT/EXFAT/NT Filesystems 1468 | # 1469 | CONFIG_FAT_FS=y 1470 | # CONFIG_MSDOS_FS is not set 1471 | CONFIG_VFAT_FS=y 1472 | CONFIG_FAT_DEFAULT_CODEPAGE=437 1473 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" 1474 | CONFIG_FAT_DEFAULT_UTF8=y 1475 | # CONFIG_EXFAT_FS is not set 1476 | # CONFIG_NTFS_FS is not set 1477 | # end of DOS/FAT/EXFAT/NT Filesystems 1478 | 1479 | # 1480 | # Pseudo filesystems 1481 | # 1482 | CONFIG_PROC_FS=y 1483 | # CONFIG_PROC_KCORE is not set 1484 | CONFIG_PROC_SYSCTL=y 1485 | CONFIG_PROC_PAGE_MONITOR=y 1486 | # CONFIG_PROC_CHILDREN is not set 1487 | CONFIG_PROC_PID_ARCH_STATUS=y 1488 | CONFIG_KERNFS=y 1489 | CONFIG_SYSFS=y 1490 | # CONFIG_HUGETLBFS is not set 1491 | CONFIG_ARCH_HAS_GIGANTIC_PAGE=y 1492 | # CONFIG_CONFIGFS_FS is not set 1493 | # end of Pseudo filesystems 1494 | 1495 | # CONFIG_MISC_FILESYSTEMS is not set 1496 | CONFIG_NLS=y 1497 | CONFIG_NLS_DEFAULT="iso8859-1" 1498 | CONFIG_NLS_CODEPAGE_437=y 1499 | # CONFIG_NLS_CODEPAGE_737 is not set 1500 | # CONFIG_NLS_CODEPAGE_775 is not set 1501 | # CONFIG_NLS_CODEPAGE_850 is not set 1502 | # CONFIG_NLS_CODEPAGE_852 is not set 1503 | # CONFIG_NLS_CODEPAGE_855 is not set 1504 | # CONFIG_NLS_CODEPAGE_857 is not set 1505 | # CONFIG_NLS_CODEPAGE_860 is not set 1506 | # CONFIG_NLS_CODEPAGE_861 is not set 1507 | # CONFIG_NLS_CODEPAGE_862 is not set 1508 | # CONFIG_NLS_CODEPAGE_863 is not set 1509 | # CONFIG_NLS_CODEPAGE_864 is not set 1510 | # CONFIG_NLS_CODEPAGE_865 is not set 1511 | # CONFIG_NLS_CODEPAGE_866 is not set 1512 | # CONFIG_NLS_CODEPAGE_869 is not set 1513 | # CONFIG_NLS_CODEPAGE_936 is not set 1514 | # CONFIG_NLS_CODEPAGE_950 is not set 1515 | # CONFIG_NLS_CODEPAGE_932 is not set 1516 | # CONFIG_NLS_CODEPAGE_949 is not set 1517 | # CONFIG_NLS_CODEPAGE_874 is not set 1518 | # CONFIG_NLS_ISO8859_8 is not set 1519 | # CONFIG_NLS_CODEPAGE_1250 is not set 1520 | # CONFIG_NLS_CODEPAGE_1251 is not set 1521 | CONFIG_NLS_ASCII=y 1522 | CONFIG_NLS_ISO8859_1=y 1523 | # CONFIG_NLS_ISO8859_2 is not set 1524 | # CONFIG_NLS_ISO8859_3 is not set 1525 | # CONFIG_NLS_ISO8859_4 is not set 1526 | # CONFIG_NLS_ISO8859_5 is not set 1527 | # CONFIG_NLS_ISO8859_6 is not set 1528 | # CONFIG_NLS_ISO8859_7 is not set 1529 | # CONFIG_NLS_ISO8859_9 is not set 1530 | # CONFIG_NLS_ISO8859_13 is not set 1531 | # CONFIG_NLS_ISO8859_14 is not set 1532 | # CONFIG_NLS_ISO8859_15 is not set 1533 | # CONFIG_NLS_KOI8_R is not set 1534 | # CONFIG_NLS_KOI8_U is not set 1535 | # CONFIG_NLS_MAC_ROMAN is not set 1536 | # CONFIG_NLS_MAC_CELTIC is not set 1537 | # CONFIG_NLS_MAC_CENTEURO is not set 1538 | # CONFIG_NLS_MAC_CROATIAN is not set 1539 | # CONFIG_NLS_MAC_CYRILLIC is not set 1540 | # CONFIG_NLS_MAC_GAELIC is not set 1541 | # CONFIG_NLS_MAC_GREEK is not set 1542 | # CONFIG_NLS_MAC_ICELAND is not set 1543 | # CONFIG_NLS_MAC_INUIT is not set 1544 | # CONFIG_NLS_MAC_ROMANIAN is not set 1545 | # CONFIG_NLS_MAC_TURKISH is not set 1546 | CONFIG_NLS_UTF8=y 1547 | CONFIG_UNICODE=y 1548 | # CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set 1549 | # end of File systems 1550 | 1551 | # 1552 | # Security options 1553 | # 1554 | # CONFIG_KEYS is not set 1555 | # CONFIG_SECURITY_DMESG_RESTRICT is not set 1556 | # CONFIG_SECURITYFS is not set 1557 | CONFIG_PAGE_TABLE_ISOLATION=y 1558 | CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y 1559 | # CONFIG_HARDENED_USERCOPY is not set 1560 | # CONFIG_FORTIFY_SOURCE is not set 1561 | # CONFIG_STATIC_USERMODEHELPER is not set 1562 | CONFIG_DEFAULT_SECURITY_DAC=y 1563 | CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" 1564 | 1565 | # 1566 | # Kernel hardening options 1567 | # 1568 | 1569 | # 1570 | # Memory initialization 1571 | # 1572 | CONFIG_INIT_STACK_NONE=y 1573 | # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set 1574 | # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set 1575 | # end of Memory initialization 1576 | # end of Kernel hardening options 1577 | # end of Security options 1578 | 1579 | CONFIG_CRYPTO=y 1580 | 1581 | # 1582 | # Crypto core or helper 1583 | # 1584 | CONFIG_CRYPTO_ALGAPI=y 1585 | CONFIG_CRYPTO_ALGAPI2=y 1586 | CONFIG_CRYPTO_HASH=y 1587 | CONFIG_CRYPTO_HASH2=y 1588 | # CONFIG_CRYPTO_MANAGER is not set 1589 | CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y 1590 | # CONFIG_CRYPTO_NULL is not set 1591 | # CONFIG_CRYPTO_CRYPTD is not set 1592 | # CONFIG_CRYPTO_AUTHENC is not set 1593 | 1594 | # 1595 | # Public-key cryptography 1596 | # 1597 | # CONFIG_CRYPTO_RSA is not set 1598 | # CONFIG_CRYPTO_DH is not set 1599 | # CONFIG_CRYPTO_ECDH is not set 1600 | # CONFIG_CRYPTO_ECRDSA is not set 1601 | # CONFIG_CRYPTO_CURVE25519 is not set 1602 | # CONFIG_CRYPTO_CURVE25519_X86 is not set 1603 | 1604 | # 1605 | # Authenticated Encryption with Associated Data 1606 | # 1607 | # CONFIG_CRYPTO_CCM is not set 1608 | # CONFIG_CRYPTO_GCM is not set 1609 | # CONFIG_CRYPTO_CHACHA20POLY1305 is not set 1610 | # CONFIG_CRYPTO_AEGIS128 is not set 1611 | # CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set 1612 | # CONFIG_CRYPTO_SEQIV is not set 1613 | # CONFIG_CRYPTO_ECHAINIV is not set 1614 | 1615 | # 1616 | # Block modes 1617 | # 1618 | # CONFIG_CRYPTO_CBC is not set 1619 | # CONFIG_CRYPTO_CFB is not set 1620 | # CONFIG_CRYPTO_CTR is not set 1621 | # CONFIG_CRYPTO_CTS is not set 1622 | # CONFIG_CRYPTO_ECB is not set 1623 | # CONFIG_CRYPTO_LRW is not set 1624 | # CONFIG_CRYPTO_OFB is not set 1625 | # CONFIG_CRYPTO_PCBC is not set 1626 | # CONFIG_CRYPTO_XTS is not set 1627 | # CONFIG_CRYPTO_KEYWRAP is not set 1628 | # CONFIG_CRYPTO_NHPOLY1305_SSE2 is not set 1629 | # CONFIG_CRYPTO_NHPOLY1305_AVX2 is not set 1630 | # CONFIG_CRYPTO_ADIANTUM is not set 1631 | # CONFIG_CRYPTO_ESSIV is not set 1632 | 1633 | # 1634 | # Hash modes 1635 | # 1636 | # CONFIG_CRYPTO_CMAC is not set 1637 | # CONFIG_CRYPTO_HMAC is not set 1638 | # CONFIG_CRYPTO_XCBC is not set 1639 | # CONFIG_CRYPTO_VMAC is not set 1640 | 1641 | # 1642 | # Digest 1643 | # 1644 | CONFIG_CRYPTO_CRC32C=y 1645 | # CONFIG_CRYPTO_CRC32C_INTEL is not set 1646 | # CONFIG_CRYPTO_CRC32 is not set 1647 | # CONFIG_CRYPTO_CRC32_PCLMUL is not set 1648 | # CONFIG_CRYPTO_XXHASH is not set 1649 | # CONFIG_CRYPTO_BLAKE2B is not set 1650 | # CONFIG_CRYPTO_BLAKE2S is not set 1651 | # CONFIG_CRYPTO_BLAKE2S_X86 is not set 1652 | # CONFIG_CRYPTO_CRCT10DIF is not set 1653 | # CONFIG_CRYPTO_GHASH is not set 1654 | # CONFIG_CRYPTO_POLY1305 is not set 1655 | # CONFIG_CRYPTO_POLY1305_X86_64 is not set 1656 | # CONFIG_CRYPTO_MD4 is not set 1657 | # CONFIG_CRYPTO_MD5 is not set 1658 | # CONFIG_CRYPTO_MICHAEL_MIC is not set 1659 | # CONFIG_CRYPTO_RMD128 is not set 1660 | # CONFIG_CRYPTO_RMD160 is not set 1661 | # CONFIG_CRYPTO_RMD256 is not set 1662 | # CONFIG_CRYPTO_RMD320 is not set 1663 | # CONFIG_CRYPTO_SHA1 is not set 1664 | # CONFIG_CRYPTO_SHA1_SSSE3 is not set 1665 | # CONFIG_CRYPTO_SHA256_SSSE3 is not set 1666 | # CONFIG_CRYPTO_SHA512_SSSE3 is not set 1667 | # CONFIG_CRYPTO_SHA256 is not set 1668 | # CONFIG_CRYPTO_SHA512 is not set 1669 | # CONFIG_CRYPTO_SHA3 is not set 1670 | # CONFIG_CRYPTO_SM3 is not set 1671 | # CONFIG_CRYPTO_STREEBOG is not set 1672 | # CONFIG_CRYPTO_TGR192 is not set 1673 | # CONFIG_CRYPTO_WP512 is not set 1674 | # CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set 1675 | 1676 | # 1677 | # Ciphers 1678 | # 1679 | # CONFIG_CRYPTO_AES is not set 1680 | # CONFIG_CRYPTO_AES_TI is not set 1681 | # CONFIG_CRYPTO_AES_NI_INTEL is not set 1682 | # CONFIG_CRYPTO_ANUBIS is not set 1683 | # CONFIG_CRYPTO_ARC4 is not set 1684 | # CONFIG_CRYPTO_BLOWFISH is not set 1685 | # CONFIG_CRYPTO_BLOWFISH_X86_64 is not set 1686 | # CONFIG_CRYPTO_CAMELLIA is not set 1687 | # CONFIG_CRYPTO_CAMELLIA_X86_64 is not set 1688 | # CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64 is not set 1689 | # CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 is not set 1690 | # CONFIG_CRYPTO_CAST5 is not set 1691 | # CONFIG_CRYPTO_CAST5_AVX_X86_64 is not set 1692 | # CONFIG_CRYPTO_CAST6 is not set 1693 | # CONFIG_CRYPTO_CAST6_AVX_X86_64 is not set 1694 | # CONFIG_CRYPTO_DES is not set 1695 | # CONFIG_CRYPTO_DES3_EDE_X86_64 is not set 1696 | # CONFIG_CRYPTO_FCRYPT is not set 1697 | # CONFIG_CRYPTO_KHAZAD is not set 1698 | # CONFIG_CRYPTO_SALSA20 is not set 1699 | # CONFIG_CRYPTO_CHACHA20 is not set 1700 | # CONFIG_CRYPTO_CHACHA20_X86_64 is not set 1701 | # CONFIG_CRYPTO_SEED is not set 1702 | # CONFIG_CRYPTO_SERPENT is not set 1703 | # CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set 1704 | # CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set 1705 | # CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set 1706 | # CONFIG_CRYPTO_SM4 is not set 1707 | # CONFIG_CRYPTO_TEA is not set 1708 | # CONFIG_CRYPTO_TWOFISH is not set 1709 | # CONFIG_CRYPTO_TWOFISH_X86_64 is not set 1710 | # CONFIG_CRYPTO_TWOFISH_X86_64_3WAY is not set 1711 | # CONFIG_CRYPTO_TWOFISH_AVX_X86_64 is not set 1712 | 1713 | # 1714 | # Compression 1715 | # 1716 | # CONFIG_CRYPTO_DEFLATE is not set 1717 | # CONFIG_CRYPTO_LZO is not set 1718 | # CONFIG_CRYPTO_842 is not set 1719 | # CONFIG_CRYPTO_LZ4 is not set 1720 | # CONFIG_CRYPTO_LZ4HC is not set 1721 | # CONFIG_CRYPTO_ZSTD is not set 1722 | 1723 | # 1724 | # Random Number Generation 1725 | # 1726 | # CONFIG_CRYPTO_ANSI_CPRNG is not set 1727 | # CONFIG_CRYPTO_DRBG_MENU is not set 1728 | # CONFIG_CRYPTO_JITTERENTROPY is not set 1729 | 1730 | # 1731 | # Crypto library routines 1732 | # 1733 | # CONFIG_CRYPTO_LIB_BLAKE2S is not set 1734 | # CONFIG_CRYPTO_LIB_CHACHA is not set 1735 | # CONFIG_CRYPTO_LIB_CURVE25519 is not set 1736 | CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 1737 | # CONFIG_CRYPTO_LIB_POLY1305 is not set 1738 | # CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set 1739 | CONFIG_CRYPTO_HW=y 1740 | # CONFIG_CRYPTO_DEV_PADLOCK is not set 1741 | # CONFIG_CRYPTO_DEV_CCP is not set 1742 | # CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set 1743 | # CONFIG_CRYPTO_DEV_QAT_C3XXX is not set 1744 | # CONFIG_CRYPTO_DEV_QAT_C62X is not set 1745 | # CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set 1746 | # CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set 1747 | # CONFIG_CRYPTO_DEV_QAT_C62XVF is not set 1748 | # CONFIG_CRYPTO_DEV_SAFEXCEL is not set 1749 | # CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set 1750 | 1751 | # 1752 | # Certificates for signature checking 1753 | # 1754 | # end of Certificates for signature checking 1755 | 1756 | # 1757 | # Library routines 1758 | # 1759 | # CONFIG_PACKING is not set 1760 | CONFIG_BITREVERSE=y 1761 | CONFIG_GENERIC_STRNCPY_FROM_USER=y 1762 | CONFIG_GENERIC_STRNLEN_USER=y 1763 | CONFIG_GENERIC_FIND_FIRST_BIT=y 1764 | # CONFIG_CORDIC is not set 1765 | # CONFIG_PRIME_NUMBERS is not set 1766 | CONFIG_RATIONAL=y 1767 | CONFIG_GENERIC_PCI_IOMAP=y 1768 | CONFIG_GENERIC_IOMAP=y 1769 | CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y 1770 | CONFIG_ARCH_HAS_FAST_MULTIPLIER=y 1771 | CONFIG_ARCH_USE_SYM_ANNOTATIONS=y 1772 | # CONFIG_CRC_CCITT is not set 1773 | CONFIG_CRC16=y 1774 | # CONFIG_CRC_T10DIF is not set 1775 | # CONFIG_CRC_ITU_T is not set 1776 | CONFIG_CRC32=y 1777 | # CONFIG_CRC32_SELFTEST is not set 1778 | CONFIG_CRC32_SLICEBY8=y 1779 | # CONFIG_CRC32_SLICEBY4 is not set 1780 | # CONFIG_CRC32_SARWATE is not set 1781 | # CONFIG_CRC32_BIT is not set 1782 | # CONFIG_CRC64 is not set 1783 | # CONFIG_CRC4 is not set 1784 | # CONFIG_CRC7 is not set 1785 | # CONFIG_LIBCRC32C is not set 1786 | # CONFIG_CRC8 is not set 1787 | # CONFIG_RANDOM32_SELFTEST is not set 1788 | CONFIG_ZLIB_INFLATE=y 1789 | # CONFIG_XZ_DEC is not set 1790 | CONFIG_DECOMPRESS_GZIP=y 1791 | CONFIG_HAS_IOMEM=y 1792 | CONFIG_HAS_IOPORT_MAP=y 1793 | CONFIG_HAS_DMA=y 1794 | CONFIG_NEED_SG_DMA_LENGTH=y 1795 | CONFIG_NEED_DMA_MAP_STATE=y 1796 | CONFIG_ARCH_DMA_ADDR_T_64BIT=y 1797 | CONFIG_SWIOTLB=y 1798 | # CONFIG_DMA_API_DEBUG is not set 1799 | CONFIG_GLOB=y 1800 | # CONFIG_GLOB_SELFTEST is not set 1801 | # CONFIG_IRQ_POLL is not set 1802 | CONFIG_HAVE_GENERIC_VDSO=y 1803 | CONFIG_GENERIC_GETTIMEOFDAY=y 1804 | CONFIG_GENERIC_VDSO_TIME_NS=y 1805 | CONFIG_FONT_SUPPORT=y 1806 | CONFIG_FONT_8x16=y 1807 | CONFIG_FONT_AUTOSELECT=y 1808 | CONFIG_SG_POOL=y 1809 | CONFIG_ARCH_HAS_PMEM_API=y 1810 | CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y 1811 | CONFIG_ARCH_STACKWALK=y 1812 | CONFIG_SBITMAP=y 1813 | # CONFIG_STRING_SELFTEST is not set 1814 | # end of Library routines 1815 | 1816 | # 1817 | # Kernel hacking 1818 | # 1819 | 1820 | # 1821 | # printk and dmesg options 1822 | # 1823 | # CONFIG_PRINTK_TIME is not set 1824 | # CONFIG_PRINTK_CALLER is not set 1825 | CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 1826 | CONFIG_CONSOLE_LOGLEVEL_QUIET=4 1827 | CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 1828 | # CONFIG_BOOT_PRINTK_DELAY is not set 1829 | # CONFIG_DYNAMIC_DEBUG is not set 1830 | # CONFIG_DYNAMIC_DEBUG_CORE is not set 1831 | # CONFIG_SYMBOLIC_ERRNAME is not set 1832 | # end of printk and dmesg options 1833 | 1834 | # 1835 | # Compile-time checks and compiler options 1836 | # 1837 | # CONFIG_DEBUG_INFO is not set 1838 | # CONFIG_ENABLE_MUST_CHECK is not set 1839 | CONFIG_FRAME_WARN=1024 1840 | # CONFIG_STRIP_ASM_SYMS is not set 1841 | # CONFIG_READABLE_ASM is not set 1842 | # CONFIG_HEADERS_INSTALL is not set 1843 | # CONFIG_DEBUG_SECTION_MISMATCH is not set 1844 | # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set 1845 | CONFIG_FRAME_POINTER=y 1846 | # CONFIG_STACK_VALIDATION is not set 1847 | # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set 1848 | # end of Compile-time checks and compiler options 1849 | 1850 | # 1851 | # Generic Kernel Debugging Instruments 1852 | # 1853 | # CONFIG_MAGIC_SYSRQ is not set 1854 | # CONFIG_DEBUG_FS is not set 1855 | CONFIG_HAVE_ARCH_KGDB=y 1856 | # CONFIG_KGDB is not set 1857 | CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y 1858 | # CONFIG_UBSAN is not set 1859 | # end of Generic Kernel Debugging Instruments 1860 | 1861 | CONFIG_DEBUG_KERNEL=y 1862 | # CONFIG_DEBUG_MISC is not set 1863 | 1864 | # 1865 | # Memory Debugging 1866 | # 1867 | # CONFIG_PAGE_EXTENSION is not set 1868 | # CONFIG_DEBUG_PAGEALLOC is not set 1869 | # CONFIG_PAGE_OWNER is not set 1870 | # CONFIG_PAGE_POISONING is not set 1871 | # CONFIG_DEBUG_RODATA_TEST is not set 1872 | CONFIG_ARCH_HAS_DEBUG_WX=y 1873 | # CONFIG_DEBUG_WX is not set 1874 | CONFIG_GENERIC_PTDUMP=y 1875 | # CONFIG_DEBUG_OBJECTS is not set 1876 | # CONFIG_SLUB_DEBUG_ON is not set 1877 | # CONFIG_SLUB_STATS is not set 1878 | CONFIG_HAVE_DEBUG_KMEMLEAK=y 1879 | # CONFIG_DEBUG_KMEMLEAK is not set 1880 | # CONFIG_DEBUG_STACK_USAGE is not set 1881 | # CONFIG_SCHED_STACK_END_CHECK is not set 1882 | CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y 1883 | # CONFIG_DEBUG_VM is not set 1884 | # CONFIG_DEBUG_VM_PGTABLE is not set 1885 | CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y 1886 | # CONFIG_DEBUG_VIRTUAL is not set 1887 | # CONFIG_DEBUG_MEMORY_INIT is not set 1888 | CONFIG_HAVE_ARCH_KASAN=y 1889 | CONFIG_HAVE_ARCH_KASAN_VMALLOC=y 1890 | CONFIG_CC_HAS_KASAN_GENERIC=y 1891 | CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y 1892 | # CONFIG_KASAN is not set 1893 | CONFIG_KASAN_STACK=1 1894 | # end of Memory Debugging 1895 | 1896 | # CONFIG_DEBUG_SHIRQ is not set 1897 | 1898 | # 1899 | # Debug Oops, Lockups and Hangs 1900 | # 1901 | # CONFIG_PANIC_ON_OOPS is not set 1902 | CONFIG_PANIC_ON_OOPS_VALUE=0 1903 | CONFIG_PANIC_TIMEOUT=0 1904 | # CONFIG_SOFTLOCKUP_DETECTOR is not set 1905 | CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y 1906 | # CONFIG_HARDLOCKUP_DETECTOR is not set 1907 | # CONFIG_DETECT_HUNG_TASK is not set 1908 | # CONFIG_WQ_WATCHDOG is not set 1909 | # CONFIG_TEST_LOCKUP is not set 1910 | # end of Debug Oops, Lockups and Hangs 1911 | 1912 | # 1913 | # Scheduler Debugging 1914 | # 1915 | CONFIG_SCHED_DEBUG=y 1916 | # CONFIG_SCHEDSTATS is not set 1917 | # end of Scheduler Debugging 1918 | 1919 | # CONFIG_DEBUG_TIMEKEEPING is not set 1920 | 1921 | # 1922 | # Lock Debugging (spinlocks, mutexes, etc...) 1923 | # 1924 | CONFIG_LOCK_DEBUGGING_SUPPORT=y 1925 | # CONFIG_PROVE_LOCKING is not set 1926 | # CONFIG_LOCK_STAT is not set 1927 | # CONFIG_DEBUG_SPINLOCK is not set 1928 | # CONFIG_DEBUG_MUTEXES is not set 1929 | # CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set 1930 | # CONFIG_DEBUG_RWSEMS is not set 1931 | # CONFIG_DEBUG_LOCK_ALLOC is not set 1932 | # CONFIG_DEBUG_ATOMIC_SLEEP is not set 1933 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 1934 | # CONFIG_LOCK_TORTURE_TEST is not set 1935 | # CONFIG_WW_MUTEX_SELFTEST is not set 1936 | # end of Lock Debugging (spinlocks, mutexes, etc...) 1937 | 1938 | # CONFIG_STACKTRACE is not set 1939 | # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set 1940 | # CONFIG_DEBUG_KOBJECT is not set 1941 | 1942 | # 1943 | # Debug kernel data structures 1944 | # 1945 | # CONFIG_DEBUG_LIST is not set 1946 | # CONFIG_DEBUG_PLIST is not set 1947 | # CONFIG_DEBUG_SG is not set 1948 | # CONFIG_DEBUG_NOTIFIERS is not set 1949 | # CONFIG_BUG_ON_DATA_CORRUPTION is not set 1950 | # end of Debug kernel data structures 1951 | 1952 | # CONFIG_DEBUG_CREDENTIALS is not set 1953 | 1954 | # 1955 | # RCU Debugging 1956 | # 1957 | # CONFIG_RCU_PERF_TEST is not set 1958 | # CONFIG_RCU_TORTURE_TEST is not set 1959 | # CONFIG_RCU_TRACE is not set 1960 | # CONFIG_RCU_EQS_DEBUG is not set 1961 | # end of RCU Debugging 1962 | 1963 | # CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set 1964 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set 1965 | # CONFIG_LATENCYTOP is not set 1966 | CONFIG_USER_STACKTRACE_SUPPORT=y 1967 | CONFIG_HAVE_FUNCTION_TRACER=y 1968 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y 1969 | CONFIG_HAVE_DYNAMIC_FTRACE=y 1970 | CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y 1971 | CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y 1972 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y 1973 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y 1974 | CONFIG_HAVE_FENTRY=y 1975 | CONFIG_HAVE_C_RECORDMCOUNT=y 1976 | CONFIG_TRACING_SUPPORT=y 1977 | # CONFIG_FTRACE is not set 1978 | # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set 1979 | # CONFIG_SAMPLES is not set 1980 | CONFIG_HAVE_ARCH_KCSAN=y 1981 | CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y 1982 | 1983 | # 1984 | # x86 Debugging 1985 | # 1986 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y 1987 | # CONFIG_X86_VERBOSE_BOOTUP is not set 1988 | # CONFIG_EARLY_PRINTK is not set 1989 | # CONFIG_DEBUG_TLBFLUSH is not set 1990 | CONFIG_HAVE_MMIOTRACE_SUPPORT=y 1991 | # CONFIG_X86_DECODER_SELFTEST is not set 1992 | CONFIG_IO_DELAY_0X80=y 1993 | # CONFIG_IO_DELAY_0XED is not set 1994 | # CONFIG_IO_DELAY_UDELAY is not set 1995 | # CONFIG_IO_DELAY_NONE is not set 1996 | # CONFIG_CPA_DEBUG is not set 1997 | # CONFIG_DEBUG_ENTRY is not set 1998 | # CONFIG_DEBUG_NMI_SELFTEST is not set 1999 | # CONFIG_X86_DEBUG_FPU is not set 2000 | # CONFIG_PUNIT_ATOM_DEBUG is not set 2001 | # CONFIG_UNWINDER_ORC is not set 2002 | CONFIG_UNWINDER_FRAME_POINTER=y 2003 | # CONFIG_UNWINDER_GUESS is not set 2004 | # end of x86 Debugging 2005 | 2006 | # 2007 | # Kernel Testing and Coverage 2008 | # 2009 | # CONFIG_KUNIT is not set 2010 | # CONFIG_NOTIFIER_ERROR_INJECTION is not set 2011 | # CONFIG_FAULT_INJECTION is not set 2012 | CONFIG_CC_HAS_SANCOV_TRACE_PC=y 2013 | # CONFIG_RUNTIME_TESTING_MENU is not set 2014 | # CONFIG_MEMTEST is not set 2015 | # end of Kernel Testing and Coverage 2016 | # end of Kernel hacking 2017 | -------------------------------------------------------------------------------- /resources/eg-kernel/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [unstable] 2 | build-std = ["core", "compiler_builtins", "alloc"] -------------------------------------------------------------------------------- /resources/eg-kernel/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eg-kernel" 3 | version = "0.1.0" 4 | authors = ["Hayato Ohhashi "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | [profile.release] 9 | opt-level = "z" 10 | 11 | [dependencies] 12 | -------------------------------------------------------------------------------- /resources/eg-kernel/example.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | SECTIONS { 3 | . = 0x100000; /* "stage3" will be loaded at 2nd page */ 4 | .first : { *(.startup) } /* Locate "stages" First Excutable code */ 5 | .text : { *(.text) } /* Excutable code */ 6 | .rodata : { *(.rodata) } /* Constants (R/O) */ 7 | .data : { *(.data) } /* Initialized data */ 8 | _data_end = .; /* The end of .data section */ 9 | .bss : { *(.bss) } /* Uninitialized data */ 10 | _bss_end = .; /* The end of .bss section */ 11 | } -------------------------------------------------------------------------------- /resources/eg-kernel/i586-example_os.json: -------------------------------------------------------------------------------- 1 | { 2 | "llvm-target": "i586-unknown-none", 3 | "data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", 4 | "arch": "x86", 5 | "cpu": "pentium", 6 | "target-endian": "little", 7 | "target-pointer-width": "32", 8 | "target-c-int-width": "32", 9 | "os": "none", 10 | "executables": true, 11 | "linker-flavor": "ld.lld", 12 | "linker": "rust-lld", 13 | "panic-strategy": "abort", 14 | "disable-redzone": true, 15 | "features": "-mmx,-sse,+soft-float", 16 | "pre-link-args": { 17 | "ld.lld": [ 18 | "--script=example.ld" 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /resources/eg-kernel/rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly -------------------------------------------------------------------------------- /resources/eg-kernel/src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | use core::panic::PanicInfo; 5 | #[panic_handler] 6 | fn panic(_info: &PanicInfo) -> ! { 7 | loop {} 8 | } 9 | 10 | macro_rules! entry { 11 | ($path:path) => { 12 | #[export_name = "main"] 13 | pub fn __main() -> () { 14 | // type check the given path 15 | let f: fn() -> () = $path; 16 | 17 | f() 18 | } 19 | } 20 | } 21 | 22 | #[link_section=".startup"] 23 | #[no_mangle] 24 | fn _start() -> ! { 25 | extern "Rust" { 26 | fn main() -> (); 27 | } 28 | unsafe { 29 | main(); 30 | } 31 | loop {} 32 | } 33 | 34 | static HELLO: &[u8] = b"Hello World!"; 35 | 36 | entry!(main); 37 | fn main() { 38 | let vga_buffer = 0xb8000 as *mut u8; 39 | 40 | for (i, &byte) in HELLO.iter().enumerate() { 41 | unsafe { 42 | *vga_buffer.offset(i as isize * 2) = byte; 43 | *vga_buffer.offset(i as isize * 2 + 1) = 0xb; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /resources/eg-kernel/x64-example_os.json: -------------------------------------------------------------------------------- 1 | { 2 | "llvm-target": "x86_64-unknown-none", 3 | "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", 4 | "arch": "x86_64", 5 | "target-endian": "little", 6 | "target-pointer-width": "64", 7 | "target-c-int-width": "32", 8 | "os": "none", 9 | "executables": true, 10 | "linker-flavor": "ld.lld", 11 | "linker": "rust-lld", 12 | "panic-strategy": "abort", 13 | "disable-redzone": true, 14 | "features": "-mmx,-sse,+soft-float" 15 | } -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly 2 | -------------------------------------------------------------------------------- /src/bios/plankton/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plankton" 3 | version = "0.1.0" 4 | authors = ["Hayato Ohhashi "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /src/bios/plankton/src/con.rs: -------------------------------------------------------------------------------- 1 | pub fn inform(s: &[u8]) { 2 | for &c in s { 3 | printc(c); 4 | } 5 | } 6 | 7 | fn printc(ch: u8) { 8 | unsafe { 9 | llvm_asm!("int $$0x10" 10 | : 11 | : "{ax}"(0x0e00 | (ch as u16 & 0xffu16)), 12 | "{ebx}"(7) 13 | ); 14 | } 15 | } 16 | 17 | use core::fmt::{self, Write}; 18 | #[macro_export] 19 | macro_rules! print { 20 | ($($arg:tt)*) => { 21 | $crate::con::_print(format_args!($($arg)*)) 22 | }; 23 | } 24 | 25 | #[macro_export] 26 | macro_rules! println { 27 | ($fmt:expr) => { 28 | print!(concat!($fmt, "\r\n")) 29 | }; 30 | ($fmt:expr, $($arg:tt)*) => { 31 | print!(concat!($fmt, "\r\n"), $($arg)*) 32 | }; 33 | } 34 | 35 | pub fn _print(args: fmt::Arguments) { 36 | let mut writer = BiosWriter {}; 37 | writer.write_fmt(args).unwrap(); 38 | } 39 | 40 | struct BiosWriter; 41 | 42 | impl Write for BiosWriter { 43 | fn write_str(&mut self, s: &str) -> fmt::Result { 44 | for c in s.bytes() { 45 | printc(c); 46 | } 47 | Ok(()) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/bios/plankton/src/dev.rs: -------------------------------------------------------------------------------- 1 | use super::layout::{INIT_SEG, TRACK_BUFFER}; 2 | use super::mem::copy_block; 3 | use core::str; 4 | 5 | #[derive(Default)] 6 | #[repr(C, packed)] 7 | pub struct Dap { 8 | size: u8, 9 | zero: u8, 10 | pub sectors: u16, 11 | pub buffer: u32, 12 | pub startlba: u64, 13 | } 14 | 15 | impl Dap { 16 | const DISK_ERR: &'static [u8] = b"X"; 17 | pub fn new(sectors: u16, buffer: u32, startlba: u64) -> Self { 18 | Dap { 19 | size: 0x10, 20 | sectors, 21 | buffer, 22 | startlba, 23 | ..Default::default() 24 | } 25 | } 26 | 27 | pub fn hd_read(&self, drv: u8) -> Result<(), &'static [u8]> { 28 | let ret: u16; 29 | let address: *const Dap = self; 30 | unsafe { 31 | llvm_asm!("int $$0x13" 32 | : "={ax}"(ret) 33 | : "{ax}"(0x4200), 34 | "{si}"(address), 35 | "{dl}"(drv) 36 | ); 37 | } 38 | if ret & 0xff00 != 0 { 39 | Err(Self::DISK_ERR) 40 | } else { 41 | Ok(()) 42 | } 43 | } 44 | 45 | pub fn hd_reset(drv: u16) -> Result<(), &'static [u8]> { 46 | let ret: u16; 47 | unsafe { 48 | llvm_asm!("int $$0x13" 49 | : "={eax}"(ret) 50 | : "{eax}"(0), 51 | "{edx}"(drv) 52 | ); 53 | } 54 | if ret & 0xff00 != 0 { 55 | Err(Self::DISK_ERR) 56 | } else { 57 | Ok(()) 58 | } 59 | } 60 | } 61 | 62 | pub const MAX_SECTOR: u16 = 16; // 8192B = 16 secs, 8192*2B = 32 63 | pub const SECTOR_SIZE: u16 = 512; 64 | 65 | pub fn read_image(image_size: u16, dst: u32, start_lba: u16) -> Result<(), &'static str> { 66 | let mut start_lba = start_lba; 67 | let mut image_size = image_size; 68 | let mut dst = dst; 69 | let mut load_sectors: u16 = MAX_SECTOR; 70 | while image_size > 0 { 71 | if load_sectors > image_size { 72 | load_sectors = image_size 73 | } 74 | Dap::new( 75 | load_sectors, 76 | TRACK_BUFFER | (0x07C0 << 16), 77 | start_lba as u64, 78 | ) 79 | .hd_read(0x80) 80 | .map_err(|err| str::from_utf8(err).unwrap())?; 81 | 82 | copy_block((INIT_SEG << 4) + TRACK_BUFFER, dst, load_sectors * 256)?; 83 | dst += (SECTOR_SIZE * load_sectors) as u32; 84 | print!("."); 85 | 86 | image_size -= load_sectors; 87 | start_lba += load_sectors; 88 | } 89 | Ok(()) 90 | } 91 | 92 | pub fn read_to_trackbuf(secs: u16, start_lba: u64) -> Result<(), &'static str> { 93 | Dap::new( 94 | secs, 95 | TRACK_BUFFER | (0x07C0 << 16), 96 | start_lba, 97 | ) 98 | .hd_read(0x80) 99 | .map_err(|err| str::from_utf8(err).unwrap())?; 100 | Ok(()) 101 | } -------------------------------------------------------------------------------- /src/bios/plankton/src/ios.rs: -------------------------------------------------------------------------------- 1 | // I/O deley 2 | pub fn io_delay() { 3 | unsafe { 4 | llvm_asm!("inb $$0x80, %al 5 | inb $$0x80, %al" 6 | :::"eax" 7 | ); 8 | } 9 | } 10 | 11 | pub fn inb(port: usize) -> u8 { 12 | let mut data: u8; 13 | unsafe { 14 | llvm_asm!("inb %dx, %al" 15 | : "={al}"(data) 16 | : "{dx}"(port) 17 | ); 18 | } 19 | data 20 | } 21 | 22 | pub fn outb(data: u8, port: usize) { 23 | unsafe { 24 | llvm_asm!("outb %al, %dx" 25 | : 26 | : "{al}"(data), "{dx}"(port) 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/bios/plankton/src/layout.rs: -------------------------------------------------------------------------------- 1 | // memlayout 2 | pub const INIT_SEG: u32 = 0x07C0; 3 | 4 | pub const STAGE2_LOAD: u32 = 0x200; // + 7C00 5 | pub const STAGE2_START: u32 = 0x206; // + 7C00 6 | pub const STAGE3_START: u32 = 0x6000; // + 7C00 7 | pub const TRACK_BUFFER: u32 = 0xD000; // + 7C00 = 0x8900 8 | pub const TRACK_BUF_SIZE: u32 = 0x2000; // 0x8900 + 0x2000 = 0xA900 9 | 10 | pub const CMD_LINE_ADDR: u32 = 0x0002_0000; // prot 11 | pub const STAGE4_START: u32 = 0x0003_0000; // ptot 12 | pub const PROT_STACK: u32 = 0x9a000; // prot 13 | pub const PGTABLE_START: u64 = 0x1000; // prot 14 | pub const ELF_START: u32 = 0x0010_0000; // prot 15 | pub const IMAGE_START: u32 = 0x0350_0000; // prot 16 | pub const INITRD_START: u32 = 0x0560_0000; // prot 17 | pub const HEAP_START: u32 = 0x0760_0000; // prot 18 | pub const HEAP_END: u32 = 0x07FF_FFFF; // prot 19 | -------------------------------------------------------------------------------- /src/bios/plankton/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(llvm_asm)] 2 | #![no_std] 3 | 4 | #[macro_use] 5 | pub mod con; 6 | pub mod dev; 7 | pub mod ios; 8 | pub mod layout; 9 | pub mod mem; 10 | -------------------------------------------------------------------------------- /src/bios/plankton/src/mem.rs: -------------------------------------------------------------------------------- 1 | pub fn copy_block(src: u32, dst: u32, wcount: u16) -> Result<(), &'static str> { 2 | let ret: u16; 3 | let mut gdt: [u64; 6] = [0; 6]; 4 | gdt[2] = 0x00CF9200 << 32 5 | | (src as u64 & 0xFF000000) << 32 6 | | (src as u64 & 0x00FFFFFF) << 16 7 | | 0xFFFF; 8 | gdt[3] = 0x00CF9200 << 32 9 | | (dst as u64 & 0xFF000000) << 32 10 | | (dst as u64 & 0x00FFFFFF) << 16 11 | | 0xFFFF; 12 | unsafe { 13 | llvm_asm!("int $$0x15" 14 | : "={ax}"(ret) 15 | : "{ax}"(0x8700), 16 | "{cx}"(wcount), 17 | "{si}"(&gdt as *const [u64;6]) 18 | ); 19 | } 20 | if ret & 0xff00 != 0 { 21 | Err("Memory transfer error!") 22 | } else { 23 | Ok(()) 24 | } 25 | } 26 | 27 | pub struct MemoryRegion { 28 | base: u64, 29 | length: u64, 30 | } 31 | 32 | impl MemoryRegion { 33 | pub fn new(base: u64, length: u64) -> Self { 34 | Self { base, length } 35 | } 36 | 37 | pub fn len(&self) -> u64 { 38 | self.length 39 | } 40 | 41 | pub fn from_slice(data: &[T]) -> Self { 42 | Self { 43 | base: data.as_ptr() as u64, 44 | length: (data.len() * core::mem::size_of::()) as u64, 45 | } 46 | } 47 | 48 | pub fn as_mut_slice(&mut self, offset: u64, length: u64) -> &mut [T] { 49 | assert!((offset + (length * core::mem::size_of::() as u64)) <= self.length); 50 | unsafe { core::slice::from_raw_parts_mut((self.base + offset) as *mut T, length as usize) } 51 | } 52 | 53 | pub fn as_slice(&self, offset: u64, length: u64) -> &[T] { 54 | assert!((offset + (length * core::mem::size_of::() as u64)) <= self.length); 55 | unsafe { core::slice::from_raw_parts((self.base + offset) as *const T, length as usize) } 56 | } 57 | 58 | // Read a value from a given offset 59 | pub fn read(&self, offset: u64) -> T { 60 | assert!((offset + (core::mem::size_of::() - 1) as u64) < self.length); 61 | unsafe { *((self.base + offset) as *const T) } 62 | } 63 | 64 | pub fn read_u8(&self, offset: u64) -> u8 { 65 | self.read(offset) 66 | } 67 | 68 | pub fn read_u16(&self, offset: u64) -> u16 { 69 | self.read(offset) 70 | } 71 | 72 | pub fn read_u32(&self, offset: u64) -> u32 { 73 | self.read(offset) 74 | } 75 | 76 | pub fn read_u64(&self, offset: u64) -> u64 { 77 | self.read(offset) 78 | } 79 | 80 | pub fn write(&self, offset: u64, value: T) { 81 | assert!((offset + (core::mem::size_of::() - 1) as u64) < self.length); 82 | unsafe { 83 | *((self.base + offset) as *mut T) = value; 84 | } 85 | } 86 | 87 | pub fn write_u8(&self, offset: u64, value: u8) { 88 | self.write(offset, value) 89 | } 90 | 91 | pub fn write_u16(&self, offset: u64, value: u16) { 92 | self.write(offset, value) 93 | } 94 | 95 | pub fn write_u32(&self, offset: u64, value: u32) { 96 | self.write(offset, value) 97 | } 98 | 99 | pub fn write_u64(&self, offset: u64, value: u64) { 100 | self.write(offset, value) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/bios/stage_1st/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stage_1st" 3 | version = "0.1.0" 4 | authors = ["Hayato Ohhashi "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | plankton = { path = "../plankton" } 11 | rlibc = "1.0.0" 12 | 13 | [profile.release] 14 | opt-level = "z" 15 | -------------------------------------------------------------------------------- /src/bios/stage_1st/i586-stage_1st.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "x86", 3 | "cpu": "pentium", 4 | "data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", 5 | "dynamic-linking": false, 6 | "executables": true, 7 | "has-elf-tls": false, 8 | "has-rpath": true, 9 | "is-builtin": false, 10 | "linker-flavor": "ld.lld", 11 | "linker": "rust-lld", 12 | "llvm-target": "i586-unknown-none-code16", 13 | "max-atomic-width": 64, 14 | "os": "none", 15 | "relocation-model": "static", 16 | "position-independent-executables": false, 17 | "relro-level": "off", 18 | "target-c-int-width": "32", 19 | "target-endian": "little", 20 | "target-pointer-width": "32", 21 | "vendor": "unknown", 22 | "panic-strategy": "abort", 23 | "disable-redzone": true, 24 | "features": "-mmx,-sse,+soft-float", 25 | "pre-link-args": { 26 | "ld.lld": [ 27 | "--script=stage_1st.ld" 28 | ] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/bios/stage_1st/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(llvm_asm)] 2 | #![no_std] 3 | 4 | use core::panic::PanicInfo; 5 | use core::hint::unreachable_unchecked; 6 | 7 | 8 | #[panic_handler] 9 | fn panic(_info: &PanicInfo) -> ! { 10 | loop {} 11 | } 12 | 13 | #[macro_export] 14 | macro_rules! entry { 15 | ($path:path) => { 16 | #[export_name = "main"] 17 | pub fn __main() -> () { 18 | // type check the given path 19 | let f: fn() -> () = $path; 20 | 21 | f() 22 | } 23 | }; 24 | } 25 | 26 | #[link_section = ".startup"] 27 | #[no_mangle] 28 | fn _start() -> ! { 29 | extern "Rust" { 30 | fn main() -> (); 31 | } 32 | unsafe { 33 | llvm_asm!("ljmp $$0x07C0, $$reentry 34 | reentry: 35 | cli 36 | movw $$0x07C0, %ax 37 | movw %ax, %ds 38 | movw %ax, %es 39 | movw %ax, %ss 40 | movl $$0xFFF0, %esp 41 | sti" 42 | ::: 43 | ); 44 | main(); 45 | unreachable_unchecked(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/bios/stage_1st/src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | extern crate rlibc; 4 | use plankton::layout::{STAGE2_LOAD, STAGE2_START}; 5 | use plankton::{con::inform, dev::Dap}; 6 | use stage_1st::entry; 7 | 8 | #[link_section = ".size"] 9 | #[no_mangle] 10 | pub static mut STAGE2_SIZE: u16 = 00; 11 | #[link_section = ".slba"] 12 | #[no_mangle] 13 | pub static mut STAGE2_SLBA: u16 = 00; 14 | 15 | entry!(main); 16 | fn main() { 17 | let ptr = STAGE2_START as *const (); 18 | let stage2: fn() = unsafe { core::mem::transmute(ptr) }; 19 | inform(b"STG1: "); 20 | match Dap::hd_reset(0x80) { 21 | Err(err) => { 22 | inform(err); 23 | return; 24 | } 25 | Ok(_) => {} 26 | } 27 | unsafe { 28 | match Dap::new( 29 | STAGE2_SIZE as u16, 30 | STAGE2_LOAD | (0x07C0 << 16), 31 | STAGE2_SLBA as u64, 32 | ) 33 | .hd_read(0x80) 34 | { 35 | Err(err) => { 36 | inform(err); 37 | return; 38 | } 39 | Ok(_) => inform(b"O"), 40 | } 41 | } 42 | stage2(); 43 | } 44 | -------------------------------------------------------------------------------- /src/bios/stage_1st/stage_1st.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | body : ORIGIN = 0, LENGTH = 442 3 | size : ORIGIN = 442, LENGTH = 2 4 | slba : ORIGIN = 444, LENGTH = 2 5 | } 6 | 7 | ENTRY(_start); 8 | 9 | EXTERN(STAGE2_SISE); 10 | 11 | SECTIONS { 12 | .text : { *(.startup) *(.text*) } > body /* Excutable code */ 13 | .rodata : { *(.rodata*) } > body /* Constants (R/O) */ 14 | .data : { *(.data*) } > body /* Initialized data */ 15 | .bss : { *(.bss*) } > body /* Unitnitialized data */ 16 | .size : { KEEP(*(.size*)) } > size /* Boot parameter table */ 17 | .slba : { KEEP(*(.slba*)) } > slba 18 | /DISCARD/ : { *(.eh_frame*) } 19 | } -------------------------------------------------------------------------------- /src/bios/stage_2nd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stage_2nd" 3 | version = "0.1.0" 4 | authors = ["Hayato Ohhashi "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | plankton = { path = "../plankton" } 11 | rlibc = "1.0.0" 12 | 13 | [profile.release] 14 | opt-level = "z" -------------------------------------------------------------------------------- /src/bios/stage_2nd/i586-stage_2nd.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "x86", 3 | "cpu": "pentium", 4 | "data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", 5 | "dynamic-linking": false, 6 | "executables": true, 7 | "has-elf-tls": false, 8 | "has-rpath": true, 9 | "is-builtin": false, 10 | "linker-flavor": "ld.lld", 11 | "linker": "rust-lld", 12 | "llvm-target": "i586-unknown-none-code16", 13 | "max-atomic-width": 64, 14 | "os": "none", 15 | "relocation-model": "static", 16 | "position-independent-executables": false, 17 | "relro-level": "off", 18 | "target-c-int-width": "32", 19 | "target-endian": "little", 20 | "target-pointer-width": "32", 21 | "vendor": "unknown", 22 | "panic-strategy": "abort", 23 | "disable-redzone": true, 24 | "features": "-mmx,-sse,+soft-float", 25 | "pre-link-args": { 26 | "ld.lld": [ 27 | "--script=stage_2nd.ld" 28 | ] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/bios/stage_2nd/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | use plankton::{dev::read_image, layout::{INIT_SEG, STAGE3_START, STAGE4_START}, print, println}; 3 | use core::panic::PanicInfo; 4 | 5 | #[panic_handler] 6 | fn panic(_info: &PanicInfo) -> ! { 7 | println!("{}", _info); 8 | loop {} 9 | } 10 | 11 | #[repr(C, packed)] 12 | pub struct ParamTable { 13 | pub stage3_poss: u16, 14 | pub stage3_size: u16, 15 | pub stage4_size: u16, 16 | } 17 | 18 | pub fn load_images(mut slba: u16, stage3_size: u16, stage4_size: u16) -> Result<(), &'static str> { 19 | if stage3_size > 0 { 20 | print!(" Loading stage3 "); 21 | read_image(stage3_size, (INIT_SEG << 4) + STAGE3_START, slba)?; 22 | println!(""); 23 | } else { 24 | return Err("stage3 is not found"); 25 | } 26 | 27 | if stage4_size > 0 { 28 | print!(" Loading stage4 "); 29 | slba += stage3_size; 30 | read_image(stage4_size, STAGE4_START, slba)?; 31 | println!(""); 32 | } else { 33 | // return Err("stage4 is not found"); 34 | } 35 | Ok(()) 36 | } -------------------------------------------------------------------------------- /src/bios/stage_2nd/src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | extern crate rlibc; 4 | use plankton::layout::STAGE3_START; 5 | use plankton::{print, println}; 6 | use stage_2nd::{ParamTable, load_images}; 7 | 8 | #[link_section = ".table"] 9 | #[no_mangle] 10 | pub static mut PARAM: ParamTable = ParamTable { 11 | stage3_poss: 00, 12 | stage3_size: 00, 13 | stage4_size: 00, 14 | }; 15 | 16 | #[link_section = ".startup"] 17 | #[no_mangle] 18 | fn stage2() { 19 | let stage3_poss: u16; 20 | let stage3_size: u16; 21 | let stage4_size: u16; 22 | unsafe { 23 | stage3_poss = PARAM.stage3_poss; 24 | stage3_size = PARAM.stage3_size; 25 | stage4_size = PARAM.stage4_size; 26 | } 27 | let ptr = STAGE3_START as *const (); 28 | let stage3: fn() -> ! = unsafe { core::mem::transmute(ptr) }; 29 | 30 | print!("\r\nSTG2: "); 31 | println!( 32 | "stage3_size = {:04X} : \ 33 | stage4_size = {:04X}", 34 | stage3_size, stage4_size, 35 | ); 36 | load_images(stage3_poss, stage3_size, stage4_size).unwrap(); 37 | stage3(); 38 | } 39 | -------------------------------------------------------------------------------- /src/bios/stage_2nd/stage_2nd.ld: -------------------------------------------------------------------------------- 1 | ENTRY(stage2) 2 | EXTERN(PARAM); 3 | SECTIONS { 4 | . = 0x200; 5 | .table : { KEEP(*(.table)) } 6 | .text : { *(.startup) *(.text*) } 7 | .rodata : { *(.rodata*) } 8 | .data : { *(.data*) } 9 | .bss : { *(.bss*) } 10 | /DISCARD/ : { *(.eh_frame*) } 11 | } -------------------------------------------------------------------------------- /src/bios/stage_3rd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stage_3rd" 3 | version = "0.1.0" 4 | authors = ["Hayato Ohhashi "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | plankton = { path = "../plankton" } 11 | rlibc = "1.0.0" -------------------------------------------------------------------------------- /src/bios/stage_3rd/i586-stage_3rd.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "x86", 3 | "cpu": "pentium", 4 | "data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", 5 | "dynamic-linking": false, 6 | "executables": true, 7 | "has-elf-tls": false, 8 | "has-rpath": true, 9 | "is-builtin": false, 10 | "linker-flavor": "ld.lld", 11 | "linker": "rust-lld", 12 | "llvm-target": "i586-unknown-none-code16", 13 | "max-atomic-width": 64, 14 | "os": "none", 15 | "relocation-model": "static", 16 | "position-independent-executables": false, 17 | "relro-level": "off", 18 | "target-c-int-width": "32", 19 | "target-endian": "little", 20 | "target-pointer-width": "32", 21 | "vendor": "unknown", 22 | "panic-strategy": "abort", 23 | "disable-redzone": true, 24 | "features": "-mmx,-sse,+soft-float", 25 | "pre-link-args": { 26 | "ld.lld": [ 27 | "--script=stage_3rd.ld" 28 | ] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init.rs: -------------------------------------------------------------------------------- 1 | pub mod a20; 2 | pub mod cur; 3 | pub mod ist; 4 | pub mod kbd; 5 | pub mod msz; 6 | pub mod vid; 7 | pub mod vrs; 8 | pub mod zero; 9 | 10 | pub fn setup() { 11 | zero::clear_bss(); 12 | zero::Pages::SecondHalf.clear(); 13 | zero::Pages::FirstHalf.clear(); 14 | msz::set_mem_size(); 15 | kbd::set_keyboard(); 16 | ist::query_ist(); 17 | vrs::set_version(); 18 | a20::enable_a20(); 19 | vid::set_screen_info(); 20 | } 21 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/a20.rs: -------------------------------------------------------------------------------- 1 | use plankton::ios::{inb, io_delay, outb}; 2 | use plankton::{print, println}; 3 | 4 | fn flush_8042() { 5 | let mut stat: u8; 6 | 7 | loop { 8 | io_delay(); 9 | stat = inb(0x64); 10 | if stat & 0x01 != 0 { 11 | io_delay(); 12 | inb(0x60); 13 | continue; 14 | } 15 | if stat & 0x02 != 0 { 16 | continue; 17 | } 18 | break; 19 | } 20 | } 21 | 22 | fn check_a20() -> Result<(), ()> { 23 | let ret: u32; 24 | unsafe { 25 | llvm_asm!("movl $$1, %ebx 26 | xorw %ax, %ax 27 | movw %ax, %fs 28 | notw %ax 29 | movw %ax, %gs 30 | movw %fs:0, %ax 31 | cmpw %gs:16, %ax 32 | jnz 1f 33 | cli 34 | movw %ax, %dx 35 | notw %ax 36 | movw %ax, %fs:0 37 | cmpw %gs:16, %ax 38 | movw %dx, %fs:0 39 | sti 40 | jnz 1f 41 | xorl %ebx, %ebx 42 | 1: 43 | movl %ebx, %eax" 44 | : "={eax}"(ret) 45 | : 46 | : "eax" "ebx" "edx" 47 | ); 48 | } 49 | if ret != 0 { 50 | Ok(()) 51 | } else { 52 | Err(()) 53 | } 54 | } 55 | 56 | pub fn enable_a20() { 57 | let data: u8; 58 | if check_a20().is_ok() { 59 | println!(" A20 line is already activated."); 60 | return; 61 | } 62 | // Classical AT type 63 | flush_8042(); 64 | outb(0x64, 0xD1); 65 | flush_8042(); 66 | outb(0x60, 0xDF); 67 | flush_8042(); 68 | if check_a20().is_ok() { 69 | println!(" A20 line is activated by classical method."); 70 | return; 71 | } 72 | // PS/2 type (Fast A20 version) 73 | data = inb(0x92); 74 | io_delay(); 75 | outb(data | 2, 0x92); 76 | while check_a20().is_err() {} 77 | println!(" A20 line is activated by fast method."); 78 | } 79 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/cur.rs: -------------------------------------------------------------------------------- 1 | use plankton::mem::MemoryRegion; 2 | 3 | pub fn set_cur() { 4 | let zero_page = MemoryRegion::new(0x000, 4096); 5 | 6 | let curs: u16; 7 | unsafe { 8 | llvm_asm!("int $$0x10" 9 | : "={dx}"(curs)//, "={dl}"(curs_x) 10 | : "{ax}"(0x0300), "{ebx}"(0) 11 | ); 12 | } 13 | zero_page.write_u16(0x00, curs); 14 | } 15 | 16 | pub fn re_cur() { 17 | let zero_page = MemoryRegion::new(0x000, 4096); 18 | let curs = zero_page.read_u16(0x00); 19 | unsafe { 20 | llvm_asm!("int $$0x10" 21 | :: "{ax}"(0x0200u16), "{dx}"(curs), "{ebx}"(0) 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/ist.rs: -------------------------------------------------------------------------------- 1 | use plankton::mem::MemoryRegion; 2 | pub fn query_ist() { 3 | let zero_page = MemoryRegion::new(0x000, 4096); 4 | let signature: u32; 5 | let command: u32; 6 | let event: u32; 7 | let perf_level: u32; 8 | 9 | unsafe { 10 | llvm_asm!("int $$0x15" 11 | : "={eax}"(signature), "={ebx}"(command), "={ecx}"(event), "={edx}"(perf_level) 12 | : "{ax}"(0xe980), "{edx}"(0x47534943) 13 | ); 14 | } 15 | // 0x60, 0x64, 0x68, 0x6c 16 | zero_page.write_u32(0x60, signature); 17 | zero_page.write_u32(0x64, command); 18 | zero_page.write_u32(0x68, event); 19 | zero_page.write_u32(0x6c, perf_level); 20 | } 21 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/kbd.rs: -------------------------------------------------------------------------------- 1 | use plankton::mem::MemoryRegion; 2 | pub fn set_keyboard() { 3 | let zero_page = MemoryRegion::new(0x000, 4096); 4 | let ret: u8; 5 | unsafe { 6 | llvm_asm!("int $$0x16" 7 | : "={al}"(ret) 8 | : "{ax}"(0x0200) 9 | ); 10 | llvm_asm!("int $$0x16" 11 | : 12 | : "{ax}"(0x0305), "{ebx}"(0) 13 | ); 14 | } 15 | zero_page.write_u8(0x1eb, ret); 16 | } 17 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/msz.rs: -------------------------------------------------------------------------------- 1 | use plankton::mem::MemoryRegion; 2 | 3 | const E820_MAX_ENTRIES_ZEROPAGE: usize = 128; 4 | const SMAP: u32 = 0x534d4150; 5 | 6 | #[derive(Default, Copy, Clone)] 7 | #[repr(C, packed)] 8 | struct E820Entry { 9 | addr: u64, 10 | size: u64, 11 | entry_type: u32, 12 | } 13 | 14 | fn detect_memory_e820() { 15 | let mut zero_page = MemoryRegion::new(0x000, 4096); 16 | let e820_table = zero_page.as_mut_slice::(0x2d0, E820_MAX_ENTRIES_ZEROPAGE as u64); 17 | let size: u32 = core::mem::size_of::() as u32; // ecx 18 | let buf: E820Entry = Default::default(); 19 | let refb: u16 = (&buf as *const E820Entry) as u16; // di 20 | let mut smap: u32 = SMAP; // edx 21 | let mut flag: u32; 22 | let mut count: usize = 0; 23 | let mut addr: u32 = 0x00; // ebx 24 | 25 | loop { 26 | unsafe { 27 | llvm_asm!("int $$0x15 28 | pushfl 29 | popl %ecx" 30 | : "={ecx}"(flag), "={eax}"(smap), "={ebx}"(addr) 31 | : "{ax}"(0xe820), "{ebx}"(addr), "{di}"(refb), "{ecx}"(size), "{edx}"(smap) 32 | : "ecx" 33 | ); 34 | } 35 | if flag & 1 != 0 { 36 | break; 37 | } 38 | if smap != SMAP { 39 | count = 0; 40 | break; 41 | } 42 | e820_table[count] = buf; 43 | count += 1; 44 | 45 | if (addr != 0) && (count < E820_MAX_ENTRIES_ZEROPAGE) { 46 | continue; 47 | } else { 48 | break; 49 | } 50 | } 51 | zero_page.write_u8(0x1e8, count as u8); 52 | } 53 | 54 | fn detect_memory_e801() { 55 | let zero_page = MemoryRegion::new(0x000, 4096); 56 | let kb01size: u16; // AX 57 | let kb64size: u16; // BX 58 | let flag: u32; // eflag 59 | 60 | unsafe { 61 | llvm_asm!("int $$0x15 62 | pushfl 63 | popl %ecx" 64 | : "={ax}"(kb01size), "={bx}"(kb64size), "={ecx}"(flag) 65 | : "{ax}"(0xe801) 66 | ); 67 | } 68 | if flag & 1 != 0 { 69 | return; 70 | } 71 | if kb01size > 15 * 1024 { 72 | return; 73 | } else if kb01size == 15 * 1024 { 74 | zero_page.write_u32(0x1E0, ((kb64size << 6) + kb01size) as u32); 75 | } else { 76 | zero_page.write_u32(0x1E0, kb01size as u32); 77 | } 78 | } 79 | 80 | fn detect_memory_88() { 81 | let zero_page = MemoryRegion::new(0x000, 4096); 82 | let size: u16; 83 | unsafe { 84 | llvm_asm!("int $$0x15" 85 | : "={ax}"(size) 86 | : "{ax}"(0x8800) 87 | ); 88 | } 89 | zero_page.write_u16(0x002, size & 0xFFFF); 90 | } 91 | 92 | pub fn set_mem_size() { 93 | detect_memory_e820(); 94 | 95 | detect_memory_e801(); 96 | 97 | detect_memory_88(); 98 | } 99 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/vid.rs: -------------------------------------------------------------------------------- 1 | use plankton::mem::MemoryRegion; 2 | 3 | pub fn set_screen_info() { 4 | let zero_page = MemoryRegion::new(0x000, 4096); 5 | 6 | let mode: u8; 7 | let page: u8; 8 | unsafe { 9 | llvm_asm!("int $$0x10" 10 | : "={al}"(mode), "={bh}"(page) 11 | : "{ax}"(0x0f00), "{ebx}"(0) 12 | ); 13 | } 14 | zero_page.write_u8(0x004, page); 15 | zero_page.write_u8(0x006, mode & 0x7f); 16 | 17 | zero_page.write_u8(0x007, 80); 18 | zero_page.write_u8(0x00E, 25); 19 | zero_page.write_u8(0x00F, 1); 20 | 21 | let font: u16; 22 | unsafe { 23 | llvm_asm!("movw %ax, %gs 24 | movw %gs:(0x485), %ax" 25 | : "={ax}"(font) 26 | : "{ax}"(0) 27 | ); 28 | } 29 | zero_page.write_u16(0x010, font); 30 | 31 | zero_page.write_u16(0x1FA, 0xFFFF); 32 | } 33 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/vrs.rs: -------------------------------------------------------------------------------- 1 | use plankton::mem::MemoryRegion; 2 | 3 | pub fn set_version() { 4 | const KERNEL_BOOT_FLAG_MAGIC: u16 = 0xaa55; 5 | const KERNEL_HDR_MAGIC: u32 = 0x5372_6448; 6 | const KERNEL_LOADER_OTHER: u8 = 0xff; 7 | const KERNEL_MIN_ALIGNMENT_BYTES: u32 = 0x0100_0000; 8 | 9 | let zero_page = MemoryRegion::new(0x000, 4096); 10 | 11 | zero_page.write_u16(0x1FE, KERNEL_BOOT_FLAG_MAGIC); 12 | zero_page.write_u32(0x202, KERNEL_HDR_MAGIC); 13 | zero_page.write_u16(0x206, 0x020C); 14 | zero_page.write_u8(0x210, KERNEL_LOADER_OTHER); 15 | zero_page.write_u32(0x230, KERNEL_MIN_ALIGNMENT_BYTES); 16 | } 17 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/init/zero.rs: -------------------------------------------------------------------------------- 1 | use plankton::mem::MemoryRegion; 2 | 3 | pub fn clear_bss() { 4 | use core::ptr; 5 | extern "C" { 6 | static mut _data_end: u8; 7 | static mut _bss_end: u8; 8 | } 9 | unsafe { 10 | let count = &_bss_end as *const u8 as usize - &_data_end as *const u8 as usize; 11 | ptr::write_bytes(&mut _data_end as *mut u8, 0, count); 12 | } 13 | } 14 | 15 | pub enum Pages { 16 | FirstHalf, 17 | SecondHalf, 18 | } 19 | 20 | impl Pages { 21 | pub fn clear(&self) { 22 | let mut zero_page = MemoryRegion::new(0x000, 0x1000); 23 | match self { 24 | Self::FirstHalf => { 25 | for elem in zero_page.as_mut_slice::(0x000, 0x800).iter_mut() { 26 | *elem = 0; 27 | } 28 | } 29 | Self::SecondHalf => { 30 | for elem in zero_page.as_mut_slice::(0x800, 0x800).iter_mut() { 31 | *elem = 0; 32 | } 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(llvm_asm)] 2 | #![no_std] 3 | 4 | pub mod init; 5 | pub mod mpm; 6 | //pub mod rfn; 7 | 8 | use core::panic::PanicInfo; 9 | use plankton::{print, println}; 10 | #[panic_handler] 11 | fn panic(_info: &PanicInfo) -> ! { 12 | println!("{}", _info); 13 | loop {} 14 | } 15 | 16 | #[repr(C, packed)] 17 | pub struct ParamTable { 18 | pub start_lba: u32, 19 | pub sectors: u32, 20 | pub ret_addr: u32, 21 | pub prot_stack: u32, 22 | } -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(llvm_asm)] 2 | #![no_std] 3 | #![no_main] 4 | extern crate rlibc; 5 | use plankton::{ 6 | layout::{PROT_STACK, STAGE4_START}, 7 | print, println, 8 | }; 9 | use stage_3rd::{init, mpm}; 10 | pub mod rfn; 11 | #[link_section = ".first"] 12 | #[no_mangle] 13 | fn stage3() -> ! { 14 | println!("STG3:"); 15 | println!(" Initializing system."); 16 | init::setup(); 17 | println!(" Moving to protected mode."); 18 | 19 | init::cur::set_cur(); 20 | mpm::move_to_protect(STAGE4_START, PROT_STACK) 21 | } -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/mpm.rs: -------------------------------------------------------------------------------- 1 | use core::hint::unreachable_unchecked; 2 | use plankton::ios::{io_delay, outb}; 3 | use plankton::{print, println}; 4 | 5 | #[repr(C, packed)] 6 | struct DescoritorTable { 7 | limit: u16, 8 | base: u32, 9 | } 10 | 11 | #[no_mangle] 12 | static GDT: [u64; 4] = [ 13 | 0x0000000000000000, 14 | 0x0000000000000000, 15 | 0x00CF9A000000FFFF, 16 | 0x00CF92000000FFFF, 17 | ]; 18 | 19 | #[no_mangle] 20 | static IDTR: DescoritorTable = DescoritorTable { limit: 0, base: 0 }; 21 | #[no_mangle] 22 | static GDTR: DescoritorTable = DescoritorTable { 23 | limit: 0x800, 24 | base: 0, 25 | }; 26 | 27 | pub fn move_to_protect(entry_addr: u32, prot_stack: u32) -> ! { 28 | reset_coprocessor(); 29 | mask_all_interrupts(); 30 | setup_idt(); 31 | setup_gdt(); 32 | protected_mode_jump(entry_addr, prot_stack) 33 | } 34 | 35 | fn mask_all_interrupts() { 36 | outb(0xFF, 0xA1); 37 | io_delay(); 38 | outb(0xFB, 0x21); 39 | io_delay(); 40 | } 41 | 42 | fn reset_coprocessor() { 43 | outb(0, 0xF0); 44 | io_delay(); 45 | outb(0, 0xF1); 46 | io_delay(); 47 | } 48 | 49 | pub fn setup_gdt() { 50 | unsafe { 51 | llvm_asm!("xorl %eax, %eax 52 | movw %ds, %ax 53 | shll $$4, %eax 54 | addl $$GDT, %eax 55 | movl %eax, (GDTR+2) 56 | lgdt GDTR" 57 | :::"eax" 58 | ); 59 | } 60 | } 61 | 62 | pub fn setup_idt() { 63 | unsafe { 64 | llvm_asm!("lidt IDTR":::); 65 | } 66 | } 67 | 68 | fn protected_mode_jump(entry_addr: u32, prot_stack: u32) -> ! { 69 | unsafe { 70 | llvm_asm!(" 71 | movl %eax, (jmp_offset) 72 | movl %ebx, %esp 73 | movl %ebx, %ebp" 74 | : 75 | :"{eax}"(entry_addr), "{ebx}"(prot_stack) 76 | : 77 | ); 78 | llvm_asm!(" 79 | movl %cr0, %eax 80 | orl $$1, %eax 81 | movl %eax, %cr0" 82 | : 83 | : 84 | : "eax" 85 | ); 86 | llvm_asm!(" 87 | jmp flushing 88 | flushing: 89 | movw %ax, %ds 90 | movw %ax, %es 91 | movw %ax, %fs 92 | movw %ax, %gs 93 | movw %ax, %ss" 94 | : 95 | : "{eax}"(0x18) 96 | ); 97 | llvm_asm!(" 98 | .byte 0x66 99 | .byte 0xEA 100 | jmp_offset: .long 0 101 | .word 0x10" 102 | ::: 103 | ); 104 | unreachable_unchecked(); 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/src/rfn.rs: -------------------------------------------------------------------------------- 1 | use stage_3rd::{init::cur::{re_cur, set_cur}, ParamTable}; 2 | use plankton::dev::read_to_trackbuf; 3 | use core::hint::unreachable_unchecked; 4 | //use plankton::{print, println}; 5 | 6 | 7 | #[link_section = ".param"] 8 | #[no_mangle] 9 | pub static mut PARAM: ParamTable = ParamTable { 10 | start_lba: 0, 11 | sectors: 0, 12 | ret_addr: 0, 13 | prot_stack: 0, 14 | }; 15 | 16 | #[link_section = ".second"] 17 | #[no_mangle] 18 | fn read() -> ! { 19 | unsafe { 20 | llvm_asm!( 21 | " 22 | movl %cr0, %eax 23 | andl $$0x7FFFFFFE, %eax 24 | movl %eax, %cr0 25 | ljmp $$0x07C0, $$reentry 26 | reentry: 27 | movw $$0x07C0, %ax 28 | movw %ax, %ds 29 | movw %ax, %es 30 | movw %ax, %fs 31 | movw %ax, %gs 32 | movw %ax, %ss 33 | sti" 34 | :::"eax"); 35 | } 36 | 37 | let start_lba: u32; 38 | let sectors: u32; 39 | unsafe { 40 | start_lba = PARAM.start_lba; 41 | sectors = PARAM.sectors; 42 | } 43 | re_cur(); 44 | //println!("slba = {}, secs = {}", start_lba, sectors); 45 | match read_to_trackbuf(sectors as u16, start_lba as u64) { 46 | Ok(_) => unsafe { PARAM.start_lba = true as u32 }, 47 | Err(_) => unsafe { PARAM.start_lba = false as u32 }, 48 | } 49 | set_cur(); 50 | 51 | 52 | 53 | // back to protected mode 54 | unsafe { 55 | llvm_asm!("cli"); 56 | stage_3rd::mpm::setup_gdt(); 57 | stage_3rd::mpm::setup_idt(); 58 | llvm_asm!(" 59 | movl %eax, (return_addr) 60 | movl %ebx, %esp" 61 | : 62 | : "{eax}"(PARAM.ret_addr), "{ebx}"(PARAM.prot_stack) 63 | ); 64 | llvm_asm!(" 65 | movl %cr0, %eax 66 | orl $$1, %eax 67 | movl %eax, %cr0" 68 | : 69 | : 70 | :"eax" 71 | ); 72 | llvm_asm!(" 73 | jmp flush 74 | flush: 75 | movw %ax, %ds 76 | movw %ax, %es 77 | movw %ax, %fs 78 | movw %ax, %gs 79 | movw %ax, %ss" 80 | : 81 | : "{eax}"(0x18) 82 | ); 83 | 84 | llvm_asm!(" 85 | .byte 0x66 86 | .byte 0xEA 87 | return_addr: .long 0 88 | .word 0x10" 89 | ::: 90 | ); 91 | unreachable_unchecked(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/bios/stage_3rd/stage_3rd.ld: -------------------------------------------------------------------------------- 1 | ENTRY(stage3) 2 | ENTRY(hello) 3 | SECTIONS { 4 | . = 0x6000; 5 | .first : { *(.first) } 6 | . = 0x6100; 7 | .param : { KEEP(*(.param)) } 8 | . = 0x6110; 9 | .second : { KEEP(*(.second)) } 10 | .text : { *(.text*) } 11 | .rodata : { *(.rodata*) } 12 | .data : { *(.data*) } 13 | .bss : { 14 | _data_end = .; 15 | *(.bss*) 16 | _bss_end = .; 17 | } 18 | /DISCARD/ : { *(.eh_frame*) } 19 | } -------------------------------------------------------------------------------- /src/bios/stage_4th/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stage_4th" 3 | version = "0.1.0" 4 | authors = ["Hayato Ohhashi "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | plankton = { path = "../plankton" } 11 | rlibc = "1.0.0" 12 | -------------------------------------------------------------------------------- /src/bios/stage_4th/i586-stage_4th.json: -------------------------------------------------------------------------------- 1 | { 2 | "llvm-target": "i586-unknown-none", 3 | "data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", 4 | "arch": "x86", 5 | "cpu": "pentium", 6 | "target-endian": "little", 7 | "target-pointer-width": "32", 8 | "target-c-int-width": "32", 9 | "os": "none", 10 | "executables": true, 11 | "linker-flavor": "ld.lld", 12 | "linker": "rust-lld", 13 | "panic-strategy": "abort", 14 | "disable-redzone": true, 15 | "features": "-mmx,-sse,+soft-float", 16 | "pre-link-args": { 17 | "ld.lld": [ 18 | "--script=stage_4th.ld" 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /src/bios/stage_4th/src/fs/blkdev.rs: -------------------------------------------------------------------------------- 1 | use plankton::{ 2 | dev::MAX_SECTOR, 3 | layout::{INIT_SEG, TRACK_BUFFER}, 4 | mem::MemoryRegion, 5 | }; 6 | use crate::{print, println}; 7 | 8 | pub trait BlockDevice { 9 | type Error; 10 | fn read(&self, buf: &mut [u8], offset: usize) -> Result<(), Self::Error>; 11 | fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), Self::Error>; 12 | } 13 | 14 | #[derive(Debug, Clone, Copy)] 15 | pub enum BIOError { 16 | IOError, 17 | } 18 | 19 | #[inline(never)] 20 | #[no_mangle] 21 | pub fn copy_bytes( 22 | buf: &mut [u8], 23 | stored_bytes: usize, 24 | buff_offset: usize, 25 | sector_offset: usize, 26 | ) -> usize { 27 | let track_buffer = MemoryRegion::new( 28 | (TRACK_BUFFER + (INIT_SEG << 4)) as u64, 29 | (512 * MAX_SECTOR) as u64, 30 | ); 31 | 32 | let buf_cap = buf.len() - buff_offset; 33 | let avail_bytes = stored_bytes - sector_offset; 34 | 35 | let n_bytes = if buf_cap < avail_bytes { 36 | buf_cap 37 | } else { 38 | avail_bytes 39 | }; 40 | println!("sector_offset = {}, n_bytes = {}, buffer_offset = {}", sector_offset, n_bytes, buff_offset); 41 | let slice = track_buffer.as_slice::(sector_offset as u64, n_bytes as u64); 42 | unsafe { 43 | core::ptr::copy_nonoverlapping(slice.as_ptr(), buf[buff_offset..(buff_offset + n_bytes)].as_mut_ptr(), slice.len()); 44 | } 45 | //buf[buff_offset..(buff_offset + n_bytes)].clone_from_slice(&slice); 46 | println!("slice = {:?}", slice); 47 | println!("buf = {:?}", buf); 48 | n_bytes 49 | } 50 | 51 | pub fn read(buf: &mut [u8], offset: usize) -> Result<(), BIOError> { 52 | let start_lba = offset / 512; 53 | let end_lba = (offset + buf.len() - 1) / 512; 54 | let mut num_sectors = end_lba - start_lba + 1; 55 | 56 | let num_invokes = (num_sectors + MAX_SECTOR as usize - 1) / MAX_SECTOR as usize; 57 | let mut buff_offset = 0; 58 | for i in 0..num_invokes { 59 | let load_sectors = if num_sectors > MAX_SECTOR as usize { 60 | MAX_SECTOR as u32 61 | } else { 62 | num_sectors as u32 63 | }; 64 | let sector_offset = if i == 0 { offset % 512 } else { 0 }; 65 | crate::svm::rm::diskread( 66 | start_lba as u32 + (i as u32 * MAX_SECTOR as u32), 67 | load_sectors, 68 | )?; 69 | 70 | buff_offset += copy_bytes(buf, load_sectors as usize * 512, buff_offset, sector_offset); 71 | num_sectors -= load_sectors as usize; 72 | } 73 | Ok(()) 74 | } 75 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/fs/fat32.rs: -------------------------------------------------------------------------------- 1 | use crate::fs::blkdev::BlockDevice; 2 | use core::convert::TryInto; 3 | use core::fmt::Debug; 4 | 5 | pub mod dir; 6 | pub mod file; 7 | 8 | const BUFFER_SIZE: usize = 512; 9 | 10 | #[derive(Debug, Copy, Clone)] 11 | pub struct BIOSParameterBlock { 12 | pub byte_per_sector: u16, 13 | pub sector_per_cluster: u8, 14 | pub reserved_sector: u16, 15 | pub num_fat: u8, 16 | pub total_sector: u32, 17 | pub sector_per_fat: u32, 18 | pub root_cluster: u32, 19 | pub id: u32, 20 | pub volume_label: [u8; 11], 21 | pub file_system: [u8; 8], 22 | } 23 | 24 | impl BIOSParameterBlock { 25 | // Get the first sector offset bytes of the cluster from the cluster number 26 | pub fn offset(&self, cluster: u32) -> usize { 27 | (((self.reserved_sector as u32) 28 | + (self.num_fat as u32) * self.sector_per_fat 29 | + (cluster - 2) * (self.sector_per_cluster as u32)) 30 | * (self.byte_per_sector as u32)) as usize 31 | } 32 | // get fat1 start offset bytes 33 | pub fn fat1(&self) -> usize { 34 | ((self.reserved_sector as u32) * (self.byte_per_sector as u32)) as usize 35 | } 36 | } 37 | 38 | pub struct FileSystem 39 | where 40 | T: BlockDevice + Clone + Copy, 41 | { 42 | partition: T, 43 | bpb: BIOSParameterBlock, 44 | } 45 | 46 | impl FileSystem 47 | where 48 | T: BlockDevice + Clone + Copy, 49 | ::Error: Debug, 50 | { 51 | // get FAT32 FileSystem 52 | pub fn new(partition: T) -> Self { 53 | let mut buf = [0; BUFFER_SIZE]; 54 | partition.read(&mut buf, 0).unwrap(); 55 | 56 | let mut volume_label = [0; 11]; 57 | volume_label.copy_from_slice(&buf[0x47..0x52]); 58 | 59 | let mut file_system = [0; 8]; 60 | file_system.copy_from_slice(&buf[0x52..0x5A]); 61 | 62 | let bps = read_le_u16(&buf[0x0B..0x0D]); 63 | if bps as usize != BUFFER_SIZE { 64 | panic!( 65 | "BUFFER_SIZE is {} Bytes, but byte_per_sector is {} Bytes", 66 | BUFFER_SIZE, bps 67 | ); 68 | } 69 | 70 | Self { 71 | partition, 72 | bpb: BIOSParameterBlock { 73 | byte_per_sector: bps, 74 | sector_per_cluster: buf[0x0D], 75 | reserved_sector: ((buf[0x0F] as u16) << 8) | buf[0x0E] as u16, 76 | num_fat: buf[0x10], 77 | total_sector: read_le_u32(&buf[0x20..0x24]), 78 | sector_per_fat: read_le_u32(&buf[0x24..0x28]), 79 | root_cluster: read_le_u32(&buf[0x2C..0x30]), 80 | id: read_le_u32(&buf[0x43..0x47]), 81 | volume_label, 82 | file_system, 83 | }, 84 | } 85 | } 86 | 87 | // into root_dir 88 | pub fn root_dir(&self) -> dir::Dir { 89 | dir::Dir:: { 90 | partition: self.partition, 91 | bpb: self.bpb, 92 | dir_name: [0; 11], 93 | dir_cluster: self.bpb.root_cluster, 94 | length: 0, 95 | } 96 | } 97 | } 98 | 99 | pub fn read_le_u16(input: &[u8]) -> u16 { 100 | let (int_bytes, _) = input.split_at(core::mem::size_of::()); 101 | u16::from_le_bytes(int_bytes.try_into().unwrap()) 102 | } 103 | 104 | pub fn read_le_u32(input: &[u8]) -> u32 { 105 | let (int_bytes, _) = input.split_at(core::mem::size_of::()); 106 | u32::from_le_bytes(int_bytes.try_into().unwrap()) 107 | } 108 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/fs/fat32/dir.rs: -------------------------------------------------------------------------------- 1 | use super::{file::File, read_le_u32, BIOSParameterBlock, BUFFER_SIZE}; 2 | use crate::fs::blkdev::BlockDevice; 3 | use core::fmt::Debug; 4 | 5 | #[derive(Debug, Copy, Clone)] 6 | pub enum DirError { 7 | NoMatch, 8 | NoMatchDir, 9 | NoMatchFile, 10 | InvalidName, 11 | } 12 | 13 | #[derive(Debug, Copy, Clone)] 14 | enum NameType { 15 | Short, 16 | Long, 17 | } 18 | 19 | #[derive(Debug, Copy, Clone)] 20 | pub struct Dir 21 | where 22 | T: BlockDevice + Clone + Copy, 23 | ::Error: Debug, 24 | { 25 | pub partition: T, 26 | pub bpb: BIOSParameterBlock, 27 | pub dir_name: [u8; 11], 28 | pub dir_cluster: u32, 29 | pub length: u32, 30 | } 31 | 32 | impl Dir 33 | where 34 | T: BlockDevice + Clone + Copy, 35 | ::Error: core::fmt::Debug, 36 | { 37 | pub fn cd(&self, dir: &str) -> Result, DirError> { 38 | match self.exists(dir) { 39 | Ok(buf) => Ok(self.get_dir(&buf.0)), 40 | Err(_) => Err(DirError::NoMatchDir), 41 | } 42 | } 43 | pub fn open_file(&self, file: &str) -> Result, DirError> { 44 | match self.exists(file) { 45 | Ok(buf) => Ok(self.get_file(&buf.0, buf.1)), 46 | Err(_) => Err(DirError::NoMatchFile), 47 | } 48 | } 49 | 50 | pub fn exists(&self, name: &str) -> Result<([u8; 32], u32), DirError> { 51 | let invalid_char = "\\/:*?\"<>|"; 52 | for ch in invalid_char.chars() { 53 | if name.contains(ch) { 54 | return Err(DirError::InvalidName); 55 | } 56 | } 57 | 58 | let bps = self.bpb.byte_per_sector as usize; 59 | let name_type = self.short_or_long(name); 60 | let op = |buf: &[u8]| -> [u8; 32] { 61 | let mut temp = [0; 32]; 62 | for (i, elem) in temp.iter_mut().enumerate() { 63 | *elem = buf[i]; 64 | } 65 | temp 66 | }; 67 | 68 | let mut buf = [0; BUFFER_SIZE]; 69 | let mut offset_count = 0; 70 | let mut step_count = 0; 71 | let mut copy_name = name; 72 | let mut long_cmp_done = false; 73 | 74 | for i in (0..).step_by(32) { 75 | if i % BUFFER_SIZE == 0 { 76 | self.partition 77 | .read( 78 | &mut buf, 79 | self.bpb.offset(self.dir_cluster) as usize + offset_count * bps, 80 | ) 81 | .unwrap(); 82 | offset_count += 1; 83 | } 84 | 85 | if step_count != 0 { 86 | step_count -= 1; 87 | continue; 88 | } 89 | 90 | let offset = i - (offset_count - 1) * bps; 91 | if buf[0x00 + offset] == 0x00 { 92 | break; 93 | } 94 | if long_cmp_done { 95 | return Ok((op(&buf[offset..offset + 32]), i as u32)); 96 | } 97 | 98 | if buf[0x00 + offset] == 0xE5 { 99 | continue; 100 | } 101 | if buf[0x0B + offset] == 0x0F { 102 | match name_type { 103 | NameType::Short => { 104 | step_count = buf[0x00 + offset] & 0x1F; 105 | continue; 106 | } 107 | NameType::Long => { 108 | let len = copy_name.chars().count(); 109 | let count = buf[0x00 + offset] & 0x1F; 110 | let info = self.get_long_name(&buf[offset..offset + 32]); 111 | let part_name = core::str::from_utf8(&info.0[0..info.1]).unwrap(); 112 | let multi = if len % 13 == 0 { 113 | len / 13 - 1 114 | } else { 115 | len / 13 116 | }; 117 | let start_at = if len <= 13 { 118 | 0 119 | } else { 120 | self.get_slice_index(copy_name, 13 * multi) 121 | }; 122 | if !©_name[start_at..].eq(part_name) { 123 | copy_name = name; 124 | step_count = count; 125 | continue; 126 | } else if start_at == 0 && count == 1 { 127 | long_cmp_done = true; 128 | } else { 129 | copy_name = ©_name[0..start_at]; 130 | } 131 | } 132 | } 133 | } else { 134 | if let NameType::Short = name_type { 135 | let info = self.get_short_name(&buf[offset..offset + 32]); 136 | let file_name = core::str::from_utf8(&info.0[0..info.1]).unwrap(); 137 | if name.eq_ignore_ascii_case(file_name) { 138 | return Ok((op(&buf[offset..offset + 32]), i as u32)); 139 | } 140 | } 141 | } 142 | } 143 | Err(DirError::NoMatch) 144 | } 145 | 146 | fn short_or_long(&self, name: &str) -> NameType { 147 | let part = match name.find('.') { 148 | Some(i) => (&name[0..i], &name[i + 1..]), 149 | None => (&name[..], ""), 150 | }; 151 | if name.is_ascii() && !name.contains(' ') && part.0.len() <= 8 && part.1.len() <= 3 { 152 | NameType::Short 153 | } else { 154 | NameType::Long 155 | } 156 | } 157 | 158 | fn get_slice_index(&self, name: &str, end: usize) -> usize { 159 | let mut len = 0; 160 | for ch in name.chars().enumerate() { 161 | if (0..end).contains(&ch.0) { 162 | len += ch.1.len_utf8(); 163 | } 164 | } 165 | len 166 | } 167 | 168 | fn get_dir(&self, buf: &[u8]) -> Dir { 169 | let mut dir_name = [0; 11]; 170 | dir_name.copy_from_slice(&buf[0x00..0x0B]); 171 | 172 | Dir:: { 173 | partition: self.partition, 174 | bpb: self.bpb, 175 | dir_name, 176 | dir_cluster: ((buf[0x15] as u32) << 24) 177 | | ((buf[0x14] as u32) << 16) 178 | | ((buf[0x1B] as u32) << 8) 179 | | (buf[0x1A] as u32), 180 | length: read_le_u32(&buf[0x1C..0x20]), 181 | } 182 | } 183 | fn get_file(&self, buf: &[u8], offset: u32) -> File { 184 | let mut file_name = [0; 8]; 185 | let mut extension_name = [0; 3]; 186 | 187 | let mut index = 0; 188 | for i in 0x00..0x08 { 189 | if buf[i] != 0x20 { 190 | file_name[index] = buf[i]; 191 | index += 1; 192 | } else { 193 | break; 194 | } 195 | } 196 | 197 | index = 0; 198 | for i in 0x08..0x0B { 199 | if buf[i] != 0x20 { 200 | extension_name[index] = buf[i]; 201 | index += 1; 202 | } else { 203 | break; 204 | } 205 | } 206 | 207 | let file_cluster = ((buf[0x15] as u32) << 24) 208 | | ((buf[0x14] as u32) << 16) 209 | | ((buf[0x1B] as u32) << 8) 210 | | (buf[0x1A] as u32); 211 | let mut len = [0; 4]; 212 | len.copy_from_slice(&buf[0x1C..0x20]); 213 | 214 | File:: { 215 | partition: self.partition, 216 | bpb: self.bpb, 217 | dir_cluster: self.dir_cluster, 218 | offset, 219 | file_name, 220 | extension_name, 221 | file_cluster, 222 | length: read_le_u32(&buf[0x1C..0x20]) as usize, 223 | } 224 | } 225 | fn get_short_name(&self, buf: &[u8]) -> ([u8; 13], usize) { 226 | let mut file_name = [0; 13]; 227 | let mut index = 0; 228 | 229 | for i in 0x00..=0x0A { 230 | if buf[i] != 0x20 { 231 | if i == 0x08 { 232 | file_name[index] = b'.'; 233 | index += 1; 234 | } 235 | file_name[index] = buf[i]; 236 | index += 1; 237 | } 238 | } 239 | (file_name, index) 240 | } 241 | fn get_long_name(&self, buf: &[u8]) -> ([u8; 13 * 3], usize) { 242 | let mut res = ([0; 13 * 3], 0); 243 | 244 | let op = |res: &mut ([u8; 13 * 3], usize), start: usize, end: usize| { 245 | for i in (start..end).step_by(2) { 246 | if buf[i] == 0x00 && buf[i + 1] == 0x00 { 247 | break; 248 | } 249 | let unicode = ((buf[i + 1] as u16) << 8) | buf[i] as u16; 250 | if unicode <= 0x007F { 251 | res.0[res.1] = unicode as u8; 252 | res.1 += 1; 253 | } else if unicode >= 0x0080 && unicode <= 0x07FF { 254 | let part1 = (0b11000000 | (0b00011111 & (unicode >> 12))) as u8; 255 | let part2 = (0b10000000 | 0b00111111 & unicode) as u8; 256 | res.0[res.1] = part1; 257 | res.0[res.1 + 1] = part2; 258 | res.1 += 2; 259 | } else if unicode >= 0x0800 { 260 | let part1 = (0b11100000 | (0b00011111 & (unicode >> 12))) as u8; 261 | let part2 = (0b10000000 | (0b00111111 & (unicode >> 6))) as u8; 262 | let part3 = (0b10000000 | 0b00111111 & unicode) as u8; 263 | res.0[res.1] = part1; 264 | res.0[res.1 + 1] = part2; 265 | res.0[res.1 + 2] = part3; 266 | res.1 += 3; 267 | } 268 | } 269 | }; 270 | 271 | if buf[0x01] != 0xFF { 272 | op(&mut res, 0x01, 0x0A); 273 | } 274 | if buf[0x0E] != 0xFF { 275 | op(&mut res, 0x0E, 0x19); 276 | } 277 | if buf[0x1C] != 0xFF { 278 | op(&mut res, 0x1C, 0x1F); 279 | } 280 | res 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/fs/fat32/file.rs: -------------------------------------------------------------------------------- 1 | use super::BIOSParameterBlock; 2 | use crate::fs::blkdev::BlockDevice; 3 | use core::fmt::Debug; 4 | 5 | #[derive(Debug, Copy, Clone)] 6 | pub enum FileError { 7 | BufTooSmall, 8 | IllegalName, 9 | } 10 | 11 | #[derive(Debug, Copy, Clone)] 12 | pub struct File 13 | where 14 | T: BlockDevice + Clone + Copy, 15 | ::Error: Debug, 16 | { 17 | pub partition: T, 18 | pub bpb: BIOSParameterBlock, 19 | pub dir_cluster: u32, 20 | pub offset: u32, 21 | pub file_name: [u8; 8], 22 | pub extension_name: [u8; 3], 23 | pub file_cluster: u32, 24 | pub length: usize, 25 | } 26 | 27 | impl File 28 | where 29 | T: BlockDevice + Clone + Copy, 30 | ::Error: Debug, 31 | { 32 | pub fn len(&self) -> usize { 33 | self.length 34 | } 35 | pub fn read(&self, buf: &mut [u8]) -> Result { 36 | if buf.len() < self.length as usize { 37 | return Err(FileError::BufTooSmall); 38 | } 39 | let bps = self.bpb.byte_per_sector as usize; 40 | let spc = self.bpb.sector_per_cluster as usize; 41 | 42 | // cluster pointer 43 | let mut loc = self.file_cluster; 44 | // buffer pointer 45 | let mut start_at = 0; 46 | 47 | // number of clusters 48 | let clusters = (self.length as usize / bps) / spc; 49 | // left sectors 50 | let sectors = (self.length as usize / bps) % spc; 51 | // left bytes 52 | let bytes = self.length as usize % bps; 53 | 54 | for _ in 0..clusters { 55 | self.partition 56 | .read( 57 | &mut buf[start_at..start_at + spc * bps], 58 | self.bpb.offset(loc), 59 | ) 60 | .unwrap(); 61 | let entry = self.get_fat_entry(loc); 62 | loc = entry; 63 | start_at += spc * bps; 64 | } 65 | if sectors > 0 || bytes > 0 { 66 | self.partition 67 | .read( 68 | &mut buf[start_at..start_at + sectors * bps + bytes], 69 | self.bpb.offset(loc), 70 | ) 71 | .unwrap(); 72 | } 73 | Ok(self.length as usize) 74 | } 75 | fn get_fat_entry(&self, loc: u32) -> u32 { 76 | let fat_addr = self.bpb.fat1(); 77 | let offset = loc as usize * 4; 78 | let mut buf = [0; 4]; 79 | 80 | self.partition.read(&mut buf, fat_addr + offset).unwrap(); 81 | u32::from_le_bytes(buf) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/fs/gpt.rs: -------------------------------------------------------------------------------- 1 | use crate::{print, println}; 2 | use crate::fs::blkdev::{read, BIOError, BlockDevice}; 3 | pub struct GPT { 4 | data: [u8; 1280], // 10 Partitions 5 | } 6 | 7 | #[repr(C, packed)] 8 | #[derive(Copy, Clone, Debug)] 9 | pub struct GPTEntry { 10 | ptype: [u8; 16], 11 | guid: [u8; 16], 12 | start_lba: u64, 13 | last_lba: u64, 14 | attr: u64, 15 | name: [u8; 72], 16 | } 17 | 18 | impl GPTEntry { 19 | pub fn is_efi_system_partition(&self) -> bool { 20 | let efisysprt: [u8; 16] = [ 21 | 0x28, 0x73, 0x2A, 0xC1, 0x1F, 0xF8, 0xD2, 0x11, 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 22 | 0xC9, 0x3B, 23 | ]; 24 | if self.ptype == efisysprt { 25 | true 26 | } else { 27 | false 28 | } 29 | } 30 | pub fn starting_lba(&self) -> u32 { 31 | self.start_lba as u32 32 | } 33 | pub fn partition_length(&self) -> usize { 34 | (self.last_lba - self.start_lba + 1) as usize 35 | } 36 | } 37 | 38 | impl GPT { 39 | pub fn new() -> Self { 40 | let mut data: [u8; 1280] = [0u8; 1280]; 41 | let offset = 2 * 512; 42 | read(&mut data, offset).unwrap(); 43 | Self { data } 44 | } 45 | // pub fn as_mut_slice(&mut self) -> &mut [T] { 46 | // unsafe { 47 | // core::slice::from_raw_parts_mut(self.data.as_mut_ptr() as *mut T, self.data.len() / 128) 48 | // } 49 | // } 50 | fn as_slice(&self) -> &[T] { 51 | unsafe { 52 | core::slice::from_raw_parts(self.data.as_ptr() as *const T, self.data.len() / 128) 53 | } 54 | } 55 | pub fn get_efi_system_partition(&self) -> Option { 56 | for entry in self.as_slice::().iter() { 57 | if entry.is_efi_system_partition() { 58 | return Some(Partition { 59 | start_lba: entry.starting_lba(), 60 | length: entry.partition_length(), 61 | }); 62 | } 63 | } 64 | None 65 | } 66 | } 67 | 68 | #[derive(Copy, Clone, Debug)] 69 | pub struct Partition { 70 | pub start_lba: u32, 71 | pub length: usize, 72 | } 73 | 74 | impl BlockDevice for Partition { 75 | type Error = BIOError; 76 | fn read(&self, buf: &mut [u8], offset: usize) -> Result<(), Self::Error> { 77 | let load_sectors = (buf.len() + offset + 512 - 1) / 512; // sectors 78 | let real_offset = (self.start_lba as usize * 512) + offset; // bytes 79 | if load_sectors <= self.length { 80 | //println!("offset = {}", offset); 81 | //println!("load sectors = {}, length = {}", load_sectors, self.length); 82 | read(buf, real_offset)?; 83 | Ok(()) 84 | } else { 85 | println!("offset = {}", offset); 86 | println!("load sectors = {}, length = {}", load_sectors, self.length); 87 | Err(BIOError::IOError) 88 | } 89 | } 90 | fn write(&self, _: &mut [u8], _: usize) -> Result<(), Self::Error> { 91 | Ok(()) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/fs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod blkdev; 2 | pub mod fat32; 3 | pub mod gpt; 4 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(llvm_asm)] 2 | #![feature(alloc_error_handler)] 3 | #![no_std] 4 | use core::{alloc::GlobalAlloc, cell::UnsafeCell, ptr}; 5 | extern crate alloc; 6 | use alloc::alloc::Layout; 7 | use plankton::layout::{HEAP_END, HEAP_START}; 8 | 9 | #[macro_use] 10 | pub mod text; 11 | pub mod fs; 12 | pub mod loader; 13 | pub mod svm; 14 | 15 | pub fn clear_bss() { 16 | extern "C" { 17 | static mut _data_end: u8; 18 | static mut _bss_end: u8; 19 | } 20 | unsafe { 21 | let count = &_bss_end as *const u8 as usize - &_data_end as *const u8 as usize; 22 | ptr::write_bytes(&mut _data_end as *mut u8, 0, count); 23 | } 24 | } 25 | 26 | struct Alloc { 27 | head: UnsafeCell, 28 | end: usize, 29 | } 30 | 31 | unsafe impl Sync for Alloc {} 32 | 33 | unsafe impl GlobalAlloc for Alloc { 34 | unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 35 | let head = self.head.get(); 36 | let align = layout.align(); 37 | let res = *head % align; 38 | let start = if res == 0 { *head } else { *head + align - res }; 39 | if start + align > self.end { 40 | ptr::null_mut() 41 | } else { 42 | *head = start + align; 43 | start as *mut u8 44 | } 45 | } 46 | unsafe fn dealloc(&self, _: *mut u8, _: Layout) { 47 | // nothing to do 48 | } 49 | } 50 | 51 | #[global_allocator] 52 | static HEAP: Alloc = Alloc { 53 | head: UnsafeCell::new(HEAP_START as usize), 54 | end: HEAP_END as usize, 55 | }; 56 | 57 | #[alloc_error_handler] 58 | fn on_oom(_layout: Layout) -> ! { 59 | panic!("Out of Memory"); 60 | } 61 | 62 | use core::panic::PanicInfo; 63 | #[panic_handler] 64 | fn panic(_info: &PanicInfo) -> ! { 65 | println!("{}", _info); 66 | loop {} 67 | } 68 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/loader.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod elf; 3 | 4 | use crate::fs::{ 5 | blkdev::BlockDevice, 6 | fat32::{dir::Dir, file::FileError}, 7 | }; 8 | use core::fmt::Debug; 9 | use plankton::{ 10 | layout::{CMD_LINE_ADDR, ELF_START, INITRD_START}, 11 | mem::MemoryRegion, 12 | }; 13 | 14 | #[derive(Debug, PartialEq)] 15 | pub enum ParseError { 16 | InvalidElfEndian, 17 | InvalidElfMagicNumber, 18 | InvalidEntryAddress, 19 | InvalidArchitecture, 20 | InvalidProgramHeaderSize, 21 | InvalidProgramHeaderOffset, 22 | InvalidProgramHeaderAddress, 23 | } 24 | 25 | pub enum GuestAddress { 26 | Addr32(u32), 27 | Addr64(u64), 28 | } 29 | 30 | pub fn load_elf(kernel_size: usize) -> Result { 31 | let elf_image = MemoryRegion::new(ELF_START as u64, kernel_size as u64); 32 | let e_ident: &[u8] = elf_image.as_slice(0, 16); 33 | 34 | // checks 35 | if e_ident[elf::EI_MAG0] != elf::ELFMAG0 36 | || e_ident[elf::EI_MAG1] != elf::ELFMAG1 37 | || e_ident[elf::EI_MAG2] != elf::ELFMAG2 38 | || e_ident[elf::EI_MAG3] != elf::ELFMAG3 39 | { 40 | return Err(ParseError::InvalidElfMagicNumber); 41 | } 42 | if e_ident[elf::EI_DATA] != elf::ELFDATA2LSB { 43 | return Err(ParseError::InvalidElfEndian); 44 | } 45 | 46 | match e_ident[elf::EI_CLSS] { 47 | elf::ELF32CL => { 48 | println!("ELF32..."); 49 | let ehdr = elf_image.read::(0); 50 | let phdrs = elf_image 51 | .as_slice::(ehdr.e_phoff as u64, ehdr.e_phnum as u64); 52 | 53 | if ehdr.e_phsize as usize != core::mem::size_of::() { 54 | return Err(ParseError::InvalidProgramHeaderSize); 55 | } 56 | if (ehdr.e_phoff as usize) < core::mem::size_of::() { 57 | return Err(ParseError::InvalidProgramHeaderOffset); 58 | } 59 | if ehdr.e_entry < 0x100000 { 60 | return Err(ParseError::InvalidEntryAddress); 61 | } 62 | 63 | for &phdr in phdrs { 64 | if phdr.p_type != elf::PT_LOAD || phdr.p_fsize == 0 { 65 | continue; 66 | } 67 | if phdr.p_paddr < 0x100000 { 68 | return Err(ParseError::InvalidProgramHeaderAddress); 69 | } 70 | let mut dst_region = 71 | plankton::mem::MemoryRegion::new(phdr.p_paddr as u64, phdr.p_fsize as u64); 72 | let dst = dst_region.as_mut_slice::(0, phdr.p_fsize as u64); 73 | let src = elf_image.as_slice::(phdr.p_offset as u64, phdr.p_fsize as u64); 74 | dst.copy_from_slice(src); 75 | } 76 | Ok(GuestAddress::Addr32(ehdr.e_entry)) 77 | } 78 | elf::ELF64CL => { 79 | println!("ELF64..."); 80 | let ehdr = elf_image.read::(0); 81 | let phdrs = elf_image 82 | .as_slice::(ehdr.e_phoff as u64, ehdr.e_phnum as u64); 83 | 84 | if ehdr.e_phsize as usize != core::mem::size_of::() { 85 | return Err(ParseError::InvalidProgramHeaderSize); 86 | } 87 | if (ehdr.e_phoff as usize) < core::mem::size_of::() { 88 | return Err(ParseError::InvalidProgramHeaderOffset); 89 | } 90 | if ehdr.e_entry < 0x100000 { 91 | return Err(ParseError::InvalidEntryAddress); 92 | } 93 | 94 | for &phdr in phdrs.iter() { 95 | if phdr.p_type != elf::PT_LOAD || phdr.p_fsize == 0 { 96 | continue; 97 | } 98 | if phdr.p_paddr < 0x100000 { 99 | return Err(ParseError::InvalidProgramHeaderAddress); 100 | } 101 | let mut dst_region = 102 | plankton::mem::MemoryRegion::new(phdr.p_paddr as u64, phdr.p_fsize as u64); 103 | let dst = dst_region.as_mut_slice::(0, phdr.p_fsize as u64); 104 | let src = elf_image.as_slice::(phdr.p_offset as u64, phdr.p_fsize as u64); 105 | dst.copy_from_slice(src); 106 | } 107 | Ok(GuestAddress::Addr64(ehdr.e_entry)) 108 | } 109 | _ => Err(ParseError::InvalidArchitecture), 110 | } 111 | } 112 | 113 | // do loading kernel, initrd and command line and setting. return kernel size 114 | pub fn load_items(root: Dir, config: config::Config) -> Result 115 | where 116 | T: BlockDevice + Clone + Copy, 117 | ::Error: Debug, 118 | { 119 | let mut initrd_size = 0; 120 | 121 | // loading kernel img 122 | print!(" Loading {}...", config.kernel); 123 | let kernel_img = root.open_file(config.kernel).unwrap(); 124 | let mut img_region = MemoryRegion::new(ELF_START as u64, kernel_img.len() as u64); 125 | let mut img = img_region.as_mut_slice::(0, img_region.len()); 126 | kernel_img.read(&mut img)?; 127 | println!(" done!"); 128 | 129 | // loading initrd if config exists 130 | if let Some(initrd) = config.initrd { 131 | print!(" Loading {}...", initrd); 132 | let initrd_img = root.open_file(initrd).unwrap(); 133 | let mut rd_region = MemoryRegion::new(INITRD_START as u64, initrd_img.len() as u64); 134 | let mut rd = rd_region.as_mut_slice::(0, rd_region.len()); 135 | initrd_img.read(&mut rd)?; 136 | initrd_size = initrd_img.len() as u32; 137 | println!(" done!") 138 | } 139 | 140 | // setting command line if config exists 141 | if let Some(cmdlin) = config.cmdlin { 142 | print!(" Setting command line..."); 143 | setup_cmdline(cmdlin); 144 | println!(" done!"); 145 | } 146 | 147 | // zero_page setup 148 | setup_zero_page(kernel_img.len() as u32, initrd_size); 149 | 150 | Ok(kernel_img.len()) 151 | } 152 | 153 | fn setup_cmdline(cmdlin: &str) { 154 | let bytes = cmdlin.as_bytes(); 155 | let mut cmdline_region = MemoryRegion::new(CMD_LINE_ADDR as u64, bytes.len() as u64 + 1); 156 | let cmdline = cmdline_region.as_mut_slice::(0, bytes.len() as u64); 157 | cmdline.copy_from_slice(bytes); 158 | cmdline_region.write_u8(bytes.len() as u64, b'\0'); 159 | } 160 | 161 | fn setup_zero_page(kernel_size: u32, initrd_size: u32) { 162 | let zero_page = MemoryRegion::new(0x7C00, 4096); 163 | zero_page.write_u32(0x218, INITRD_START); 164 | zero_page.write_u32(0x21C, initrd_size); 165 | zero_page.write_u16(0x1fc, 0x0100); 166 | zero_page.write_u32(0x100, kernel_size); 167 | zero_page.write_u32(0x228, CMD_LINE_ADDR); 168 | } 169 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/loader/config.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | pub struct Config<'a> { 3 | pub kernel: &'a str, 4 | pub initrd: Option<&'a str>, 5 | pub cmdlin: Option<&'a str>, 6 | } 7 | 8 | impl<'a> Config<'a> { 9 | pub fn new(contents: &'a str) -> Result { 10 | let kernel = get_item(contents, "main.kernel"); 11 | let initrd = get_item(contents, "main.initrd"); 12 | let cmdlin = get_item(contents, "main.cmdlin"); 13 | 14 | if let Some(kernel) = kernel { 15 | Ok(Self { 16 | kernel, 17 | initrd, 18 | cmdlin, 19 | }) 20 | } else { 21 | Err("Kernel file is not specifyed!") 22 | } 23 | } 24 | } 25 | 26 | fn get_item<'a, 'b>(contents: &'a str, pat: &'b str) -> Option<&'a str> { 27 | let mut res = None; 28 | for line in contents.lines() { 29 | if line.starts_with(pat) { 30 | res = Some(line.split_at(pat.len() + 1).1); 31 | break; 32 | } 33 | } 34 | res 35 | } 36 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/loader/elf.rs: -------------------------------------------------------------------------------- 1 | pub const EI_MAG0: usize = 0; 2 | pub const EI_MAG1: usize = 1; 3 | pub const EI_MAG2: usize = 2; 4 | pub const EI_MAG3: usize = 3; 5 | pub const EI_CLSS: usize = 4; 6 | pub const EI_DATA: usize = 5; 7 | 8 | pub const ELFMAG0: u8 = 127; 9 | pub const ELFMAG1: u8 = b'E'; 10 | pub const ELFMAG2: u8 = b'L'; 11 | pub const ELFMAG3: u8 = b'F'; 12 | 13 | pub const ELF32CL: u8 = 1; 14 | pub const ELF64CL: u8 = 2; 15 | 16 | pub const ELFDATA2LSB: u8 = 1; 17 | 18 | pub const PT_LOAD: u32 = 1; 19 | 20 | #[derive(Copy, Clone, Default)] 21 | #[repr(C, packed)] 22 | pub struct Elf32Header { 23 | pub e_ident: [u8; 16], 24 | pub e_type: u16, 25 | pub e_cpu: u16, 26 | pub e_version: u32, 27 | pub e_entry: u32, 28 | pub e_phoff: u32, 29 | pub e_shoff: u32, 30 | pub e_flags: u32, 31 | pub e_ehsize: u16, 32 | pub e_phsize: u16, 33 | pub e_phnum: u16, 34 | pub e_shsize: u16, 35 | pub e_shnum: u16, 36 | pub e_shname: u16, 37 | } 38 | 39 | #[derive(Copy, Clone, Default)] 40 | #[repr(C, packed)] 41 | pub struct Elf32ProgramHeader { 42 | pub p_type: u32, 43 | pub p_offset: u32, 44 | pub p_vaddr: u32, 45 | pub p_paddr: u32, 46 | pub p_fsize: u32, 47 | pub p_msize: u32, 48 | pub p_flags: u32, 49 | pub p_align: u32, 50 | } 51 | 52 | #[derive(Copy, Clone, Default)] 53 | #[repr(C, packed)] 54 | pub struct Elf64Header { 55 | pub e_ident: [u8; 16], 56 | pub e_type: u16, 57 | pub e_cpu: u16, 58 | pub e_version: u32, 59 | pub e_entry: u64, 60 | pub e_phoff: u64, 61 | pub e_shoff: u64, 62 | pub e_flags: u32, 63 | pub e_ehsize: u16, 64 | pub e_phsize: u16, 65 | pub e_phnum: u16, 66 | pub e_shsize: u16, 67 | pub e_shnum: u16, 68 | pub e_shname: u16, 69 | } 70 | 71 | #[derive(Copy, Clone, Default)] 72 | #[repr(C, packed)] 73 | pub struct Elf64ProgramHeader { 74 | pub p_type: u32, 75 | pub p_flags: u32, 76 | pub p_offset: u64, 77 | pub p_vaddr: u64, 78 | pub p_paddr: u64, 79 | pub p_fsize: u64, 80 | pub p_msize: u64, 81 | pub p_align: u64, 82 | } 83 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(llvm_asm)] 2 | #![no_std] 3 | #![no_main] 4 | extern crate alloc; 5 | extern crate rlibc; 6 | 7 | #[macro_use] 8 | use alloc::vec; 9 | use stage_4th::fs::{fat32::FileSystem, gpt::GPT}; 10 | use stage_4th::{ 11 | clear_bss, 12 | loader::{config::Config, load_elf, load_items, GuestAddress}, 13 | print, println, svm, 14 | }; 15 | 16 | #[link_section = ".first"] 17 | #[no_mangle] 18 | fn stage4() -> ! { 19 | clear_bss(); 20 | println!("STG4: "); 21 | let file_name = "config.txt"; 22 | 23 | // Mount FileSystem. 24 | print!(" Mounting FAT32 EFI System Partition..."); 25 | let partition = match GPT::new().get_efi_system_partition() { 26 | Some(partition) => partition, 27 | None => panic!("None"), 28 | }; 29 | let fs = FileSystem::new(partition); 30 | let root = fs.root_dir(); 31 | println!(" done!"); 32 | 33 | // Read CONFIG File 34 | print!(" Reading {}...", file_name); 35 | let config_txt = root.open_file(file_name).unwrap(); 36 | //loop {} 37 | //println!("{}", config_txt.len()); 38 | let mut buf = vec![0u8; config_txt.len()]; 39 | config_txt.read(&mut buf).unwrap(); 40 | let config = Config::new(core::str::from_utf8(&buf).unwrap()).unwrap(); 41 | println!(" done!"); 42 | //loop {} 43 | // Load items 44 | let kernel_size = load_items(root, config).unwrap(); 45 | 46 | // Relocating ELF formatted Kernel 47 | print!(" Relocating kernel "); 48 | let entry_addr = load_elf(kernel_size).unwrap(); 49 | 50 | // Excute 51 | match entry_addr { 52 | GuestAddress::Addr32(entry_addr) => svm::pm::start_kernel(entry_addr), 53 | GuestAddress::Addr64(entry_addr) => svm::lm::start_kernel(entry_addr), 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/svm/lm.rs: -------------------------------------------------------------------------------- 1 | use core::hint::unreachable_unchecked; 2 | 3 | #[repr(C, packed)] 4 | struct DescoritorTable { 5 | limit: u16, 6 | base: u32, 7 | } 8 | 9 | #[no_mangle] 10 | static GDT: [u64; 6] = [ 11 | 0x0000000000000000, 12 | 0x0000000000000000, 13 | 0x00AF9A000000FFFF, // __KERNEL_CS 14 | 0x00CF92000000FFFF, // __KERNEL_DS 15 | 0x0080890000000000, // TS descripter 16 | 0x0000000000000000, // TS continued 17 | ]; 18 | 19 | #[no_mangle] 20 | static mut GDTR: DescoritorTable = DescoritorTable { 21 | limit: 0x800, 22 | base: 0, 23 | }; 24 | 25 | fn setup_gdt() { 26 | unsafe { 27 | llvm_asm!("movl $$GDT, %eax 28 | movl %eax, (GDTR+2) 29 | lgdt GDTR" 30 | ::: "eax" 31 | ); 32 | } 33 | } 34 | 35 | fn enable_pae() { 36 | unsafe { 37 | // Enable PAE 38 | llvm_asm!("movl %cr4, %eax 39 | orl $$0x20, %eax 40 | movl %eax, %cr4" 41 | ::: "eax" 42 | ); 43 | } 44 | } 45 | 46 | fn setup_page_tables() { 47 | use plankton::layout::PGTABLE_START; 48 | use plankton::mem::MemoryRegion; 49 | let mut pg_table = MemoryRegion::new(PGTABLE_START, 8 * 6 * 512); 50 | pg_table 51 | .as_mut_slice::(0x0000, 6 * 512) 52 | .copy_from_slice(&[0; 6 * 512]); 53 | 54 | // Build Level 4 55 | let level4 = pg_table.as_mut_slice::(0x0000, 512); 56 | for i in 0..1 { 57 | level4[i] = (PGTABLE_START + 0x1000) | 0x7; 58 | } 59 | 60 | // Build Level 3 61 | let level3 = pg_table.as_mut_slice::(0x1000, 512); 62 | for i in 0..4 { 63 | level3[i] = (PGTABLE_START + 0x2000 + 0x1000 * (i as u64)) | 0x7; 64 | } 65 | 66 | // Build Level 2 67 | let level2 = pg_table.as_mut_slice::(0x2000, 4 * 512); 68 | for i in 0..2048 { 69 | level2[i] = (0x00200000 * (i as u64)) | 0x00000183; 70 | } 71 | } 72 | 73 | fn enable_paging() { 74 | unsafe { 75 | // Enable the boot page tables 76 | llvm_asm!("movl %eax, %cr3" 77 | :: "{eax}"(plankton::layout::PGTABLE_START) 78 | ); 79 | 80 | // Enable Long mode in EFER (Extended Feature Enable Register) 81 | llvm_asm!("movl $$0xC0000080, %ecx 82 | rdmsr 83 | btsl $$8, %eax 84 | wrmsr" 85 | ::: "eax", "ecx" 86 | ); 87 | } 88 | } 89 | 90 | fn jmp64(entry_addr: u64) -> ! { 91 | unsafe { 92 | llvm_asm!("pushl $$0x10 93 | pushl %eax 94 | movl %ebx, %eax 95 | movl %eax, %cr0 96 | lret" 97 | : 98 | : "{eax}"(entry_addr), "{ebx}"((1<<31)|(1<<0)) "{esi}"(0x7C00) 99 | : 100 | ); 101 | unreachable_unchecked(); 102 | } 103 | } 104 | 105 | pub fn start_kernel(entry_addr: u64) -> ! { 106 | setup_gdt(); 107 | enable_pae(); 108 | setup_page_tables(); 109 | enable_paging(); 110 | jmp64(entry_addr); 111 | } 112 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/svm/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod lm; 2 | pub mod pm; 3 | pub mod rm; 4 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/svm/pm.rs: -------------------------------------------------------------------------------- 1 | use core::hint::unreachable_unchecked; 2 | 3 | pub fn start_kernel(entry_addr: u32) -> ! { 4 | unsafe { 5 | llvm_asm!("xorl %ebx, %ebx 6 | movl %ebx, %ebp 7 | movl %ebx, %edi 8 | jmp *%eax" 9 | : 10 | : "{eax}"(entry_addr), "{esi}"(0x7C00) 11 | ); 12 | unreachable_unchecked(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/svm/rm.rs: -------------------------------------------------------------------------------- 1 | use crate::fs::blkdev::BIOError; 2 | use plankton::{layout::INIT_SEG, mem::MemoryRegion}; 3 | 4 | macro_rules! scratch_push { 5 | () => { 6 | llvm_asm!(" 7 | pushl %eax 8 | pushl %ecx 9 | pushl %edx 10 | pushl %edi 11 | pushl %esi 12 | ":::); 13 | }; 14 | } 15 | 16 | macro_rules! scratch_pop { 17 | () => { 18 | llvm_asm!(" 19 | popl %esi 20 | popl %edi 21 | popl %edx 22 | popl %ecx 23 | popl %eax 24 | ":::); 25 | }; 26 | } 27 | 28 | macro_rules! preserved_push { 29 | () => { 30 | llvm_asm!(" 31 | pushl %ebx 32 | pushl %ebp 33 | ":::); 34 | }; 35 | } 36 | 37 | macro_rules! preserved_pop { 38 | () => { 39 | llvm_asm!(" 40 | popl %ebp 41 | popl %ebx 42 | ":::); 43 | }; 44 | } 45 | 46 | // real mode gdt 47 | #[repr(C, packed)] 48 | struct Descriptortable { 49 | limit: u16, 50 | base: u32, 51 | } 52 | 53 | #[no_mangle] 54 | static GDT16: [u64; 4] = [ 55 | 0x0000000000000000, 56 | 0x0000000000000000, 57 | 0x00009E000000FFFF, // 16 bit real mode CS 58 | 0x000092000000FFFF, // 16 bit real mode DS 59 | ]; 60 | 61 | #[no_mangle] 62 | static IDTR16: Descriptortable = Descriptortable { 63 | limit: 0x400, 64 | base: 0, 65 | }; 66 | #[no_mangle] 67 | static GDTR16: Descriptortable = Descriptortable { 68 | limit: 0x1f, 69 | base: 0, 70 | }; 71 | 72 | #[inline(never)] 73 | #[no_mangle] 74 | pub fn diskread(start_lba: u32, sectors: u32) -> Result<(), BIOError> { 75 | let mut param_region = MemoryRegion::new(((INIT_SEG << 4) + 0x6100) as u64, 16); 76 | let param = param_region.as_mut_slice::(0, 4); 77 | // save start_lba and sectors 78 | param[0] = start_lba; 79 | param[1] = sectors; 80 | //loop {} 81 | unsafe { 82 | llvm_asm!("start:"); 83 | scratch_push!(); 84 | preserved_push!(); 85 | 86 | llvm_asm!("cli"); 87 | 88 | // save return address and stack pointer 89 | llvm_asm!("movl $$continue, %eax":"={eax}"(param[2])); 90 | llvm_asm!("movl %esp, %eax":"={eax}"(param[3])); 91 | 92 | // setup gdt & idt 93 | llvm_asm!(" 94 | movl $$GDT16, %eax 95 | movl %eax, (GDTR16+2) 96 | lgdt GDTR16 97 | lidt IDTR16" 98 | ::: 99 | ); 100 | // set up new stack for real mode 0x07C0:0xFFF0 101 | llvm_asm!(" 102 | movl $$0xFFF0, %eax 103 | movl %eax, %esp 104 | movl %eax, %ebp" 105 | :::"eax" 106 | ); 107 | // setup segment 108 | llvm_asm!(" 109 | movw $$0x18, %ax 110 | movw %ax, %ds 111 | movw %ax, %es 112 | movw %ax, %fs 113 | movw %ax, %gs 114 | movw %ax, %ss" 115 | ); 116 | 117 | // goto real mode 118 | llvm_asm!("jmp $$0x10, $$0xDD10"); 119 | 120 | // return point 121 | llvm_asm!(" 122 | continue: 123 | sti" 124 | ); 125 | preserved_pop!(); 126 | scratch_pop!(); 127 | llvm_asm!("end:") 128 | } 129 | //loop {} 130 | if param[0] == 1 { 131 | Ok(()) 132 | } else { 133 | Err(BIOError::IOError) 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/bios/stage_4th/src/text.rs: -------------------------------------------------------------------------------- 1 | use core::fmt; 2 | use plankton::ios::{io_delay, outb}; 3 | 4 | pub const CURSOR_START: u8 = 13; 5 | pub const CURSOR_END: u8 = 14; 6 | pub const VGA_CRT_ADDR: usize = 0x3D4; 7 | pub const VGA_CRT_DATA: usize = 0x3D5; 8 | pub const VGA_CRT_CURSTART: u8 = 10; 9 | pub const VGA_CRT_CUREND: u8 = 11; 10 | pub const VGA_CRT_CURADDH: u8 = 14; 11 | pub const VGA_CRT_CURADDL: u8 = 15; 12 | 13 | pub const TEXT_MODE_START: usize = 0xB8000; 14 | pub const TEXT_DEF_ATTRIBUTE: u8 = 0x07; 15 | 16 | macro_rules! vram_data { 17 | ($moji:expr, $iro:expr) => { 18 | (($iro as u16) << 8) + $moji as u16 19 | }; 20 | } 21 | 22 | pub struct Screen { 23 | buffer: usize, 24 | width: usize, 25 | height: usize, 26 | x: usize, 27 | y: usize, 28 | attr: u8, 29 | } 30 | 31 | static mut SCRN: [Screen; 8] = [ 32 | Screen { 33 | buffer: TEXT_MODE_START + 0x0000, 34 | width: 80, 35 | height: 25, 36 | x: 0, 37 | y: 0, 38 | attr: TEXT_DEF_ATTRIBUTE, 39 | }, 40 | Screen { 41 | buffer: TEXT_MODE_START + 0x0800, 42 | width: 80, 43 | height: 25, 44 | x: 0, 45 | y: 0, 46 | attr: TEXT_DEF_ATTRIBUTE, 47 | }, 48 | Screen { 49 | buffer: TEXT_MODE_START + 0x1000, 50 | width: 80, 51 | height: 25, 52 | x: 0, 53 | y: 0, 54 | attr: TEXT_DEF_ATTRIBUTE, 55 | }, 56 | Screen { 57 | buffer: TEXT_MODE_START + 0x1800, 58 | width: 80, 59 | height: 25, 60 | x: 0, 61 | y: 0, 62 | attr: TEXT_DEF_ATTRIBUTE, 63 | }, 64 | Screen { 65 | buffer: TEXT_MODE_START + 0x2000, 66 | width: 80, 67 | height: 25, 68 | x: 0, 69 | y: 0, 70 | attr: TEXT_DEF_ATTRIBUTE, 71 | }, 72 | Screen { 73 | buffer: TEXT_MODE_START + 0x2800, 74 | width: 80, 75 | height: 25, 76 | x: 0, 77 | y: 0, 78 | attr: TEXT_DEF_ATTRIBUTE, 79 | }, 80 | Screen { 81 | buffer: TEXT_MODE_START + 0x3000, 82 | width: 80, 83 | height: 25, 84 | x: 0, 85 | y: 0, 86 | attr: TEXT_DEF_ATTRIBUTE, 87 | }, 88 | Screen { 89 | buffer: TEXT_MODE_START + 0x3800, 90 | width: 80, 91 | height: 25, 92 | x: 0, 93 | y: 0, 94 | attr: TEXT_DEF_ATTRIBUTE, 95 | }, 96 | ]; 97 | 98 | static mut SCRN_PAGE: usize = 0; 99 | 100 | pub struct Writer { 101 | page: &'static mut usize, 102 | scrn: &'static mut [Screen; 8], 103 | } 104 | 105 | impl Writer { 106 | pub fn new() -> Self { 107 | unsafe { 108 | Writer { 109 | page: &mut SCRN_PAGE, 110 | scrn: &mut SCRN, 111 | } 112 | } 113 | } 114 | 115 | fn cursor_size(start: u8, end: u8) { 116 | outb(VGA_CRT_CURSTART, VGA_CRT_ADDR); 117 | io_delay(); 118 | outb(start, VGA_CRT_DATA); 119 | io_delay(); 120 | outb(VGA_CRT_CUREND, VGA_CRT_ADDR); 121 | io_delay(); 122 | outb(end, VGA_CRT_DATA); 123 | } 124 | 125 | pub fn cursor_pos(&self) { 126 | let page = *(self.page); 127 | let addr = self.scrn[page].y * self.scrn[page].width + self.scrn[page].x; 128 | Self::cursor_size(1, 0); 129 | io_delay(); 130 | outb(VGA_CRT_CURADDH, VGA_CRT_ADDR); 131 | io_delay(); 132 | outb(((addr >> 8) & 0xFF) as u8, VGA_CRT_DATA); 133 | io_delay(); 134 | outb(VGA_CRT_CURADDL, VGA_CRT_ADDR); 135 | io_delay(); 136 | outb((addr & 0xFF) as u8, VGA_CRT_DATA); 137 | Self::cursor_size(CURSOR_START, CURSOR_END); 138 | } 139 | 140 | pub fn select_page(&mut self, num: usize) { 141 | if num > 8 { 142 | *(self.page) = 7; 143 | } else { 144 | *(self.page) = num; 145 | } 146 | } 147 | 148 | pub fn color(&mut self, attr: u8) { 149 | self.scrn[*(self.page)].attr = attr; 150 | } 151 | 152 | pub fn locate(&mut self, xx: usize, yy: usize) { 153 | let page = *(self.page); 154 | if xx > self.scrn[page].width { 155 | self.scrn[page].x = self.scrn[page].width - 1; 156 | } else { 157 | self.scrn[page].x = xx; 158 | } 159 | 160 | if yy > self.scrn[page].height { 161 | self.scrn[page].y = self.scrn[page].height - 1; 162 | } else { 163 | self.scrn[page].y = yy; 164 | } 165 | } 166 | 167 | pub fn init(&mut self) { 168 | let zero_page = plankton::mem::MemoryRegion::new(0x7C00, 4096); 169 | let xx = zero_page.read_u8(0x00); 170 | let yy = zero_page.read_u8(0x01); 171 | self.locate(xx as usize, yy as usize); 172 | } 173 | 174 | pub fn store(&self) { 175 | let zero_page = plankton::mem::MemoryRegion::new(0x7C00, 4096); 176 | let page = *(self.page); 177 | let xx: u8 = self.scrn[page].x as u8; 178 | let yy: u8 = self.scrn[page].y as u8; 179 | zero_page.write_u8(0x00, xx); 180 | zero_page.write_u8(0x01, yy); 181 | } 182 | 183 | fn xfer_line(src: usize, dst: usize, len: usize) { 184 | let src = unsafe { core::slice::from_raw_parts(src as *mut u16, len) }; 185 | let dst = unsafe { core::slice::from_raw_parts_mut(dst as *mut u16, len) }; 186 | dst.copy_from_slice(src); 187 | } 188 | 189 | fn fill_line(dst: usize, len: usize, data: u16) { 190 | let dst = unsafe { core::slice::from_raw_parts_mut(dst as *mut u16, len) }; 191 | for v in dst { 192 | *v = data; 193 | } 194 | } 195 | 196 | fn fill_char(dst: usize, data: u16) { 197 | let dst = dst as *mut u16; 198 | unsafe { 199 | *dst = data; 200 | } 201 | } 202 | 203 | fn scrollup(&self) { 204 | let mut cnt: usize = 0; 205 | let h = self.scrn[*(self.page)].height; 206 | let w = self.scrn[*(self.page)].width; 207 | let mut dst = self.scrn[*(self.page)].buffer; 208 | let mut src = dst + w * 2; 209 | while cnt < h { 210 | Self::xfer_line(src, dst, w); 211 | src += w * 2; 212 | dst += w * 2; 213 | cnt += 1; 214 | } 215 | Self::fill_line(dst, w, vram_data!(b' ', self.scrn[*(self.page)].attr)); 216 | } 217 | 218 | pub fn clear(&self) { 219 | let h = self.scrn[*(self.page)].height; 220 | let w = self.scrn[*(self.page)].width; 221 | let mut dst = self.scrn[*(self.page)].buffer; 222 | let mut cnt = 0; 223 | while cnt < h { 224 | Self::fill_line(dst, w, vram_data!(b' ', self.scrn[*(self.page)].attr)); 225 | dst += w * 2; 226 | cnt += 1; 227 | } 228 | } 229 | 230 | pub fn putchar(&mut self, ch: u8) { 231 | let page = *(self.page); 232 | let h = self.scrn[page].height; 233 | let w = self.scrn[page].width; 234 | match ch { 235 | b'\n' => { 236 | self.scrn[page].x = 0; 237 | if self.scrn[page].y < (h - 1) { 238 | self.scrn[page].y += 1; 239 | } else { 240 | self.scrollup(); 241 | } 242 | } 243 | 0x08 => { 244 | if self.scrn[page].x > 0 { 245 | self.scrn[page].x -= 1; 246 | let dst = 247 | self.scrn[page].buffer + self.scrn[page].y * w * 2 + self.scrn[page].x * 2; 248 | Self::fill_char(dst, vram_data!(b' ', self.scrn[page].attr)); 249 | } 250 | } 251 | 0x20..=0x7e => { 252 | let ch = ch & 0xff; 253 | let dst = 254 | self.scrn[page].buffer + self.scrn[page].y * w * 2 + self.scrn[page].x * 2; 255 | Self::fill_char(dst, vram_data!(ch, self.scrn[page].attr)); 256 | if self.scrn[page].x < (w - 1) { 257 | self.scrn[page].x += 1; 258 | } else { 259 | self.scrn[page].x = 0; 260 | if self.scrn[page].y < (h - 1) { 261 | self.scrn[page].y += 1; 262 | } else { 263 | self.scrollup(); 264 | } 265 | } 266 | } 267 | _ => {} 268 | } 269 | self.cursor_pos(); 270 | } 271 | } 272 | 273 | impl fmt::Write for Writer { 274 | fn write_str(&mut self, s: &str) -> fmt::Result { 275 | for c in s.bytes() { 276 | self.putchar(c); 277 | } 278 | Ok(()) 279 | } 280 | } 281 | 282 | pub fn _print(args: fmt::Arguments) { 283 | use core::fmt::Write; 284 | let mut writer = Writer::new(); 285 | writer.init(); 286 | writer.write_fmt(args).unwrap(); 287 | writer.store(); 288 | } 289 | 290 | #[macro_export] 291 | macro_rules! print { 292 | ($($arg:tt)*) => { 293 | $crate::text::_print(format_args!($($arg)*)) 294 | }; 295 | } 296 | 297 | #[macro_export] 298 | macro_rules! println { 299 | ($fmt:expr) => { 300 | print!(concat!($fmt, "\n")) 301 | }; 302 | ($fmt:expr, $($arg:tt)*) => { 303 | print!(concat!($fmt, "\n"), $($arg)*) 304 | }; 305 | } 306 | -------------------------------------------------------------------------------- /src/bios/stage_4th/stage_4th.ld: -------------------------------------------------------------------------------- 1 | ENTRY(stage4) 2 | SECTIONS { 3 | . = 0x30000; /* "stage4" will be loaded at phyisical addr */ 4 | .first : { *(.first) } /* Locate "stage4" First Excutable code */ 5 | .text : { *(.text*) } /* Excutable code */ 6 | .rodata : { *(.rodata*) } /* Constants (R/O) */ 7 | .data : { *(.data*) } /* Initialized data */ 8 | _data_end = .; /* The end of .data section */ 9 | .bss : { *(.bss*) } /* Uninitialized data */ 10 | _bss_end = .; /* The end of .bss section */ 11 | /DISCARD/ : { *(.eh_frame*) } 12 | } -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::error::Error; 3 | use std::fs; 4 | use std::io::prelude::*; 5 | use std::io::{self, BufReader, BufWriter, Read, SeekFrom, Write}; 6 | use std::path::{Path, PathBuf}; 7 | use std::process::{Command, Stdio}; 8 | use structopt::StructOpt; 9 | 10 | /// Search for a pattern in a file and display the lines that contain it. 11 | #[derive(StructOpt)] 12 | struct Cli { 13 | #[structopt(parse(from_os_str))] 14 | path: std::path::PathBuf, 15 | #[structopt(short = "w", long = "write")] 16 | pub write: bool, 17 | #[structopt(short = "e", long = "emurate")] 18 | emu: bool, 19 | #[structopt( 20 | short = "d", 21 | long = "debug", 22 | default_value("4"), 23 | possible_values(&["1", "2", "3", "4"]), 24 | )] 25 | pub debug: usize, 26 | } 27 | 28 | type BuildStatus = Option; 29 | #[derive(Debug, Default)] 30 | struct Builds { 31 | stage_1st: BuildStatus, 32 | stage_2nd: BuildStatus, 33 | stage_3rd: BuildStatus, 34 | stage_4th: BuildStatus, 35 | } 36 | 37 | #[derive(Debug, Clone)] 38 | enum SomeError { 39 | InvalidBuildNumber, 40 | NoBIOSBootPartition, 41 | NoEFISystemPartition, 42 | NoDiskImage, 43 | SomeBuildsFailed, 44 | Stage1stOverSize, 45 | Stage2ndOverSize, 46 | Stage3rdOverSize, 47 | Stage4thOverSize, 48 | } 49 | impl std::fmt::Display for SomeError { 50 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 51 | write!(f, "{}", self) 52 | } 53 | } 54 | impl std::error::Error for SomeError {} 55 | 56 | impl Builds { 57 | fn new(root_target_dir: &Path) -> Self { 58 | let stages = ["stage_1st", "stage_2nd", "stage_3rd", "stage_4th"]; 59 | let mut pathes: Vec = Vec::with_capacity(4); 60 | for stage in stages.iter() { 61 | pathes.push( 62 | root_target_dir 63 | .join(stage) 64 | .join(format!("i586-{}", stage)) 65 | .join("release") 66 | .join(format!("{}.bin", stage)), 67 | ); 68 | } 69 | let stage_1st = if pathes[0].exists() { 70 | Some(pathes[0].to_owned()) 71 | } else { 72 | Default::default() 73 | }; 74 | let stage_2nd = if pathes[1].exists() { 75 | Some(pathes[1].to_owned()) 76 | } else { 77 | Default::default() 78 | }; 79 | let stage_3rd = if pathes[2].exists() { 80 | Some(pathes[2].to_owned()) 81 | } else { 82 | Default::default() 83 | }; 84 | let stage_4th = if pathes[3].exists() { 85 | Some(pathes[3].to_owned()) 86 | } else { 87 | Default::default() 88 | }; 89 | Self { 90 | stage_1st, 91 | stage_2nd, 92 | stage_3rd, 93 | stage_4th, 94 | } 95 | } 96 | fn check(&self, d: usize) -> Result<(), Box> { 97 | eprintln!("Checking the first [{}] stage(s) build...", d); 98 | let mut result = true; 99 | for n in 1..=d { 100 | match n { 101 | 1 => result &= self.stage_1st.is_some(), 102 | 2 => result &= self.stage_2nd.is_some(), 103 | 3 => result &= self.stage_3rd.is_some(), 104 | 4 => result &= self.stage_4th.is_some(), 105 | _ => return Err(SomeError::InvalidBuildNumber.into()), 106 | } 107 | } 108 | match result { 109 | false => { 110 | eprintln!("{:?}", self); 111 | Err(SomeError::SomeBuildsFailed.into()) 112 | } 113 | true => { 114 | println!(" Build exists. {:?}", self); 115 | Ok(()) 116 | } 117 | } 118 | } 119 | } 120 | 121 | pub fn diskimg_check(path: &Path) -> Result<(u64, u64), Box> { 122 | println!("Checking partitions..."); 123 | let mut result = (None, None, None, None); 124 | if !path.exists() { 125 | return Err(SomeError::NoDiskImage.into()); 126 | } 127 | let cfg = gpt::GptConfig::new().writable(false); 128 | let disk = cfg.open(path)?; 129 | for (_, value) in disk.partitions().iter() { 130 | if value.part_type_guid.guid.as_bytes() == "21686148-6449-6E6F-744E-656564454649".as_bytes() 131 | { 132 | result.0 = Some(value.first_lba); 133 | result.1 = Some(value.last_lba); 134 | } 135 | if value.part_type_guid.guid.as_bytes() == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B".as_bytes() 136 | { 137 | result.2 = Some(value.first_lba); 138 | result.3 = Some(value.last_lba); 139 | } 140 | } 141 | let result = ( 142 | result.0.ok_or(SomeError::NoBIOSBootPartition)?, 143 | result.1.ok_or(SomeError::NoBIOSBootPartition)?, 144 | result.2.ok_or(SomeError::NoEFISystemPartition)?, 145 | result.3.ok_or(SomeError::NoEFISystemPartition)?, 146 | ); 147 | println!( 148 | " BIOS boot partition: start = {}, end = {}\n EFI System Partition: start = {}, end = {}", 149 | result.0, result.1, result.2, result.3 150 | ); 151 | Ok((result.0, result.1)) 152 | } 153 | 154 | fn write_into_disk( 155 | disk_path: &Path, 156 | builds: &Builds, 157 | bbp: (u64, u64), 158 | debug: usize, 159 | ) -> Result<(), Box> { 160 | println!("Burn each stage to disk...."); 161 | let output = fs::OpenOptions::new() 162 | .write(true) 163 | .truncate(false) 164 | .open(disk_path)?; 165 | let mut writer = BufWriter::new(&output); 166 | let default_sizes = 512; 167 | let mut total_sector_size: u64 = 0; 168 | 169 | // write stage_1st into disk 170 | if let Some(stage_1st) = &builds.stage_1st { 171 | print!(" stage_1st..."); 172 | if 446 < fs::metadata(stage_1st)?.len() { 173 | return Err(SomeError::Stage1stOverSize.into()); 174 | } 175 | let input = fs::File::open(stage_1st)?; 176 | let buf = BufReader::new(input) 177 | .bytes() 178 | .collect::>>()?; 179 | writer.seek(SeekFrom::Start(0))?; 180 | writer.write_all(&buf)?; 181 | println!(" done.") 182 | } 183 | 184 | // write stage_2nd into disk, if it exists 185 | if let Some(stage_2nd) = &builds.stage_2nd { 186 | if debug < 2 { 187 | return Ok(()); 188 | } 189 | print!(" stage_2nd..."); 190 | let stage2_ssize = fs::metadata(stage_2nd)?.len() / default_sizes + 1; 191 | if bbp.1 < bbp.0 + total_sector_size + stage2_ssize { 192 | return Err(SomeError::Stage2ndOverSize.into()); 193 | } 194 | // write stage2 size and bbp start sector as parameter 195 | writer.seek(SeekFrom::Start(442))?; 196 | writer.write_all(&(stage2_ssize as u16).to_le_bytes())?; 197 | writer.seek(SeekFrom::Start(444))?; 198 | writer.write_all(&(bbp.0 as u16).to_le_bytes())?; // bbp start sector size 199 | // write stage_2nd.bin 200 | writer.seek(SeekFrom::Start(bbp.0 * default_sizes))?; 201 | for result in BufReader::new(fs::File::open(stage_2nd)?).bytes() { 202 | let byte = result?; 203 | writer.write_all(&[byte])?; 204 | } 205 | total_sector_size += stage2_ssize; 206 | println!(" done"); 207 | } 208 | 209 | // write stage_3rd into disk, if it exists 210 | if let Some(stage_3rd) = &builds.stage_3rd { 211 | if debug < 3 { 212 | return Ok(()); 213 | } 214 | print!(" stage_3rd..."); 215 | let stage3rd_ssize = fs::metadata(stage_3rd)?.len() / default_sizes + 1; 216 | if bbp.1 < bbp.0 + total_sector_size + stage3rd_ssize { 217 | return Err(SomeError::Stage3rdOverSize.into()); 218 | } 219 | 220 | // write stage3 start sector position 221 | writer.seek(SeekFrom::Start(bbp.0 * default_sizes))?; 222 | writer.write_all(&((total_sector_size + bbp.0) as u16).to_le_bytes())?; 223 | // write stage3 sector size as a parameter 224 | writer.seek(SeekFrom::Start(bbp.0 * default_sizes + 2))?; 225 | writer.write_all(&(stage3rd_ssize as u16).to_le_bytes())?; 226 | // write stage_3rd.bin 227 | writer.seek(SeekFrom::Start((bbp.0 + total_sector_size) * default_sizes))?; 228 | for result in BufReader::new(fs::File::open(stage_3rd)?).bytes() { 229 | let byte = result?; 230 | writer.write_all(&[byte])?; 231 | } 232 | total_sector_size += stage3rd_ssize; 233 | println!(" done"); 234 | } 235 | 236 | // write stage_4th into disk, it it exists 237 | if let Some(stage_4th) = &builds.stage_4th { 238 | if debug < 4 { 239 | return Ok(()); 240 | } 241 | print!(" stage_4th..."); 242 | let stage4th_ssize = fs::metadata(stage_4th)?.len() / default_sizes + 1; 243 | if bbp.1 < bbp.0 + total_sector_size + stage4th_ssize { 244 | return Err(SomeError::Stage4thOverSize.into()); 245 | } 246 | // write stage4 sector size as a parameter 247 | writer.seek(SeekFrom::Start(bbp.0 * default_sizes + 4))?; 248 | writer.write_all(&(stage4th_ssize as u16).to_le_bytes())?; 249 | // write stage_4th.bin 250 | writer.seek(SeekFrom::Start((bbp.0 + total_sector_size) * default_sizes))?; 251 | for result in BufReader::new(fs::File::open(stage_4th)?).bytes() { 252 | let byte = result?; 253 | writer.write_all(&[byte])?; 254 | } 255 | println!(" done"); 256 | } 257 | writer.flush()?; 258 | Ok(()) 259 | } 260 | fn run_emu(disk_path: &Path) -> Result<(), Box> { 261 | println!("Try qemu..."); 262 | let mut qemu = Command::new("qemu-system-x86_64") 263 | .arg("--hda") 264 | .arg(disk_path) 265 | .arg("-m") 266 | .arg("1G") 267 | .stdout(Stdio::null()) 268 | .stderr(Stdio::null()) 269 | .spawn()?; 270 | qemu.wait()?; 271 | Ok(()) 272 | } 273 | fn main() -> Result<(), Box> { 274 | // Prepare 275 | let manifest_dir_path = 276 | env::var("CARGO_MANIFEST_DIR").expect("Missing CARGO_MANIFEST_DIR environment variable"); 277 | let manifest_dir = Path::new(&manifest_dir_path); 278 | let current_dir = env::current_dir().expect("Couldn't get current directory"); 279 | let target_dir_rel = manifest_dir.join("target"); 280 | let target_dir = current_dir.join(target_dir_rel); 281 | let builds = Builds::new(&target_dir); 282 | 283 | // main start 284 | let args = Cli::from_args(); 285 | let disk_path = &args.path; 286 | 287 | // check builds and patitions. 288 | if args.debug > 0 { 289 | // check build status 290 | builds.check(args.debug)?; 291 | // check disk status 292 | let bbp = diskimg_check(disk_path)?; 293 | // if above all is ok, let's write binaries into the disk 294 | if args.write { 295 | write_into_disk(disk_path, &builds, bbp, args.debug)?; 296 | } 297 | } 298 | 299 | if args.emu { 300 | run_emu(disk_path)?; 301 | } 302 | Ok(()) 303 | } 304 | --------------------------------------------------------------------------------