Message ID | 1402950432.3708.22.camel@smoke (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Jun 16, 2014 at 09:27:12PM +0100, Geoff Levand wrote: > Hi Mark, Hi Geoff, > Sorry for such a delay in my reply. > > On Fri, 2014-05-16 at 10:50 +0100, Mark Rutland wrote: > > Both the image load offset and the effective image size are forced to be > > little-endian regardless of the native endianness of the kernel to > > enable bootloaders to load a kernel of arbitrary endianness. Bootloaders > > which wish to make use of the load offset can inspect the effective > > image size field for a non-zero value to determine if the offset is of a > > known endianness. > > Doing this conversion in the linker script seems complicated. My > thought was to just have an image header field that specifies the > byte order, in the same way that the EI_DATA part of the ELF > e_ident field does. While the conversion in the linker script is a little ugly, it does work, and that complexity is hidden behind the macro I added. While I initially considered having a field to specify byte order, it's incredibly likely that bootloaders will not use it. Maintaining a fixed endianness everywhere makes it simpler for bootloaders to do the right thing, and matches what existing bootloaders are already doing. That's less pain for loaders and less pain for the kernel, as things are less likely to go wrong. To me it makes more sense to ensure these fields have a consistent endianness, rather than adding more room for possible mistakes. > Another advantage of having the byte order in the header is that > tools other than a boot loader that need to know the byte order > can get that info from the header, otherwise they would need to > guess the order with some kind of inspection. What kind of tools do you envision which would need to know the endianness of the kernel but would be looking at the Image rather than the vmlinux? Mark.
On Wed, Jun 18, 2014 at 11:49 AM, Mark Rutland <mark.rutland@arm.com> wrote: > On Mon, Jun 16, 2014 at 09:27:12PM +0100, Geoff Levand wrote: >> Hi Mark, > > Hi Geoff, > >> Sorry for such a delay in my reply. >> >> On Fri, 2014-05-16 at 10:50 +0100, Mark Rutland wrote: >> > Both the image load offset and the effective image size are forced to be >> > little-endian regardless of the native endianness of the kernel to >> > enable bootloaders to load a kernel of arbitrary endianness. Bootloaders >> > which wish to make use of the load offset can inspect the effective >> > image size field for a non-zero value to determine if the offset is of a >> > known endianness. >> >> Doing this conversion in the linker script seems complicated. My >> thought was to just have an image header field that specifies the >> byte order, in the same way that the EI_DATA part of the ELF >> e_ident field does. > > While the conversion in the linker script is a little ugly, it does > work, and that complexity is hidden behind the macro I added. > > While I initially considered having a field to specify byte order, it's > incredibly likely that bootloaders will not use it. Maintaining a fixed > endianness everywhere makes it simpler for bootloaders to do the right > thing, and matches what existing bootloaders are already doing. That's > less pain for loaders and less pain for the kernel, as things are less > likely to go wrong. > > To me it makes more sense to ensure these fields have a consistent > endianness, rather than adding more room for possible mistakes. > >> Another advantage of having the byte order in the header is that >> tools other than a boot loader that need to know the byte order >> can get that info from the header, otherwise they would need to >> guess the order with some kind of inspection. > > What kind of tools do you envision which would need to know the > endianness of the kernel but would be looking at the Image rather than > the vmlinux? Seems like this has the same problem as being discussed for arm32: http://permalink.gmane.org/gmane.linux.kernel/1727993 Rob
Hi Mark, On Wed, 2014-06-18 at 17:49 +0100, Mark Rutland wrote: > On Mon, Jun 16, 2014 at 09:27:12PM +0100, Geoff Levand wrote: > While I initially considered having a field to specify byte order, it's > incredibly likely that bootloaders will not use it. Maintaining a fixed > endianness everywhere makes it simpler for bootloaders to do the right > thing, and matches what existing bootloaders are already doing. That's > less pain for loaders and less pain for the kernel, as things are less > likely to go wrong. > > To me it makes more sense to ensure these fields have a consistent > endianness, rather than adding more room for possible mistakes. I guess my view is that any software expected to support arm64 in both big and little endian configurations should be tested with such, and with this it is pretty simple to test and fix, so we shouldn't over engineer it, but I don't really care how we fix it. > > Another advantage of having the byte order in the header is that > > tools other than a boot loader that need to know the byte order > > can get that info from the header, otherwise they would need to > > guess the order with some kind of inspection. > > What kind of tools do you envision which would need to know the > endianness of the kernel but would be looking at the Image rather than > the vmlinux? I have no idea, but I can imagine it may be of use to someone who is trying to figure out why things don't work and would like to know what kind of image they have. -Geoff
On Wed, Jun 18, 2014 at 9:49 AM, Mark Rutland <mark.rutland@arm.com> wrote: > What kind of tools do you envision which would need to know the > endianness of the kernel but would be looking at the Image rather than > the vmlinux? Automated boot infrastructure which has access to the [zu]Image but not the vmlinux and wants to know which endian rootfs to pass to the kernel. Kevin
On Wed, Jun 18, 2014 at 07:41:42PM +0100, Geoff Levand wrote: > Hi Mark, Hi Geoff, Thanks for raising the issue. I can see from Kevin's comments that the kernel endianness is a useful piece of information, so I'll add a field to the header to export that for v3. > On Wed, 2014-06-18 at 17:49 +0100, Mark Rutland wrote: > > On Mon, Jun 16, 2014 at 09:27:12PM +0100, Geoff Levand wrote: > > While I initially considered having a field to specify byte order, it's > > incredibly likely that bootloaders will not use it. Maintaining a fixed > > endianness everywhere makes it simpler for bootloaders to do the right > > thing, and matches what existing bootloaders are already doing. That's > > less pain for loaders and less pain for the kernel, as things are less > > likely to go wrong. > > > > To me it makes more sense to ensure these fields have a consistent > > endianness, rather than adding more room for possible mistakes. > > I guess my view is that any software expected to support arm64 in both > big and little endian configurations should be tested with such, and > with this it is pretty simple to test and fix, so we shouldn't over > engineer it, but I don't really care how we fix it. I disagree that the bootloader _must_ have to deal with the endianness of the kernel. If the user knows the endianness of the kernel and provides a filesystem of the appropriate endianness, I don't see why the bootloader should have to do anything differently. In most cases the bootloader has no need to care. IMO It's far better to export the fields in the kernel header in a consistent endianness than it is to force every boot loader to inspect the endianness of the kernel image. I can imagine there are going to be plenty of bootloaders which will not attempt to determine the endianness and will blindly assume a particular case. Exporting the kernel endianness does seem to make sense, but I think this should be in addition to the information bootloaders require rather than being part of the information bootloaders require. Thanks, Mark.
Hi Mark, On Thu, 2014-06-19 at 11:25 +0100, Mark Rutland wrote: > I disagree that the bootloader _must_ have to deal with the endianness > of the kernel. If the user knows the endianness of the kernel and > provides a filesystem of the appropriate endianness, I don't see why the > bootloader should have to do anything differently. In most cases the > bootloader has no need to care. As I mentioned, I don't really care how this is fixed, but there will be bootloaders built as both big and little endian (kexec based ones for example), and so no matter what, bootloaders will need to deal with converting values. -Geoff
On Thu, Jun 19, 2014 at 07:07:48PM +0100, Geoff Levand wrote: > Hi Mark, > > On Thu, 2014-06-19 at 11:25 +0100, Mark Rutland wrote: > > I disagree that the bootloader _must_ have to deal with the endianness > > of the kernel. If the user knows the endianness of the kernel and > > provides a filesystem of the appropriate endianness, I don't see why the > > bootloader should have to do anything differently. In most cases the > > bootloader has no need to care. > > As I mentioned, I don't really care how this is fixed, but there will be > bootloaders built as both big and little endian (kexec based ones for > example), and so no matter what, bootloaders will need to deal with > converting values. Sure, bootloaders will need to convert values in some cases. By having a fixed endian header format, whether or not you need to byteswap values becomes a fixed property of the bootloader (i.e. whether it is BE or not) rather than a dynamic property of the kernel Image. So you only require a single path through your loader for BE and LE kernels. If you have constructs like LE64_TO_CPU available to your loader, then it becomes trivial to write an endian-clean loader. The only pain is having to test if image_size is non-zero first, but that test is independent of endiannness. Mark.
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index b96a732..70c3656 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -109,7 +109,11 @@ * DO NOT MODIFY. Image header expected by Linux boot-loaders. */ b stext // branch to kernel start, magic - .long 0 // reserved + CPU_LE(.byte 1) // 1=LSB (little endian) + CPU_BE(.byte 2) // 2=MSB (big endian) + .byte 0 // reserved + .byte 0 // reserved + .byte 0 // reserved .quad TEXT_OFFSET // Image load offset from start of RAM .quad 0 // reserved .quad 0 // reserved