x86 Boot enhancements, boot params 1/11

x86 Boot enhancements, boot params 1/11

Post by Eric W. Biederm » Sat, 04 May 2002 00:00:13



This is the first in a set of 11 patches that enhance the x86 boot
process.  

This takes work that I am using everyday and makes a good version
of it that can be included in the kernel.  

The major themes are:
- cleanups
- setup.c splitting to handle multiple BIOS flavors.
   - Needed to handle LinuxBIOS.
- a 32bit entry point.
   - Needed if you don't have a traditional x86 BIOS
   - Needed for reliable linux booting linux patches until
     the kernel can be fixed.  On some systems running linux trashes
     he BIOS.
- bean counting of the bootimage.  
   - Needed for computing the lowest possible ramdisk address about
     2.6M with my test kernels.
   - Useful for knowing what is actually happening in the boot
     process.

If you'd like I'll rip out support for zImages.

The last time I posted this code I heard no criticism of it.  
Since last time I posted this code I have made 2 functional changes.
- make clean now deletes the bzElf images
- The linker script now reserves room for the bootmem bitmap,
  and with that information I have enough information to load
  the ramdisk immediately after the kernel in ram.

#1  boot.boot_params
============================================================
- Introduce asm-i386/boot_param.h and struct boot_params
- Implement struct boot_params in misc.c & setup.c

This removes a lot of magic macros and by keeping all of the
boot parameters in a structure it becomes much easier to track
which boot_paramters we have and where they live.  Additionally
this keeps the names more uniform making grepping easier.

#2  boot.vmlinuxlds
============================================================
- i386/Makefile remove bogus linker command line of -e stext
- Fix vmlinux.lds so vmlinux knows it loads at 0x100000 (1MB)
- Fix vmlinux.lds so we correctly use startup_32 for our entry point
- Fix vmlinux.lds so we reserve the bootmem bitmap at the end
  of the bss segment.
- Make startup_32 global

#3  boot.spring-cleaning
============================================================
Some pieces of code only make sense if we are a bzImage or
a zImage.  Since size is relatively important use conditional
compilation to select between the two.

Plus this clearly marks dead code that we can kill we we drop
support for the zImage format.

#4  boot.syntax
============================================================
  All changes are syntactic the generated code is not affected.

- e820.h Add define E820ENTRY_SIZE

- boot.h Add defines for address space divisions.

- Add define KERNEL_START in setup.S so if I need this
  value more than once it is easy to get at.

#5  boot.heap
============================================================
Modify video.S so that mode_list is also allocated from
the boot time heap.  This probably saves a little memory,
and makes a compiled in command line a sane thing to implement.

- Made certain we don't overwrite code with the E820_MAP
  Previously we actually reserved to much memory.

- Changed the lables around the setup.S to _setup && _esetup

The Effective the bootsector size is reduced by 200 bytes.

#6  boot.clean_32bit_entries
============================================================
In general allow any kernel entry point to work given any set of
initial register values, while saving the original registers
values so the C code can do something with it if we desire.

- trampoline.S fix comments, and enter the kernel at
  secondary_startup_32 instead of startup_32
- trampoline.S fix gdt_48 to have the correct gdt limit
- Save all of the registers we get from any 32bit entry point,
  and don't assume they have any particular value.
- head.S split up startup_32
  - secondary_startup_32 handles the SMP case
  - move finding the command line to startup.c
  - Don't copy the kernel parameters to the initial_zero_page,
    instead just pass setup.c where they are located.
- Seperate the segments used by setup.S from the rest of the kernel.
  This way bootloader can continue to make assumptions about
  which segments setup.S uses while the rest of the kernel
  can do whatever is convinient.
- Move boot specific defines into boot.h

#7  boot.footprint
============================================================
Solve the space/reliability tradeoff misc.c asks bootloaders
to make, with belt and suspenders.

- modify misc.c to relocate the real mode code to maximize low
  memory usage.
- modify misc.c to do inplace decompression
- modify setup.S to query int12 to get the low memory size
- Introduce STAY_PUT flag for bootloaders that don't pass a
  command_line but still don't need the bootsector to relocate
  itself.

The kernel now uses approximately 78KB of memory below 1MB and 8 bytes
more than the decompressesed kernel above 1MB.  And if required
everything except the 5KB of real mode code can go above 1MB.

The 78KB below 1MB 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).  With the the bootmem bitmap
reserved in vmlinux.lds I can put initrds down at 2.6MB and not have
to worry about them getting stomped :)

#8  boot.build
============================================================
Rework the actual build/link step for kernel images.  
- remove the need for objcopy
- Kill the ROOT_DEV Makefile variable, the implementation
  was only half correct and there are much better ways
  to specify your root device than modifying the kernel Makefile.
- Don't loose information when the executable is built

Except for a few extra fields in setup.S the binary image
is unchanged.

#9  boot.proto
============================================================
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 parameters between those that
     are compiled in or specified by the bootloader and
     those that are queried from the BIOS.

#10  boot.linuxbios
============================================================
Support for reading information from the linuxbios table.
For now I just get the memory size more to come as things
evolve.

#11  boot.elf
============================================================
Add support for generating an ELF executable kernel.  External
tools are only needed now to manipulate the command line,
and to add a ramdisk.  For netbooting this is very handy.

To revert to a bzImgae you simply strip off the the ELF header.
This should keep the kinds of kernel images floating around low.

diff -uNr linux-2.5.12/Documentation/i386/zero-page.txt linux-2.5.12.boot.boot_params/Documentation/i386/zero-page.txt
--- linux-2.5.12/Documentation/i386/zero-page.txt       Mon Aug 30 11:47:02 1999
+++ linux-2.5.12.boot.boot_params/Documentation/i386/zero-page.txt      Wed May  1 09:38:29 2002
@@ -9,7 +9,11 @@
   arch/i386/boot/video.S
   arch/i386/kernel/head.S
   arch/i386/kernel/setup.c
-
+
+See include/asm-i386/boot_param.h a structure is kept there with
+uptodate information.  The kernel no longer copies this information
+into the empty zero page, but instead uses it directly.
+

 Offset Type            Description
 ------  ----           -----------
@@ -65,7 +69,7 @@
 0x21c  unsigned long   INITRD_SIZE, size in bytes of ramdisk image
 0x220  4 bytes         (setup.S)
 0x224  unsigned short  setup.S heap end pointer
-0x2d0 - 0x600          E820MAP
+0x2d0 - 0x550          E820MAP

 0x800  string, 2K max  COMMAND_LINE, the kernel commandline as
                        copied using CL_OFFSET.
diff -uNr linux-2.5.12/arch/i386/boot/compressed/misc.c linux-2.5.12.boot.boot_params/arch/i386/boot/compressed/misc.c
--- linux-2.5.12/arch/i386/boot/compressed/misc.c       Mon Nov 12 10:59:43 2001
+++ linux-2.5.12.boot.boot_params/arch/i386/boot/compressed/misc.c      Wed May  1 09:38:29 2002
@@ -13,6 +13,9 @@
 #include <linux/vmalloc.h>
 #include <linux/tty.h>
 #include <asm/io.h>
+#include <linux/apm_bios.h>
+#include <asm/e820.h>
+#include <asm/boot_param.h>

 /*
  * gzip declarations
@@ -84,13 +87,9 @@
 /*
  * This is set up by the setup-routine at boot-time
  */
-static unsigned char *real_mode; /* Pointer to real-mode data */
-
-#define EXT_MEM_K   (*(unsigned short *)(real_mode + 0x2))
-#ifndef STANDARD_MEMORY_BIOS_CALL
-#define ALT_MEM_K   (*(unsigned long *)(real_mode + 0x1e0))
-#endif
-#define SCREEN_INFO (*(struct screen_info *)(real_mode+0))
+static struct boot_params *real_mode; /* Pointer to real-mode data */
+/* Amount of memory in kilobytes, if it isn't set assume enough */
+static unsigned long mem_k = 0xFFFFFFFF;

 extern char input_data[];
 extern int input_len;
@@ -176,8 +175,8 @@
        int x,y,pos;
        char c;

-       x = SCREEN_INFO.orig_x;
-       y = SCREEN_INFO.orig_y;
+       x = real_mode->screen.info.orig_x;
+       y = real_mode->screen.info.orig_y;

        while ( ( c = *s++ ) != '\0' ) {
                if ( c == '\n' ) {
@@ -198,8 +197,8 @@
                }
        }

-       SCREEN_INFO.orig_x = x;
-       SCREEN_INFO.orig_y = y;
+       real_mode->screen.info.orig_x = x;
+       real_mode->screen.info.orig_y = y;

        pos = (x + cols * y) * 2;       /* Update cursor position */
        outb_p(14, vidport);
@@ -208,6 +207,20 @@
        outb_p(0xff & (pos >> 1), vidport+1);
 }

+static void vid_puts_init(void)
+{
+       if (real_mode->screen.info.orig_video_mode == 7) {
+               vidmem = (char *) 0xb0000;
+               vidport = 0x3b4;
+       } else {
+               vidmem = (char *) 0xb8000;
+               vidport = 0x3d4;
+       }
+      
+       lines = real_mode->screen.info.orig_video_lines;
+       cols = real_mode->screen.info.orig_video_cols;
+}
+
 static void* memset(void* s, int c, size_t n)
 {
        int i;
@@ -307,11 +320,7 @@

 static void setup_normal_output_buffer(void)
 {
-#ifdef STANDARD_MEMORY_BIOS_CALL
-       if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
-#else
-       if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
...

read more »

 
 
 

x86 Boot enhancements, boot params 1/11

Post by Eric W. Biederm » Sat, 04 May 2002 00:00:15


diff -uNr linux-2.5.12.boot.boot_params/arch/i386/Makefile linux-2.5.12.boot.vmlinuxlds/arch/i386/Makefile
--- linux-2.5.12.boot.boot_params/arch/i386/Makefile    Thu Apr 12 13:20:31 2001

 LD=$(CROSS_COMPILE)ld -m elf_i386
 OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
-LDFLAGS=-e stext
+LDFLAGS=
 LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)

 CFLAGS += -pipe
diff -uNr linux-2.5.12.boot.boot_params/arch/i386/kernel/head.S linux-2.5.12.boot.vmlinuxlds/arch/i386/kernel/head.S
--- linux-2.5.12.boot.boot_params/arch/i386/kernel/head.S       Mon Apr 29 00:17:11 2002

  *
  * On entry, %esi points to the real-mode code as a 32-bit pointer.
  */
-startup_32:
+ENTRY(startup_32)
 /*
  * Set segments to known values
  */
diff -uNr linux-2.5.12.boot.boot_params/arch/i386/vmlinux.lds linux-2.5.12.boot.vmlinuxlds/arch/i386/vmlinux.lds
--- linux-2.5.12.boot.boot_params/arch/i386/vmlinux.lds Sun Mar 10 20:09:08 2002

  */
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
-ENTRY(_start)
+physical_startup_32 = startup_32 - 0xC0000000;
+ENTRY(physical_startup_32)
+PHDRS
+{
+       text PT_LOAD AT(0x100000);
+
+}
 SECTIONS
 {

        *(.text)
        *(.fixup)
        *(.gnu.warning)
-       } = 0x9090
+       } :text = 0x9090

   _etext = .;                  /* End of text section */

   __bss_start = .;             /* BSS */
   .bss : {
        *(.bss)
+        _end = . ;
+       /* Reserve space for the bootmem bitmap,
+        * With a start at 0xC0000000 this is just 32k in the worst case.
+        *
+        * Ideally this would be in an initdata segment but that causes
+        * problems with memory being reserved twice.
+        */
+       . = ALIGN(4096);
+       . = . + 32768;
        }
-  _end = . ;

   /* Sections to be discarded */
   /DISCARD/ : {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

x86 Boot enhancements, boot params 1/11

Post by Pavel Mache » Tue, 07 May 2002 19:00:09


Hi!

Quote:> #5  boot.heap
> ============================================================
> Modify video.S so that mode_list is also allocated from
> the boot time heap.  This probably saves a little memory,
> and makes a compiled in command line a sane thing to implement.

Do you see easy way to pass video mode used to kernel? S3 suspend support
is going to need that..
                                                                Pavel
--
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

x86 Boot enhancements, boot params 1/11

Post by Eric W. Biederm » Tue, 07 May 2002 19:30:09



> Hi!

> > #5  boot.heap
> > ============================================================
> > Modify video.S so that mode_list is also allocated from
> > the boot time heap.  This probably saves a little memory,
> > and makes a compiled in command line a sane thing to implement.

> Do you see easy way to pass video mode used to kernel? S3 suspend support
> is going to need that..

Do you mean something other than the vga= command line option?
Which actually just sets a 16bit mode in the kernel parameter structure.

Eric
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

x86 Boot enhancements, boot params 1/11

Post by Eric W. Biederm » Wed, 08 May 2002 03:10:07



> Hi!

> > > > #5  boot.heap
> > > > ============================================================
> > > > Modify video.S so that mode_list is also allocated from
> > > > the boot time heap.  This probably saves a little memory,
> > > > and makes a compiled in command line a sane thing to implement.

> > > Do you see easy way to pass video mode used to kernel? S3 suspend support
> > > is going to need that..

> > Do you mean something other than the vga= command line option?
> > Which actually just sets a 16bit mode in the kernel parameter structure.

> In case of vga=ask, it is kernel that gets number from the user,
> right?

Right.

Quote:> I'd need to know what mode was actually selected, so I can restore it
> after S3 resume.

I guess that works.  In this case it makes sense for the kernel to
store it in the same variable the video mode is specified in.  This
may require an extra store but it should be trivial to implement.

How are you handling the case of X and friends?  Are you making
certain to switch to kernel controlled vt?

My hunch is that this is a decent argument for real framebuffer drivers
in the kernel.  But that is a separate problem.

Eric
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/