19 ms·
Booting to 'Hello Rust' on x86_64
- micouay 6y agoIt's my first post. I'd appreciate your feedback :)
- messe 6y agoHey, just a couple of points 1. Don't link the bootsector and the rest of your binary together. It's more trouble than it's worth, and if you ever progress to loading off a filesystem, then you won't be linking them together anyway. 2. You can use LBA addressing in real mode with int 13h (just specify a hard disk rather than a floppy when booting): https://wiki.osdev.org/ATA_in_x86_RealMode_(BIOS)#LBA_in_Extended_Mode https://wiki.osdev.org/ATA_in_x86_RealMode_(BIOS)#LBA_in_Ext... 3. You need to switch to protected mode, set up paging, and then enter long mode. 4. I'd recommend compiling your rust code to an ELF binary, and then using objcopy to create a binary: objcopy -O binary $input.elf $output.bin Alternatively, ELF isn't that hard to parse, so you could load it yourself and then copy sections to the right locations with your bootsector. 5. OSDev.org is your friend. Maybe get a C-based kernel running first, as the toolchain when dealing with freestanding code is a lot friendlier for beginners - https://wiki.osdev.org/Protected_Mode https://wiki.osdev.org/Protected_Mode - https://wiki.osdev.org/Long_Mode#Long_Mode https://wiki.osdev.org/Long_Mode#Long_Mode You might be better off starting with 32-bit rust code instead, in order to avoid paging and long mode at first (you'll still need to switch to protected mode)
- steveklabnik 6y agoI am extremely biased, but I’ve always found the rust tool chain far easier than the C ones, especially as a Windows user. No need to set up a cross compiler, given that rustc already is one, and is easy to add more targets to via the JSON target spec.
- messe 6y agoA cross compiler is easy enough to set up with clang too (just specify the -target command line option). I just think that when starting out in kernel development, you're likely going to be dealing with linker scripts for likely the first time. It's been a while since I tried rust for this, but C generates pretty clean object files, so the linker scripts from the OSDev wiki can often be copied verbatim.
- steveklabnik 6y agoThat’s fair re:clang, seems like gcc is used way more often in tutorials. I don’t think that the linker script stuff ends up different but it’s been a minute since I started from scratch.
- micouay 6y agoThanks! 1. I have a Makefile that links it for me so I don't have to do anything special. I intend the Rust program to work like a second stage bootloader. I'm going to experiment with it and try to get a file system working to load an actual kernel from a file. 2. I'll look into that. 3. That's what the bootloader does. Sorry if I wasn't clear. 4. If I understand correctly if I compile my Rust project to a binary (which is a default output and I don't really understand why I would use objcopy for that) I won't be able to link with with the bootloader. I link them to allow the bootloader to jump to the _start function at the correct address. 5. My Rust program already works in 64-bit so I don't see a reason to change it. In this project I want to explore low level programming and understand things like paging. I appreciate your feedback.
- saagarjha 6y ago(Hacker News likes two eat single newlines. Try using two.)
- steveklabnik 6y agoFull reference here: https://news.ycombinator.com/formatdoc https://news.ycombinator.com/formatdoc
- kens 6y agoInteresting post. I apologize for this feedback but there's a typo "begginer" in the first paragraph. Also "form 1970s" should be "from".
- sowbug 6y agoI think there's a typo in the final screenshot. It looks like your original code outputs "RM" (maybe "real mode" or "hello Rust" in a different language?), but the example source seems like it should output "HR." That or I'm very confused.
- spencerwgreene 6y agoThe HR is in the top left, it overwrites the pre-initialized text console.
- sowbug 6y agoThanks, I see it now!
- micouay 6y agoSorry for that. I thought it would be visible enough in red. RM, LM and PM were printed by the bootloader.
- kgraves 6y agoThis post got me extremely excited, will have a read on the way home! great job OP!
- micouay 6y agoThank you so much!
- ajross 6y agoFor those checking comments first: this is mostly a tutorial on how to build and link a 16/32 bit MBR loader and mode switch implementation in assembly. It's very similar to what you'll find on osdev.org. The Rust content is limited to a single function at the end which writes some characters to an assumed-pre-initialized EGA text console. While modern hardware does continue to support these modes via various detection tricks, "real" handoff from the firmware happens in a 64 bit EFI environment these days, and the framebuffer tends to be in a graphics mode and expects to be accesesed initially via the exposed UEFI API (or to be reset from scratch by an OS graphics driver, of course). This is fun and instructive, but not really reflective of the way modern hardware boots.
- javajosh 6y agoI'm curious to learn more about "real" handoffs and the EFI environment. If you had any suggestions about where to start I'd be grateful.
- ajross 6y agoThere's sort of a paucity of tutorials in that space. You're pretty much stuck reading specs and studying source code. Here's the UEFI specification and a link to the "gnu-efi" project, which provide a reasonably clean (if... idiosyncratic) environment for building and running EFI binaries with a free toolchain: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8... https://sourceforge.net/projects/gnu-efi/ https://sourceforge.net/projects/gnu-efi/ Broadly: EFI is a simple C environment (albeit one based on windows-style PE binaries and not ELF). The firmware will load and run your application binary and jump to its entry point, passing a giant table of API hooks and callbacks for you to use to interact with its services. You then read and assemble your own OS image using these tools and jump into it.
- sjtindell 6y agoThanks for sharing on HN.
- 6y ago
- secondcoming 6y agoI did something similar many years ago using nothing but debug.exe that came with windows 95, a spare floppy and an older version of The Indispensible PC Hardware Book [0]. It was very satisfying seeing my PC boot to printing my name. [0] https://www.amazon.co.uk/Indispensable-PC-Hardware-Book/dp/0201596164 https://www.amazon.co.uk/Indispensable-PC-Hardware-Book/dp/0...
- azhenley 6y agoA relevant tutorial on making an OS in Rust but for RISC-V: http://osblog.stephenmarz.com/index.html http://osblog.stephenmarz.com/index.html
- Tainnor 6y agoI really appreciate posts like this and wish there were more of them. Tutorials by experts are valuable, but I also find it comforting to read that other people are sometimes as clueless as I am, and I think posts like this can end up explaining some of the pitfalls that some more expert users aren't really aware of. We need more humility in software. (I remember that I had tried to write a bootloader myself in assembler, maybe 10 years ago or so, and in the end was just incapable of getting it to work.)
- micouay 6y agoThank you! I also wish there was more content like this.
- eloisius 6y agoNeat! I read The little book about OS development[1] and wrote this little OS in Rust a few years ago: https://github.com/zacstewart/tinyos https://github.com/zacstewart/tinyos 1: https://littleosbook.github.io/ https://littleosbook.github.io/
- blargmaster33 6y agoGod Rusts syntax is off-putting.
- ggcr3ss 6y agoThank you for this!
- micouay 6y agoI'm glad you like it.
- ekidd 6y agoIf anybody enjoys this and wants to take it much further, you might want to check out https://os.phil-opp.com/ https://os.phil-opp.com/. This is basically a book-in-progress that shows how to build an OS in Rust OS from scratch. It shows how boot up an OS, and it goes on to show how to set up basic drivers and memory management. He does a great job of explaining each step as he goes. (This is linked near the end of the article, but I think it's worth pointing out.) Full disclosure: I think he uses a library I wrote to initialize the keyboard controller.
- historyremade 6y agoBoot to "FUCK RUST PROPAGANDA"