Skip to contentSkip to conversation

x86 Boot enhancements, boot protocol 2.04 7/9

PATCH In review Eric W. Biederman 3 participants 13 messages Apr 3, 2002 – Apr 5, 2002 Documentation

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86 Boot enhancements, boot protocol 2.04 7/9

Linus, please apply

This patch is what my earlier patches were building to. In this patch I upgrade the linux boot protocol to version 2.04 and export a 32bit entry point, and the which memory the kernel uses during bootup. In imitation of the arm and ppc ports a CONFIG_CMDLINE option is also implemented.

While the 32bit entry point allows us to avoid 16bit BIOS calls this is not the only reason people to use it. So if we come in the 32bit entry point with too little information we drop back to real mode query the BIOS and then do the normal kernel startup. The policy decision for this is implemented in setup.c

Update the boot protocol to include:
- A compiled in command line
- A 32bit entry point
- File and memory usage information enabling a 1 to 1 conversion between the bzImage format and the static ELF executable file format.
- In setup.c split the variables between those that
are private to linux and those that are exported to bootloaders.

Eric

Documentation/i386/boot.txt +88 -2
diff -uNr linux-2.5.7.boot3.build/Documentation/i386/boot.txt linux-2.5.7.boot3.proto/Documentation/i386/boot.txt
@@ -127,7 +127,18 @@
 0224/2	2.01+	heap_end_ptr	Free memory after setup end
 0226/2	N/A	pad1		Unused
 0228/4	2.02+	cmd_line_ptr	32-bit pointer to the kernel command line
-022C/4	2.03+	initrd_addr_max	Highest legal initrd address
+022C/4	2.03+	ramdisk_max	Highest legal initrd address
+0230/2	2.04+	entry32_off	offset of 32bit entry point
+0230/2	2.04+	internal_cmdline_off	offset of compiled in command line
+0234/4	2.04+	low_base	0x1000
+0238/4	2.04+	low_memsz	Memory used @ 0x1000
+023C/4	2.04+	low_filesz	Precomputed data for 0x1000
+0240/4	2.04+	real_base	0x90000
+0244/4	2.04+	real_memsz	Memory used @ 0x90000
+0248/4	2.04+	real_filesz	Precomputed data for @ 0x90000
+024C/4	2.04+	high_memsz	Memory used @ 0x100000
+0250/4	2.04+	high_base	0x100000
+0254/4	2.04+	high_filesz	Amount of file used for the compressed kernel
 
 For backwards compatibility, if the setup_sects field contains 0, the
 real value is 4.
@@ -198,7 +209,7 @@
 	The initrd should typically be located as high in memory as
 	possible, as it may otherwise get overwritten by the early
 	kernel initialization sequence.	 However, it must never be
-	located above the address specified in the initrd_addr_max
+	located above the address specified in the ramdisk_max
 	field.	The initrd should be at least 4K page aligned.
 
   cmd_line_ptr:
@@ -219,6 +230,76 @@
 	if your ramdisk is exactly 131072 bytes long and this field is
 	0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)
 
+  entry32_off:
+	The offset of the 32bit entry point from the real mode kernel.
+	For boot protocols 2.03 or earlier, this field is not present,
+	and there is no 32bit entry point.
+
+  internal_cmdline_off:
+	The offset of the null terminated compiled in command line
+	from the real mode kernel.   For boot protocols 2.03 or
+	earlier this field is not present, and there is no built in
+	command line.  The memory from internal_cmdline_off to
+	real_filesz is reserved for the compiled in command_line.  An
+	external utility may modify this command line.
+
+	To change the maximum size of the compiled in command line several
+	variables need to be modified.  real_filesz to indicate the
+	new maximum size.  setup_sects to indicate if the number of
+	sectors needed for the realmode kernel changes.  
+
+	A heap is maintained between real_filesz and real_memsz/heap_end_ptr.
+	Increasing the size of the heap is not a problem, decreasing
+	it is.  So when changing the real_filesz, real_memsz and
+	heap_end_ptr should also be changed.  real_memsz and
+	heap_end_ptr should always indicate the same maximum except
+	at runtime when a bootloader may indicate a larger heap is
+	present.
+
+  low_base, low_memsz, low_filesz, 
+  real_base, real_memsz, real_filesz, 
+  high_base, high_memsz, high_filesz:
+	Up to this point building a zImage or a bzImage has been a very lossy
+	process.  The introduction of these six variables attempts to
+	rectify that situation.  They document exactly which pieces
+	of memory, the kernel uses during the boot process, and they
+	indicate exactly how large the various data segments of the
+	kernel are.  It is now possible to create a lossless
+	transformation to and from a static ELF executable.
+
+	For a bzImage the low program segment describes the memory
+	from 4KB - 572KB the kernel decompressors uses as a temorary
+	buffer.  For a zImage the low program segment describes the
+	memory from 4KB - 572KB where the compressed kernel is loaded. 
+
+	For a bzImage the high program segment describes the memory
+	from 1MB on where the compressed kernel is loaded, where
+	decompression takes place, where the kernel initially runs,
+	and where the kernels bss segment is.  For a zImage the high
+	program segment describes the memory from 1MB on where the
+	kernel is decompressed to, where the kernel initial runs, and
+	where the kernels bss segment is located.
+
+	The real program segment describes the memory from 572KB
+	(0x90000) to 640KB (0xa0000) that the real mode kernel uses.
+	This region may be moved lower in memory if the BIOS has
+	reserved region for some other purpose.  When doing so
+	the following considerations should be applied.
+	
+		For a zImage you may move the real mode kernel now
+		lower than low_base + low_memsz.
+
+		For a bzImage if you move real_base below (low_base +
+		low_memsz) the following are the values of the other
+		variables.
+			low_memsz -= (low_base + low_memsz) - real_base
+			high_memsz += (low_base + low_memsz) - real_base
+		
+	
+	With this information it becomes safe to to statically
+	relocate the real mode kernel as well as dynamically relocate
+	it.  real_base should not be > 0x90000.
+
 
 **** THE KERNEL COMMAND LINE
 
@@ -247,6 +328,11 @@
 	The kernel command line *must* be within the memory region
 	covered by setup_move_size, so you may need to adjust this
 	field.
+
+If the protocol version is 2.04 or higher a compiled in command line
+may be present.  If this is the case the passed command line is
+appended onto the tail of the compiled command line.  Assuming
+there is room.
 
 
 **** SAMPLE BOOT CONFIGURATION
arch/i386/Config.help +6 -0
diff -uNr linux-2.5.7.boot3.build/arch/i386/Config.help linux-2.5.7.boot3.proto/arch/i386/Config.help
@@ -797,6 +797,12 @@
   a work-around for a number of buggy BIOSes. Switch this option on if
   your computer crashes instead of powering off properly.
 
+CONFIG_CMDLINE
+  Generally it is best to pass command line parameters via the
+  bootloader but there are times it is convinient not to do this.
+  This allows you to hard code a default kernel command line, whatever
+  the bootloader passes will be appended to it.
+
 CONFIG_TOSHIBA
   This adds a driver to safely access the System Management Mode of
   the CPU on Toshiba portables with a genuine Toshiba BIOS. It does
arch/i386/boot/realmode.lds +1 -1
diff -uNr linux-2.5.7.boot3.build/arch/i386/boot/realmode.lds linux-2.5.7.boot3.proto/arch/i386/boot/realmode.lds
@@ -1,5 +1,5 @@
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-ENTRY(_start)
+ENTRY(entry32)
 OUTPUT_ARCH(i386)
 SECTIONS
 {
arch/i386/boot/setup.S +182 -13

245 lines not on this page · raw message

arch/i386/config.in +1 -0
diff -uNr linux-2.5.7.boot3.build/arch/i386/config.in linux-2.5.7.boot3.proto/arch/i386/config.in
@@ -279,6 +279,7 @@
    bool '    Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
 fi
 
+string 'Initial kernel command line' CONFIG_CMDLINE ""
 endmenu
 
 source drivers/mtd/Config.in
arch/i386/kernel/setup.c +56 -18

129 lines not on this page · raw message

include/asm-i386/boot_param.h +17 -1
diff -uNr linux-2.5.7.boot3.build/include/asm-i386/boot_param.h linux-2.5.7.boot3.proto/include/asm-i386/boot_param.h
@@ -76,7 +76,23 @@
 	__u32 cmd_line_ptr;			/* 0x228 */
 	/* 2.03+ */
 	__u32 ramdisk_max;			/* 0x22c */
-	__u8  reserved15[0x2d0 - 0x230];	/* 0x230 */
+	/* 2.04+ */
+	__u16 entry32_off;			/* 0x230 */
+	__u16 internal_cmdline_off;		/* 0x232 */
+	__u32 low_base;				/* 0x234 */
+	__u32 low_memsz;			/* 0x238 */
+	__u32 low_filesz;			/* 0x23c */
+	__u32 real_base;			/* 0x240 */
+	__u32 real_memsz;			/* 0x244 */
+	__u32 real_filesz;			/* 0x248 */
+	__u32 high_base;			/* 0x24C */
+	__u32 high_memsz;			/* 0x250 */
+	__u32 high_filesz;			/* 0x254 */
+	/* entry32 values (for internal kernel use only) */
+	__u32 entry32_used;			/* 0x258 */
+	__u32 entry32_16_off;			/* 0x25c */
+	struct initial_regs32 regs;		/* 0x260 */
+	__u8  reserved15[0x2d0 - 0x280];	/* 0x280 */
 	struct e820entry e820_map[E820MAX];	/* 0x2d0 */
 						/* 0x550 */
 } __attribute__((packed));
#1 lore raw
Quoted 2 lines · Eric W. Biederman

In imitation of the arm and ppc ports a CONFIG_CMDLINE option is also implemented.

Just wondering, why didn't you do it with a CONFIG_CMDLINE_BOOL/CONFIG_CMDLINE set of options? The way you did it, I _think_ you can't actually get a help msg from 'config' or 'oldconfig', you'll just set the commandline to '?'.

Also, on current PPC, if we have a compiled-in commandline we put it in arch/ppc/kernel/setup.c and allow it to be overridden. This even makes it semi-useful outside of the self-containted {b,}zImage situation.

Signature · 2 lines
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
#2 lore raw
In reply to Eric W. Biederman
Followup to:  <[email protected]>
By author:    [email protected] (Eric W. Biederman)
In newsgroup: linux.dev.kernel
Quoted 5 lines

+0240/4 2.04+ real_base 0x90000
+0244/4 2.04+ real_memsz Memory used @ 0x90000
+0248/4 2.04+ real_filesz Precomputed data for @ 0x90000

[...]

Quoted 36 lines
Documentation/i386/boot.txt +35 -0
+
+  low_base, low_memsz, low_filesz, 
+  real_base, real_memsz, real_filesz, 
+  high_base, high_memsz, high_filesz:
+	Up to this point building a zImage or a bzImage has been a very lossy
+	process.  The introduction of these six variables attempts to
+	rectify that situation.  They document exactly which pieces
+	of memory, the kernel uses during the boot process, and they
+	indicate exactly how large the various data segments of the
+	kernel are.  It is now possible to create a lossless
+	transformation to and from a static ELF executable.
+
+	For a bzImage the low program segment describes the memory
+	from 4KB - 572KB the kernel decompressors uses as a temorary
+	buffer.  For a zImage the low program segment describes the
+	memory from 4KB - 572KB where the compressed kernel is loaded. 
+
+	For a bzImage the high program segment describes the memory
+	from 1MB on where the compressed kernel is loaded, where
+	decompression takes place, where the kernel initially runs,
+	and where the kernels bss segment is.  For a zImage the high
+	program segment describes the memory from 1MB on where the
+	kernel is decompressed to, where the kernel initial runs, and
+	where the kernels bss segment is located.
+
+	The real program segment describes the memory from 572KB
+	(0x90000) to 640KB (0xa0000) that the real mode kernel uses.
+	This region may be moved lower in memory if the BIOS has
+	reserved region for some other purpose.  When doing so
+	the following considerations should be applied.
+	
+		For a zImage you may move the real mode kernel now
+		lower than low_base + low_memsz.
+
+		For a bzImage if you move real_base below (low_base +

Documentation/i386/boot.txt line 302

Quoted 10 lines
Documentation/i386/boot.txt +10 -0
+		low_memsz) the following are the values of the other
+		variables.
+			low_memsz -= (low_base + low_memsz) - real_base
+			high_memsz += (low_base + low_memsz) - real_base
+		
+	
+	With this information it becomes safe to to statically
+	relocate the real mode kernel as well as dynamically relocate
+	it.  real_base should not be > 0x90000.
+

Whereas this is technically correct, it is dangerously misleading. Please rephrase this to remove any unnecessary references to the legacy address 0x90000.

-hpa

Signature · 3 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt	<[email protected]>
#3 lore raw
In reply to Eric W. Biederman
Quoted 9 lines · Tom Rini
Quoted 2 lines · Eric W. Biederman

In imitation of the arm and ppc ports a CONFIG_CMDLINE option is also implemented.

Just wondering, why didn't you do it with a CONFIG_CMDLINE_BOOL/CONFIG_CMDLINE set of options? The way you did it, I _think_ you can't actually get a help msg from 'config' or 'oldconfig', you'll just set the commandline to '?'.

I just tested it and oldconfig at least works. The overhead is exactly one byte.

Quoted 3 lines

Also, on current PPC, if we have a compiled-in commandline we put it in arch/ppc/kernel/setup.c and allow it to be overridden. This even makes it semi-useful outside of the self-containted {b,}zImage situation.

I currently allow a compiled in command line to be appended to. lilo also does this when you specify a command line, and to my knowledge all boot options prefer the last value specified so that should be good enough. As the decision happens in C code it isn't to hard to change either way.

Eric

#4 lore raw
In reply to Eric W. Biederman
Quoted 7 lines · Eric W. Biederman
Quoted 5 lines · Tom Rini
Quoted 2 lines · Eric W. Biederman

In imitation of the arm and ppc ports a CONFIG_CMDLINE option is also implemented.

Quoted 6 lines
Quoted 4 lines

Just wondering, why didn't you do it with a CONFIG_CMDLINE_BOOL/CONFIG_CMDLINE set of options? The way you did it, I _think_ you can't actually get a help msg from 'config' or 'oldconfig', you'll just set the commandline to '?'.

I just tested it and oldconfig at least works.

That's sort of supprising.

Quoted 9 lines
Quoted 3 lines

Also, on current PPC, if we have a compiled-in commandline we put it in arch/ppc/kernel/setup.c and allow it to be overridden. This even makes it semi-useful outside of the self-containted {b,}zImage situation.

I currently allow a compiled in command line to be appended to. lilo also does this when you specify a command line, and to my knowledge all boot options prefer the last value specified so that should be good enough. As the decision happens in C code it isn't to hard to change either way.

The way you're doing it now, you're sticking it into final image itself tho, and passing it along. If you're not going to be able to change the commandline, why not handle it all in C? eg:
strcpy(cmd_line, CONFIG_CMDLINE);
if ( passed a new commandline )
strcpy(cmd_line, new_cmdline);

Tho I have to admit I'm not sure where x86 ends up passing the commandline in now..

Signature · 2 lines
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
#5 lore raw
In reply to Eric W. Biederman
Quoted 8 lines · Tom Rini
Quoted 7 lines · Eric W. Biederman
Quoted 5 lines · Tom Rini
Quoted 2 lines · Eric W. Biederman

In imitation of the arm and ppc ports a CONFIG_CMDLINE option is also implemented.

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

Just wondering, why didn't you do it with a CONFIG_CMDLINE_BOOL/CONFIG_CMDLINE set of options? The way you did it, I _think_ you can't actually get a help msg from 'config' or 'oldconfig', you'll just set the commandline to '?'.

I just tested it and oldconfig at least works.

That's sort of supprising.

True. But I'm not complaining.

What I find funny is that with menuconfig I can't backspace when editing the command line.

Quoted 6 lines

The way you're doing it now, you're sticking it into final image itself tho, and passing it along. If you're not going to be able to change the commandline, why not handle it all in C? eg:
strcpy(cmd_line, CONFIG_CMDLINE);
if ( passed a new commandline )
strcpy(cmd_line, new_cmdline);

I actually put it at a location where you can edit it in the final image. Which is why I don't do it all in C. I have even documented this...

Eric

#6 lore raw
In reply to Eric W. Biederman
Quoted 51 lines · H. Peter Anvin
Followup to:  <[email protected]>
By author:    [email protected] (Eric W. Biederman)
In newsgroup: linux.dev.kernel
Quoted 5 lines

+0240/4 2.04+ real_base 0x90000
+0244/4 2.04+ real_memsz Memory used @ 0x90000
+0248/4 2.04+ real_filesz Precomputed data for @ 0x90000

[...]

Quoted 42 lines
Documentation/i386/boot.txt +42 -0
+
+  low_base, low_memsz, low_filesz, 
+  real_base, real_memsz, real_filesz, 
+  high_base, high_memsz, high_filesz:
+	Up to this point building a zImage or a bzImage has been a very lossy
+	process.  The introduction of these six variables attempts to
+	rectify that situation.  They document exactly which pieces
+	of memory, the kernel uses during the boot process, and they
+	indicate exactly how large the various data segments of the
+	kernel are.  It is now possible to create a lossless
+	transformation to and from a static ELF executable.
+
+	For a bzImage the low program segment describes the memory
+	from 4KB - 572KB the kernel decompressors uses as a temorary
+	buffer.  For a zImage the low program segment describes the
+	memory from 4KB - 572KB where the compressed kernel is loaded. 
+
+	For a bzImage the high program segment describes the memory
+	from 1MB on where the compressed kernel is loaded, where
+	decompression takes place, where the kernel initially runs,
+	and where the kernels bss segment is.  For a zImage the high
+	program segment describes the memory from 1MB on where the
+	kernel is decompressed to, where the kernel initial runs, and
+	where the kernels bss segment is located.
+
+	The real program segment describes the memory from 572KB
+	(0x90000) to 640KB (0xa0000) that the real mode kernel uses.
+	This region may be moved lower in memory if the BIOS has
+	reserved region for some other purpose.  When doing so
+	the following considerations should be applied.
+	
+		For a zImage you may move the real mode kernel now
+		lower than low_base + low_memsz.
+
+		For a bzImage if you move real_base below (low_base +
+		low_memsz) the following are the values of the other
+		variables.
+			low_memsz -= (low_base + low_memsz) - real_base
+			high_memsz += (low_base + low_memsz) - real_base
+		
+	
+	With this information it becomes safe to to statically
Quoted 8 lines

Documentation/i386/boot.txt line 302

Quoted 4 lines
Documentation/i386/boot.txt +3 -0
+	relocate the real mode kernel as well as dynamically relocate
+	it.  real_base should not be > 0x90000.
+

Whereas this is technically correct, it is dangerously misleading. Please rephrase this to remove any unnecessary references to the legacy address 0x90000.

It's not legacy it is still the optimal address. The amount of memory required to load the kernel is directly related to how much low memory the decompresser can use. If you move it lower you need more memory above 1MB to load the kernel.

To load the real mode code at < 0x90000 requires a fairly sophisticated bootloader. You have already convinced me how it is bad for bootloaders to make BIOS calls on behalf of the kernel, and how bad it is to need bootloaders to change. So unless the real mode code does the int 12 call itself and relocates itself as high as it can go I really don't see the default load address changing. And I am documenting the default load address.

I'd like to change the way we do this, so I'm going to stare at this problem a little bit more. Changing the default load address and still being able to compute how much memory the kernel is going to use is a challenge.

Eric

#7 lore raw
In reply to Eric W. Biederman
Quoted 6 lines · Eric W. Biederman

It's not legacy it is still the optimal address. The amount of memory required to load the kernel is directly related to how much low memory the decompresser can use. If you move it lower you need more memory above 1MB to load the kernel.

Quoted 8 lines

To load the real mode code at < 0x90000 requires a fairly sophisticated bootloader. You have already convinced me how it is bad for bootloaders to make BIOS calls on behalf of the kernel, and how bad it is to need bootloaders to change. So unless the real mode code does the int 12 call itself and relocates itself as high as it can go I really don't see the default load address changing. And I am documenting the default load address.

No, that's not how that works in reality. In practice, the boot loader picks the lowest address it can practically use, in order to minimize the conventional memory ceiling. For example, PXELINUX always loads at 0x50000, simply because odds that you have a PXE stack and can use 0x90000 is about zero to none. In fact, these days there are enough BIOSes that load stuff in the high part of memory that using 0x90000 is actively dangerous and **needs to be avoided**. Theoretically, you're right; it adds a very small amount of memory to the decompression. If that matters, there is actually a very easy way to deal with it: for any boot loader there is a Lowest Usable Address (conventional memory ceiling). You can use INT 12h and adjust the load address all the way up to 0x90000 if the conventional memory ceiling permits; this usually is something like five lines of assembly.

Quoted 4 lines

I'd like to change the way we do this, so I'm going to stare at this problem a little bit more. Changing the default load address and still being able to compute how much memory the kernel is going to use is a challenge.

There can't be a "default load address". 0x90000 is actively dangerous and trying to encourage it for anything than legacy kernels is WRONG. If you can't handle this, then you need to go back to the drawing board.

-hpa

#8 lore raw
In reply to Eric W. Biederman
Quoted 5 lines · H. Peter Anvin

Eric W. Biederman wrote:

No, that's not how that works in reality. In practice, the boot loader picks the lowest address it can practically use, in order to minimize the conventional memory ceiling.

A very sane thing to do. Which makes the requirements/assumptions in misc.c broken.

Quoted 3 lines

For example, PXELINUX always loads at 0x50000, simply because odds that you have a PXE stack and can use 0x90000 is about zero to none.

O.k. Than PXELINUX does what I would expect, instead of what seems to be requested by the boot.txt

Quoted 9 lines

In
fact, these days there are enough BIOSes that load stuff in the high part of memory that using 0x90000 is actively dangerous and **needs to be avoided**. Theoretically, you're right; it adds a very small amount of memory to the decompression. If that matters, there is actually a very easy way to deal with
it: for any boot loader there is a Lowest Usable Address (conventional memory ceiling). You can use INT 12h and adjust the load address all the way up to 0x90000 if the conventional memory ceiling permits; this usually is something like five lines of assembly.

Unless the fact is only recorded in the e820 memory map...

Quoted 8 lines
Quoted 4 lines

I'd like to change the way we do this, so I'm going to stare at this problem a little bit more. Changing the default load address and still being able to compute how much memory the kernel is going to use is a challenge.

There can't be a "default load address". 0x90000 is actively dangerous and trying to encourage it for anything than legacy kernels is WRONG. If you can't handle this, then you need to go back to the drawing board.

I agree. But I do think being able to hard code the load address is a very good thing.

After digesting the requirements I plan on having setup.S call int 12h (so the information is available), and then having misc.c relocate the real mode code, and the command line, out of the way, of it's decompression buffer. This removes the need for bootloaders to make a tradeoff between memory use efficiency and reliability.

This should give me about 630KB on machines designed to run DOS, where
this matters. Better than the current best of 572KB, with the real
mode code @ 0x90000.

And when your total size is 1-4MB. +-640KB is a significant change.

Eric

#9 lore raw
In reply to Eric W. Biederman
Quoted 15 lines · Eric W. Biederman
Quoted 4 lines

There can't be a "default load address". 0x90000 is actively dangerous and trying to encourage it for anything than legacy kernels is WRONG. If you can't handle this, then you need to go back to the drawing board.

I agree. But I do think being able to hard code the load address is a very good thing.

After digesting the requirements I plan on having setup.S call int 12h (so the information is available), and then having misc.c relocate the real mode code, and the command line, out of the way, of it's decompression buffer. This removes the need for bootloaders to make a tradeoff between memory use efficiency and reliability.

Quoted 6 lines

This should give me about 630KB on machines designed to run DOS, where
this matters. Better than the current best of 572KB, with the real
mode code @ 0x90000.

And when your total size is 1-4MB. +-640KB is a significant change.

Agreed. Note that so far putting the real mode code *above* 0x90000 is completely untested. It *should* work with boot protocol 2.02 support; it almost certainly *does not* work with earlier boot protocols (due to the "move it back to 0x90000" braindamage.)

-hpa

#10 lore raw
In reply to Eric W. Biederman
Quoted 4 lines · H. Peter Anvin

Agreed. Note that so far putting the real mode code *above* 0x90000 is completely untested. It *should* work with boot protocol 2.02 support; it almost certainly *does not* work with earlier boot protocols (due to the "move it back to 0x90000" braindamage.)

:)

When I got to thinking about this the biggest savings in memory usage I can implement is having misc.c relocate it's compressed data before decompression, instead of having it relocate the decompressed data afterwards. Ugh more heavy lifting to do.

Running the real mode code above 0x90000 is likely to happen in one of my test cases.
- Load the kernel under a normal BIOS.
- Enter through the 32bit entry point
- Decompress the kernel
- Realize we need to do 16bit BIOS calls
- Renter through the 16bit entry point.

Sounds like fun.

I suspect the reason I didn't consider moving the real mode address lower is that (a) I haven't run into the problems with 0x900000 and
(b) under etherboot I can easily load the real mode code at 0x1000, which makes it look absolutely absurd. And won't work because of the current misc.c code.

Eric

#11 lore raw
In reply to Eric W. Biederman
Quoted 4 lines · H. Peter Anvin

Agreed. Note that so far putting the real mode code *above* 0x90000 is completely untested. It *should* work with boot protocol 2.02 support; it almost certainly *does not* work with earlier boot protocols (due to the "move it back to 0x90000" braindamage.)

Having misc.c move the real mode code and the command line above 0x90000 avoids this issue. I relocate the command line so cmd_line_ptr must be written. This looses track of exactly which protocol version the bootloader was using, but it doesn't matter as all the kernel cares about is being able to find it's command line, and the command line can still be found. For code coming in the new 32bit entry point we are above protocol version 2.02 when the problem was fixed.

I have now solved the space/reliability tradeoff with belt and suspenders.

I have modified misc.c to do an inplace decompression. This means I use approximately 78KB of memory below 1MB and 8 bytes more than the decompressesed kernel above 1MB. And if I have to except for the 5KB of real mode code I can put everything above 1MB. The 78KB is 5KB real mode code 10KB decompressor code 61KB bss.

The change is especially nice because now in my worst case of only using 5KB real mode data, I do better than the best case with previous kernels (assuming it isn't a zImage). And if I ever get the bootmem bootmap fixed I can put initrds down at 2.6MB and not have to worry about them getting stomped :)

Eric

#12 lore raw
In reply to Eric W. Biederman
Quoted 23 lines · Eric W. Biederman
Quoted 5 lines

Agreed. Note that so far putting the real mode code *above* 0x90000 is completely untested. It *should* work with boot protocol 2.02 support; it almost certainly *does not* work with earlier boot protocols (due to the "move it back to 0x90000" braindamage.)

Having misc.c move the real mode code and the command line above 0x90000 avoids this issue. I relocate the command line so cmd_line_ptr must be written. This looses track of exactly which protocol version the bootloader was using, but it doesn't matter as all the kernel cares about is being able to find it's command line, and the command line can still be found. For code coming in the new 32bit entry point we are above protocol version 2.02 when the problem was fixed.

I have now solved the space/reliability tradeoff with belt and suspenders.

I have modified misc.c to do an inplace decompression. This means I use approximately 78KB of memory below 1MB and 8 bytes more than the decompressesed kernel above 1MB. And if I have to except for the 5KB of real mode code I can put everything above 1MB. The 78KB is 5KB real mode code 10KB decompressor code 61KB bss.

Quoted 6 lines

The change is especially nice because now in my worst case of only using 5KB real mode data, I do better than the best case with previous kernels (assuming it isn't a zImage). And if I ever get the bootmem bootmap fixed I can put initrds down at 2.6MB and not have to worry about them getting stomped :)

Nice.