[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Would a cleanup+extending of docs/multiboot.h be acceptable?

From: Goswin von Brederlow
Subject: Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
Date: Fri, 08 Apr 2011 19:18:59 +0200
User-agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE)

"Vladimir 'φ-coder/phcoder' Serbinenko" <address@hidden> writes:

> On 08.04.2011 16:43, Goswin von Brederlow wrote:
>> "Vladimir 'φ-coder/phcoder' Serbinenko" <address@hidden> writes:
>>> On 07.04.2011 19:32, Goswin von Brederlow wrote:
>>>> I see that you have added 32bit MIPS support. No 64bit x86_64 support
>>>> though. So my trampoline + 64bit kernel stuff would still be interesting
>>>> to people.
>>> We already have the needed infrastructure to load in 64-bit mode. Have a
>>> look at loader/i386/bsd.c. Mostly you just need to use
>>> grub_relocator64_boot and not grub_relocator32_boot. The main issue is
>>> clear specification of intended behaviour.
>> I'm adding an implementation of this to kvm, proof of concept kind of
>> way. For that I'm assuming the following changes to the specs:
>> // Why is this in steps of 4?
> Because the lower 2 bits pertain to the number of bits on platform.
> 0 -> 32
> 1 -> 64
> 2 -> 16
> 3 -> everything else

Ok, so I should be using

#define MULTIBOOT_NUMBITS_32   0
#define MULTIBOOT_NUMBITS_64   1
#define MULTIBOOT_NUMBITS_16   2


> Are you familiar with mips? Unlike on x86, mips32 and mips64 don't refer
> to different modes but mips32 is a subset of mips64. So unless you're
> familiar with mips, leave this part out for now.

I looked at mips a while back but not in enough detail to implement any
bootloader parts. I know mips is a lot cleaner so it might not even be
worth having a destinction between 32bit and 64bit there.

>> All structures remain as they are. That means that addresses must be
>> below 4GB (maybe even 2GB or sign extention screws things up) unless
>> they are defined as 64bit (memory mappings use 64bit, entry point only
>> 32bit). The kernel + modules must be loaded below 4GB (2GB?).
> No. For 64-bit mode all fields must be extended to 64-bit and kernel and
> modules can be loaded anywhere


Sure it is a restriction to limit kernel+module to the lower 4GB. But
would it be a limiting restriction? Assuming we stick with the P=V
mapping declaring a kernel location above 4GB would require the host or
virtual machine to have more than 4GB physical ram to load the kernel at
all. That would still be a serious restriction for any kernel. And we
would need a variable amount of page tables to map far enough for the
kernel to be loaded. We would also need to first load the kernel below
4GB and then relocate it above 4GB after we switched. All complications
I think we don't need.

For addresses over 4GB to make any sense I think we would have to
specify that the kernel will be loaded at a virtual address with V != P
mapping and something like

struct virt_map_entry {
  multiboot_uint64_t virt_base;
  multiboot_uint64_t phys_base;
  multiboot_uint64_t size;

struct multiboot_tag_virt_map
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  struct virt_map_entry entry[0]; /* sorted by virt_base */

struct multiboot_tag_phys_map
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  struct virt_map_entry entry[0]; /* sorted by phys_base */

Assuming continious pages (xen doesn't always have them for example) the
bootloader would then normaly come with 2 map entries. One for the
kernel+module and one for the boot infos. Maybe a third for the active
gdt+page tables if they aren't merged with the boot infos segment. This
would tell the kernel which virtual and physical address ranges are in
use and which are safe to use.

Overall this would make things more complicated so it might be best to
make this optional, only when a MULTIBOOT_HEADER_TAG_VIRTUAL is
requested. Without the tag the 4GB limit would be imposed and 1:1
mapping would be used.

Next: I would rather not have different structures for 32bit and
64bit. That would mean bootloader have to create the structures
differently depending on the number of bits of the kernel. It would be
easy to define all structures suitable for 64bit and declare the upper
32bit reserved (=zero) for 32bit use.

I also noticed you have multiboot_header_tag_address and
multiboot_header_tag_entry_address. Won't they allways appear as pair?
Why seperate the entry address into its own tag?

>> The system state when leaving the bootloader is like in 32bit but
>> modified as follows:
>> - PAE is enabled
>> - Paging is enabled
>> - Long mode is enabled
>> - Long mode is active
>> - CS contains a 64bit code segment
>> - the lower 4GB of memory are mapped 1:1 accessible R/W to Ring 0 and in
>>   2MB granularity
> I would rather make it "all segments reffered to in memory map are P=V

I'm not sure how to parse that. It also lacks the detail that only some
(or more than) the physical memory will be mapped. Before accessing ram
above 4GB the kernel has to install its own page tables. There would be
a static page table consisting of 6 pages. We could even define that the
6 pages must be continious with cr3 pointing at the first page. No
multiboot_tag_page_tables needed then. The extra tag would be more
flexible though.

> mapped". It may be good to specify where page table is to be located to
> ease avoiding overwriting it.

See multiboot_tag_page_tables below.

>> I'm tempted to add 2 new info tags: multiboot_tag_gpt and
> This would be a separate proposal. I think it would be better to have a
> tag for partition start and end byte rather than the partition number.

Sorry, I ment GDT here. The descriptor table. In 32bit mode it is
currently defined that the GDT is invalid and kernels have to load their
own before loading any segment register. The multiboot_tag_gdt would
contain the gdt the bootloader has activated and make it valid.

>> multiboot_tag_page_tables. The later would contain the number of tables
>> and an array of pointers to the pages. But that might be too i386/x86
>> specific.
> This information is available through cr registers.

The L4 page table is in the register and then you have to go and decode
the entries one by one, looping over the table and recursing into sub
tables. So not quite trivial while you have no stack, no gdt, no idea
where free space is ...

struct multiboot_tag_page_tables
  multiboot_uint32_t type;
  multiboot_uint32_t size;
  multiboot_uint64_t pages[0];

A tag with a simple array of the pages in use should be easier to
handle than having to decode the tables. With a P != V mapping the
physical pages might also not be mapped or mapped to a different virtual
address making decoding impossible or nearly so.

>> MfG
>>         Goswin


PS: Nobody is using multiboot2 productively yet, right? Otherwise it
would be too late to change the 32bit structures.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]