2007-08-09 09:47:28

by Etienne Lorrain

[permalink] [raw]
Subject: Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document

Eric W Biederman wrote:
> >> This is the classic skip the 16bit code and enter the kernel
> >> in 32bit mode filling in the fields that the 16bit mode code would
> >> have filled in the same way approach.
> > ......
> >
> > For in tree code it can be just updated. But weirdo-EFI-boot loader
> > cannot.
>
> So far the logic has been.
>
> Inspect bzImage. And get boot protocol version.
> If field we need for returning data is not supported do not give
> data. Or something like that. Usually the fields always exist
> and you can just fill them in and we only append to the boot
> protocol structure.
>
> In practice this has been working for the last 7 years or so,
> for EFI, and LinuxBIOS, and kexec, and Gujin and I don't remember what
> else.

Note that Gujin has a simple problem by using that 32 bits entry point:
there is no way to detect if the bzImage is compiled for 32 bits or 64 bits,
and Linux-real-mode calls a BIOS service for 64 bits only (to tell the BIOS you
are going to 64 bits - interrupt not really documented).
Gujin can now be set to start at the 16 bits entry point, and load ELF32/ELF64
where you now the target word size, but the 32 bits entry point will "forget"
to call that service if the Linux kernel is 64 bits.
The 32 bits entry point can still be used (-p parameter of tiny.exe) because
there seems to be a problem using the 16 bits entry point under DOS, at least
the old assembly version of the code - no more details known.

Etienne.


_____________________________________________________________________________
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail


2007-08-09 10:51:34

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document


> Note that Gujin has a simple problem by using that 32 bits entry point:

There is really no 32bit entry point today usable for external users. Or rather
it might by chance work today, but if we change the zero page (and there
is no guarantee it'll not be changed). I can pretty much guarantee it'll
be changed at some point. And you'll break if you use it.

kexec can use the 32bit entry, but only because it is in tree so it can be fixed
up for any changes.

If you want to use it you would need to define some versionable protocol
first similar to the real mode boot protocol. That would require some work
and some thought to make sure it is forwards and backwards compatible.

I'll add a comment to zero-page.txt to make this more clear. Just because
something is documented in Documentation doesn't mean it's an external stable
ABI.

-Andi

2007-08-09 11:24:07

by Etienne Lorrain

[permalink] [raw]
Subject: RE : Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document

--- Andi Kleen <[email protected]> wrote:
> > Note that Gujin has a simple problem by using that 32 bits entry point:
>
> There is really no 32bit entry point today usable for external users.

That is why I added the 16 bits entry point support (selected by default),
my target with Gujin was not only to load Linux but also another simpler
format - gzip'ed ELF 32/64 files with real-mode embedded at address 0 .
I also had to show that it was possible to write the Linux-real-mode
code in C with GCC so that someone else would do it and maintain it.
I may (in few version) remove Gujin code which fills Linux zero-page
structure if the 16 bit entry point works in all cases (mostly in DOS
which help me to create a DBG debug file to sort out Gujin/BIOS problems
remotely).
I may maintain another patch to produce this gzip'ed ELF32/64 for Linux
as an example of how to use that Gujin interface, but that is not really
related. That patch is in Gujin Sourceforge download.
Note that I call (instead of jump to) the 16 bits entry point so that
this "function" can return to the bootloader if it detects a problem.

Etienne.


_____________________________________________________________________________
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail

2007-08-09 14:09:38

by huang ying

[permalink] [raw]
Subject: Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document

On 8/9/07, Andi Kleen <[email protected]> wrote:
> There is really no 32bit entry point today usable for external users. Or rather
> it might by chance work today, but if we change the zero page (and there
> is no guarantee it'll not be changed). I can pretty much guarantee it'll
> be changed at some point. And you'll break if you use it.

Yes, there is no official 32bit external entry point. But on EFI
platform, the 16bit entry point can not be used because there is no
16bit BIOS call available. So, I think it is necessary to define a
32bit external entry point.

> kexec can use the 32bit entry, but only because it is in tree so it can be fixed
> up for any changes.

The kexec uses the 32bit entry point in a user space tool named
kexec-tools, not in the kernel.

> If you want to use it you would need to define some versionable protocol
> first similar to the real mode boot protocol. That would require some work
> and some thought to make sure it is forwards and backwards compatible.

I think at least the following should be done to make it a external
boot protocol.

1. A version number field should be added.
2. The pointers (especially these come from firmware) should be 64bit
to make the entry point can be used for both 32bit and 64bit platform.
3. More complete and formal document.

Can you kindly tell me what's more should be done?

Best Regards,
Huang Ying

2007-08-09 16:29:25

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document

huang ying wrote:
>
> I think at least the following should be done to make it a external
> boot protocol.
>
> 1. A version number field should be added.
> 2. The pointers (especially these come from firmware) should be 64bit
> to make the entry point can be used for both 32bit and 64bit platform.
> 3. More complete and formal document.
>
> Can you kindly tell me what's more should be done?
>

I have been looking at this recently, and also found that we already
have to make unacceptable compromises in order to fit into 4K, which is
set completely arbitrary (once upon a time, it was recycled as the
zeropage, but that is ancient history.)

Part of a formalizing the 32-bit/64-bit entrypoint involves a clean way
to extend this data set.

I mentioned in private email to a few people that I think a linked list
of tagged data items (similar to the way PCI capabilities work) would
probably make sense; we want a piece of code to know the structure
without needing to know the contents, in order to rescue data.

It's worth realizing that this is inherently never going to be as stable
as the real-mode entrypoint, and there is always going to be more
catch-up, simply because it's a broader interface. What is blatantly
clear, however, is that the current structure is utterly ad hoc and has
been totally prematurely adopted as some sort of standard interface.
Since I've spent time formalizing the structure over the last few months
I've been rather horrified; it is truly as bad as you could get.

So, anyway, this has popped up on my radar already; it needs to happen
anyway so let's get the discussion started.

-hpa

2007-08-09 17:01:50

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document

On Thursday 09 August 2007 16:09:23 huang ying wrote:
> On 8/9/07, Andi Kleen <[email protected]> wrote:
> > There is really no 32bit entry point today usable for external users. Or rather
> > it might by chance work today, but if we change the zero page (and there
> > is no guarantee it'll not be changed). I can pretty much guarantee it'll
> > be changed at some point. And you'll break if you use it.
>
> Yes, there is no official 32bit external entry point. But on EFI
> platform, the 16bit entry point can not be used because there is no
> 16bit BIOS call available. So, I think it is necessary to define a
> 32bit external entry point.

Ok. How do you collect all the data in the zero page then?
There's much more in there than just the memory map.

Anyways for EFI the best way is probably to define a EFI entry
point that does the same work as the real mode code today just
using EFI services.

And for kexec :- well need a proper protocol.

>
> > kexec can use the 32bit entry, but only because it is in tree so it can be fixed
> > up for any changes.
>
> The kexec uses the 32bit entry point in a user space tool named
> kexec-tools, not in the kernel.

Ah i didn't realize this. Ok then kexec is also quite broken.
Somehow this must have been missed this fundamental flaw when this code was
reviewed.

>
> > If you want to use it you would need to define some versionable protocol
> > first similar to the real mode boot protocol. That would require some work
> > and some thought to make sure it is forwards and backwards compatible.
>
> I think at least the following should be done to make it a external
> boot protocol.
>
> 1. A version number field should be added.
> 2. The pointers (especially these come from firmware) should be 64bit
> to make the entry point can be used for both 32bit and 64bit platform.

32bit pointers are not too bad; it needs to be all physical anyways
because kernel virtual mapping can change any time.

> 3. More complete and formal document.
>
> Can you kindly tell me what's more should be done?

It's a minimum start. But at least for EFI I still think it's better
to just move that code back into the kernel. Just cleanly separated.

-Andi

2007-08-09 17:26:25

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document

Andi Kleen wrote:
>
> Ah i didn't realize this. Ok then kexec is also quite broken.
> Somehow this must have been missed this fundamental flaw when this code was
> reviewed.
>

It wasn't missed. It was given the "there is no other way" defence, and
somehow that was considered sufficient.

Now, one could argue that kexec can just pass the boot_params from the
previous kernel boot, except there is no way to read them out, and so
it's not how it actually works.

-hpa

2007-08-10 13:03:32

by Huang, Ying

[permalink] [raw]
Subject: Re: [PATCH 5/5] x86_64 EFI support -v3: EFI document

On Thu, 2007-08-09 at 19:01 +0200, Andi Kleen wrote:
> > Yes, there is no official 32bit external entry point. But on EFI
> > platform, the 16bit entry point can not be used because there is no
> > 16bit BIOS call available. So, I think it is necessary to define a
> > 32bit external entry point.
>
> Ok. How do you collect all the data in the zero page then?
> There's much more in there than just the memory map.

Now all the data in the zero page and standard boot protocol are
collected by the EFI bootloader. The EFI bootloader does this through
calling the EFI boot services. If the data is intended to be collected
in kernel setup code, the EFI boot services must be used inside kernel
setup code to collect the data.

> Anyways for EFI the best way is probably to define a EFI entry
> point that does the same work as the real mode code today just
> using EFI services.

So, for booting Linux kernel on EFI platform, the process you proposed
(named process A in the letter) will be as follow:

1. Bootloader loads the Linux kernel image into memory
2. Bootloader setups the parameter defined in standard boot protocol
(need some extension for EFI)
3. Bootloader jumps to kernel EFI 32bit/64bit entry point
4. Kernel EFI setup code collects the data in the zero pages through
calling the EFI boot services
5. Kernel EFI setup code jumps to decompressor entry point
6. Kernel decompressor jumps to kernel entry point (startup_64), which
then jumps to x86_64_start_kernel
7. The EFI memory map is converted to E820 map in x86_64_start_kernel,
and the result is stuffed into zero page.
8. Kernel booting up continues with the E820 map and other data of zero
page.

The process of current EFI implementation (named process B in the
letter) is as follow:

1. Bootloader loads the Linux kernel image into memory
2. Bootloader setups the parameter defined in standard boot protocol
3. Bootloader collects the data in the zero pages through calling the
EFI boot services
4. Bootloader converts EFI memory map to E820 map, the result is stuffed
into zero page.
5. Bootloader jumps to kernel decompressor entry point
6. Kernel decompressor jumpto kernel entry point (startup_64), which
jumps to x86_64_start_kernel
7. Kernel booting up continues with the E820 map and other data of zero
page.

Compares the above two process, we can find that the main difference
lies in:
1. Boot protocol. The process A uses standard boot protocol with some
EFI extension + EFI 32bit. The process B uses the standard boot protocol
+ zero page protocol (which is internal now).
2. In process A, the zero page data setupping and E820 converting are
done by kernel, while in process B, these are done done by bootloader.

The advantages of process A:
1. The zero page protocol can be made internal, so it is more
extensible.

The advantages of process B:
1. The EFI boot support code of Linux kernel is minimal. In fact,
current EFI boot support patch only adds a frame buffer driver. And I do
not see any more needed except some firmware information (ACPI root
pointer, SMBIOS pointer, etc) maybe need to be passed through zero page.

The issues of process A:
1. To support multiple BIOS/bootloader with one kernel binary image,
multiple setup binaries must be integrated into kernel binary image. At
end, the layout of the bzImage of Linux kernel may become as follow:
bootsect + lagacy BIOS setup + EFI32 setup + EFI64 setup + LinuxBIOS
setup + kexec setup + decompressor + vmlinux binary
That is, there is one "setup" for each BIOS type. Because the EFI32 and
EFI64 is not bianry compatible, two EFI setup is needed at least for
i386 kernel.

> And for kexec :- well need a proper protocol.

It seems that the only way for kexec is to use the standard boot
protocol + zero page protocol. If this is true, the zero page protocol
should be made external, so EFI can use it too.

> > > kexec can use the 32bit entry, but only because it is in tree so
it can be fixed
> > > up for any changes.
> >
> > The kexec uses the 32bit entry point in a user space tool named
> > kexec-tools, not in the kernel.
>
> Ah i didn't realize this. Ok then kexec is also quite broken.
> Somehow this must have been missed this fundamental flaw when this
code was
> reviewed.
>
> >
> > > If you want to use it you would need to define some versionable
protocol
> > > first similar to the real mode boot protocol. That would require
some work
> > > and some thought to make sure it is forwards and backwards
compatible.
> >
> > I think at least the following should be done to make it a external
> > boot protocol.
> >
> > 1. A version number field should be added.
> > 2. The pointers (especially these come from firmware) should be
64bit
> > to make the entry point can be used for both 32bit and 64bit
platform.
>
> 32bit pointers are not too bad; it needs to be all physical anyways
> because kernel virtual mapping can change any time.

Yes, all pointers should be physical. But some pointers come from
firmware such as ACPI root pointer, EFI system table pointer should be
64bit, because we can not control the actual position pointed to.

> > 3. More complete and formal document.
> >
> > Can you kindly tell me what's more should be done?
>
> It's a minimum start. But at least for EFI I still think it's better
> to just move that code back into the kernel. Just cleanly separated.

Best Regards,
Huang Ying