Skip to content
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

Bootloader incorrectly marks up the memory occupied by itself #468

Closed
mrjbom opened this issue Oct 29, 2024 · 9 comments
Closed

Bootloader incorrectly marks up the memory occupied by itself #468

mrjbom opened this issue Oct 29, 2024 · 9 comments

Comments

@mrjbom
Copy link

mrjbom commented Oct 29, 2024

Trying to figure out why I can't initialize the allocator for ISA DMA memory, I found that I don't have any usable memory in the first 16 MB.

log::info!("Used by kernel: 0x{:x} {}", boot_info.kernel_addr, boot_info.kernel_len);
log::info!("Memory map: {:#x?}", boot_info.memory_regions.iter());

That's what data I get:

Used by kernel: 0x1000000 2865032
...
MemoryRegion {
            start: 0x100000,
            end: 0x12ff000,
            kind: Bootloader,
        }
...

0x12ff000 - 0x100000 = 0x11ff000(18870272)
18 MB from first MB used by bootloader
I doubt that the bootloader has placed so much data in this region. It looks like the memory map is incorrect.

Bootloader on stage 4 contains this memory map

...
E820MemoryRegion {
    start_addr: 0x100000, 
    len: 0x7ee0000, ~128 MB
    region_type: 0x1, Usable
    acpi_extended_attributes: 0x0,
}
...

Bootloader places something incredibly large in this 16 megabytes

I dug into the bootloader's code and found that last_used_addr when initializing LegacyFrameAllocator is 0x12bd000, it seems that even before creating the allocator, the first 18 megabytes are occupied with something.

@bjorn3
Copy link
Contributor

bjorn3 commented Oct 29, 2024

Maybe a stupid question, but how big is your kernel binary?

@mrjbom
Copy link
Author

mrjbom commented Oct 29, 2024

Maybe a stupid question, but how big is your kernel binary?

The size of the elf kernel file exactly corresponds to boot_info.kernel_len: 2865032

@mrjbom
Copy link
Author

mrjbom commented Oct 30, 2024

This memory also cannot be occupied by page tables, since I am running qemu with 128 megabytes.
Disabling mapping of all physical memory also does not affect the occupancy of this area.

@mrjbom mrjbom changed the title Memory occupied by the kernel is not consistent with the memory map Bootloader takes up an abnormally large amount of memory Oct 30, 2024
@mrjbom
Copy link
Author

mrjbom commented Oct 30, 2024

I think I found a bug that makes the first 16 megabytes disappear.
I investigated bios stage2 and saw that info.last_used_addr is always above 16 MB, and since info.last_used_addr is used as next_free_frame in frame_allocator, when LegacyFrameAllocator::construct_memory_map is called, the whole chunk from 0x100000 (1 MB) to next_free (which is always above 16 MB because of this line”) will be marked as used by bootloader.

Thus the first 16 MB are always marked as occupied by the bootloader, which not only wastes memory but also makes it impossible to allocate memory for DMA.

Also bootloader freezes if physical memory size is less than 16 + kernel_size or something, probably it's related.
Anyway, this code always(if the region from 0x100000 is larger than the kernel (which is almost always the case)) marks the region 0x100000 to (16 MB + kernel_size)] as occupied by bootloader, although it is not.

@mrjbom mrjbom changed the title Bootloader takes up an abnormally large amount of memory Bootloader incorrectly marks up the memory occupied by itself Oct 30, 2024
@bjorn3
Copy link
Contributor

bjorn3 commented Oct 31, 2024

but also makes it impossible to allocate memory for DMA.

Why is that? DMA should work fine everywhere in the address space where RAM is mapped in the first place.

@mrjbom
Copy link
Author

mrjbom commented Oct 31, 2024

DMA should work fine everywhere in the address space where RAM is mapped in the first place.

Since the first 16 megabytes are always marked as occupied by the bootloader, I simply cannot know which of these addresses are really free and can be used by me to allocate memory for ISA DMA needs.

@bjorn3
Copy link
Contributor

bjorn3 commented Oct 31, 2024

Ah, this is for ISA DMA. I figured you wanted PCI DMA, which even for old devices should work everywhere in the first 4GB. I agree that the bootloader should be fixed.

@Freax13
Copy link
Member

Freax13 commented Oct 31, 2024

I can't reproduce this on the main branch. I think this issue was fixed by #446 (even though the PR title doesn't mention 16MiB). Could you please test on main and see if the memory map still doesn't contain usable memory in the ISA DMA range? If this issue has already been fixed, we can do a patch release.

@mrjbom
Copy link
Author

mrjbom commented Oct 31, 2024

@Freax13, You are correct, it has been fixed in the main branch! Nice work!

@mrjbom mrjbom closed this as completed Oct 31, 2024
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

No branches or pull requests

3 participants