Skip to content

Transitioning from bootimage to the new system #150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ethindp opened this issue Apr 19, 2021 · 18 comments · Fixed by #166
Closed

Transitioning from bootimage to the new system #150

ethindp opened this issue Apr 19, 2021 · 18 comments · Fixed by #166

Comments

@ethindp
Copy link
Contributor

ethindp commented Apr 19, 2021

So, my kernel still uses the old bootimage building system, but that's now deprecated. However, I don't know how to (safely) transition from the old to the new system. So how do I go about doing this?

@phil-opp
Copy link
Member

Bootimage is not deprecated yet, it's just that the newest bootloader version uses a different build approach (documented here. I'm currently working on updating the Writing an OS in Rust blog for the new version and I plan to create a migration guide too. The fundamental differences are:

  • New build system instead of bootimage.
  • Pixel-based framebuffer instead of VGA text buffer.
  • When using the new UEFI support, you need to use the APIC since the legacy PIC is no longer supported.

@ethindp
Copy link
Contributor Author

ethindp commented Apr 19, 2021 via email

@ethindp
Copy link
Contributor Author

ethindp commented Apr 26, 2021

Update: so I just re-read the documentation and it makes a bit more sense, but it still raises some questions, e.g.: where do I get "cargo-builder"? How do you go about writing one if that's necessary? (I was thinking of using something like cargo-make to automate that process a bit as well.)

@phil-opp
Copy link
Member

cargo builder is an alias command defined in the .cargo/config.toml of the bootloader, so it is automatically available in the bootloader dir without installing anything.

@ethindp
Copy link
Contributor Author

ethindp commented Apr 30, 2021

Oh, okay, I understand. Thank you!

@ethindp ethindp closed this as completed Apr 30, 2021
@ethindp
Copy link
Contributor Author

ethindp commented Apr 30, 2021

So I have one more question and then I should (maybe?) understand this properly. I'll give it a test drive at least. :-) For my config, I have:

[unstable]
build-std = ["core", "compiler_builtins", "alloc"]

[build]
target = "x86_64-kernel-none.json"

[target.'cfg(target_os = "none")']
runner = "bootimage runner"

And for my target config, I have:

{
"llvm-target": "x86_64-kernel-none",
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"disable-redzone": true,
"features": "-mmx,-sse,+soft-float"
}

Do I alter the config.toml to look like so:

[unstable]
build-std = ["core", "compiler_builtins", "alloc"]

[build]
target = "x86_64-kernel-none.json"

And keep the target JSON and then run cargo build? So my build process, were I to automate it, might look like this?

  1. cargo build
  2. cargo metadata kernel (and find bootloader as a direct dependency and not a subdependency of any libraries that my main package pulls in)
  3. cd $bootloader_path
  4. cargo builder <args>

If so, I could probably automate this with cargo-make. Not really sure how but that would be really nice.

@ethindp ethindp reopened this May 1, 2021
@JonahPlusPlus
Copy link

@ethindp Maybe this is what you want: https://gist.github.com/JonahHenriksson/f037c778881918ac57ee131e0a045735
Tried automating this with cargo make, but it was really nasty. I wanted to separate the builder command into its own task, but working with environment variables didn't work. Finally got something that works, but requires you to set some of your own project specific variables. The bootimage tool was definitely easier to automate, but I'm happy to see UEFI support.

@JonahPlusPlus
Copy link

@phil-opp Hey, how do we use the framebuffer? I tried writing to it, but get nothing. Is there something I need to enable or set before using it? Where would I go to learn more? The UEFI spec?

@phil-opp
Copy link
Member

@JonahHenriksson Writing to the memory area reported by the boot info should work. If it doesn't, that would be a bug.

I also wanted to say sorry about the missing documentation around the new build system. I thought I would get to this earlier, but the latst few weeks have been busy for me. I try to create a small example for the build crate in the next few days.

@ethindp
Copy link
Contributor Author

ethindp commented May 16, 2021 via email

@phil-opp
Copy link
Member

The framebuffers that bootloader v0.10 sets up are pixel-based (on both UEFI and BIOS systems). This means that you can (and need to) control each individual pixel, there is no such thing as the ASCII-aware VGA text buffer anymore. So to display text, you need to render it to pixels first. You can do that using full TTF rendering, or you can use some simpler bitmap font such as font8x8.

@ethindp
Copy link
Contributor Author

ethindp commented May 21, 2021

I didn't notice this until now -- thanks for that information! So, say I want to render the string "Hello!" using fontdue. So, would I do the following?

  1. I create a layout and append text to it.
  2. I get the glyphs from the font
  3. I loop through each glyph and... write what exactly to the framebuffer? Relevant information is over here.

I've never done font rendering before so I've no idea what to do.

@phil-opp
Copy link
Member

@ethindp I haven't worked with fontdue yet, so I don't know any specifics. However, there are typically two high-level steps in font rendering: determining where the glyphs should be placed (e.g. dependent on the spacing between glyphs) and rendering each glyph. The GlyphPosition struct you linked looks like it's related to the first step. For the second step, you probably need something like the rasterize method. This outputs a bitmap, which is a two-dimensional array that contains the alpha value (0-255) for each pixel. By combining this alpha with the color of your choice, you can calculate the pixel values that you need to set in the framebuffer.
Hope this helps!

@JonahPlusPlus
Copy link

Lol, came back to work on my OS project after finishing up my school work, and now I see what I did. I iterated though the range of the buffer, instead of the buffer itself, setting those values instead... 🤦‍♂️

@ethindp
Copy link
Contributor Author

ethindp commented Jun 12, 2021

@JonahHenriksson Your makefile is (sort-of) working. Its just not building the script properly -- cargo apparently still has that bug where it builds everything with the target specified in .cargo/config.toml. Removing that (sort-of) fixes the problem (though you then need to annotate each cargo command with --target) but then it fails to build the script because of -Z build-std.

@ethindp
Copy link
Contributor Author

ethindp commented Jun 13, 2021

So I got it to work and its booting (sort-of).
@phil-opp You mentioned 8x8 bitmap fonts. If I use font8x8 (I was looking at the docs a few minutes ago at time of writing) what is the process for rendering a character via the framebuffer? I've done a lot of thinking and think that 8-bit fonts might be easier for now.

@PatchMixolydic
Copy link

Are there plans for a definitive migration guide from bootloader 0.9 to 0.10?

@phil-opp
Copy link
Member

phil-opp commented Jan 2, 2023

We now have migration guides available at https://github.com/rust-osdev/bootloader/tree/main/docs/migration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants