> Note that we need to clone the iterator because the order of areas in the memory map isn't specified.
Could you elaborate on that? I'm probably getting something wrong, but I can't reproduce issues omitting the clone:
{% raw %}
> Note that we need to clone the iterator because the order of areas in the memory map isn't specified.
Could you elaborate on that? I'm probably getting something wrong, but I can't reproduce issues omitting the clone:
The `clone` is required because the min_by function consumes the iterator. I updated that sentence. My initial reasoning was that we can't just use the next area in the iterator because Multiboot doesn't specify an increasing ordering. Thus we need to use `min_by` and clone the iterator.
Later you are identity mapping the VGA buffer address..but in the frame allocator allocate_frame() function you are not pointing that out...may be some time later when you allocate more frames...it may be allocated to some other page...
Good catch! Fortunately it is part of the memory hole below the 1MiB mark. Thus it is never allocated by the frame allocator.
if let Some(area) = self.current_area {
produces a `if let` arms have incompatible types [E0308] for me. (expected type `_` found type `()`.
is this due to my rust version (rustc 1.11.0-nightly (0554abac6 2016-06-10)? :o
EDIT:
i found my error!
// `frame` was not valid, try it again with the updated `next_free_frame`
self.allocate_frame();
should be ->
// `frame` was not valid, try it again with the updated `next_free_frame`
return self.allocate_frame();
in my own code of course :)
These articles of yours are very good: I'm following them in C because they are better than any C tutorial I have yet found. However, I ran into a small problem with this one. In your Multiboot crate you define the ELF symbols tag as having 3 32 bit integers where the multiboot specification pdf you link to specifies 4 16 bit integers. The layout in your crate seems to be correct though, because I defined a struct in C (using __attribute__((packed))) according to the pdf and it did not work, but when I mirrored your layout it did.
Thanks for the nice words :). Honestly, I'm not quite sure about this. It's been a while since I wrote this code…
The multiboot specification (PDF) says:
This tag contains section header table from an ELF kernel, the size of each entry, number of entries, and the string table used as the index of names. They correspond to the ‘shdr_*’ entries (‘shdr_num’, etc.) in the Executable and Linkable Format (elf) specification in the program header.
So the `shdr_` entries are just the entries of the ELF header. The problem is that the multiboot specification uses 32-bit elf files implicitly, but our kernel is a 64-bit elf. There seem to be some format differences… However, the ELF64 specification (PDF) uses u16s too…
In the Readme of the multiboot2 crate I wrote:
Note that this format differs from the description in the Multiboot specification because if seems to be wrong for ELF 64 kernels: The number of entries, entry size, and string table fields seem to be u32 instead of u16 (but I'm not sure on this).
So I wasn't even sure on this when I wrote it :D.
I did some digging in the GRUB2 source and found the definition of `multiboot_tag_elf_sections`. Like the multiboot2 crate, it uses 3 u32s. So it seems like the crate is correct.
When I get to the part when we're getting the kernel start and end, I'm getting a triple fault and the OS is stuck in a bootloop. This is my Bochs log https://gist.github.com/Red...
Hmm, I don't use Bochs, but according to this page of the Bochs user manual it seems to be a “no atapi cdrom found“ error. I have no idea why it occurs though… Does it work in QEMU?
Could we not use the start_address() and end_address() that are available in the BootInformation instead of doing the address calculation ourselves?
let multiboot_start = boot_info.start_address();
let multiboot_end = boot_info.end_address();
Hi! Your link for "re-export" under the section "Testing it" is broken.
Are you supposed to do something with the instruction "In order to test it in main, we need to re-export the AreaFrameAllocator in the memorymodule." ?
I keep getting this error:
"Could not find AreaFrameAllocator in memory "
in src/lib.rs on this row:
let mut frame_allocator = memory::AreaFrameAllocator::new(...
Hi (again)! I just found the code to add to fix my problem. Perhaps you can add it to your blog post?
From this commit I added the new lines from the file mod.rs:
There is some interesting discussion on reddit.