* Would a cleanup+extending of docs/multiboot.h be acceptable?
@ 2011-04-07 12:09 Goswin von Brederlow
2011-04-07 12:56 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 1 reply; 10+ messages in thread
From: Goswin von Brederlow @ 2011-04-07 12:09 UTC (permalink / raw)
To: The development of GNU GRUB
Hi,
I've been working on a 32bit->64bit trampoline based on the example
kernel that just switches to 64bit mode and executes a real kernel
passed as module. As real kernel I want to use grubs example kernel as
well to just verify the multiboot infos passed through the trampoline
are intact.
And there I hit a problem. The docs/multiboot.h does not use the types
set out in the multiboot specs:
typedef struct multiboot_header
{
unsigned long magic;
unsigned long flags;
unsigned long checksum;
...
All of those should be u32. But long is 32bit on 32bit cpus and 64bit on
64bit cpus.
Since I want to reuse the multiboot specs for 64bit as much as possible
I would like to change the code like this:
typedef unsigned int u32;
typedef struct multiboot_header
{
u32 magic;
u32 flags;
u32 checksum;
...
I would also like to expand the multiboot.h file to cover the full specs
and #define all the bits and masks and not just those used in the
example. Basically join the stage2/mb_header.h and stage2/mb_info.h (and
replace 'unsigned *' types with 'u*'). That way the multiboot.h would be
better reusable for people implementing their own multiboot compliant
bootloader or kernel.
Would a change like that be acceptable? If so I could provide patches
for further review. Otherwise I won't bother and just make my own
multiboot.h file.
Also would you be interested in the 32->64bit trampoline and 64bit
example kernel for inclusion in grub?
The trampoline is based on the example kernel with a few lines added to
boot.S and kernel.c to jump to 64bit mode and call the 64bit entry
point. The 64bit kernel needs some changes to kernel.c (varargs for
printf), which I think can be made to work for 32bit and 64bit, and a
boot64.S similar to boot.S but rewritten for 64bit.
What I propose would be to have boot.S, boot64.S and kernel.c with some
#ifdef lines to switch between 32bit kernel, 32bit->64bit trampoline and
64bit kernel mode.
MfG
Goswin
PS: It is still work-in-progress but I can already execute the 64bit
kernel and everything works but printf (varargs issue I believe).
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-07 12:09 Would a cleanup+extending of docs/multiboot.h be acceptable? Goswin von Brederlow
@ 2011-04-07 12:56 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-07 14:50 ` Goswin von Brederlow
0 siblings, 1 reply; 10+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-04-07 12:56 UTC (permalink / raw)
To: The development of GNU GRUB; +Cc: Goswin von Brederlow
[-- Attachment #1: Type: text/plain, Size: 634 bytes --]
On 07.04.2011 14:09, Goswin von Brederlow wrote:
> Hi,
>
> I've been working on a 32bit->64bit trampoline based on the example
> kernel that just switches to 64bit mode and executes a real kernel
> passed as module. As real kernel I want to use grubs example kernel as
> well to just verify the multiboot infos passed through the trampoline
> are intact.
Please don't use outdated code as base. Now we work on multiboot2 and
before just "let's replace all 32 with 64" some things like page table
need to be duîscussed. Please start a discussion thread for those
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-07 12:56 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2011-04-07 14:50 ` Goswin von Brederlow
2011-04-07 14:57 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 1 reply; 10+ messages in thread
From: Goswin von Brederlow @ 2011-04-07 14:50 UTC (permalink / raw)
To: Vladimir coder/phcoder' Serbinenko; +Cc: The development of GNU GRUB
"Vladimir 'Ï-coder/phcoder' Serbinenko" <phcoder@gmail.com> writes:
> On 07.04.2011 14:09, Goswin von Brederlow wrote:
>> Hi,
>>
>> I've been working on a 32bit->64bit trampoline based on the example
>> kernel that just switches to 64bit mode and executes a real kernel
>> passed as module. As real kernel I want to use grubs example kernel as
>> well to just verify the multiboot infos passed through the trampoline
>> are intact.
> Please don't use outdated code as base. Now we work on multiboot2 and
I've seen multiboot2 mentioned but I can't find specs for it. What I
did find are the "Multiboot Specification version 0.6.96" [1]
So where is this multiboot2?
> before just "let's replace all 32 with 64" some things like page table
> need to be duîscussed. Please start a discussion thread for those
Actualy what I needed to do was replace the 64 with 32. My 64bit mode
still uses the multiboot specs with its 32bit fields. I use that because
that is what grub and kvm give me. Most changes were just to make it use
32bit data types in 32bit and 64bit mode as required by the specs.
For page tables I use 6 pages. 1x Level 4, 1x Level 3, 4x Level 2 with
2MB granularity creating a 1:1 mapping of the first 4 GB ram. But I've
been thinking that maybe the multiboot header could have entries for
the gpt and page table to be used. But that is something do discuss in
another thread.
MfG
Goswin
[1] http://www.gnu.org/software/grub/manual/multiboot/multiboot.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-07 14:50 ` Goswin von Brederlow
@ 2011-04-07 14:57 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-07 17:32 ` Goswin von Brederlow
0 siblings, 1 reply; 10+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-04-07 14:57 UTC (permalink / raw)
To: Goswin von Brederlow; +Cc: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 1847 bytes --]
On 07.04.2011 16:50, Goswin von Brederlow wrote:
> "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com> writes:
>
>> On 07.04.2011 14:09, Goswin von Brederlow wrote:
>>> Hi,
>>>
>>> I've been working on a 32bit->64bit trampoline based on the example
>>> kernel that just switches to 64bit mode and executes a real kernel
>>> passed as module. As real kernel I want to use grubs example kernel as
>>> well to just verify the multiboot infos passed through the trampoline
>>> are intact.
>> Please don't use outdated code as base. Now we work on multiboot2 and
> I've seen multiboot2 mentioned but I can't find specs for it. What I
> did find are the "Multiboot Specification version 0.6.96" [1]
>
> So where is this multiboot2?
>
Latest multiboot1 (cleanups) is at
http://bzr.savannah.gnu.org/r/grub/trunk/multiboot/
Multiboot2 is at http://bzr.savannah.gnu.org/r/grub/branches/multiboot2/
>> before just "let's replace all 32 with 64" some things like page table
>> need to be duîscussed. Please start a discussion thread for those
> Actualy what I needed to do was replace the 64 with 32. My 64bit mode
> still uses the multiboot specs with its 32bit fields. I use that because
> that is what grub and kvm give me. Most changes were just to make it use
> 32bit data types in 32bit and 64bit mode as required by the specs.
>
> For page tables I use 6 pages. 1x Level 4, 1x Level 3, 4x Level 2 with
> 2MB granularity creating a 1:1 mapping of the first 4 GB ram. But I've
> been thinking that maybe the multiboot header could have entries for
> the gpt and page table to be used. But that is something do discuss in
> another thread.
>
> MfG
> Goswin
>
> [1] http://www.gnu.org/software/grub/manual/multiboot/multiboot.html
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-07 14:57 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2011-04-07 17:32 ` Goswin von Brederlow
2011-04-07 17:50 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 1 reply; 10+ messages in thread
From: Goswin von Brederlow @ 2011-04-07 17:32 UTC (permalink / raw)
To: Vladimir 'Ï-coder/phcoder' Serbinenko
Cc: The development of GNU GRUB, Goswin von Brederlow
"Vladimir 'Ï-coder/phcoder' Serbinenko" <phcoder@gmail.com> writes:
> On 07.04.2011 16:50, Goswin von Brederlow wrote:
>> "Vladimir 'Ãâ -coder/phcoder' Serbinenko" <phcoder@gmail.com> writes:
>>
>>> On 07.04.2011 14:09, Goswin von Brederlow wrote:
>>>> Hi,
>>>>
>>>> I've been working on a 32bit->64bit trampoline based on the example
>>>> kernel that just switches to 64bit mode and executes a real kernel
>>>> passed as module. As real kernel I want to use grubs example kernel as
>>>> well to just verify the multiboot infos passed through the trampoline
>>>> are intact.
>>> Please don't use outdated code as base. Now we work on multiboot2 and
>> I've seen multiboot2 mentioned but I can't find specs for it. What I
>> did find are the "Multiboot Specification version 0.6.96" [1]
>>
>> So where is this multiboot2?
>>
> Latest multiboot1 (cleanups) is at
> http://bzr.savannah.gnu.org/r/grub/trunk/multiboot/
Ok, this is much cleaner than what is in the grub source in Debian already.
Remaining issues:
1) hardcoded bit numbers:
/* Check if the bit BIT in FLAGS is set. */
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
...
/* Are mem_* valid? */
if (CHECK_FLAG (mbi->flags, 0))
The multiboot.h does not define the bit numbers, only masks for each
bit. Maybe this could be changed to
In multiboot.h add:
#define MULTIBOOT_INFO_MEMORY_BIT 0
In kernel.c:
/* Check if the bit BIT in FLAGS is set. */
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (MULTIBOOT_INFO_##bit##_BIT)))
...
/* Are mem_* valid? */
if (CHECK_FLAG (mbi->flags, MEMORY))
2) Wrong types
void cmain (unsigned long magic, unsigned long addr);
static void itoa (char *buf, int base, int d);
should be:
void cmain (multiboot_uint32_t magic, multiboot_uint32_t addr);
static void itoa (char *buf, char base, int d);
All occurances of '(unsigned)' should be '(multiboot_uint32_t)'.
3) Could we use 64bit types?
It might be nice to teach printf about '%llx' (or '%q' for quad word)
and add a 64bit itoa. And maybe add a '%p' which would be 64bit in
64bit code and 32bit in 32bit code while '%x' is allways 32bit.
> Multiboot2 is at http://bzr.savannah.gnu.org/r/grub/branches/multiboot2/
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.
The bigger problem though is the thing doesn't build or work:
1) ./autogen.sh
doc/Makefile.am:2: compiling `kernel.c' with per-target flags requires `AM_PROG_CC_C_O' in `configure.ac'
2) wrong source file
Making all in doc
make[2]: Entering directory `/home/mrvn/t/t/multiboot2/doc'
make[2]: *** No rule to make target `boot_mips.o', needed by `kernel'. Stop.
There is only the boot.S, which is for x86. Fixing that:
3) -m32 missing
gcc -DHAVE_CONFIG_H -I. -I.. -DHAVE_CONFIG_H -I. -I.. -nostdlib -g -O2 -MT boot.o -MD -MP -MF .deps/boot.Tpo -c -o boot.o boot.S
boot.S: Assembler messages:
boot.S:97: Error: invalid instruction suffix for `push'
boot.S:101: Error: invalid instruction suffix for `push'
boot.S:103: Error: invalid instruction suffix for `push'
boot.S:109: Error: invalid instruction suffix for `push'
make[2]: *** [boot.o] Error 1
Note that the CFLAGS aren't used for the assembler file at all.
exporting CC="gcc -m32" to work around this.
4) typos in boot.S
--- doc/boot.S.orig 2011-04-07 18:58:41.000000000 +0200
+++ doc/boot.S 2011-04-07 18:58:59.000000000 +0200
@@ -50,11 +50,11 @@
/* magic */
.long MULTIBOOT2_HEADER_MAGIC
/* ISA: i386 */
- .long GRUB_MULTIBOOT_ARCHITECTURE_I386
+ .long MULTIBOOT_ARCHITECTURE_I386
/* Header length. */
.long multiboot_header_end - multiboot_header
/* checksum */
- .long -(MULTIBOOT2_HEADER_MAGIC + GRUB_MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))
+ .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))
#ifndef __ELF__
address_tag_start:
.short MULTIBOOT_HEADER_TAG_ADDRESS
Ok, after all this I get:
% make
gcc -m32 -DHAVE_CONFIG_H -I. -I.. -DHAVE_CONFIG_H -I. -I.. -nostdlib -g -O2 -MT boot.o -MD -MP -MF .deps/boot.Tpo -c -o boot.o boot.S
gcc -m32 -DHAVE_CONFIG_H -I. -I.. -fno-builtin -nostdinc -O -g -Wall -imacros ../config.h -nostdlib -g -O2 -MT kernel-kernel.o -MD -MP -MF .deps/kernel-kernel.Tpo -c -o kernel-kernel.o `test -f 'kernel.c' || echo './'`kernel.c
gcc -m32 -fno-builtin -nostdinc -O -g -Wall -imacros ../config.h -nostdlib -g -O2 -nostdlib -Wl,-N -Wl,-Ttext -Wl,80100000 -Wl,--build-id=none -o kernel boot.o kernel-kernel.o
% file doc/kernel
doc/kernel: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
% kvm -m 64 -kernel doc/kernel
doesn't output anything, doesn't clear the screen.
And here I'm stuck. Everything looks alright.
I thought maybe the extra "-O2" screws something up. So I tried
doc% gcc -m32 -DHAVE_CONFIG_H -I. -I.. -DHAVE_CONFIG_H -I. -I.. -nostdlib -g -O -MT boot.o -MD -MP -MF .deps/boot.Tpo -c -o boot.o boot.S
doc% gcc -m32 -DHAVE_CONFIG_H -I. -I.. -fno-builtin -nostdinc -O -g -Wall -imacros ../config.h -nostdlib -g -O -MT kernel-kernel.o -MD -MP -MF .deps/kernel-kernel.Tpo -c -o kernel-kernel.o `test -f 'kernel.c' || echo './'`kernel.c
doc% gcc -m32 -fno-builtin -nostdinc -O -g -Wall -imacros ../config.h -nostdlib -g -O -nostdlib -Wl,-N -Wl,-Ttext -Wl,80100000 -Wl,--build-id=none -o kernel boot.o kernel-kernel.o
doc% kvm -m 64 -kernel kernel
open /dev/kvm: No such file or directory
Could not initialize KVM, will disable KVM support
Failed to allocate memory: Cannot allocate memory
zsh: abort kvm -m 64 -kernel kernel
It tries to allocate -0xE000 byte of memory, which is a few trillion
gazillion byte.
Trying the commands the old multiboot (from your first url) used to
build:
doc% gcc -DHAVE_CONFIG_H -I. -I.. -m32 -nostdlib -fno-builtin -nostdinc -O -g -Wall -imacros ../config.h -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT kernel-boot.o -MD -MP -MF .deps/kernel-boot.Tpo -c -o kernel-boot.o `test -f 'boot.S' || echo './'`boot.S
doc% gcc -DHAVE_CONFIG_H -I. -I.. -m32 -nostdlib -fno-builtin -nostdinc -O -g -Wall -imacros ../config.h -g -O2 -MT kernel-kernel.o -MD -MP -MF .deps/kernel-kernel.Tpo -c -o kernel-kernel.o `test -f 'kernel.c' || echo './'`kernel.c
doc% gcc -g -O2 -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000 -Wl,--build-id=none -o kernel kernel-boot.o kernel-kernel.o
doc% kvm -m 64 -kernel kernel
doesn't output anything, doesn't clear the screen.
Any idea what is going wrong?
MfG
Goswin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-07 17:32 ` Goswin von Brederlow
@ 2011-04-07 17:50 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-08 14:43 ` Goswin von Brederlow
0 siblings, 1 reply; 10+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-04-07 17:50 UTC (permalink / raw)
To: Goswin von Brederlow; +Cc: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 519 bytes --]
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.
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-07 17:50 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2011-04-08 14:43 ` Goswin von Brederlow
2011-04-08 14:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 1 reply; 10+ messages in thread
From: Goswin von Brederlow @ 2011-04-08 14:43 UTC (permalink / raw)
To: Vladimir coder/phcoder' Serbinenko; +Cc: The development of GNU GRUB
"Vladimir 'Ï-coder/phcoder' Serbinenko" <phcoder@gmail.com> 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?
#define MULTIBOOT_ARCHITECTURE_X86_64 8
#define MULTIBOOT_ARCHITECTURE_MIPS64 12
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?).
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'm tempted to add 2 new info tags: multiboot_tag_gpt and
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.
MfG
Goswin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-08 14:43 ` Goswin von Brederlow
@ 2011-04-08 14:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-08 17:18 ` Goswin von Brederlow
2011-04-18 19:49 ` Goswin von Brederlow
0 siblings, 2 replies; 10+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-04-08 14:53 UTC (permalink / raw)
To: Goswin von Brederlow; +Cc: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 2600 bytes --]
On 08.04.2011 16:43, Goswin von Brederlow wrote:
> "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com> 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?
> #define MULTIBOOT_ARCHITECTURE_X86_64 8
> #define MULTIBOOT_ARCHITECTURE_MIPS64 12
>
Because the lower 2 bits pertain to the number of bits on platform.
0 -> 32
1 -> 64
2 -> 16
3 -> everything else
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.
> 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
> 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
mapped". It may be good to specify where page table is to be located to
ease avoiding overwriting it.
> 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.
> 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.
> MfG
> Goswin
>
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-08 14:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2011-04-08 17:18 ` Goswin von Brederlow
2011-04-18 19:49 ` Goswin von Brederlow
1 sibling, 0 replies; 10+ messages in thread
From: Goswin von Brederlow @ 2011-04-08 17:18 UTC (permalink / raw)
To: Vladimir 'Ï-coder/phcoder' Serbinenko
Cc: The development of GNU GRUB, Goswin von Brederlow
"Vladimir 'Ï-coder/phcoder' Serbinenko" <phcoder@gmail.com> writes:
> On 08.04.2011 16:43, Goswin von Brederlow wrote:
>> "Vladimir 'Ãâ -coder/phcoder' Serbinenko" <phcoder@gmail.com> 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?
>> #define MULTIBOOT_ARCHITECTURE_X86_64 8
>> #define MULTIBOOT_ARCHITECTURE_MIPS64 12
>>
> 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_MASK 3
#define MULTIBOOT_NUMBITS_32 0
#define MULTIBOOT_NUMBITS_64 1
#define MULTIBOOT_NUMBITS_16 2
then.
> 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
MUST?
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
MfG
Goswin
PS: Nobody is using multiboot2 productively yet, right? Otherwise it
would be too late to change the 32bit structures.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Would a cleanup+extending of docs/multiboot.h be acceptable?
2011-04-08 14:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-08 17:18 ` Goswin von Brederlow
@ 2011-04-18 19:49 ` Goswin von Brederlow
1 sibling, 0 replies; 10+ messages in thread
From: Goswin von Brederlow @ 2011-04-18 19:49 UTC (permalink / raw)
To: Vladimir coder/phcoder' Serbinenko
Cc: The development of GNU GRUB, Goswin von Brederlow
Hi,
haven't heard from you in a few days now. So here is some progress report:
"Vladimir 'Ï-coder/phcoder' Serbinenko" <phcoder@gmail.com> writes:
> On 08.04.2011 16:43, Goswin von Brederlow wrote:
>> "Vladimir 'Ãâ -coder/phcoder' Serbinenko" <phcoder@gmail.com> 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?
>> #define MULTIBOOT_ARCHITECTURE_X86_64 8
>> #define MULTIBOOT_ARCHITECTURE_MIPS64 12
>>
> Because the lower 2 bits pertain to the number of bits on platform.
> 0 -> 32
> 1 -> 64
> 2 -> 16
> 3 -> everything else
> 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 implemented 64bit support in qemu-kvm now. This comes in 2 flavours:
1) 64bit elf file with multiboot1 header or MULTIBOOT_ARCHITECTURE_I386
The file is loaded and the entry point is jumped to in 32bit mode. The
only new thing here is that kvm doesn't refuse to load an 64bit elf
file. The kernel must still follow the multiboot specs for 32bit images
and manage the transition to 64bit itself. The advantage of this is that
compiling a 64bit kernel as 64bit elf file (with just a little 32bit
startup code thrown in) is a lot simpler than putting 64bit code into a
32bit elf.
2) True 64bit kernel
I've added
#define MULTIBOOT_ARCHITECTURE_X86_64 1
If this is set in the header the kernel entry point is jumped to in
64bit mode with an identity mapping for the lower 4GB ram. The
bootloader magic and tags pointer are passed in registers acording to
the C calling convention on x86_64. Only thing missing is the stack. The
startup code becomes as simple as this:
multiboot_entry:
/* Initialize the stack pointer. */
movl $(stack + STACK_SIZE), %esp
/* Now enter the C main function... */
call EXT_C(cmain)
Addresses (except for the mmap tag that already has 64bit fields) are
32bit so the kernel needs to be compiled below 4GB.
You can test this with the patches in
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=621529
I've included a example kernel based on the 32bit kernel from the specs.
Just a few adjustements in casts and using va_list for printf() to fit
the x86_64 C calling conventions.
I've been wondering if we could add a 64bit flag to the multiboot1 specs
that would call the entry point in 64bit while leaving all data
structure as is. But if multiboot2 has it then personally I don't need
it in older loaders.
>> 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
If you intend to do this then please make those changes soon so I can
finish the patches for qemu-kvm.
As for other changes I think it would be nice to have a tag for the
stack. This would allow the kernel image to specify an initial stack and
allow using a C function as entry point.
And last I think you forgot to change struct
multiboot_header_tag_module_align. That has the same definition as
struct multiboot_header_tag_framebuffer and "depth" doesn't make sense
for module alignment.
MfG
Goswin
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-04-18 19:49 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-07 12:09 Would a cleanup+extending of docs/multiboot.h be acceptable? Goswin von Brederlow
2011-04-07 12:56 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-07 14:50 ` Goswin von Brederlow
2011-04-07 14:57 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-07 17:32 ` Goswin von Brederlow
2011-04-07 17:50 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-08 14:43 ` Goswin von Brederlow
2011-04-08 14:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-08 17:18 ` Goswin von Brederlow
2011-04-18 19:49 ` Goswin von Brederlow
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.